Makefile

一、Makefile简介

Makefile是一个包含了一系列规则和指令的文件,它告诉make工具如何编译和链接程序。直接生成gcc的指令。make是一个在Unix和类Unix系统上广泛使用的构建自动化工具,它能够根据文件的时间戳自动判断哪些文件需要更新,并仅重新编译那些发生变化的部分,从而大大节省构建时间。

二、Makefile的基本结构

一个典型的Makefile包含以下元素:
变量定义:用于存储编译选项、源文件列表等常用信息,便于后续规则引用。
规则:每个规则指定了一个目标文件及其依赖文件,以及生成该目标所需的命令。
模式规则:使用通配符匹配文件,为特定类型的文件(如.c或.cpp)定义统一的编译规则。
伪目标:不以文件名命名的目标,通常用于执行清理、测试等非构建任务。

三、执行顺序

all:$(S_TARGET)
$(S_TARGET):$(SRC_OBJS)
	$(AR)  -r $@ $^
%.o:%.c
	$(CC) $(INCLUDE_DIR) $(CFLAGS) $^ -o $@ 
%.o:%.cpp
	$(CXX) $(INCLUDE_DIR) $(CXXFLAGS)  $^ -o $@

首先,make会查看all目标,并发现它依赖于(S_TARGET)。
接着,make会检查(S_TARGET)是否比它的依赖(SRC_OBJS)新。
如果(S_TARGET)不存在或过时,make会开始处理(S_TARGET)的依赖,即(SRC_OBJS)列表中的对象文件。
对于列表中的每个对象文件,make会根据其扩展名选择合适的编译规则(.c文件使用%.o:%.c规则,.cpp文件使用%.o:%.cpp规则)。
一旦所有依赖的对象文件都是最新的,make就会执行构建$(S_TARGET)的规则,链接这些对象文件和任何指定的库来生成最终的目标文件。

四、高级特性

自动变量:如$@(目标文件)、$<(第一个依赖文件)、$^(所有依赖文件)等,简化了规则的编写。
条件判断:允许根据环境变量或文件的存在与否选择不同的编译路径。
函数:Makefile提供了一系列内置函数,如wildcard(匹配文件)、patsubst(模式字符串替换)等,增强了其灵活性。
递归调用:在大型项目中,可以通过包含子Makefile来实现模块化构建。

五、关于CXXFLAGS

生成库文件:CXXFLAGS += -std=c++11 -O3 -DNDEBUG -c -fPIC -shared
生成执行文件:CXXFLAGS += -std=c++11 -O3 -DNDEBUG -fPIC

-std=c++11:指定使用C++11标准。C++11是C++语言的一个标准版本,引入了许多新特性,比如auto关键字、范围for循环、lambda表达式等。
-O3:这是一个优化级别标志,-O3表示使用最高级别的优化。编译器会尝试通过改变代码的结构、合并循环、使用更快的算法等手段来提高程序的运行速度。但需要注意的是,高级别的优化可能会导致编译时间增加,并且在某些情况下,可能会增加生成的二进制文件大小。
-DNDEBUG:这个标志用于定义宏NDEBUG。在C++标准库中,NDEBUG通常用于控制断言(assertions)的行为。当定义了NDEBUG时,所有的断言都会被禁用,这通常用于提高程序的运行速度,因为断言主要用于调试阶段。
-c:这个标志告诉编译器只进行编译(compile)操作,不进行链接(link)操作。也就是说,它会将源代码编译成目标文件(.o或.obj文件),但不会生成可执行文件。
-fPIC:这个标志用于生成位置无关代码(Position Independent Code)。这在创建共享库时非常重要,因为它允许库被加载到内存中的任何位置。
-shared:这个标志告诉编译器生成共享库(动态链接库)而不是可执行文件。共享库是一种特殊的文件,它包含了代码和数据,可以被多个程序同时使用,从而节省内存和磁盘空间。

六、库文件编译示例

