CMake常用命令- set()、find_package()、...

CMake:学习笔记,包含一些指令函数功能

1. CMake 

 cmake是 kitware 公司以及一些开源开发者在开发几个工具套件(VTK)的过程中所产生的衍生品。后来经过发展,最终形成体系,在2001年成为一个独立的开放源代码项目。

下载地址(官方)www.cmake.org,可以通过访问官方网站来获得更多关于cmake的信息,而且目前官方的英文文档比以前有了很大的改进,可以作为实践中的参考手册。


 

2. CMake - hello world

创建一个项目目录,例如创建一个CMake文件(我的目录为user_name/my_work/cmake),在cmake目录中新建 hello_cmake.c、CMakeLists.txt文件以及build文件夹,内容如下:

hello_cmake.c

#include <stdio.h>

int main() {
	printf("Hello CMake\n");
	return 0;
}

CMakeLists.txt

cmake_minimum_required (VERSION 2.8)
project (HelloCMake)
add_executable(HelloCMake hello_cmake.c)

ubuntu系统中,alt+ctrl+T打开一个终端,cd my_work/cmake/build(移动至build目录),cmake .. ,make ,./HelloCMake 运行可执行文件,在Unix系列的操作系统上,使用CMake步骤分为:

  1. 编写 CMakeLists.txt 配置文件。
  2. 执行 Cmake 命令生成 makefile 文件。
  3. 执行 make 命令编译执行,生成最终的目标文件。
  4. 运行最终生成的可执行文件即可,这步可选。

CMake命令行说明:(终端内输入cmake --help查看。更详尽的解释可以查看CMake的官方手册)

  1. cmake [<options>] (<path-to-source> | <path-to-existing-build>)
  2. cmake [(-D <var>=<value>)...] -P <cmake-script-file>
  3. cmake --build <dir> [<options>...] [-- <build-tool-options>...]
  4. cmake -E <command> [<options>...]
  5. cmake --find-package <options>...

常见的使用方式是上述第一种,这里也主要介绍这种方式。

[<options>],表示option为可选的。path-to-source 和 path-to-existing-build二选一,分别表示一个CMakeLists.txt所在的路径和一个已存在的构建工程所在的路径。例如:

cmake .

其中option常用的有-G <generator-name>-D <var>:<type>=<value>, -D <var>=<value>等,如:-Torch_DIR=/pytorch/torch/lib . ,会在CMakeCache.txt中添加一条

set(Torch_DIR /pytorch/torch/lib)
# 这样,可以在CMakeLists.txt文件中使用该变量的值。

 

3. CMake语法、常用的命令

3.1 set() 

其功能为将一个变量设置为给定值,函数原型:

# 将一个CMAKE变量设置为给定值
set(<variable> <value>... [PARENT_SCOPE])

例子-CMakelists.txt 

set(COCOS2D_ROOT ${CMAKE_SOURCE_DIR}/cocos2d)
# 这个命令完成了这么一件事情:
# 定义了一个变量COCOS2D_ROOT,并且变量的值为${CMAKE_SOURCE_DIR}/cocos2d
# CMAKE_SOURCE_DIR为源码树的顶层路径

3.2 find_package()

例子-CMakelists.txt: 

project(test_pytorch)
set(CMAKE_CXX_STANDARD 11)

# libtorch
set(Torch_DIR /home/xxx/libtorch/share/cmake/Torch)
find_package(Torch REQUIRED)

add_executable(test_pytorch test_pytorch.cpp)
target_link_libraries(test_pytorch ${TORCH_LIBRARIES})

概括来说,以Torch为例:find_package()函数,如果找到了相关的头文件和库文件,则会相应保存在

${Torch_INCLUDE_DIRS} ${Torch_LIBRARIES }中。

函数原型:

find_package(<package> [version] [EXACT] [QUIET] [MODULE] [REQUIRED] [[COMPONENTS]         
            [components...]] [OPTIONAL_COMPONENTS components...] [NO_POLICY_SCOPE])

