Makefile、CMake

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 更多的使用例子

  1. 定义CC为gcc编译,CXX为g++编译
CROSS=
CC = $(CROSS)gcc
CXX = $(CROSS)g++
  1. 定义编译参数
DEBUG = -g -O2
CFLAGS = $(DEBUG) -Wall -c
RM = rm -rf
  1. 定义SRCS为当前工程目录下的所有.cpp文件
SRCS = $(whildcard ./*.cpp)
  • wildcard是通配符函数,通过它可以得到我们所需的文件形式:$(wildcard pattern),例如以上定义的SRCS
  1. 定义OBJS为SRCS对应的.o文件
OBJS = $(patsubst %.cpp, %.o, $(SRCS))
  • patsubst是用来进行字符串替换的,其形式是:$(patsubst pattern, replacement, text),例如以上定义的OBJS
  1. 定义HEADER_PATH为当前工程中的头文件路径
HEADER_PATH = -I ./include/
  1. 定义LIB_PATH为当前工程中的库文件路径
LIB_PATH = -L ./lib/
$(warning LIB_PATH) # 输出当前LIB_PATH中的内容
  1. 指定LIBS链接库的名称
LIBS = -lpthread
  1. 定义当前生成的版本
VERSION = 1.0.0
  1. 定义生成可执行文件的名称
TARGET = simple.$(VERSION)
$(TARGET) : $(OBJS)
	$(CXX) $^ -o $@ $(LIB_PATH) $(LIBS) # 告诉编译器生成可执行文件时库存放的目录,以及库的名字
$(OBJS):%.o : %.c
	$(CXX) $(CFLAGS) $< -o $@ $(HEADER_PATH) # 告诉编译器生成中间文件时头文件所在的目录
  1. 伪对象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),然后再依一般的建构方式使用。

  1. CMake最低版本要求
cmake_minimum_required (VERSION 2.8)
  1. 工程名,不是可执行文件名
PROJECT(XXX)
  1. 手动加入文件 ${变量名},比如 ${SRC_LIST}
SET(SRC_LIST main.cpp)
set(SRC_LIST2 main2.cpp) # CMake关键字的大小写并没有影响
  1. MESSAGE,和echo类似
MESSAGE(STATUS "This is binary dir" ${PROJECT_BINARY_DIR})
MESSAGE(STATUS "This is source dir" ${PROJECT_SOURCE_DIR})
  1. 该CMakeLists.txt所在的目录
MESSAGE(STATUS "This is CMAKE_CURRENT_SOURCE_DIR" ${CMAKE_CURRENT_SOURCE_DIR})
  1. 添加子目录
ADD_SUBDIRECTORY(src)
  1. 产生的可执行文件
ADD_EXECUTABLE(main ${SRC_LIST})
ADD_EXECUTABLE(main2 ${SRC_LIST2})
  1. 将可执行文件安装到bin目录。默认/usr/local/;指定安装目录:cmke -DCMAKE_INSTALL_PREFIX=/tmp/usr …
INSTALL(TARGET software RUNTIME DESTINATION bin)
INSTALL(TARGET software2 RUNTIME DESTINATION bin)
  1. 子目录编译成库文件
  • 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)
  1. 找在某个路径下的所有源文件:aux_source_directory(< dir > < variable >)
AUX_SOURCE_DIRECTORY(. DIR_SOURCE)
ADD_LIBRARIES(dir2 ${DIR_SOURCE})
  1. CMake中几个变量的作用
    CMAKE_ARCHIVE_OUTPUT_DIRECTORY:默认存放静态库的文件夹位置
    CMAKE_LIBRARY_OUTPUT_DIRECTORY:默认存放动态库的文件夹位置
    LIBRARY_OUTPUT_PATH:默认存放库文件的位置,如果产生的是静态库并且没有指定 CMAKE_ARCHIVE_OUTPUT_DIRECTORY 则存放在该目录下,动态库也类似
    CMAKE_RUNTIME_OUTPUT_DIRECTORY:存放可执行软件的目录

你可能感兴趣的:(笔记,cmake,makefile)