cmake常用的用法记录
- 以下谈论的都是新建build文件夹并编译的情况(也称为源外编译):
cmake构建项目、编译、安装的处理流程
一般进入build文件夹中进行以下处理
cmake .. //根据CMakeLists.txt构建cmake项目,指定文件、文件夹处理。
make //根据制定进行处理:编译可执行文件、库
make install //根据CMakeLists.txt指定的路径进行安装(其实就是把生成文件放到指定的位置)
cmake项目构建(CMakeLists.txt的编写,指定文件和文件夹的处理)
每个有文件夹都可以有一个CMakeLists.txt文件,用来指定包含的文件和文件夹处理,而且cmake处理是从根文件夹下的CMakeLists.txt开始处理。只有在CMakeLists.txt指定子文件夹,才会根据子文件夹中的CMakeLists.txt进行处理。
-
对于文件处理:生成可执行文件、库、安装到指定位置等操作。
- 生成可执行文件并指定安装位置
add_executable(hello main.cpp) install(TARGETS hello RUNTIME DESTINATION bin)
- hello : 指定的生成二进制可执行文件名称
- main.cpp :源文件的名称
- TARGETS:目标文件标志
- RUNTIME:可执行文件标志
- DESTINATION:标志
- bin:相对路径(也可用绝对路径表示)
相对路径的完整路径应为:${CMAKE_INSTALL_PREFIX}/bin,CMAKE_INSTALL_PREFIX默认为:/usr/local。
在安装时可以指定CMAKE_INSTALL_PREFIX,如下
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
- 生成动态库文件并指定安装位置
ADD_LIBRARY(hello SHARED hello.cpp) INSTALL(TARGETS hello LIBRARY DESTINATION lib)
- hello:库文件名称
- SHARED:动态库标志
- hello.cpp:源文件名称
- TARGETS:目标文件标志
- LIBRARY:动态库标志
- DESTINATION:标志
- lib:相对路径(也可用绝对路径表示)
- 生成静态库文件并指定安装位置
ADD_LIBRARY(hello_static STATIC hello.cpp) INSTALL(TARGETS hello ARCHIVE DESTINATION lib)
- 生成同名的静态库和动态库并指定安装位置
思路是先生成不同名的文件,再更改名字。如下
SET(LIBHELLO_SRC hello.cpp) //用LIBHELLO_SRC指代 hello.c ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC}) ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC}) SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello") SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1) INSTALL(TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) //install output: -- Installing: /usr/local/lib/libhello.so.1.2 带版本号动态库 -- Installing: /usr/local/lib/libhello.so.1 带版本号动态库 -- Installing: /usr/local/lib/libhello.so 动态库 -- Installing: /usr/local/lib/libhello.a 静态库
- 头文件指定安装位置
INSTALL(FILES hello.h DESTINATION include/hello)
- 脚本文件指定安装位置
INSTALL(PROGRAMS runhello.sh DESTINATION bin)
- 文档指定安装位置
INSTALL(FILES COPYRIGHT README.md DESTINATION share/doc/cmake/t2)
-
对于子文件夹的处理INSTALL(FILES COPYRIGHT README.md DESTINATION share/doc/cmake/t2)
- 子文件夹中包含自己的CMakeLists.txt,那我们只要添加以下指令,该子文件夹会根据自己包含的CMakeLists.txt对自己包含的文件和文件夹进行处理。
ADD_SUBDIRECTORY(src bin) // 子目录文件夹名 输出.../build/bin
- 子文件夹不包含CMakeLists.txt文件,直接指定安装(复制)位置。(一般用来安装(复制)整个目录下的内容)
//安装目录的例子 INSTALL(DIRECTORY doc/ DESTINATION share/doc/camke/t2)
- DIRECTORY:标志
- doc/: 子文件名称
- DESTINATION:标志
- share/doc/camke/t2: 相对路径(也可以直接指定绝对路径,以“/”开头)
相对路径的完整路径应为:${CMAKE_INSTALL_PREFIX}/share/doc/cmake/t2,CMAKE_INSTALL_PREFIX默认为:/usr/local
在安装时可以指定CMAKE_INSTALL_PREFIX,如下
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
-
添加头文件目录和链接库文件
- 在生成目标文件(TARGET)时,需要确保源文件中引用的头文件在搜索的路径内,并链接库文件到目标文件。
- 库文件未指定安装位置,默认安装到usr/local/lib,头文件是默认安装到usr/local/include下。安装在这下面的头文件可以不用显式的指定目录。
- 添加头文件目录
INCLUDE_DIRECTORIES(/usr/include/hello) // 添加/usr/include/hello到搜索路径
- 库文件链接到目标文件
ADD_EXECUTABLE(main main.c) TARGET_LINK_LIBRARIES(main libhello.a) // 库文件libhello.a链接到可目标文件main
-
FIND_PACKAGE()的使用
- 我们在构建一个工程时往往会引用到其他模块,我们需要知道该模块的头文件和库文件安装位置。该模块可以提供一个cmake文件,记录这些信息。我们在引用时,只要路径中找到该文件,就能利用这些定义执行编译和链接。
- 添加cmake文件的搜索目录
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
- CMAKE_MODULE_PATH:标志
- ${PROJECT_SOURCE_DIR}/cmake : .cmake文件存储位置
- 搜索模块对应的cmake文件
find_package(HELLO REQUIRED)
- HELLO:模块名称,对应的cmake文件名应为:FindHELLO.cmake
- REQUIRED:标志
- .cmake文件编写:指定头文件和库文件的位置
find_path(HELLO_INCLUDE_DIR hello.h /usr/local/include/hello) find_library(HELLO_LIBRARY NAMES hello PATH /usr/local/lib)
- HELLO_INCLUDE_DIR :定义变量名,指代头文件目录
- HELLO_LIBRARY :定义变量名,指代库文件目录
- 引用模块的源文件添加
include_directories(${HELLO_INCLUDE_DIR}) target_link_libraries(hello ${HELLO_LIBRARY})
备注:
- 可执行文件(RUNTIME)、动态库(LIBRARY)、静态库(ARCHIVE)通常称为目标文件(TARGET)。
- 编译中报C++头文件没有找到。给定源文件为.c,更改为.cpp解决。