CFLAGS += -O3 -DNDEBUG -c -fPIC -shared
CXXFLAGS += -std=c++11 -O3 -DNDEBUG -c -fPIC -shared
C_SRC_FILES = 
# 因为我们只写了cpp的规则,这里不要用cc文件
CXX_SRC_FILES = src/RunParaManager.cpp
# just use g++ command
# g++ -g -I. -I.. -I../.. -I../../commonComponents/ src/RunParaManager.cc -c -o libRunParaManager.o
# g++ -std=c++11 -O3 -DNDEBUG -c -fPIC -shared -I. -I.. -I../.. -I../../commonComponents/ src/RunParaManager.cc -c -o libRunParaManager.o
# ar -r libRunParaManager.a libRunParaManager.o
INCLUDE_DIR = -I./ \
			  -I../ \
			  -I../.. \
			  -I../../commonComponents
LDFLAGS+=
QNX+=
ifeq (${type},qnx)
	CFLAGS += -D_QNX_SOURCE -Vgcc_ntoaarch64le
	CXXFLAGS += -D_QNX_SOURCE -Vgcc_ntoaarch64le
	QNX += -D_QNX_SOURCE -Vgcc_ntoaarch64le
else ifeq (${type},UT)
	CFLAGS += -ftest-coverage -fprofile-arcs
	CXXFLAGS += -ftest-coverage -fprofile-arcs
	LDFLAGS += -lgcov
endif

SRC_OBJS=${patsubst %.c, %.o, ${C_SRC_FILES}}
SRC_OBJS+=${patsubst %.cpp, %.o, ${CXX_SRC_FILES}}

S_TARGET := libRunParaManager.a

unexport CFLAGS
unexport CXX_SRC_FILES

all:$(S_TARGET)
$(S_TARGET):$(SRC_OBJS)
	$(AR)  -r $@ $^

%.o:%.c
	$(CC) $(INCLUDE_DIR) $(CFLAGS) $^ -o $@ 

%.o:%.cpp
	$(CXX) $(INCLUDE_DIR) $(CXXFLAGS)  $^ -o $@

clean:
	rm -rf $(S_TARGET)
	rm -rf src/*.o
	rm -rf src/*.gcno
	rm -rf src/*.gcda

七、执行文件示例

主要区别是需要链接库

CFLAGS += -O3 -DNDEBUG -c -fPIC -shared
CXXFLAGS += -std=c++11 -O3 -DNDEBUG -fPIC
C_SRC_FILES = 
CXX_SRC_FILES = testRunParaManager.cpp

# just use g++ command to replace make
# g++ -g -I. -I.. -I../.. -I../../../commonComponents/ testRunParaManager.cpp -o testRunParaManager -L .. -L ../../../libs/  -L ../../../libs/x86/  -lRunParaManager -lDesayLog -ldbConnector -lsqlite3 -pthread -ldl
INCLUDE_DIR = -I. \
			  -I../ \
			  -I../.. \
			  -I../../../ \
			  -I../../../commonComponents

LDFLAGS+=

QNX+=

ifeq (${type},qnx)
	CFLAGS += -D_QNX_SOURCE -Vgcc_ntoaarch64le
	CXXFLAGS += -D_QNX_SOURCE -Vgcc_ntoaarch64le
	QNX += -D_QNX_SOURCE -Vgcc_ntoaarch64le
else ifeq (${type},UT)
	CFLAGS += -ftest-coverage -fprofile-arcs
	CXXFLAGS += -ftest-coverage -fprofile-arcs
	LDFLAGS += -lgcov
endif

LIBDIRS = -L.. -L../../../libs/ -L../../../libs/x86/
LIBS = -lRunParaManager -lDesayLog -ldbConnector -lsqlite3 -pthread -ldl

SRC_OBJS=${patsubst %.c, %.o, ${C_SRC_FILES}}
SRC_OBJS+=${patsubst %.cpp, %.o, ${CXX_SRC_FILES}}

S_TARGET := testRunParaManager

unexport CFLAGS
unexport CXX_SRC_FILES

all:$(S_TARGET)
$(S_TARGET):$(SRC_OBJS) 
	@echo "Building target: $@"
	$(CXX) $(QNX) $(INCLUDE_DIR) $(CXXFLAGS) $(SRC_OBJS) $(LIBDIRS) $(LIBS) $(LDFLAGS) -o $@


%.o:%.c
	$(CC) $(INCLUDE_DIR) $(CFLAGS) -c $< -o $@ 

%.o:%.cpp
	$(CXX) $(INCLUDE_DIR) $(CXXFLAGS) -c $< -o $@

clean:
	rm -rf $(S_TARGET)
	rm -rf src/*.o
	rm -rf src/*.gcno
	rm -rf src/*.gcda
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值