官网教程: https://cmake.org/cmake-tutorial/
中文版 https://www.jianshu.com/p/bbf68f9ddffa
这个教程,个人感觉不是很好。顺便看了看别人的使用心得,总结一点东西:
CMakeLists.txt 这个文件名的大小写一定不能错 (之前看过的教程,找不到出处了)。
CMakeLists.txt 文件,依次出现了几个命令:
1 | cmake_minimum_required:指定运行此配置文件所需的 CMake 的最低版本 |
2 | project:命名项目 project(<projectname> [languageName1 languageName2 ... ] ) 默认的语言是 C/CXX, 也可以设置为 其他 |
3 | add_executable: 将名为 除去第一个参数之外的源文件编译成一个名称为第一个参数命名的可执行文件 |
4 | include 命令包含预定义的模块 |
# Find boost 1.40 一般开头部分的解释都相当有用,可满足80%需求: The components list needs to contain actual names of boost libraries | |
5 | include_directories()用于添加头文件的包含搜索路径 include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...) |
6 | link_directories()用于添加查找库文件的搜索路径 |
7 | AUX_SOURCE_DIRECTORY(. SRC_LIST) #把当前目录(.)下所有源代码文件和头文件加入变量SRC_LIST 之后用户可以通过 ${SRC_LIST} 引用当前目录下的所有文件 |
8 | find_package 程序可以使用扩展的库、工程、文件等等 |
一般外部库的link方式可以通过两种方法来做,一种是显示添加路径,采用 link_directories(), 一种是通过find_library()去查找对应的库的绝对路径。后一种方法是更好的,因为它可以减少不少潜在的冲突。
一般 find_library 会根据一些默认规则来搜索文件,如果找到,将会set传入的第一个变量参数。否则,对应的参数不被定义,并且有一个xxx-NOTFOUND被定义;可以通过这种方式来调试库搜索是否成功。
对于库文件的名字而言,动态库搜索的时候会自动搜索libxxx.so (xxx.dll),静态库则是libxxx.a(xxx.lib),对于动态库和静态库混用的情况,可能会出现一些混乱,需要格外小心;一般尽量做匹配连接。
【实例学习1】3个文件夹,一个最外面的文件夹和两个子文件夹(Demo 和 Hello)。 在 Hello 子文件夹中,构建了一个库。在Demo 子文件夹中,构建一个 exe文件并链接到了库文件。
总共有三个 CMakeList.txt 文件,每个文件夹都有一个。
最外面的文件夹:工程中的CMakeLists 文件可以用 ${PROJECTNAME_SOURCE_DIR} 指代工程的源文件根目录的路径,用${PROJECTNAME_BINARY_DIR} 指代工程的二进制根目录的路径。
|
Hello (它是一个库) 这个子文件夹的CMakeList.txt
add_library (LIB_NAME SOURCE_FILES_LIST)
|
Demo (一个可执行的程序)子文件夹中CMakeLists.txt 如下:
|
【实例学习2】一个跨平台的实例。
【实例学习3】Building a simple program + shared library
源文件结构如下:
acrolibre.c, the main C program
acrodict.h, the Acrodict library header
acrodict.c, the Acrodict library source
CMakeLists.txt, the soon to be updated CMake entry file
cmake minimum required (VERSION 2.8) # 库连接到exe,这个例子中 acrolibre.c文件就可以直接使用库中的内容 |
【实例学习4】用户可以控制生成的选项
cmake_minimum_required (VERSION 2.8) # This project use C source code project ( TotallyFree C) # Build option with default value to ON option (WITH_ACRODICT "Include acronym dictionary support" ON) set (BUILD SHARED LIBS true ) # build executable using specified list of source files add_executable ( Acrolibre acrolibre.c ) if (WITH_ACRODICT) set (LIBSRC acrodict.h acrodict.c ) add_library ( acrodict ${LIBSRC}) add_executable ( Acrodictlibre acrolibre.c ) target_link_librariee acrodict ) set_target_properties ( Acrodictlibre PROPERTIES COMPILE_FLAGS "-DUSE_ACRODICT") endif(WITH_ACRODICT) |
【实例学习5】使用一个外面的库 - libxml2
find_package ( LibXml2 ) if (LIBXML2_FOUND) add_definitions(−DHAVE_XML ${LIBXML2_DEFINITIONS}) include_directories (${LIBXML2_INCLUDE_DIR}) else (LIBXML2_FOUND) set (LIBXML2_LIBRARIES "") endif (LIBXML2_FOUND) . . . target_link_libraries (MyTarget ${LIBXML2_LIBRARIES}) |
Find modules usually defines standard variables (for module XXX)
1 XXX_FOUND: Set to false, or undefined, if we haven’t found, or don’t want to use XXX.
2 XXX_INCLUDE_DIRS: The final set of include directories listed in one variable for use by client code.
3 XXX_LIBRARIES: The libraries to link against to use XXX. These should include full paths.
4 XXX_DEFINITIONS: Definitions to use when compiling code that uses XXX.
5 XXX_EXECUTABLE: Where to find the XXX tool.
6 XXX_LIBRARY_DIRS: Optionally, the final set of library directories listed in one variable for use by client code.
【实例学习MINI】CMakeList.txt 文件可以只是简单的一行代码。
一个工程:
add_executable(hello hello.c)
或者最简单的一个动态库:
add_library(hellolib SHARED hellolib.c)
PS:
CMake工作流: