CMake 使用教程
makefile很重要什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专业人士,你还是要了解HTML的标识的含义。特别在Unix下的软件编译,你就不能不自己写makefile了,会不会
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 文件
- RPATH: 写在elf文件中
- LD_LIBRARY_PATH: 环境变量
- RUNPATH: 写在elf文件中
- ldconfig的缓存:配置/etc/ld.conf*可改变
- 默认的/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)
更多推荐


所有评论(0)