【持续更新】总结:C++开发时积累的一些零碎的东西
Makefile template update:
1.调整了顺序,把经常编辑的部分集中在了Makefile的下半部分
2.进行了一些重构实现更多的代码复用,见红色高亮部分,LIBPATH_ALL和LIBFILE_ALL的引入简化了LINK命令,思想与HEADER_PATH一样,你需要多少就往里写多少,你不需要,就留空,从而避免了直接去修改LINK或者COMPILE命令。AR_OBJ和LINK_OBJ也是为了简化LIB或者LINK命令
NMAKE
# configurations # Flag to choose targets to build, to disable debug, just comment out the following line or !UNDEF DEBUG
# Normally when debugging, you don't want to generate lib files, to do that, !UNDEF LIB_GEN as you can see below # By default, DEBUG is on. To turn it off, use 'nmake DEBUG=0 ', eg. 'nmake DEBUG=0' to build the product
# and 'nmake DEBUG=0 clean' to clean the product.
DEBUG = 1 # src, obj, bin and lib folders paths
PATH_SRC = src
PATH_OBJ = obj
PATH_BIN = bin
PATH_LIB = lib # headers in this project PATH_INC = include # compiler
CC = cl
# linker
LINK = link # options
EHSC = /EHsc
COMPILATION_ONLY = /c
C_OUT = /Fo:
L_OUT = /OUT: # compiler & linker debug options:
!IF $(DEBUG)==1
C_DEBUG = /Zi
L_DEBUG = /DEBUG
!ELSE
# No debug flags
!ENDIF # libraries
LIBPATH_REPLACEALL = /LIBPATH:E:\cppwksp\thinkingincppvol2\demo\96-ReplaceAll\lib
LIBFILE_REPLACEALL = ReplaceAll.lib
HEADER_REPLACEALL = /I E:\cppwksp\thinkingincppvol2\demo\96-ReplaceAll\include HEADER_REQUIRE = /I E:\cppwksp\thinkingincppvol2\demo\570-require\include HEADER_BOOST = /I F:\ZJ\tools\cpp_libs\boost_1_57_0 HEADER_URAND = /I E:\cppwksp\thinkingincppvol2\demo\176-Urand\include HEADER_APPLYSEQUENCE = /I E:\cppwksp\thinkingincppvol2\demo\195-ApplySequence\include HEADER_PURGE = /I E:\cppwksp\thinkingincppvol2\demo\392-purge\include HEADER_GENERATORS = /I E:\cppwksp\thinkingincppvol2\demo\259-FunctionObjects\include
LIBPATH_GENERATORS = /LIBPATH:E:\cppwksp\thinkingincppvol2\demo\259-FunctionObjects\lib
LIBFILE_GENERATORS = Generators.lib HEADER_NUMSTRINGGEN = /I E:\cppwksp\thinkingincppvol2\demo\268-NumStringGen\include
LIBPATH_NUMSTRINGGEN = /LIBPATH:E:\cppwksp\thinkingincppvol2\demo\268-NumStringGen\lib
LIBFILE_NUMSTRINGGEN = NumStringGen.lib HEADER_THIS = /I $(PATH_INC) # headers & library files HEADER_PATH = $(HEADER_THIS) $(HEADER_NUMSTRINGGEN) LIBPATH_ALL = $(LIBPATH_NUMSTRINGGEN)
LIBFILE_ALL = $(LIBFILE_NUMSTRINGGEN) # Generate different targets - debug or product.
!IF $(DEBUG)==1 debug: $(PATH_BIN) $(PATH_OBJ) $(PATH_BIN)\test.exe # Flags to control cleanup
# PATH_BIN and BIN_GEN must appear in pairs, the same applies to PATH_LIB and LIB_GEN
BIN_GEN = TRUE !ELSE product: $(PATH_BIN) $(PATH_OBJ) $(PATH_BIN)\test.exe BIN_GEN = TRUE # LIB_GEN = TRUE !ENDIF # targets # Object files for archiver (LIB.exe or ar)
AR_OBJ =
# Object files for linker
LINK_OBJ = $(PATH_OBJ)\ComposeFinal.obj $(PATH_BIN)\test.exe: $(LINK_OBJ)
$(LINK) $(L_DEBUG) $(LIBPATH_ALL) $(L_OUT)$(PATH_BIN)\test.exe $(LINK_OBJ) $(LIBFILE_ALL) $(PATH_OBJ)\ComposeFinal.obj: $(PATH_SRC)\ComposeFinal.cpp
$(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) $(PATH_SRC)\ComposeFinal.cpp $(C_OUT)$(PATH_OBJ)\ComposeFinal.obj # folders $(PATH_BIN):
mkdir $(PATH_BIN) $(PATH_LIB):
mkdir $(PATH_LIB) $(PATH_OBJ):
mkdir $(PATH_OBJ) # clean .PHONY: clean
clean:
!IFDEF LIB_GEN
-rmdir /s /q $(PATH_LIB)
!ENDIF
!IFDEF BIN_GEN
-rmdir /s /q $(PATH_BIN)
!ENDIF
-rmdir /s /q $(PATH_OBJ)
!IF $(DEBUG)==1
-del *.pdb
!ENDIF
GNU-MAKE
# configurations # Flag to choose targets to build, to disable debug, just comment out the following line or !UNDEF DEBUG
# Normally when debugging, you don't want to generate lib files, to do that, comment out DEBUG so LIB_GEN will not be defined. # By default, DEBUG is on. To turn it off, use 'make DEBUG=0 ', eg. 'make DEBUG=0' to build the product
# and 'make DEBUG=0 clean' to clean the product.
DEBUG = 1 # src, obj, bin and lib folders paths
PATH_SRC = src
PATH_OBJ = obj
PATH_BIN = bin
PATH_LIB = lib # headers in this project PATH_INC = include # compiler
CC = g++
# linker
LINK = g++ # options
COMPILATION_ONLY = -c
C_OUT = -o
L_OUT = -o # compiler & linker debug options:
ifeq ($(DEBUG),1)
C_DEBUG = -g
L_DEBUG = -ggdb
else
# No debug flags
endif # Some of ZThread's code are old-fashioned and may not be accepted by modern compilers
FPERMISSIVE = -fpermissive # libraries
LIBPATH_ZTHREAD = -L/home/lqr/Documents/ZThread-2.3.2/lib
LIBFILE_ZTHREAD = -lZThread -lpthread LIBPATH_SYNC_OUTPUT = -L/home/lqr/Documents/ZJ/531-SynchronizedOutput-linux/lib
LIBFILE_SYNC_OUTPUT = -lSynchronizedOutput HEADER_SYNC_OUTPUT = -I/home/lqr/Documents/ZJ/531-SynchronizedOutput-linux/include HEADER_ZTHREAD = -I/home/lqr/Documents/ZThread-2.3.2/include HEADER_APUE = -I/home/lqr/Documents/ZJ/APUE/include
LIBPATH_APUE = -L/home/lqr/Documents/ZJ/APUE/lib
LIBFILE_APUE = -lapue HEADER_UTIL = -I/home/lqr/Documents/ZJ/APUE/demo/Figure2.16-util-path_alloc/include
LIBPATH_UTIL = -L/home/lqr/Documents/ZJ/APUE/demo/Figure2.16-util-path_alloc/lib
LIBFILE_UTIL = -lutil HEADER_THIS = -I$(PATH_INC) # headers HEADER_PATH = $(HEADER_THIS) LIBPATH_ALL = $(LIBPATH_APUE)
LIBFILE_ALL = $(LIBFILE_APUE) # Generate different targets - debug or product.
ifeq ($(DEBUG),1) # you may remove $(PATH_BIN) and $(PATH_OBJ) if they are not needed
debug: $(PATH_BIN) $(PATH_OBJ) $(PATH_BIN)/test_exe # Flags to control cleanup
# If PATH_BIN is created, then you must define BIN_GEN, otherwise
# the cleanup logic will not delete PATH_BIN, the same applies
# to PATH_LIB
# In other words, PATH_BIN and BIN_GEN must appear in pair,
# the same applies to PATH_LIB and LIB_GEN BIN_GEN = TRUE else # you may add $(PATH_LIB) if it's necessary
product: $(PATH_BIN) $(PATH_OBJ) $(PATH_BIN)/test_exe BIN_GEN = TRUE endif # targets # Object files for archiver (LIB.exe or ar)
AR_OBJ =
# Object files for linker
LINK_OBJ = $(PATH_OBJ)/demo.o $(PATH_BIN)/test_exe: $(LINK_OBJ)
$(LINK) $(L_DEBUG) $(LIBPATH_ALL) $(L_OUT) $(PATH_BIN)/test_exe $(LINK_OBJ) $(LIBFILE_ALL) $(PATH_OBJ)/demo.o: $(PATH_SRC)/demo.cpp
$(CC) $(FPERMISSIVE) $(C_DEBUG) $(HEADER_PATH) $(COMPILATION_ONLY) $(PATH_SRC)/demo.cpp $(C_OUT) $(PATH_OBJ)/demo.o # folders $(PATH_BIN):
mkdir $(PATH_BIN) $(PATH_LIB):
mkdir $(PATH_LIB) $(PATH_OBJ):
mkdir $(PATH_OBJ) # clean .PHONY: clean
clean:
ifeq ($(LIB_GEN),TRUE)
-rm -r -f $(PATH_LIB)
endif
ifeq ($(BIN_GEN),TRUE)
-rm -r -f $(PATH_BIN)
endif
-rm -r -f $(PATH_OBJ)
--------------------------------------------------------------------------
Makefile template update:
NMAKE
# configurations # Flag to choose targets to build, to disable debug, just comment out the following line or !UNDEF DEBUG
# Normally when debugging, you don't want to generate lib files, to do that, !UNDEF LIB_GEN as you can see below # By default, DEBUG is on. To turn it off, use 'nmake DEBUG=0 <target-name>', eg. 'nmake DEBUG=0' to build the product
# and 'nmake DEBUG=0 clean' to clean the product.
DEBUG = 1 # src, obj, bin and lib folders paths
PATH_SRC = src
PATH_OBJ = obj
PATH_BIN = bin
PATH_LIB = lib # headers in this project PATH_INC = include # compiler
CC = cl
# linker
LINK = link # options
EHSC = /EHsc
COMPILATION_ONLY = /c
C_OUT = /Fo:
L_OUT = /OUT: # libraries
LIBPATH_REPLACEALL = /LIBPATH:E:\cppwksp\thinkingincppvol2\demo\96-ReplaceAll\lib
LIBFILE_REPLACEALL = ReplaceAll.lib
HEADER_REPLACEALL = /I E:\cppwksp\thinkingincppvol2\demo\96-ReplaceAll\include HEADER_REQUIRE = /I E:\cppwksp\thinkingincppvol2\demo\570-require\include HEADER_BOOST = /I F:\ZJ\tools\cpp_libs\boost_1_57_0 HEADER_URAND = /I E:\cppwksp\thinkingincppvol2\demo\176-Urand\include HEADER_APPLYSEQUENCE = /I E:\cppwksp\thinkingincppvol2\demo\195-ApplySequence\include HEADER_PURGE = /I E:\cppwksp\thinkingincppvol2\demo\392-purge\include HEADER_GENERATORS = /I E:\cppwksp\thinkingincppvol2\demo\259-FunctionObjects\include
LIBPATH_GENERATORS = /LIBPATH:E:\cppwksp\thinkingincppvol2\demo\259-FunctionObjects\lib
LIBFILE_GENERATORS = Generators.lib HEADER_THIS = /I $(PATH_INC) # headers HEADER_PATH = $(HEADER_THIS) $(HEADER_PURGE) # compiler & linker debug options:
!IF $(DEBUG)==1
C_DEBUG = /Zi
L_DEBUG = /DEBUG
!ELSE
# No debug flags
!ENDIF # Generate different targets - debug or product.
!IF $(DEBUG)==1 debug: $(PATH_BIN) $(PATH_OBJ) $(PATH_BIN)\test.exe # Flags to control cleanup
# PATH_BIN and BIN_GEN must appear in pairs, the same applies to PATH_LIB and LIB_GEN
BIN_GEN = TRUE LIB_GEN = TRUE
!UNDEF LIB_GEN !ELSE product: $(PATH_BIN) $(PATH_OBJ) $(PATH_BIN)\test.exe BIN_GEN = TRUE LIB_GEN = TRUE
!UNDEF LIB_GEN !ENDIF # targets $(PATH_BIN)\test.exe: $(PATH_OBJ)\MemFun2.obj
$(LINK) $(L_DEBUG) $(L_OUT)$(PATH_BIN)\test.exe $(PATH_OBJ)\MemFun2.obj $(PATH_OBJ)\MemFun2.obj: $(PATH_SRC)\MemFun2.cpp
$(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) $(PATH_SRC)\MemFun2.cpp $(C_OUT)$(PATH_OBJ)\MemFun2.obj # folders $(PATH_BIN):
mkdir $(PATH_BIN) $(PATH_LIB):
mkdir $(PATH_LIB) $(PATH_OBJ):
mkdir $(PATH_OBJ) # clean .PHONY: clean
clean:
!IFDEF LIB_GEN
-rmdir /s /q $(PATH_LIB)
!ENDIF
!IFDEF BIN_GEN
-rmdir /s /q $(PATH_BIN)
!ENDIF
-rmdir /s /q $(PATH_OBJ)
!IF $(DEBUG)==1
-del *.pdb
!ENDIF
GNU-MAKE
测试发现GNU-MAKE貌似不支持ifdef和ifndef(参考:http://www.gnu.org/software/make/manual/html_node/Conditionals.html#Conditionals),如果想表达nmake的ifdef/ifndef就用如下代码
ifeq ($(SOME_MACRO),)
# if SOME_MACRO isn't defined
endif ifneq($(SOME_MACRO),)
# if SOME_MACRO is defined
endif
例如
# configurations # Flag to choose targets to build, to disable debug, just comment out the following line or !UNDEF DEBUG
# Normally when debugging, you don't want to generate lib files, to do that, comment out DEBUG so LIB_GEN will not be defined. # By default, DEBUG is on. To turn it off, use 'make DEBUG=0 <target-name>', eg. 'make DEBUG=0' to build the product
# and 'make DEBUG=0 clean' to clean the product.
DEBUG = 1 # src, obj, bin and lib folders paths
PATH_SRC = src
PATH_OBJ = obj
PATH_BIN = bin
PATH_LIB = lib # headers in this project PATH_INC = include # compiler
CC = g++
# linker
LINK = g++ # options
COMPILATION_ONLY = -c
C_OUT = -o
L_OUT = -o # Some of ZThread's code are old-fashioned and may not be accepted by modern compilers
FPERMISSIVE = -fpermissive # libraries
LIBPATH_ZTHREAD = -L/home/lqr/Documents/ZThread-2.3.2/lib
LIBFILE_ZTHREAD = -lZThread -lpthread LIBPATH_SYNC_OUTPUT = -L/home/lqr/Documents/ZJ/531-SynchronizedOutput-linux/lib
LIBFILE_SYNC_OUTPUT = -lSynchronizedOutput HEADER_SYNC_OUTPUT = -I/home/lqr/Documents/ZJ/531-SynchronizedOutput-linux/include HEADER_ZTHREAD = -I/home/lqr/Documents/ZThread-2.3.2/include HEADER_APUE = -I/home/lqr/Documents/ZJ/APUE/include
LIBPATH_APUE = -L/home/lqr/Documents/ZJ/APUE/lib
LIBFILE_APUE = -lapue HEADER_THIS = -I$(PATH_INC) # headers HEADER_PATH = $(HEADER_THIS) $(HEADER_APUE) # compiler & linker debug options:
ifeq ($(DEBUG),1)
C_DEBUG = -g
L_DEBUG = -ggdb
else
# No debug flags
endif # Generate different targets - debug or product.
ifeq ($(DEBUG),1) # you may remove $(PATH_BIN) and $(PATH_OBJ) if they are not needed
debug: $(PATH_BIN) $(PATH_OBJ) $(PATH_BIN)/test_exe # Flags to control cleanup
# If PATH_BIN is created, then you must define BIN_GEN, otherwise
# the cleanup logic will not delete PATH_BIN, the same applies
# to PATH_LIB
# In other words, PATH_BIN and BIN_GEN must appear in pair,
# the same applies to PATH_LIB and LIB_GEN BIN_GEN = TRUE # LIB_GEN = TRUE else # you may add $(PATH_LIB) if it's necessary
product: $(PATH_BIN) $(PATH_OBJ) $(PATH_BIN)/test_exe BIN_GEN = TRUE endif # targets $(PATH_BIN)/test_exe: $(PATH_OBJ)/demo.o
$(LINK) $(L_DEBUG) $(LIBPATH_APUE) $(L_OUT) $(PATH_BIN)/test_exe $(PATH_OBJ)/demo.o $(LIBFILE_APUE) $(PATH_OBJ)/demo.o: $(PATH_SRC)/demo.cpp
$(CC) $(FPERMISSIVE) $(C_DEBUG) $(HEADER_PATH) $(COMPILATION_ONLY) $(PATH_SRC)/demo.cpp $(C_OUT) $(PATH_OBJ)/demo.o # folders $(PATH_BIN):
mkdir $(PATH_BIN) $(PATH_LIB):
mkdir $(PATH_LIB) $(PATH_OBJ):
mkdir $(PATH_OBJ) # clean .PHONY: clean
clean:
ifeq ($(LIB_GEN),TRUE)
-rm -r -f $(PATH_LIB)
endif
ifeq ($(BIN_GEN),TRUE)
-rm -r -f $(PATH_BIN)
endif
-rm -r -f $(PATH_OBJ)
ifeq ($(DEBUG),1)
# -del *.pdb
--------------------------------------------------------------------------
Makefile template update(GNU make version, you can also use ideas from this update on nmake makefiles):
1. Whether to create folder PATH_OBJ PATH_BIN PATH_LIB are determined by DEBUG, if DEBUG are not defined (note that unlike nmake, GNU make does not support undef, so you have to manually comment out DEBUG) you probably don't want to create PATH_LIB, so there's an ifdef block to check whether DEBUG is defined.
2. Unlike the previous version, the creation of PATH_OBJ, PATH_BIN, PATH_LIB are in the ifdef-DEBUG block rather than in the executable target so they're controled by DEBUG
Generally speaking, the structure of this version is a bit cleaner and better organized than the previous version.
# configurations # Flag to choose targets to build, to disable debug, just comment out the following line or !UNDEF DEBUG
# Normally when debugging, you don't want to generate lib files, to do that, comment out DEBUG so LIB_GEN will not be defined. DEBUG = TRUE # src, obj, bin and lib folders paths
PATH_SRC = src
PATH_OBJ = obj
PATH_BIN = bin
PATH_LIB = lib # headers in this project PATH_INC = include # compiler
CC = g++
# linker
LINK = g++ # options
COMPILATION_ONLY = -c
C_OUT = -o
L_OUT = -o # Some of ZThread's code are old-fashioned and may not be accepted by modern compilers
FPERMISSIVE = -fpermissive # libraries
LIBPATH_ZTHREAD = -L/home/lqr/Documents/ZThread-2.3.2/lib
LIBFILE_ZTHREAD = -lZThread -lpthread LIBPATH_SYNC_OUTPUT = -L/home/lqr/Documents/ZJ/531-SynchronizedOutput-linux/lib
LIBFILE_SYNC_OUTPUT = -lSynchronizedOutput HEADER_SYNC_OUTPUT = -I/home/lqr/Documents/ZJ/531-SynchronizedOutput-linux/include HEADER_ZTHREAD = -I/home/lqr/Documents/ZThread-2.3.2/include HEADER_THIS = -I$(PATH_INC) # headers HEADER_PATH = $(HEADER_THIS) $(HEADER_ZTHREAD) $(HEADER_SYNC_OUTPUT) # compiler & linker debug options:
ifdef DEBUG
C_DEBUG = -g
L_DEBUG = -ggdb
else
# No debug flags
endif # Generate different targets - debug or product.
ifdef DEBUG # you may remove $(PATH_BIN) and $(PATH_OBJ) if they are not needed
debug: $(PATH_BIN) $(PATH_OBJ) $(PATH_BIN)/test.exe # Flags to control cleanup
# If PATH_BIN is created, then you must define BIN_GEN, otherwise
# the cleanup logic will not delete PATH_BIN, the same applies
# to PATH_LIB
# In other words, PATH_BIN and BIN_GEN must appear in pair,
# the same applies to PATH_LIB and LIB_GEN BIN_GEN = TRUE # LIB_GEN = TRUE else # you may add $(PATH_LIB) if it's necessary
product: $(PATH_BIN) $(PATH_OBJ) $(PATH_BIN)/test.exe BIN_GEN = TRUE endif # targets $(PATH_BIN)/test.exe: $(PATH_OBJ)/main.o $(PATH_OBJ)/Chopstick.o $(PATH_OBJ)/Philosopher.o
$(LINK) $(L_DEBUG) $(LIBPATH_ZTHREAD) $(LIBPATH_SYNC_OUTPUT) $(L_OUT) $(PATH_BIN)/test.exe $(PATH_OBJ)/main.o $(PATH_OBJ)/Chopstick.o $(PATH_OBJ)/Philosopher.o $(LIBFILE_ZTHREAD) $(LIBFILE_SYNC_OUTPUT) $(PATH_OBJ)/main.o: $(PATH_SRC)/main.cpp $(PATH_INC)/Philosopher.h $(PATH_INC)/Chopstick.h
$(CC) $(FPERMISSIVE) $(C_DEBUG) $(HEADER_PATH) $(COMPILATION_ONLY) $(PATH_SRC)/main.cpp $(C_OUT) $(PATH_OBJ)/main.o $(PATH_OBJ)/Philosopher.o: $(PATH_SRC)/Philosopher.cpp $(PATH_INC)/Philosopher.h $(PATH_INC)/Chopstick.h
$(CC) $(FPERMISSIVE) $(C_DEBUG) $(HEADER_PATH) $(COMPILATION_ONLY) $(PATH_SRC)/Philosopher.cpp $(C_OUT) $(PATH_OBJ)/Philosopher.o $(PATH_OBJ)/Chopstick.o: $(PATH_SRC)/Chopstick.cpp $(PATH_INC)/Chopstick.h
$(CC) $(FPERMISSIVE) $(C_DEBUG) $(HEADER_PATH) $(COMPILATION_ONLY) $(PATH_SRC)/Chopstick.cpp $(C_OUT) $(PATH_OBJ)/Chopstick.o # folders $(PATH_BIN):
mkdir $(PATH_BIN) $(PATH_LIB):
mkdir $(PATH_LIB) $(PATH_OBJ):
mkdir $(PATH_OBJ) # clean .PHONY: clean
clean:
ifdef LIB_GEN
-rm -r -f $(PATH_LIB)
endif
ifdef BIN_GEN
-rm -r -f $(PATH_BIN)
endif
-rm -r -f $(PATH_OBJ)
ifdef DEBUG
# -del *.pdb
endif
The improved version for nmake is like the following. Download demo.
# configurations # Flag to choose targets to build, to disable debug, just comment out the following line or !UNDEF DEBUG
# Normally when debugging, you don't want to generate lib files, to do that, !UNDEF LIB_GEN as you can see below DEBUG = TRUE
#!UNDEF DEBUG # src, obj, bin and lib folders paths
PATH_SRC = src
PATH_OBJ = obj
PATH_BIN = bin
PATH_LIB = lib # headers in this project PATH_INC = include # compiler
CC = cl
# linker
LINK = link # options
EHSC = /EHsc
COMPILATION_ONLY = /c
C_OUT = /Fo:
L_OUT = /OUT: # libraries
LIBPATH_REPLACEALL = /LIBPATH:E:\cppwksp\thinkingincppvol2\demo\96-ReplaceAll\lib
LIBFILE_REPLACEALL = ReplaceAll.lib
HEADER_REPLACEALL = /I E:\cppwksp\thinkingincppvol2\demo\96-ReplaceAll\include HEADER_REQUIRE = /I E:\cppwksp\thinkingincppvol2\demo\570-require\include HEADER_BOOST = /I F:\ZJ\tools\cpp_libs\boost_1_57_0 HEADER_URAND = /I E:\cppwksp\thinkingincppvol2\demo\176-Urand\include HEADER_APPLYSEQUENCE = /I E:\cppwksp\thinkingincppvol2\demo\195-ApplySequence\include HEADER_PURGE = /I E:\cppwksp\thinkingincppvol2\demo\392-purge\include HEADER_THIS = /I $(PATH_INC) # headers HEADER_PATH = $(HEADER_THIS) # compiler & linker debug options:
!IFDEF DEBUG
C_DEBUG = /Zi
L_DEBUG = /DEBUG
!ELSE
# No debug flags
!ENDIF # Generate different targets - debug or product.
!IFDEF DEBUG debug: $(PATH_BIN) $(PATH_OBJ) $(PATH_BIN)\test.exe # Flags to control cleanup
# PATH_BIN and BIN_GEN must appear in pairs, the same applies to PATH_LIB and LIB_GEN
BIN_GEN = TRUE LIB_GEN = TRUE
!UNDEF LIB_GEN !ELSE product: $(PATH_BIN) $(PATH_OBJ) $(PATH_BIN)\test.exe BIN_GEN = TRUE LIB_GEN = TRUE
!UNDEF LIB_GEN !ENDIF # targets $(PATH_BIN)\test.exe: $(PATH_OBJ)\ReplaceStrings.obj
$(LINK) $(L_DEBUG) $(L_OUT)$(PATH_BIN)\test.exe $(PATH_OBJ)\ReplaceStrings.obj $(PATH_OBJ)\ReplaceStrings.obj: $(PATH_SRC)\ReplaceStrings.cpp
$(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) $(PATH_SRC)\ReplaceStrings.cpp $(C_OUT)$(PATH_OBJ)\ReplaceStrings.obj # folders $(PATH_BIN):
mkdir $(PATH_BIN) $(PATH_LIB):
mkdir $(PATH_LIB) $(PATH_OBJ):
mkdir $(PATH_OBJ) # clean .PHONY: clean
clean:
!IFDEF LIB_GEN
-rmdir /s /q $(PATH_LIB)
!ENDIF
!IFDEF BIN_GEN
-rmdir /s /q $(PATH_BIN)
!ENDIF
-rmdir /s /q $(PATH_OBJ)
!IFDEF DEBUG
-del *.pdb
!ENDIF
-------------------------------------------------------------
Makefile模板更新:
主要是libraries和headers的更新(还是以之前的那个版本为例子):
每个library一般都有自己的header,所以,一个library设置三个:LIBFILE_XXX, LIBPATH_XXX, HEADER_XXX
然后所有的HEADER_XXX被HEADERPATH所引用,修改后如下
1、headers在libraries下方,因为headers要引用libraries中的HEADER_XXX
2、每个library包含(但不一定全包含,视情况而定)LIBFILE_XXX和LIBPATH_XXX以及HEADER_XXX
3、你可以把常用的library都定义好,然后只需要修改headers和link指令即可,就可以灵活使用模板了
4、除了configurations那一段,其他地方对路径的使用都使用MACRO_NAME,另外PATH_INC前面不要加/I,因为在target中可能用到PATH_INC引起指令错误,所以,在libraries那一段的HEADER_THIS就是指的当前project中处于“开发”阶段的headers,其实就是/I $(PATH_INC)
# configurations # src, obj, bin and lib folders paths
PATH_SRC = src
PATH_OBJ = obj
PATH_BIN = bin
PATH_LIB = lib # headers in this project PATH_INC = include # compiler
CC = cl
# linker
LINK = link # libraries
LIBPATH_REPLACEALL = /LIBPATH:E:\cppwksp\thinkingincppvol2\demo\96-ReplaceAll\lib
LIBFILE_REPLACEALL = ReplaceAll.lib
HEADER_REPLACEALL = /I E:\cppwksp\thinkingincppvol2\demo\96-ReplaceAll\include HEADER_THIS = /I $(PATH_INC)
# headers
HEADER_PATH = $(PATH_INC) $(HEADER_REPLACEALL) # options
EHSC = /EHsc
COMPILATION_ONLY = /c
C_OUT = /Fo:
L_OUT = /OUT: # Flags to control cleanup
# If you need to generate executable files, make sure the following macro is defined, otherwise just comment it out.
BIN_GEN = TRUE
# If you need to generate library files, make sure the following macro is defined, otherwise just comment it out.
LIB_GEN = TRUE # Flag to choose targets to build, to disable debug, just comment out the following line or !UNDEF DEBUG
# Normally when debugging, you don't want to generate lib files, to do that, !UNDEF LIB_GEN as you can see below DEBUG = TRUE
!UNDEF DEBUG # compiler & linker debug options:
!IFDEF DEBUG
C_DEBUG = /Zi
L_DEBUG = /DEBUG
!ENDIF # If the C_DEBUG and L_DEBUG flags are empty, generate the lib file. Otherwise lib file will not be generated.
!IFDEF DEBUG debug: $(PATH_BIN)\test.exe !UNDEF LIB_GEN !ELSE product: $(PATH_BIN)\test.exe $(PATH_LIB)\FileClass.lib !ENDIF # targets $(PATH_BIN)\test.exe: $(PATH_BIN) $(PATH_OBJ) $(PATH_OBJ)\main.obj $(PATH_OBJ)\FileClass.obj
$(LINK) $(L_DEBUG) $(L_OUT)$(PATH_BIN)\test.exe $(PATH_OBJ)\main.obj $(PATH_OBJ)\FileClass.obj $(PATH_LIB)\FileClass.lib: $(PATH_LIB) $(PATH_OBJ)\FileClass.obj
LIB $(L_OUT)$(PATH_LIB)\FileClass.lib $(PATH_OBJ)\FileClass.obj $(PATH_BIN)\main.obj: $(PATH_SRC)\main.cpp $(PATH_INC)\FileClass.h
$(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) $(PATH_SRC)\main.cpp $(C_OUT)$(PATH_OBJ)\main.obj $(PATH_BIN)\FileClass.obj: $(PATH_SRC)\FileClass.cpp $(PATH_INC)\FileClass.h
$(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) $(PATH_SRC)\FileClass.cpp $(C_OUT)$(PATH_OBJ)\FileClass.obj # folders $(PATH_BIN):
mkdir $(PATH_BIN) $(PATH_LIB):
mkdir $(PATH_LIB) $(PATH_OBJ):
mkdir $(PATH_OBJ) # clean .PHONY: clean
clean:
!IFDEF LIB_GEN
-rmdir /s /q $(PATH_LIB)
!ENDIF
!IFDEF BIN_GEN
-rmdir /s /q $(PATH_BIN)
!ENDIF
-rmdir /s /q $(PATH_OBJ)
!IFDEF DEBUG
-del *.pdb
!ENDIF
-------------------------------------------------------------------
最新使用的Makefile
更新:
1、主要是使用了IF ELSE这些指令,在DEBUG的情况下不生成LIB文件夹以及LIB文件,在CLEANUP的时候也不删除LIB文件夹。如果在!UNDEF DEBUG的情况下,就要生成LIB文件夹以及LIB文件。
2、对src, obj, bin, lib这些目录都用MACRO DEFINITION来代替,方便统一修改。另外,建议target-name还是使用plain-text而不是MACRO避免混淆和保证清晰,你可以在这个Makefile中看出来我是这么做的
使用这个Makefile模板的话,debug的时候就保留DEBUG,如果不debug就!UNDEF DEBUG,从而实现2种不同的BUILD(当然也可以扩展出更多的情况),根据具体情况修改使用即可
随笔里的Makefile内容与demo文件夹中的Makefile内容稍微有点不同(修改了一点排版的顺序),以随笔里的为准
# configurations # src, obj, bin and lib folders paths
PATH_SRC = src
PATH_OBJ = obj
PATH_BIN = bin
PATH_LIB = lib # headers in this project PATH_INC = include # compiler
CC = cl
# linker
LINK = link
# headers
HEADER_PATH = /I $(PATH_INC)
# libraries
LIBPATH_REPLACEALL = /LIBPATH:E:\cppwksp\thinkingincppvol2\demo\96-ReplaceAll\lib
LIBFILE_REPLACEALL = ReplaceAll.lib
# options
EHSC = /EHsc
COMPILATION_ONLY = /c
C_OUT = /Fo:
L_OUT = /OUT: # Flags to control cleanup
# If you need to generate executable files, make sure the following macro is defined, otherwise just comment it out.
BIN_GEN = TRUE
# If you need to generate library files, make sure the following macro is defined, otherwise just comment it out.
LIB_GEN = TRUE # Flag to choose targets to build, to disable debug, just comment out the following line or !UNDEF DEBUG
# Normally when debugging, you don't want to generate lib files, to do that, !UNDEF LIB_GEN as you can see below DEBUG = TRUE
!UNDEF DEBUG # compiler & linker debug options:
!IFDEF DEBUG
C_DEBUG = /Zi
L_DEBUG = /DEBUG
!ENDIF # If the C_DEBUG and L_DEBUG flags are empty, generate the lib file. Otherwise lib file will not be generated.
!IFDEF DEBUG debug: bin\test.exe !UNDEF LIB_GEN !ELSE product: bin\test.exe lib\FileClass.lib !ENDIF # targets bin\test.exe: $(PATH_BIN) $(PATH_OBJ) $(PATH_OBJ)\main.obj $(PATH_OBJ)\FileClass.obj
$(LINK) $(L_DEBUG) $(L_OUT)$(PATH_BIN)\test.exe $(PATH_OBJ)\main.obj $(PATH_OBJ)\FileClass.obj lib\FileClass.lib: $(PATH_LIB) $(PATH_OBJ)\FileClass.obj
LIB $(L_OUT)$(PATH_LIB)\FileClass.lib $(PATH_OBJ)\FileClass.obj obj\main.obj: $(PATH_SRC)\main.cpp $(PATH_INC)\FileClass.h
$(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) $(PATH_SRC)\main.cpp $(C_OUT)$(PATH_OBJ)\main.obj obj\FileClass.obj: $(PATH_SRC)\FileClass.cpp $(PATH_INC)\FileClass.h
$(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) $(PATH_SRC)\FileClass.cpp $(C_OUT)$(PATH_OBJ)\FileClass.obj # folders bin:
mkdir $(PATH_BIN) lib:
mkdir $(PATH_LIB) obj:
mkdir $(PATH_OBJ) # clean .PHONY: clean
clean:
!IFDEF LIB_GEN
-rmdir /s /q $(PATH_LIB)
!ENDIF
!IFDEF BIN_GEN
-rmdir /s /q $(PATH_BIN)
!ENDIF
-rmdir /s /q $(PATH_OBJ)
!IFDEF DEBUG
-del *.pdb
!ENDIF
------------------------------------------------------------------
0、学习的时候用Editor、Make、Compiler、Linker以及Debugger还有各种工具,了解开发细节。实战的时候用IDE加快开发速度。
除非你的项目简单到了只需要命令:compiler a.cpp就能生成a.exe。否则,请使用良好的文件组织结构:
your_project_folder\
src\
module_a\
a.cpp
ax.cpp
axx.cpp
module_b\
b.cpp
bx.cpp
bxx.cpp
bin\
lib\
library_a\
xxx.lib
yyy.lib
zzz.lib
library_b\
hhh.lib
jjj.lib
kkk.lib
include\
library_a\
iii.h
uuu.h
library_b\
ggg.h
fff.h
module_a\
a.h
ax.h
axx.h
module_b\
b.h
bx.h
bxx.h
我平时使用的Makefile可以从这里下载到(持续更新,demo中会有更全面的例子),里面随便一个C++demo下载下来就有Makefile,可以参考(我不是很深入的了解Makefile,所以写的可能有些啰嗦、、不过好歹能用。。。),下面贴上我自己平时用的Makefile模板(配合Visual Studio的NMAKE程序,换到linux下其实也就是改改compiler和linker还有一些其他操作系统相关的指令就能用,差不太多)
下面提供一个demo及其Makefile
首先是Windows下的Makefile,适用于NMAKE程序,然后给出LINUX下的Makefile适用于GNU MAKE程序
点此下载demo文件夹(注意,ZThread的.lib文件或者.a文件就不提供了,在Windows下,建议命名为ZThread.lib(只要跟Makefile里的名字相同就行);在Linux下,命名为libZThread.a,在Makefile中用-lZThread选项来代表这个文件,注意,文件名的前缀lib是不可缺少的。)
注意:如果你的Makefile或者其他文件是用Windows下的编辑器写的,然后用U盘拷贝到linux下使用,不一定能被linux的编辑器正确解释(不同的系统编码啊,字节安排什么的不太一样),所以经常可能编译啊读取什么的出莫名其妙的错误,所以最好是在linux下新建文件并手动拷贝过去,比如说给你Makefile是在Windows下写的,拷到linux系统上一运行make,给你报错:Makefile:xxx: *** missing seperator. stop,其中xxx是你Makefile的最后一行行号。这种错误其实很简单,新建一个文件,把Makefile的内容复制粘贴进去,然后改名为Makefile,删掉原来的Makefile,就可以用了。
GNU MAKE Makefile
# compiler
CC = g++
# linker
LINK = g++
# libraries
# The following 2 options specify library files /home/lqr/Documents/ZThread-2.3.2/lib/libZThread.a
# AND /home/lqr/Documents/531-SynchronizedOutput/lib/libSynchronizedOutput.a
# A -L<PATH_NAME> option specifies 1 search path
# A -l<LIBRARY_NAME> option specifies 1 library file to search in all
# the paths specified by -L options and system's default search paths
# A library file's name is something like libLIBRARY_NAME.a
# note that the 'lib' prefix must exist for -l<LIBRARY_NAME> to work
# properly
# -lpthread specifies pthread, which is an operating system's library,
# it's one of the basis for ZThread library
LIBPATH_ZTHREAD = -L/home/lqr/Documents/ZThread-2.3.2/lib
LIBPATH_SYNC_OUTPUT = -Llib # Unlike Microsoft's LINK program, the GNU linker searches object
# files in a sequential (even if not strictly sequential) manner, you
# must place LIBFILES in a proper order, so you cannot put those -l
# options right next to the above -L options like I did in the
# Makefile for Microsoft's NMAKE program. Otherwise you'll get undefined reference error. LIBFILES_ZTHREAD = -lZThread -lpthread
LIBFILES_SYNC_OUTPUT = -lSynchronizedOutput # headers
# One -I<PATH_NAME> specifies 1 path name to search for header files,
# it works for both #include"" and #include<> commands
HEADER_PATH = -I/home/lqr/Documents/ZThread-2.3.2/include -Iinclude # options
COMPILATION_ONLY = -c
C_OUT = -o
L_OUT = -o # Some ZThread's code are old-fashioned and may not be accepted by modern compilers
FPERMISSIVE = -fpermissive # targets
bin/test.exe: bin lib/SynchronizedOutput.a obj/SynchronizedOutputTask.o obj/NormalTask.o obj/Task.o obj/main.o
$(LINK) $(LIBPATH_ZTHREAD) $(LIBPATH_SYNC_OUTPUT) $(L_OUT) bin/test.exe obj/main.o obj/SynchronizedOutputTask.o obj/NormalTask.o obj/Task.o $(LIBFILES_ZTHREAD) $(LIBFILES_SYNC_OUTPUT) lib/SynchronizedOutput.a: lib obj obj/SynchronizedOutput.o
ar -r lib/libSynchronizedOutput.a obj/SynchronizedOutput.o obj/SynchronizedOutput.o: src/SynchronizedOutput.cpp include/SynchronizedOutput.h
$(CC) $(HEADER_PATH) $(COMPILATION_ONLY) $(FPERMISSIVE) src/SynchronizedOutput.cpp $(C_OUT) obj/SynchronizedOutput.o obj/main.o: src/main.cpp include/SynchronizedOutputTask.h include/NormalTask.h include/Task.h include/SynchronizedOutput.h
$(CC) $(HEADER_PATH) $(COMPILATION_ONLY) src/main.cpp $(C_OUT) obj/main.o obj/SynchronizedOutputTask.o: src/SynchronizedOutputTask.cpp include/SynchronizedOutputTask.h include/SynchronizedOutput.h
$(CC) $(HEADER_PATH) $(COMPILATION_ONLY) src/SynchronizedOutputTask.cpp $(C_OUT) obj/SynchronizedOutputTask.o obj/NormalTask.o: src/NormalTask.cpp include/NormalTask.h
$(CC) $(HEADER_PATH) $(COMPILATION_ONLY) src/NormalTask.cpp $(C_OUT) obj/NormalTask.o obj/Task.o: src/Task.cpp include/Task.h
$(CC) $(HEADER_PATH) $(COMPILATION_ONLY) $(FPERMISSIVE) src/Task.cpp $(C_OUT) obj/Task.o # folders
bin:
mkdir bin obj:
mkdir obj lib:
mkdir lib # clean
# bin, lib, obj folders
.PHONY: clean
clean:
-rm -r -f bin
-rm -r -f lib
-rm -r -f obj
NMAKE Makefile
# compiler
CC = cl
# linker
LINK = link
# libraries
LIB_ZTHREAD = /LIBPATH:E:\cppwksp\zthreaddemo_win\libs\zthread ZThread_win32.lib
LIB_SYNC_OUTPUT = /LIBPATH:lib SynchronizedOutput.lib
# headers
HEADER_PATH = /I E:\cppwksp\zthreaddemo_win\include /I include
# options
EHSC = /EHsc
COMPILATION_ONLY = /c
C_OUT = /Fo:
L_OUT = /OUT:
# compiler & linker debug option, to disable debug, replace '/Zi' & '/DEBUG' with empty strings
# C_DEBUG = /Zi
# L_DEBUG = /DEBUG
C_DEBUG =
L_DEBUG =
# targets
bin\test.exe: bin lib\SynchronizedOutput_win32.lib obj\SynchronizedOutputTask.obj obj\NormalTask.obj obj\Task.obj obj\main.obj
$(LINK) $(L_DEBUG) $(LIB_ZTHREAD) $(LIB_SYNC_OUTPUT) $(L_OUT)bin\test.exe obj\main.obj obj\SynchronizedOutputTask.obj obj\NormalTask.obj obj\Task.obj lib\SynchronizedOutput_win32.lib: lib obj obj\SynchronizedOutput.obj
LIB $(L_OUT)lib\SynchronizedOutput_win32.lib obj\SynchronizedOutput.obj obj\SynchronizedOutput.obj: src\SynchronizedOutput.cpp include\SynchronizedOutput.h
$(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) src\SynchronizedOutput.cpp $(C_OUT)obj\SynchronizedOutput.obj obj\main.obj: src\main.cpp include\SynchronizedOutputTask.h include\NormalTask.h include\Task.h
$(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) src\main.cpp $(C_OUT)obj\main.obj obj\SynchronizedOutputTask.obj: src\SynchronizedOutputTask.cpp include\SynchronizedOutputTask.h include\Task.h include\SynchronizedOutput.h
$(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) src\SynchronizedOutputTask.cpp $(C_OUT)obj\SynchronizedOutputTask.obj obj\NormalTask.obj: src\NormalTask.cpp include\NormalTask.h include\Task.h
$(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) src\NormalTask.cpp $(C_OUT)obj\NormalTask.obj obj\Task.obj: src\Task.cpp include\Task.h
$(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) src\Task.cpp $(C_OUT)obj\Task.obj # folders
bin:
mkdir bin obj:
mkdir obj lib:
mkdir lib # clean
# bin, lib, obj folders and pdb files
.PHONY: clean
clean:
-rmdir /s /q bin
-rmdir /s /q lib
-rmdir /s /q obj
-del *.pdb
关于Makefile,我写了一篇笔记很重要,点此查看
另外,如果你希望在windows下编译的时候用一个文件叫Makefile.win32,在linux下编译的时候用另一个文件叫Makefile.linux,那么下面是典型的Makefile.linux的例子。(点此下载DEMO)
# compiler
CC = g++
# linker
LINK = g++
# libraries
LIBPATH_ZTHREAD = -L/home/lqr/Documents/ZThread-2.3.2/lib
LIBFILE_ZTHREAD = -lZThread -lpthread
# headers
HEADER_PATH = -I/home/lqr/Documents/ZThread-2.3.2/include -Iinclude -I/home/lqr/Documents/ZJ/548-TestTQueue-linux/include
# options COMPILATION_ONLY = -c
C_OUT = -o
L_OUT = -o # Some ZThread's code are old-fashioned and may not be accepted by modern compilers
FPERMISSIVE = -fpermissive obj = linux/obj
bin = linux/bin # targets $(bin)/test.exe: linux $(obj)/main.o $(obj)/Car.o $(obj)/EngineRobot.o $(obj)/Cradle.o $(obj)/DriveTrainRobot.o $(obj)/WheelRobot.o $(obj)/Director.o $(obj)/ChassisBuilder.o $(obj)/Reporter.o
$(LINK) $(L_DEBUG) $(LIBPATH_ZTHREAD) $(L_OUT) $(bin)/test.exe $(obj)/main.o $(obj)/EngineRobot.o $(obj)/Cradle.o $(obj)/DriveTrainRobot.o $(obj)/WheelRobot.o $(obj)/Director.o $(obj)/ChassisBuilder.o $(obj)/Reporter.o $(obj)/Car.o $(LIBFILE_ZTHREAD) $(obj)/main.o: src/main.cpp include/EngineRobot.h include/Cradle.h include/DriveTrainRobot.h include/WheelRobot.h include/Director.h include/ChassisBuilder.h include/Reporter.h include/typedefs.h
$(CC) $(FPERMISSIVE) $(HEADER_PATH) $(COMPILATION_ONLY) src/main.cpp $(C_OUT) $(obj)/main.o $(obj)/EngineRobot.o: src/EngineRobot.cpp include/EngineRobot.h include/typedefs.h
$(CC) $(FPERMISSIVE) $(HEADER_PATH) $(COMPILATION_ONLY) src/EngineRobot.cpp $(C_OUT) $(obj)/EngineRobot.o $(obj)/DriveTrainRobot.o: src/DriveTrainRobot.cpp include/DriveTrainRobot.h include/typedefs.h
$(CC) $(FPERMISSIVE) $(HEADER_PATH) $(COMPILATION_ONLY) src/DriveTrainRobot.cpp $(C_OUT) $(obj)/DriveTrainRobot.o $(obj)/WheelRobot.o: src/WheelRobot.cpp include/WheelRobot.h include/typedefs.h
$(CC) $(FPERMISSIVE) $(HEADER_PATH) $(COMPILATION_ONLY) src/WheelRobot.cpp $(C_OUT) $(obj)/WheelRobot.o $(obj)/Cradle.o: src/Cradle.cpp include/Cradle.h include/Car.h
$(CC) $(FPERMISSIVE) $(HEADER_PATH) $(COMPILATION_ONLY) src/Cradle.cpp $(C_OUT) $(obj)/Cradle.o $(obj)/Director.o: src/Director.cpp include/Director.h include/typedefs.h
$(CC) $(FPERMISSIVE) $(HEADER_PATH) $(COMPILATION_ONLY) src/Director.cpp $(C_OUT) $(obj)/Director.o $(obj)/ChassisBuilder.o: src/ChassisBuilder.cpp include/ChassisBuilder.h include/typedefs.h include/Car.h
$(CC) $(FPERMISSIVE) $(HEADER_PATH) $(COMPILATION_ONLY) src/ChassisBuilder.cpp $(C_OUT) $(obj)/ChassisBuilder.o $(obj)/Car.o: src/Car.cpp include/Car.h
$(CC) $(HEADER_PATH) $(COMPILATION_ONLY) src/Car.cpp $(C_OUT) $(obj)/Car.o $(obj)/Reporter.o: src/Reporter.cpp include/Reporter.h include/typedefs.h
$(CC) $(FPERMISSIVE) $(HEADER_PATH) $(COMPILATION_ONLY) src/Reporter.cpp $(C_OUT) $(obj)/Reporter.o # folders linux:
mkdir linux
cd linux; mkdir bin; mkdir obj # clean .PHONY: clean
clean:
-rm -r -f linux
下面给一个在windows下使用的简单的demo的Makefile(就是说你只有一个cpp文件,我一般命名为main.cpp,用来进行一些小的demo的验证啥的)
CC = cl
DEBUG = /Zi target:
$(CC) $(DEBUG) main.cpp clean:
-del *.obj
-del *.pdb
-del *.exe
-del *.ilk
linux:
CC = g++ target:
$(CC) main.cpp clean:
rm -f *.o
rm -f *.out
如果上面的makefile不够用的话,也可以用这个版本(也是适用于只有一个cpp文件的demo),这个makefile的demo也可以在我上面上传的文件夹中找到:
CC = cl
LINK = link # options
EHSC = /EHsc
COMPILATION_ONLY = /c
C_OUT = /Fo:
L_OUT = /OUT:
# compiler & linker debug option, to disable debug, replace '/Zi' & '/DEBUG' with empty strings
C_DEBUG = /Zi
L_DEBUG = /DEBUG
# C_DEBUG =
# L_DEBUG = # libraries
LIBPATH_TESTSUITE = /LIBPATH:E:\cppwksp\thinkingincppvol2\demo\72-TestSuite\lib
LIBFILE_TESTSUITE = TestSuite.lib # headers
HEADER_PATH = /I E:\cppwksp\thinkingincppvol2\demo\72-TestSuite\include target:
$(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) main.cpp $(C_OUT)main.obj
$(LINK) $(L_DEBUG) $(LIBPATH_TESTSUITE) $(L_OUT)test.exe main.obj $(LIBFILE_TESTSUITE) clean:
-del *.obj
-del *.pdb
-del *.exe
-del *.ilk
1、头文件的#include顺序:自己写的头文件、第三方工具的头文件、标准头文件,尽量从上到下这样安排顺序
头文件一定要写上#ifndef xxx #define xxx #endif的header guard
头文件中除了template和inline以外,都只写declaration不要把implementation代码写在头文件里,免得xxx redefined错误,保持一个好的习惯
2、头文件里不要包含:using指令和using namespace指令
头文件中不要初始化static member,避免xxx redefined错误,放到cpp文件中去初始化
3、如果你有一个class,尽量为这个class建立一个单独的header文件和cpp文件,需要隐藏实现细节的时候除外
4、待补充。。。
【持续更新】总结:C++开发时积累的一些零碎的东西的更多相关文章
- 【持续更新】.Net 开发中给自己埋下的坑!
1.文件“XXX”正在由另一进程使用,因此该进程无法访问此文件. 原因剖析:文件在主线程操作,在子线程中读写操作文件,刚开始没有意识到程序的问题所在,总是在FileStream中报错,google后常 ...
- web开发工具flask中文英文书籍-持续更新
web开发工具flask中文英文书籍-持续更新 python测试开发_AI命理关注 0.9222018.11.10 07:48:43字数 625阅读 885 python测试开发项目实战-目录 pyt ...
- 开发常用Git/Linux/idea命令快捷键总结(持续更新)
在开发过程中,会使用越来越多的命令,或快捷键,来帮助我们提高工作效率.本文记录了我在平时积累的常用命令,分享给大家. git命令 基本命令 set LESSCHARSET=utf-8 --idea T ...
- 关于ASP.NET MVC开发设计中出现的问题与解决方案汇总 【持续更新】
最近一直用ASP.NET MVC 4.0 +LINQ TO SQL来开发设计公司内部多个业务系统网站,在这其中发现了一些问题,也花了不少时间来查找相关资料或请教高人,最终都还算解决了,现在我将这些问题 ...
- java开发中遇到的问题及解决方法(持续更新)
摘自 http://blog.csdn.net/pony12/article/details/38456261 java开发中遇到的问题及解决方法(持续更新) 工作中,以C/C++开发为主,难免与其他 ...
- 移动端WEBAPP开发遇到的坑,以及填坑方案!持续更新~~~~
前言:在移动端WEBAPP开发中会遇到各种各样的问题,通过此文对遇到的问题做一个归纳总结,方便自己日后查询,也给各位前端开发友人做一个参考. 此文中涉及的问题是本人开发中遇到的,解决方案是本人思考 ...
- ReactNative开发笔记(持续更新...)
本文均为RN开发过程中遇到的问题.坑点的分析及解决方案,各问题点之间无关联,希望能帮助读者少走弯路,持续更新中... (2019年3月29日更新) 原文链接:http://www.kovli.com/ ...
- (转)iOS开发——来改掉那些被禁用的方法吧(持续更新中)
iOS平台在快速的发展,各种接口正在不断的更新.随着iOS9的发布,又有一批老方法不推荐使用了,你若调用这些方法,运行的结果是没有问题的,但是会出现警告“***is deprecated :first ...
- iOS开发系列文章(持续更新……)
iOS开发系列的文章,内容循序渐进,包含C语言.ObjC.iOS开发以及日后要写的游戏开发和Swift编程几部分内容.文章会持续更新,希望大家多多关注,如果文章对你有帮助请点赞支持,多谢! 为了方便大 ...
随机推荐
- C# 调用 Web Service 时出现 : 407 Proxy Authentication Required错误的解决办法
// 记得 using System.Net; System.Net.WebProxy myProxy = new System.Net.WebProxy("localhost:9099&q ...
- Servlet拦截静态图片的解决方案
一.现象 建立一个使用Freemarker的Web Project程序. Product.ftl中的代码为: <!DOCTYPE html PUBLIC "-//W3C//DTDHTM ...
- maven工程小红叉处理方法
搞了个Maven工程在Eclipse上,刚开始说JDK版本不对,编译的时候老报错误,很容易搞明白, 本地JDK版本为1.7.0_79: diamond operator is not supporte ...
- [转] copy_to_user和copy_from_user两个函数的分析
在内核的学习中会遇到很多挺有意思的函数,而且能沿着一个函数扯出来很多个相关的函数.copy_to_user和copy_from_user就是在进行驱动相关程序设计的时候,要经常遇到的两个函数.由于内核 ...
- Netty利用ChannelGroup广播消息
在Netty中提供了ChannelGroup接口,该接口继承Set接口,因此可以通过ChannelGroup可管理服务器端所有的连接的Channel,然后对所有的连接Channel广播消息. Serv ...
- 【树莓派】Box相关手册-4 Web代理
在盒子上安装配置web代理,通过此代理,用户访问盒子的内网地址实现web portal访问.目前我们使用tinyproxy作为web代理 安装: >sudo apt-get install ti ...
- Firefly 其他博客
http://www.cnblogs.com/9miaoshetuan/tag/Firefly/ http://www.cnblogs.com/9miaoshetuan/p/3853124.html ...
- Java学习笔记3、变量、数据类型
标识符 常见的命名规则(见名知意) 包名全部小写 类或者接口,一个单词:首字母大写,多个单词:每个单词首字母大写. 方法或者变量:一个单词:首字母小写,多个单词:从第二个单词开始,每个单词首字母大写. ...
- WindowManager.LayoutParams全解
WindowManager是Android中一个重要的服务(Service ).WindowManager Service 是全局的,是唯一的.它将用户的操作,翻译成为指令,发送给呈现在界面上的各个W ...
- HttpClient4.3教程 第二章 连接管理
2.1.持久连接 两个主机建立连接的过程是很复杂的一个过程,涉及到多个数据包的交换,并且也很耗时间.Http连接需要的三次握手开销很大,这一开销对于比较小的http消息来说更大.但是如果我们直接使用已 ...