CMake指令详解

目录

1、add_definitions()

语法: 

代码中应用

运行时

2、find_package()

语法

作用

3、include_directories

语法

作用

4、target_include_directories

语法

作用

语法

作用

6、ADD_LIBRARY()

语法

使用

关于动态库的版本号

7、add_executable

方式1

方式2

语法:

作用

9、aux_source_directory

语法

作用

10、set_target_properties

语法

作用1

作用2


1、add_definitions()

语法: 

add_definitions(-D${宏名字})

代码中应用

这种可以在我们更改别人代码做实验时使用,既不对其源码进行破坏,又可以添加自己的功能。之前都是在程序中进行#define,有了这个后可以直接在编译的时候进行选择。具体的,在工程CMakeLists.txt 中,使用add_definitions()函数控制代码的开启和关闭:

option(TEST_DEBUG "option for debug" OFF)   
if (TEST_DEBUG)                    # 这个TEST_DEBUG 是CMake中的变量
	add_definitions(-DTEST_DEBUG)  # 这个TEST_DEBUG 是CMake中的变量
endif(TEST_DEBUG)

*.c源码中就可以使用:

#ifdef TEST_DEBUG
...
...
#else 
...
#endif

对程序进行控制。

运行时

运行构建项目的时候可以添加参数控制宏的开启和关闭.

cmake     -DUSE_MACRO = on ..   #打开
cmake  -DUSE_MACRO=off ..   #关闭

2、find_package()

语法

find_package(catkin REQUIRED COMPONENTS
             common
             map
             roscpp
)

作用

引入外部依赖包,执行之后,会为以下几个变量 赋值(这些变量需要模块预先定义):

<LibaryName>_FOUND
<LibaryName>_INCLUDE_DIR or <LibaryName>_INCLUDES
<LibaryName>_LIBRARY     or <LibaryName>_LIBRARIES

使用:

find_package(CURL)
add_executable(curltest curltest.cc)
if(CURL_FOUND)
    target_include_directories(clib PRIVATE ${CURL_INCLUDE_DIR})
    target_link_libraries(curltest ${CURL_LIBRARY})
else(CURL_FOUND)
    message(FATAL_ERROR ”CURL library not found”)
endif(CURL_FOUND)

3、include_directories

语法

include_directories([AFTER|BEFORE] [SYSTEM]  dir1  dir2 ...)

作用

将给定目录 dir1  dir2 加给编译器搜索到的包含文件 .默认情况下,加到目录列表的最后. 通过设定 CMAKE_include_directories_BEFORE 为 ON 来改变. 通过使用 BEFORE or AFTER 可以加在前面或者后面. 如果设定 SYSTEM 选项 编译器认定为系统包含目录.

4、target_include_directories

语法

target_include_directories(t x / y)

作用

指定目标文件 t 的搜索目录范围 – 它将x / y添加到目标t的包含路径。

语法

link_directories( self/define/lib/path )

作用

该指令的作用主要是指定要链接的库文件的路径,该指令有时候不一定需要。因为find_package和find_library指令可以得到库文件的绝对路径。不过你自己写的动态库文件放在自己新建的目录下时,可以用该指令指定该目录的路径以便工程能够找到。

6、ADD_LIBRARY()

语法

add_library(<name> [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            source1 [source2 ...])

作用:将源码source构建成一个库, 供他人使用

<name> :库的名字,直接写名字即可,不要写lib,会自动加上前缀的哈。

[STATIC | SHARED | MODULE] :类型有三种。

	SHARED,动态库
	STATIC,静态库
	MODULE,在使用 dyld 的系统有效,如果不支持 dyld,则被当作 SHARED 对待。

XCLUDE_FROM_ALL:这个库不会被默认构建,除非有其他的组件依赖或者手工构建。

使用

SET(LIBHELLO_SRC hello.c)
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})

注意,一般我们使用的静态库/动态库只是后缀名不同而已,上面构建的libhello.so与libhello_static.a,显然名字不同哦。这时你会有一个想法,那我把hello_static改成hello,结果是不可行的,静态库无法构建。重名会忽略第二条指令。

解决方法:改libhello_static.a的属性–输出名字

SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")

样就可以生成libhello.so与libhello.a了

关于动态库的版本号

#VERSION 指代动态库版本,SOVERSION 指代 API 版本。
SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)

在这里插入图片描述

从中我们可以看出:不管你的动态库版本是什么,对外调用总是libxxx.so。

7、add_executable

方式1

add_executable(< name> [WIN32] [MACOSX_BUNDLE]
                [EXCLUDE_FROM_ALL]  source1 source2 … sourceN)

