CMake是一个非常强大的编译自动配置工具,支持各种平台,支持嵌套目录,子目录下可以有自己的CMakeLists.txt文件。

CMake 语法规则

1.指定cmake最小版本
cmake_minimum_required(VERSION 2.8)

2.设置项目名称
project(demo)

3.生成可执行文件

add_executable(demo demo.cpp) # 生成可执行文件

4. 生成库文件

add_library(common STATIC util.cpp) # 生成静态库
add_library(common SHARED util.cpp) # 生成动态库或共享库

5.指定编译包含的源文件

明确指定包含哪些

add_library(demo demo.cpp test.cpp util.cpp)

搜索所有的CPP文件

aux_source_directory(. SRC_LIST) # 搜索当前目录下的所有.cpp文件
add_library(demo ${SRC_LIST})

5.设置变量
set(SRC_LIST demo.cpp)

6. 设置子目录

add_subdirectory:向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置
语法:add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
// 添加src子目录,src中需要有一个CMakeLists.txt
add_subdirectory(src)

注意不能互相嵌套

7.设置包含目录

include_directories(
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_BINARY_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}/include
)

8.设置库目录

link_directories(
    ${CMAKE_CURRENT_SOURCE_DIR}/libs
)

9.设置链接库

TARGET_LINK_LIBRARIES

target_link_libraries( # 目标库
                       demo
                       # 目标库需要链接的库
                       # log-lib 是上面 find_library 指定的变量名
                       ${log-lib} )

三种写法

target_link_libraries(myProject eng mx)     

#equals to below 
#target_link_libraries(myProject -leng -lmx) `
#target_link_libraries(myProject libeng.so libmx.so)`

LINK_LIBRARIES(添加需要链接的库文件路径,注意这里是全路径)

LINK_LIBRARIES("/opt/MATLAB/R2012a/bin/glnxa64/libeng.so")

注意:link_directories需要在add_executable和add_library之前否则会导致动态库找不到,add_executable 需要在target_link_libraries之前

10. 常用变量
预定义变量

PROJECT_SOURCE_DIR:工程的根目录
PROJECT_BINARY_DIR:运行 cmake 命令的目录,通常是 ${PROJECT_SOURCE_DIR}/build
PROJECT_NAME:返回通过 project 命令定义的项目名称
CMAKE_CURRENT_SOURCE_DIR:当前处理的 CMakeLists.txt 所在的路径
CMAKE_CURRENT_BINARY_DIR:target 编译目录
CMAKE_CURRENT_LIST_DIR:CMakeLists.txt 的完整路径
CMAKE_CURRENT_LIST_LINE:当前所在的行
CMAKE_MODULE_PATH:定义自己的 cmake 模块所在的路径,SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake),然后可以用INCLUDE命令来调用自己的模块
EXECUTABLE_OUTPUT_PATH:重新定义目标二进制可执行文件的存放位置
LIBRARY_OUTPUT_PATH:重新定义目标链接库文件的存放位置


11. 查找包

find_package这个指令以被用来在系统中自动查找配置构建工程所需的程序库。
以opencv为例:
find_package(OpenCV REQUIRED)
当它找到OpenCV程序库之后,就会帮助我们预定义几个变量,OpenCV_FOUND、OpenCV_INCLUDE_DIRS、OpenCV_LIBRARY_DIRS、OpenCV_LIBRARIES,它们分别指是否找到OpenCV,OpenCV的头文件目录,OpenCV的库文件目录,OpenCV的所有库文件列表。接着我们就可以使用这些变量来配置了:

include_directories(${OpenCV_INCLUDE_DIRS})
link_directories(${OpenCV_LIBRARY_DIRS})
target_link_libraries(opencv_test ${OpenCV_LIBS})

同时可以通过设置OpenCV_DIR变量(packname_DIR)来指定包的优先搜索路径,实现加载指定版本的包。

set(OpenCV_DIR /opt/opencv2.4.9/build)
find_package(OpenCV REQUIRED)

注意这个地方的路径,要是构建路径(build 路径),不然找不到的
实际上find_package是找一个.cmake文件。packnameConfig.cmake。查找顺序
(1)packname_ROOT变量路径,cmake3.12新增
(2)packname_DIR变量路径,有了就不用上面那个了(可以用这个,定义这个变量)

set(OpenCV_ROOT "/usr/lib/opencv_249/build") #可在子目录查找
#为了在这里查找.cmake文件
set(OpenCV_DIR "/usr/lib/opencv_300/build")  #弱智,不能在子目录查找
find_package(OpenCV REQUIRED
          NO_MODULE        # tells CMake to use config mode
          NO_DEFAULT_PATH) # and don't look other anywhere
 #此时用的在${OpenCV}查找的.cmake文件

使用静态库
set(packname_STATIC ON)

12. 指定运行时加载库路径
可执行程序按照下列顺序搜索.so 文件

  1. RPATH: 写在elf文件中
  2. LD_LIBRARY_PATH: 环境变量
  3. RUNPATH: 写在elf文件中
  4. ldconfig的缓存:配置/etc/ld.conf*可改变
  5. 默认的/lib, /usr/lib
    可以看到,RPATH与RUNPATH中间隔着LD_LIBRARY_PATH。为了让用户可以通过修改LD_LIBRARY_PATH来指定.so文件,大多数编译器都将输出的RPATH留空,并用RUNPATH代替RPATH。

通过CMake设置rpath
rpath全称是run-time search path。Linux下所有elf格式的文件都包含它,特别是可执行文件。它规定了可执行文件在寻找.so文件时的第一优先位置。另外,elf文件中还规定了runpath。它与rpath相同,只是优先级低一些。

SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) #编译是写入INSTALL_RPATH
SET(CMAKE_INSTALL_RPATH "\${ORIGIN}/lib") #指定运行时动态库的加载路径,ORIGIN指运行文件所在目录

${ORIGIN}是指运行程序所在目录,如果你的lib放在其它路径下,你就改为你的路径即可

13.cmake install

# 设置统一安装路径前缀
set(CMAKE_INSTALL_PREFIX /usr/local)
# 定义安装对象及安装路径
install(TARGETS mainPro DESTINATION testPro/bin)

以一个Hello World程序为例:

test.cpp

#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
     cout << "Hello world!" << std::endl;
     return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project( Test )
aux_source_directory(./src SRC_LIST)
add_executable( Test ${SRC_LIST} )

在这里插入图片描述

使用cmake编译

mkdir build
cd build
cmake …
make

常见错误

/usr/bin/ld: cannot find -lxxx 的解决办法

link_directories(
/usr/local/jpeg/lib
)
target_link_libraries(compress jpeg)

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