下面我们说一说find_package()的语法:

  • Version 和 EXACT : 都是可选的,version指定的是版本,如果指定就必须检查找到的包的版本是否和version兼容。如果指定EXACT则表示必须完全匹配的版本而不是兼容版本就可以。
  • QUIET : 可选字段,表示如果查找失败,不会在屏幕进行输出(但是如果指定了REQUIRED字段,则QUIET无效,仍然会输出查找失败提示语)。
  • MODULE : 可选字段。前面提到说“如果Module模式查找失败则回退到Config模式进行查找”,但是假如设定了MODULE选项,那么就只在Module模式查找,如果Module模式下查找失败并不回落到Config模式查找。
  • CONFIG : 可选字段。直接在Config模式中查找。下文会介绍什么是Moudule模式什么是Config模式。
  • REQUIRED : 可选字段。表示一定要找到包,找不到的话就立即停掉整个cmake。而如果不指定REQUIRED则cmake会继续执行。
  • COMPONENTS : 可选字段,表示查找的包中必须要找到的组件(components),如果有任何一个找不到就算失败,类似于REQUIRED,导致cmake停止执行。上面的例子中find_package( PCL REQUIRED COMPONENT common io )我们就利用了该关键字寻找了common和io包。
  • OPTIONAL_COMPONENTS : 可选的模块,找不到也不会让cmake停止执行。 

 find_package工作原理

cmake本身不提供任何搜索库的便捷方法,所有搜索库并给变量赋值的操作必须由cmake代码完成,比如FindXXX.cmake 和 XXXConfig.cmake。只不过,开源的库通常会提供这两个文件,以方便使用者调用。

[1] find_package采用两种模式搜索库:

  • Module模式:搜索CMAKE_MODULE_PATH指定路径下的FindXXX.cmake文件,执行该文件从而找到XXX库。其中,具体查找库并给XXX_INCLUDE_DIRS和XXX_LIBRARIES两个变量赋值的操作由FindXXX.cmake模块完成(先搜索当前项目里面的Module文件夹里面提供的FindXXX.cmake,然后再搜索系统路径/usr/local/share/cmake-x.y/Modules/FindXXX.cmake)
  • Config模式:搜索XXX_DIR指定路径下的XXXConfig.cmake文件,执行该文件从而找到XXX库。其中具体查找库并给XXX_INCLUDE_DIRS和XXX_LIBRARIES两个变量赋值的操作由XXXConfig.cmake模块完成。

[2] 此外:

  • 对于可能没有***.cmake和***Config.cmake的库文件,可以直接找到其头文件和库文件所在文件夹,直接进行路径赋值:
set(LAPACK_DIR /usr/local/lib/) 
set(LAPACK_INCLUDE_DIRS /usr/local/include) 
set(LAPACK_LIBRARIES /usr/local/lib)

3.3 install命令

install用于指定在安装时运行的规则。它可以用来安装很多内容,可以包括目标二进制、动态库、静态库以及文件、目录、脚本等:

install(TARGETS <target>... [...])
install({FILES | PROGRAMS} <file>... [...])
install(DIRECTORY <dir>... [...])
install(SCRIPT <file> [...])
install(CODE <code> [...])
install(EXPORT <export-name> [...])

有时候,也会用到一个非常有用的变量CMAKE_INSTALL_PREFIX用于指定cmake install时的相对地址前缀。用法如:

cmake -DCMAKE_INSTALL_PREFIX=/usr ..

目标文件的安装:

install(TARGETS targets... [EXPORT <export-name>]
        [[ARCHIVE|LIBRARY|RUNTIME|OBJECTS|FRAMEWORK|BUNDLE|
          PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE]
         [DESTINATION <dir>]
         [PERMISSIONS permissions...]
         [CONFIGURATIONS [Debug|Release|...]]
         [COMPONENT <component>]
         [NAMELINK_COMPONENT <component>]
         [OPTIONAL] [EXCLUDE_FROM_ALL]
         [NAMELINK_ONLY|NAMELINK_SKIP]
        ] [...]
        [INCLUDES DESTINATION [<dir> ...]]
        )

参数中的TARGET可以是很多种目标文件,最常见的是通过ADD_EXECUTABLEADD_LIBRARY定义的目标文件,即可执行二进制、动态库、静态库:

 为了符合一般的默认安装路径,如果设置了DESTINATION参数,推荐配置在安装目录变量下的文件夹。

例如:

INSTALL(TARGETS myrun mylib mystaticlib
       RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
       LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
       ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

上面的例子会将:可执行二进制 myrun 安装到 ${CMAKE_INSTALL_BINDIR} 目录,动态库 libmylib.so 安装到${CMAKE_INSTALL_LIBDIR}目录,静态库 libmystaticlib.a 安装到 ${CMAKE_INSTALL_LIBDIR}目录。

猜你喜欢

转载自blog.csdn.net/u013271656/article/details/108720443