add_executable:使用给定的源文件,为工程引入一个可执行文件。引入一个名为< name>的可执行目标,该目标会由调用该命令时在源文件列表中指定的源文件来构建。< name>对应于逻辑目标名字,并且在工程范围内必须是全局唯一的。被构建的可执行目标的实际文件名将根据具体的本地平台创建出来(比如< name>.exe或者仅仅是< name>)。

  默认情况下,可执行文件将会在构建树的路径下被创建,对应于该命令被调用的源文件树的路径。如果要改变这个位置,查看RUNTIME_OUTPUT_DIRECTORY目标属性的相关文档。如果要改变最终文件名的< name >部分,查看OUTPUT_NAME目标属性的相关文档。

  如果指定了MACOSX_BUNDLE选项,对应的属性会附加在创建的目标上。查看MACOSX_BUNDLE目标属性的文档可以找到更多的细节。

  如果指定了EXCLUDE_FROM_ALL选项,对应的属性将会设置在被创建的目标上。查看EXCLUDE_FROM_ALL目标属性的文档可以找到更多的细节。

方式2

add_executable(< name> IMPORTED)

 一个导入的可执行目标引用了一个位于工程之外的可执行文件。该格式不会生成构建这个目标的规则。该目标名字的作用域在它被创建的路径以及底层路径有效。它可以像在该工程内的其他任意目标一样被引用。导入可执行文件为类似于add_custom_command之类的命令引用它提供了便利。

  关于导入的可执行文件的细节可以通过设置以IMPORTED_开头的属性来指定。这类属性中最重要的是IMPORTED_LOCATION(以及它对应于具体配置的版本IMPORTED_LOCATION_< CONFIG>);该属性指定了执行文件主文件在磁盘上的位置。查看IMPORTED_*属性的文档来获得更多信息。

语法:

target_link_libraries(<target> [item1] [item2] [...]
                      [[debug|optimized|general] <item>] ...)

作用

该指令的作用为将目标文件与库文件进行链接。

上述指令中的<target>是指通过add_executable()和add_library()指令生成已经创建的目标文件。而[item]表示库文件没有后缀的名字。默认情况下,库依赖项是传递的。当这个目标链接到另一个目标时,链接到这个目标的库也会出现在另一个目标的连接线上。这个传递的接口存储在interface_link_libraries的目标属性中,可以通过设置该属性直接重写传递接口。

target_link_libraries里库文件的顺序符合gcc链接顺序的规则,即被依赖的库放在依赖它的库的后面,例如:

target_link_libraries(hello A B.a C.so)

在上面的命令中,libA.so可能依赖于libB.a和libC.so,如果顺序有错,链接时会报错。还有一点,B.a会告诉CMake优先使用静态链接库libB.a,C.so会告诉CMake优先使用动态链接库libC.so,也可直接使用库文件的相对路径或绝对路径。使用绝对路径的好处在 于,当依赖的库被更新时,make的时候也会重新链接。

9、aux_source_directory

语法

aux_source_directory(<dir> <variable>)

作用

在目录中查找所有源文件。

收集指定目录中所有源文件的名称,并将列表存储在提供的变量中。 该命令旨在供使用显式模板实例化的项目使用。 模板实例化文件可以存储在Templates子目录中,并使用此命令自动收集,以避免手动列出所有实例化。

试图使用此命令来避免编写库或可执行目标的源文件列表。 尽管这似乎可行,但是CMake无法生成知道何时添加新源文件的生成系统。 通常,生成的构建系统知道何时需要重新运行CMake,因为修改了CMakeLists.txt文件以添加新的源。 当仅将源代码添加到目录而不修改该文件时,将不得不手动重新运行CMake来生成包含新文件的构建系统。

10、set_target_properties

语法

set_target_properties(target1 target2 ...
                              PROPERTIES prop1 value1
                              prop2 value2 ...)  

作用1

set_target_properties(

Thirdlib

PROPERTIES IMPORTED_LOCATION

${CMAKE_CURRENT_SOURCE_DIR}/jniLibs/libThirdlib.so

)

   导入外部库,设置外部库的头文件路径。

   导入外部库,设置外部库文件所在的路径。

作用2

设置动态库版本号

SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)

VERSION:动态库版本

SOVERSION:API版本

最后生成的结果是:

libhello.so.1.2

libhello.so.1->libhello.so.1.2

libhello.so->libhello.so.1

11、add_subdirectory

语法

add_subdirectory (source_dir [binary_dir] [EXCLUDE_FROM_ALL])

作用

添加一个子目录并构建该子目录。

  • source_dir
    必选参数。该参数指定一个子目录,子目录下应该包含CMakeLists.txt文件和代码文件。子目录可以是相对路径也可以是绝对路径,如果是相对路径,则是相对当前目录的一个相对路径。
  • binary_dir
    可选参数。该参数指定一个目录,用于存放输出文件。可以是相对路径也可以是绝对路径,如果是相对路径,则是相对当前输出目录的一个相对路径。如果该参数没有指定,则默认的输出目录使用source_dir

  • EXCLUDE_FROM_ALL

    可选参数。当指定了该参数,则子目录下的目标不会被父目录下的目标文件包含进去,父目录的CMakeLists.txt不会构建子目录的目标文件,必须在子目录下显式去构建。例外情况:当父目录的目标依赖于子目录的目标,则子目录的目标仍然会被构建出来以满足依赖关系(例如使用了target_link_libraries)

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Op_chaos

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值