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.

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, 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

下载demo

更新:

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++开发时积累的一些零碎的东西的更多相关文章

  1. 【持续更新】.Net 开发中给自己埋下的坑!

    1.文件“XXX”正在由另一进程使用,因此该进程无法访问此文件. 原因剖析:文件在主线程操作,在子线程中读写操作文件,刚开始没有意识到程序的问题所在,总是在FileStream中报错,google后常 ...

  2. web开发工具flask中文英文书籍-持续更新

    web开发工具flask中文英文书籍-持续更新 python测试开发_AI命理关注 0.9222018.11.10 07:48:43字数 625阅读 885 python测试开发项目实战-目录 pyt ...

  3. 开发常用Git/Linux/idea命令快捷键总结(持续更新)

    在开发过程中,会使用越来越多的命令,或快捷键,来帮助我们提高工作效率.本文记录了我在平时积累的常用命令,分享给大家. git命令 基本命令 set LESSCHARSET=utf-8 --idea T ...

  4. 关于ASP.NET MVC开发设计中出现的问题与解决方案汇总 【持续更新】

    最近一直用ASP.NET MVC 4.0 +LINQ TO SQL来开发设计公司内部多个业务系统网站,在这其中发现了一些问题,也花了不少时间来查找相关资料或请教高人,最终都还算解决了,现在我将这些问题 ...

  5. java开发中遇到的问题及解决方法(持续更新)

    摘自 http://blog.csdn.net/pony12/article/details/38456261 java开发中遇到的问题及解决方法(持续更新) 工作中,以C/C++开发为主,难免与其他 ...

  6. 移动端WEBAPP开发遇到的坑,以及填坑方案!持续更新~~~~

    前言:在移动端WEBAPP开发中会遇到各种各样的问题,通过此文对遇到的问题做一个归纳总结,方便自己日后查询,也给各位前端开发友人做一个参考.   此文中涉及的问题是本人开发中遇到的,解决方案是本人思考 ...

  7. ReactNative开发笔记(持续更新...)

    本文均为RN开发过程中遇到的问题.坑点的分析及解决方案,各问题点之间无关联,希望能帮助读者少走弯路,持续更新中... (2019年3月29日更新) 原文链接:http://www.kovli.com/ ...

  8. (转)iOS开发——来改掉那些被禁用的方法吧(持续更新中)

    iOS平台在快速的发展,各种接口正在不断的更新.随着iOS9的发布,又有一批老方法不推荐使用了,你若调用这些方法,运行的结果是没有问题的,但是会出现警告“***is deprecated :first ...

  9. iOS开发系列文章(持续更新……)

    iOS开发系列的文章,内容循序渐进,包含C语言.ObjC.iOS开发以及日后要写的游戏开发和Swift编程几部分内容.文章会持续更新,希望大家多多关注,如果文章对你有帮助请点赞支持,多谢! 为了方便大 ...

随机推荐

  1. Delphi 资源文件( .res)

    一.    现在的Windows应用程序几乎都使用图标.图片.光标.声音等,我们称它们为资源(Resource).最简单的使用资源的办法是把这些资源的源文件打入软件包,以方便程序需要的时候调用.资源是 ...

  2. unity mipmap 糊

    unity 开miapmap会糊很多 尤其在editor里面 我估计和editor的 tempRT resolution 957x380有关 -----确实是这样 手机上糊的程度低很多 中间rt我用的 ...

  3. java nb

    Java领域有非常多著名的人物.他们为Java社区编写框架.产品.工具或撰写书籍改变了Java编程的方式. 本文是<最受欢迎的8位Java牛人>的2.0版本号. PS:排名不分先后.本文的 ...

  4. Win7盗版提示,屏幕右下角出现 Windows内部版本7601此Windows副本不是正版怎么办

    Windows7 屏幕右下角出现 Windows内部版本7601此Windows副本不是正版 有很多人反应windows7会出现提示"Win7内部版本7600此Windows副本不是正版&q ...

  5. JMeter 十四:最佳实践

    参考:http://jmeter.apache.org/usermanual/best-practices.html 1. 总是使用最新版本的JMeter 2. 使用合适数目的Thread Threa ...

  6. PHP中is_*() 函数用法

    PHP中is_*() 函数用法 is_a - 如果对象属于该类或该类是此对象的父类则返回 TRUE is_array - 检测变量是否是数组 is_bool - 检测变量是否是布尔型 is_calla ...

  7. spring中autowire的用法

    Autowire模式就是在spring的声明文件里用作进行对象间的关联关系自动绑定的,就是在spring beanfactory内的一个bean对其bean的引用可以自动进行,而不一定用ref=的方式 ...

  8. 带有key参数的函数filter,map,max,min

    内置函数———filter def is_not_empty(s): return s and len(s.strip()) > 0 filter(is_not_empty, ['test', ...

  9. iOS触摸事件哦

    主要是记录下iOS的界面触摸事件处理机制,然后用一个实例来说明下应用场景. 一.处理机制 界面响应消息机制分两块,(1)首先在视图的层次结构里找到能响应消息的那个视图.(2)然后在找到的视图里处理消息 ...

  10. android 模拟器上传文件 Read-only file system

    在cmd窗口一条命令就可以了:adb shellmount -o remount rw /