1. Makefile
1.1 简单Makefile示例
.PHONY: clean
CC = gcc
RM = rm
EXE = simple #用于存放可执行文件名
OBJS = main.o foo.o #用于放置所有的目标文件名
$(EXE): $(OBJS)
$(CC) -o $@ $^
main.o: main.c
$(CC) -o $@ -c $^
foo.o: foo.c
$(CC) -o $@ -c $^
clean:
$(rm) $(EXE) $(OBJS)
- Makefile三要素:目标,依赖,命令
- CC、RM、EXE、OBJS都是定义的变量,在使用时通过
$(变量名)
来替换成对应的值。 $@
用于表示一个规则中的目标。当我们的一个规则中有多个目标时,$@
所指的是其中任何造成命令被运行的目标$^
则表示的是规则中所有的先决条件(依赖)$<
表示的是规则中的第一个先决条件(依赖)
1.2 更多的使用例子
- 定义CC为gcc编译,CXX为g++编译
CROSS=
CC = $(CROSS)gcc
CXX = $(CROSS)g++
- 定义编译参数
DEBUG = -g -O2
CFLAGS = $(DEBUG) -Wall -c
RM = rm -rf
- 定义SRCS为当前工程目录下的所有.cpp文件
SRCS = $(whildcard ./*.cpp)
wildcard
是通配符函数,通过它可以得到我们所需的文件形式:$(wildcard pattern)
,例如以上定义的SRCS
- 定义OBJS为SRCS对应的.o文件
OBJS = $(patsubst %.cpp, %.o, $(SRCS))
patsubst
是用来进行字符串替换的,其形式是:$(patsubst pattern, replacement, text),例如以上定义的OBJS
- 定义HEADER_PATH为当前工程中的头文件路径
HEADER_PATH = -I ./include/
- 定义LIB_PATH为当前工程中的库文件路径
LIB_PATH = -L ./lib/
$(warning LIB_PATH) # 输出当前LIB_PATH中的内容
- 指定LIBS链接库的名称
LIBS = -lpthread
- 定义当前生成的版本
VERSION = 1.0.0
- 定义生成可执行文件的名称
TARGET = simple.$(VERSION)
$(TARGET) : $(OBJS)
$(CXX) $^ -o $@ $(LIB_PATH) $(LIBS) # 告诉编译器生成可执行文件时库存放的目录,以及库的名字
$(OBJS):%.o : %.c
$(CXX) $(CFLAGS) $< -o $@ $(HEADER_PATH) # 告诉编译器生成中间文件时头文件所在的目录
- 伪对象clean:执行清理操作
.PHONY: clean
clean:
$(RM) $(TARGET) *.o
2. CMake
2.2 CMakeLists.txt的使用
CMake是一个跨平台安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译)过程。它能够输出各种各样的makefile和project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。只是CMake的组态档取名为CMakeLists.txt。CMake并不直接构建出最终的软件,而是产生标准的建构档(如UNIX的Makefile或Windows Visual C++的project/workspaces),然后再依一般的建构方式使用。
- CMake最低版本要求
cmake_minimum_required (VERSION 2.8)
- 工程名,不是可执行文件名
PROJECT(XXX)
- 手动加入文件 ${变量名},比如 ${SRC_LIST}
SET(SRC_LIST main.cpp)
set(SRC_LIST2 main2.cpp) # CMake关键字的大小写并没有影响
- MESSAGE,和echo类似
MESSAGE(STATUS "This is binary dir" ${PROJECT_BINARY_DIR})
MESSAGE(STATUS "This is source dir" ${PROJECT_SOURCE_DIR})
- 该CMakeLists.txt所在的目录
MESSAGE(STATUS "This is CMAKE_CURRENT_SOURCE_DIR" ${CMAKE_CURRENT_SOURCE_DIR})
- 添加子目录
ADD_SUBDIRECTORY(src)
- 产生的可执行文件
ADD_EXECUTABLE(main ${SRC_LIST})
ADD_EXECUTABLE(main2 ${SRC_LIST2})
- 将可执行文件安装到bin目录。默认/usr/local/;指定安装目录:cmke -DCMAKE_INSTALL_PREFIX=/tmp/usr …
INSTALL(TARGET software RUNTIME DESTINATION bin)
INSTALL(TARGET software2 RUNTIME DESTINATION bin)
- 子目录编译成库文件
- INCLUDE_DIRECTORIES 找头文件
INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/dir1")
- ADD_SUBDIRECTORY 添加子目录
ADD_SUBDIRECTORY("${CMAKE_CURRENT_SOURCE_DIR}/dir1")
- ADD_LIBRARY 生成库文件
ADD_LIBRAR(hello_shared SHARED libHelloSLAM.cpp) # 生成动态库
ADD_LIBRAR(hello_shared STATIC libHelloSLAM.cpp) # 生成静态库
- TARGET_LINK_LIBRARIES 链接库到可执行文件上
TARGET_LINK_LIBRARIES(test dir1 dir2)
- 找在某个路径下的所有源文件:aux_source_directory(< dir > < variable >)
AUX_SOURCE_DIRECTORY(. DIR_SOURCE)
ADD_LIBRARIES(dir2 ${DIR_SOURCE})
- CMake中几个变量的作用
CMAKE_ARCHIVE_OUTPUT_DIRECTORY
:默认存放静态库的文件夹位置
CMAKE_LIBRARY_OUTPUT_DIRECTORY
:默认存放动态库的文件夹位置
LIBRARY_OUTPUT_PATH
:默认存放库文件的位置,如果产生的是静态库并且没有指定 CMAKE_ARCHIVE_OUTPUT_DIRECTORY 则存放在该目录下,动态库也类似
CMAKE_RUNTIME_OUTPUT_DIRECTORY
:存放可执行软件的目录