zoukankan      html  css  js  c++  java
  • 【持续更新】总结: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	hinkingincppvol2demo96-ReplaceAlllib
    LIBFILE_REPLACEALL = ReplaceAll.lib
    HEADER_REPLACEALL = /I E:cppwksp	hinkingincppvol2demo96-ReplaceAllinclude
    
    HEADER_REQUIRE = /I E:cppwksp	hinkingincppvol2demo570-requireinclude
    
    HEADER_BOOST = /I F:J	oolscpp_libsoost_1_57_0
    
    HEADER_URAND = /I E:cppwksp	hinkingincppvol2demo176-Urandinclude
    
    HEADER_APPLYSEQUENCE = /I E:cppwksp	hinkingincppvol2demo195-ApplySequenceinclude
    
    HEADER_PURGE = /I E:cppwksp	hinkingincppvol2demo392-purgeinclude
    
    HEADER_GENERATORS = /I E:cppwksp	hinkingincppvol2demo259-FunctionObjectsinclude
    LIBPATH_GENERATORS = /LIBPATH:E:cppwksp	hinkingincppvol2demo259-FunctionObjectslib
    LIBFILE_GENERATORS = Generators.lib
    
    HEADER_NUMSTRINGGEN = /I E:cppwksp	hinkingincppvol2demo268-NumStringGeninclude
    LIBPATH_NUMSTRINGGEN = /LIBPATH:E:cppwksp	hinkingincppvol2demo268-NumStringGenlib
    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)	est.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)	est.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)	est.exe: $(LINK_OBJ)
    	$(LINK) $(L_DEBUG) $(LIBPATH_ALL) $(L_OUT)$(PATH_BIN)	est.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	hinkingincppvol2demo96-ReplaceAlllib
    LIBFILE_REPLACEALL = ReplaceAll.lib
    HEADER_REPLACEALL = /I E:cppwksp	hinkingincppvol2demo96-ReplaceAllinclude
    
    HEADER_REQUIRE = /I E:cppwksp	hinkingincppvol2demo570-requireinclude
    
    HEADER_BOOST = /I F:J	oolscpp_libsoost_1_57_0
    
    HEADER_URAND = /I E:cppwksp	hinkingincppvol2demo176-Urandinclude
    
    HEADER_APPLYSEQUENCE = /I E:cppwksp	hinkingincppvol2demo195-ApplySequenceinclude
    
    HEADER_PURGE = /I E:cppwksp	hinkingincppvol2demo392-purgeinclude
    
    HEADER_GENERATORS = /I E:cppwksp	hinkingincppvol2demo259-FunctionObjectsinclude
    LIBPATH_GENERATORS = /LIBPATH:E:cppwksp	hinkingincppvol2demo259-FunctionObjectslib
    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)	est.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)	est.exe
    
    BIN_GEN = TRUE
    
    LIB_GEN = TRUE
    !UNDEF LIB_GEN
    
    !ENDIF 
    
    # targets
    
    $(PATH_BIN)	est.exe: $(PATH_OBJ)MemFun2.obj
    	$(LINK) $(L_DEBUG) $(L_OUT)$(PATH_BIN)	est.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	hinkingincppvol2demo96-ReplaceAlllib
    LIBFILE_REPLACEALL = ReplaceAll.lib
    HEADER_REPLACEALL = /I E:cppwksp	hinkingincppvol2demo96-ReplaceAllinclude
    
    HEADER_REQUIRE = /I E:cppwksp	hinkingincppvol2demo570-requireinclude
    
    HEADER_BOOST = /I F:J	oolscpp_libsoost_1_57_0
    
    HEADER_URAND = /I E:cppwksp	hinkingincppvol2demo176-Urandinclude
    
    HEADER_APPLYSEQUENCE = /I E:cppwksp	hinkingincppvol2demo195-ApplySequenceinclude
    
    HEADER_PURGE = /I E:cppwksp	hinkingincppvol2demo392-purgeinclude
    
    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)	est.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)	est.exe
    
    BIN_GEN = TRUE
    
    LIB_GEN = TRUE
    !UNDEF LIB_GEN
    
    !ENDIF 
    
    # targets
    
    $(PATH_BIN)	est.exe: $(PATH_OBJ)ReplaceStrings.obj
    	$(LINK) $(L_DEBUG) $(L_OUT)$(PATH_BIN)	est.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	hinkingincppvol2demo96-ReplaceAlllib
    LIBFILE_REPLACEALL = ReplaceAll.lib
    HEADER_REPLACEALL = /I E:cppwksp	hinkingincppvol2demo96-ReplaceAllinclude
    
    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)	est.exe
    
    !UNDEF LIB_GEN
    
    !ELSE
    
    product: $(PATH_BIN)	est.exe $(PATH_LIB)FileClass.lib
    
    !ENDIF 
    
    # targets
    
    $(PATH_BIN)	est.exe: $(PATH_BIN) $(PATH_OBJ) $(PATH_OBJ)main.obj $(PATH_OBJ)FileClass.obj
    	$(LINK) $(L_DEBUG) $(L_OUT)$(PATH_BIN)	est.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	hinkingincppvol2demo96-ReplaceAlllib
    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	est.exe
    
    !UNDEF LIB_GEN
    
    !ELSE
    
    product: bin	est.exe libFileClass.lib
    
    !ENDIF 
    
    # targets
    
    bin	est.exe: $(PATH_BIN) $(PATH_OBJ) $(PATH_OBJ)main.obj $(PATH_OBJ)FileClass.obj
    	$(LINK) $(L_DEBUG) $(L_OUT)$(PATH_BIN)	est.exe $(PATH_OBJ)main.obj $(PATH_OBJ)FileClass.obj
    
    libFileClass.lib: $(PATH_LIB) $(PATH_OBJ)FileClass.obj
    	LIB $(L_OUT)$(PATH_LIB)FileClass.lib $(PATH_OBJ)FileClass.obj
    	
    objmain.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
    
    objFileClass.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

     1 # compiler
     2 CC = g++
     3 # linker
     4 LINK = g++
     5 # libraries
     6 
     7 # The following 2 options specify library files /home/lqr/Documents/ZThread-2.3.2/lib/libZThread.a 
     8 # AND /home/lqr/Documents/531-SynchronizedOutput/lib/libSynchronizedOutput.a
     9 
    10 # A -L<PATH_NAME> option specifies 1 search path
    11 # A -l<LIBRARY_NAME> option specifies 1 library file to search in all
    12 # the paths specified by -L options and system's default search paths
    13 
    14 # A library file's name is something like libLIBRARY_NAME.a
    15 # note that the 'lib' prefix must exist for -l<LIBRARY_NAME> to work
    16 # properly
    17 
    18 # -lpthread specifies pthread, which is an operating system's library,
    19 # it's one of the basis for ZThread library
    20 
    21 LIBPATH_ZTHREAD = -L/home/lqr/Documents/ZThread-2.3.2/lib
    22 LIBPATH_SYNC_OUTPUT = -Llib
    23 
    24 # Unlike Microsoft's LINK program, the GNU linker searches object
    25 # files in a sequential (even if not strictly sequential) manner, you
    26 # must place LIBFILES in a proper order, so you cannot put those -l
    27 # options right next to the above -L options like I did in the
    28 # Makefile for Microsoft's NMAKE program. Otherwise you'll get undefined reference error.
    29 
    30 LIBFILES_ZTHREAD = -lZThread -lpthread
    31 LIBFILES_SYNC_OUTPUT = -lSynchronizedOutput
    32 
    33 # headers
    34 
    35 # One -I<PATH_NAME> specifies 1 path name to search for header files,
    36 # it works for both #include"" and #include<> commands
    37 
    38 HEADER_PATH = -I/home/lqr/Documents/ZThread-2.3.2/include -Iinclude
    39 
    40 # options
    41 
    42 COMPILATION_ONLY = -c
    43 C_OUT = -o
    44 L_OUT = -o
    45 
    46 # Some ZThread's code are old-fashioned and may not be accepted by modern compilers
    47 FPERMISSIVE = -fpermissive
    48 
    49 # targets
    50 
    51 bin/test.exe: bin lib/SynchronizedOutput.a obj/SynchronizedOutputTask.o obj/NormalTask.o obj/Task.o obj/main.o
    52     $(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)
    53     
    54 lib/SynchronizedOutput.a: lib obj obj/SynchronizedOutput.o
    55     ar -r lib/libSynchronizedOutput.a obj/SynchronizedOutput.o
    56 
    57 obj/SynchronizedOutput.o: src/SynchronizedOutput.cpp include/SynchronizedOutput.h
    58     $(CC) $(HEADER_PATH) $(COMPILATION_ONLY) $(FPERMISSIVE) src/SynchronizedOutput.cpp $(C_OUT) obj/SynchronizedOutput.o
    59 
    60 obj/main.o: src/main.cpp include/SynchronizedOutputTask.h include/NormalTask.h include/Task.h include/SynchronizedOutput.h
    61     $(CC) $(HEADER_PATH) $(COMPILATION_ONLY) src/main.cpp $(C_OUT) obj/main.o
    62 
    63 obj/SynchronizedOutputTask.o: src/SynchronizedOutputTask.cpp include/SynchronizedOutputTask.h include/SynchronizedOutput.h
    64     $(CC) $(HEADER_PATH) $(COMPILATION_ONLY) src/SynchronizedOutputTask.cpp $(C_OUT) obj/SynchronizedOutputTask.o
    65     
    66 obj/NormalTask.o: src/NormalTask.cpp include/NormalTask.h
    67     $(CC) $(HEADER_PATH) $(COMPILATION_ONLY) src/NormalTask.cpp $(C_OUT) obj/NormalTask.o
    68 
    69 obj/Task.o: src/Task.cpp include/Task.h
    70     $(CC) $(HEADER_PATH) $(COMPILATION_ONLY) $(FPERMISSIVE) src/Task.cpp $(C_OUT) obj/Task.o
    71     
    72 # folders
    73 
    74 bin:
    75     mkdir bin
    76 
    77 obj:
    78     mkdir obj
    79     
    80 lib:
    81     mkdir lib
    82     
    83 # clean
    84 # bin, lib, obj folders
    85 
    86 .PHONY: clean
    87 clean:
    88     -rm -r -f bin
    89     -rm -r -f lib
    90     -rm -r -f obj

      NMAKE Makefile

     1 # compiler
     2 CC = cl
     3 # linker
     4 LINK = link
     5 # libraries
     6 LIB_ZTHREAD = /LIBPATH:E:cppwkspzthreaddemo_winlibszthread ZThread_win32.lib
     7 LIB_SYNC_OUTPUT = /LIBPATH:lib SynchronizedOutput.lib
     8 # headers
     9 HEADER_PATH = /I E:cppwkspzthreaddemo_wininclude /I include
    10 # options
    11 EHSC = /EHsc
    12 COMPILATION_ONLY = /c
    13 C_OUT = /Fo:
    14 L_OUT = /OUT:
    15 # compiler & linker debug option, to disable debug, replace '/Zi' & '/DEBUG' with empty strings
    16 # C_DEBUG = /Zi
    17 # L_DEBUG = /DEBUG
    18 C_DEBUG = 
    19 L_DEBUG = 
    20 # targets
    21 
    22 bin	est.exe: bin libSynchronizedOutput_win32.lib objSynchronizedOutputTask.obj objNormalTask.obj objTask.obj objmain.obj
    23     $(LINK) $(L_DEBUG) $(LIB_ZTHREAD) $(LIB_SYNC_OUTPUT) $(L_OUT)bin	est.exe objmain.obj objSynchronizedOutputTask.obj objNormalTask.obj objTask.obj
    24     
    25 libSynchronizedOutput_win32.lib: lib obj objSynchronizedOutput.obj
    26     LIB $(L_OUT)libSynchronizedOutput_win32.lib objSynchronizedOutput.obj
    27 
    28 objSynchronizedOutput.obj: srcSynchronizedOutput.cpp includeSynchronizedOutput.h
    29     $(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) srcSynchronizedOutput.cpp $(C_OUT)objSynchronizedOutput.obj
    30 
    31 objmain.obj: srcmain.cpp includeSynchronizedOutputTask.h includeNormalTask.h includeTask.h
    32     $(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) srcmain.cpp $(C_OUT)objmain.obj
    33 
    34 objSynchronizedOutputTask.obj: srcSynchronizedOutputTask.cpp includeSynchronizedOutputTask.h includeTask.h includeSynchronizedOutput.h
    35     $(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) srcSynchronizedOutputTask.cpp $(C_OUT)objSynchronizedOutputTask.obj
    36     
    37 objNormalTask.obj: srcNormalTask.cpp includeNormalTask.h includeTask.h
    38     $(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) srcNormalTask.cpp $(C_OUT)objNormalTask.obj
    39 
    40 objTask.obj: srcTask.cpp includeTask.h
    41     $(CC) $(C_DEBUG) $(EHSC) $(HEADER_PATH) $(COMPILATION_ONLY) srcTask.cpp $(C_OUT)objTask.obj
    42     
    43 # folders
    44 
    45 bin:
    46     mkdir bin
    47 
    48 obj:
    49     mkdir obj
    50     
    51 lib:
    52     mkdir lib
    53     
    54 # clean
    55 # bin, lib, obj folders and pdb files
    56 
    57 .PHONY: clean
    58 clean:
    59     -rmdir /s /q bin
    60     -rmdir /s /q lib
    61     -rmdir /s /q obj
    62     -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	hinkingincppvol2demo72-TestSuitelib
    LIBFILE_TESTSUITE = TestSuite.lib
    
    # headers
    HEADER_PATH = /I E:cppwksp	hinkingincppvol2demo72-TestSuiteinclude
    
    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、待补充。。。

  • 相关阅读:
    Angular2 组件通信
    vue跨组件通信的几种方法
    Angular React 和 Vue的比较
    vue对比其他框架
    ReactJS 生命周期、数据流与事件
    LeetCode 1089. 复写零(Duplicate Zeros) 72
    LeetCode 421. 数组中两个数的最大异或值(Maximum XOR of Two Numbers in an Array) 71
    12
    11
    10
  • 原文地址:https://www.cnblogs.com/qrlozte/p/4232641.html
Copyright © 2011-2022 走看看