Linux Makefile简单模板
-I(大写i),添加包含路径 -I在编译时用,告诉编译器去哪个路径下找文件 如:-I /home/hello/include 表示将/home/hello/include目录作为第一个寻找头文件的目录。 编译器的寻找顺序是:/home/hello/include-->/usr/include-->/usr/local/include。
如果在/home/hello/include中有个文件hello.h,则在程序中用#include<hello.h>就能引用到这个文件。 可以加多个包含路径,编译器的寻找顺序为添加的顺序。
-l(小写L),添加引用链接库 -l在链接时用到,它的作用是告诉链接器,要用到哪个库。 如:-lpthread 告诉链接器(linker),程序需要链接pthread这个库,这里的pthread是库名不是文件名,具体来说文件句是libpthread.so。
-L,添加链接库路径 -L 后跟路径,告诉链接器从哪找库(.so文件或者.a文件),只有在链接时会用到。 如:-L /home/hello/lib 表示将/home/hello/lib目录作为第一个寻找库文件的目录,寻找顺序是:/home/hello/lib-->/usr/lib-->/usr/local/lib。 可以加多个包含路径,链接器的寻找顺序为添加的顺序。
-Wl,rpath,添加运行时库路径 -Wl,rpath 后面也是路径,运行的时候用。这条编译指令会在编译时记录到target文件中,所以编译之后的target文件在执行时会按这里给出的路径去找库文件。 如:-Wl,rpath=/home/hello/lib 表示将/home/hello/lib目录作为程序运行时第一个寻找库文件的目录,程序寻找顺序是:/home/hello/lib-->/usr/lib-->/usr/local/lib。 可以加多个包含路径,程序在运行时的寻找顺序为添加的顺序。
-L是编译路径,-Wl,rpath是运行路径,在配置工程的时候为了标准化,编译出的target(.so或是可执行文件)
不一定跟源文件(main.cpp,XX.cpp)放在一个文件夹下。如不在一个文件夹下,在编译时,-L后面跟的是相对
于源文件的路径,-Wl,rpath后面跟的是相对于target(.so或是可执行文件)的路径,确切来说是相对于工作
目录的路径。不同的IDE在配置有时候会一些细微不同,需要注意。
########################################### #Makefile for simple programs ########################################### # ---------------------------------------------------------------------------------------- # 全局变量 INCLUDES = # 链接库设置 LDFLAGS = # 可执行文件rpath设置(示例: -Wl,-rpath .) EXERPATH = # ---------------------------------------------------------------------------------------- # 编译器配置 CC = gcc CXX = g++ LINK = g++ AR = ar # ======================================================================================== # ---------------------------------------------------------------------------------------- # 生成文件设置 static-library = libtest.a dynamic-library = libtest.so execution = test # ======================================================================================== # ---------------------------------------------------------------------------------------- # 具体项配置 # 可执行文件,静态库,动态库只可以互斥生成,默认生成可执行文件 # 生成可执行文件 use_execution = 1 # 生成静态库 use_static = 0 # 生成动态库 use_dynamic = 0 # 增加调试信息 use_debug = 1 # 位置无关代码 use_pic = 1 # 位置无关的执行 use_pie = 0 # ======================================================================================== # ---------------------------------------------------------------------------------------- # 头文件路径配置 INCLUDES += -I ./core -I ./unix -I ./event -I ./nlu # ======================================================================================== # ---------------------------------------------------------------------------------------- # 第三方链接库配置 LDFLAGS += -Wl,-rpath ./lib/dui/libs -Wl,-rpath ./lib/bcdv2/libs ./lib/dui/libs/semantic.so ./lib/bcdv2/libs/bcdv2.so -lpthread -lz -ldl # ======================================================================================== # ---------------------------------------------------------------------------------------- # 局部变量定义 CFLAGS = CXXFLAGS = OBJECT = # 生成文件 TARGET = # 获取.o文件 OBJECT += $(patsubst %.c,%.o,$(wildcard *.c ./core/*.c ./core/modules/*.c ./event/*.c ./unix/*.c ./nlu/*.c)) # 多目录 C_OBJS=$(patsubst %.c,%.o,$(wildcard *.c ./目录1/*.c ./目录2/*.c)) OBJECT += $(patsubst %.cpp,%.o,$(wildcard *.cpp ./core/*.cpp ./core/modules/*.cpp ./event/*.cpp ./unix/*.cpp ./nlu/*.cpp)) # 静态库编译命令 static-library-cmd = ${AR} -r $(1) $(2) # 动态库编译命令 dynamic-library-cmd = $(CXX) $(2) $(LDFLAGS) -shared -o $(1) # 可执行文件编译命令 execution-cmd = $(CXX) $(2) $(EXERPATH) $(LDFLAGS) -o $(1) # debug设置 ifeq (${use_debug},1) CFLAGS += -g -O0 -Wall CXXFLAGS += -g -O0 -Wall else CFLAGS += -O3 -Wall CXXFLAGS += -O3 -Wall endif # 位置无关代码设置 ifeq (${use_pic},1) CFLAGS += -fPIC CXXFLAGS += -fPIC endif # 位置无关的执行设置 ifeq (${use_pie},1) CFLAGS += -fPIE endif # 设置生成目标文件 ifeq (${use_execution}, 1) TARGET += $(execution) # 可以在此添加自定义的宏 CFLAGS += -DTEST #CFLAGS += -DTEST -DNLU_DEBUG #CXXFLAGS += -DTEST -std=c++11 #CXXFLAGS += -DTEST -DSCHEDULER_DEBUG else ifeq (${use_static}, 1) TARGET += $(static-library) else CFLAGS += -fvisibility=hidden TARGET += $(dynamic-library) endif # 设置头文件 ifneq (${INCLUDES}, "") CFLAGS += ${INCLUDES} CXXFLAGS += ${INCLUDES} endif # default target all: compile @echo "make successful ." # 创建库文件目录 libs: @mkdir -p ./libs # 清理库文件 libs_clear: @rm -rf ./libs # 生成静态库 $(static-library): libs ${OBJECT} $(call static-library-cmd, $@, ${OBJECT}) @chmod 0755 $(static-library) @mv $(static-library) ./libs # 生成动态库 $(dynamic-library): libs ${OBJECT} $(call dynamic-library-cmd, $@, ${OBJECT}) @chmod 0755 $(dynamic-library) @mv $(dynamic-library) ./libs # 生成可执行文件 $(execution): ${OBJECT} -$(call execution-cmd, $@, ${OBJECT}) compile: ${TARGET} # .o文件的生成target #编译的时候需要头文件 %.o:%.cpp $(CXX) $(CXXFLAGS) -c $< -o $@ %.o:%.c $(CC) $(CFLAGS) -c $< -o $@ .PRONY:clean clean: libs_clear rm -rf $(execution) $(OBJECT)