cmake学习笔记

    以下笔记部分来自于cmake practice

    1. 最基本的几个命令:
      PROJECT(projectname [CXX] [C] [Java])
      你可以用这个指令定义工程名称,并可指定工程支持的语言,支持的语言列表是可以忽略的,
      默认情况表示支持所有语言。 这个指令隐式的定义了两个 cmake 变量:<projectname>_BINARY_DIR 以及<projectname>_SOURCE_DIR,同时PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR和这两个变量同值。推荐使用PROJECT开头的。
      SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
      现阶段,你只需要了解 SET 指令可以用来显式的定义变量即可。
      MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display" ...)
      这个指令用于向终端输出用户定义的信息,包含了三种类型:
      SEND_ERROR,产生错误,生成过程被跳过。
      SATUS,输出前缀为—的信息。
      FATAL_ERROR,立即终止所有 cmake 过程.
      ADD_EXECUTABLE(hello ${SRC_LIST})
      定义了这个工程会生成一个文件名为 hello 的可执行文件
    2. cmake的语法:
      ${name}: 引用名为name的变量的值。
      指令(参数 1 参数 2...): 其中指令的大小写不区分,参数用空格或分号隔开。
      值可以用双引号括起来,也可以不用。
    3. 当在cmake之后的make出现错误,可以用make VERBOSE=1来看详细的错误是什么。
    4. cmake不会生成make distclean,这是因为cmake鼓励使用out-of-source build,也就是在source tree之外建一个build目录,这样cmake完全不会在source tree生成任何中间文件。
    5. 在source tree中,需要在每个目录下都放一个CMakeLists.txt文件。
    6. ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
      这个指令用于向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存
      放的位置。EXCLUDE_FROM_ALL 参数的含义是将这个目录从编译过程中排除
    7. cmake里面指定binary的安装方法:
      CMAKE_INSTALL_PREFIX 变量类似于 configure 脚本的 –prefix,常见的使用方法看
      起来是这个样子:
      cmake -DCMAKE_INSTALL_PREFIX=/usr .
      INSTALL命令
      目标文件的安装:
           INSTALL(TARGETS targets...
               [[ARCHIVE|LIBRARY|RUNTIME]
                           [DESTINATION <dir>]
                           [PERMISSIONS permissions...]
                           [CONFIGURATIONS
             [Debug|Release|...]]
                           [COMPONENT <component>]
                           [OPTIONAL]
                          ] [...])
      参数中的 TARGETS 后面跟的就是我们通过 ADD_EXECUTABLE 或者 ADD_LIBRARY 定义的
      目标文件,可能是可执行二进制、动态库、静态库。
      目标类型也就相对应的有三种,ARCHIVE 特指静态库,LIBRARY 特指动态库,RUNTIME
      特指可执行目标二进制。
      DESTINATION 定义了安装的路径,如果路径以/开头,那么指的是绝对路径,这时候
      CMAKE_INSTALL_PREFIX 其实就无效了。如果你希望使用 CMAKE_INSTALL_PREFIX 来
      定义安装路径,就要写成相对路径,即不要以/开头,那么安装后的路径就是
      ${CMAKE_INSTALL_PREFIX}/<DESTINATION 定义的路径>

      普通文件的安装:       
      INSTALL(FILES files... DESTINATION <dir>
                  [PERMISSIONS permissions...]
                  [CONFIGURATIONS [Debug|Release|...]]
                  [COMPONENT <component>]
                  [RENAME <name>] [OPTIONAL])
      可用于安装一般文件,并可以指定访问权限,文件名是此指令所在路径下的相对路径。如果
      默认不定义权限 PERMISSIONS,安装后的权限为:
      OWNER_WRITE, OWNER_READ,  GROUP_READ,和 WORLD_READ,即 644 权限。

      非目标文件的可执行程序安装(比如脚本之类):
               INSTALL(PROGRAMS files... DESTINATION <dir>
                   [PERMISSIONS permissions...]
                   [CONFIGURATIONS [Debug|Release|...]]
                   [COMPONENT <component>]
                   [RENAME <name>] [OPTIONAL])
      跟上面的 FILES 指令使用方法一样,唯一的不同是安装后权限为:
      OWNER_EXECUTE, GROUP_EXECUTE, 和 WORLD_EXECUTE,即 755 权限

      目录的安装:
               INSTALL(DIRECTORY dirs... DESTINATION <dir>
                   [FILE_PERMISSIONS permissions...]
                   [DIRECTORY_PERMISSIONS permissions...]
                   [USE_SOURCE_PERMISSIONS]
                   [CONFIGURATIONS [Debug|Release|...]]
                   [COMPONENT <component>]
                   [[PATTERN <pattern> | REGEX <regex>]
                    [EXCLUDE] [PERMISSIONS permissions...]] [...])
      这里主要介绍其中的 DIRECTORY、PATTERN 以及 PERMISSIONS 参数。
      DIRECTORY 后面连接的是所在 Source 目录的相对路径,但务必注意:
      abc 和 abc/有很大的区别。
      如果目录名不以/结尾,那么这个目录将被安装为目标路径下的 abc,如果目录名以/结尾,
      代表将这个目录中的内容安装到目标路径,但不包括这个目录本身。
      PATTERN 用于使用正则表达式进行过滤,PERMISSIONS 用于指定 PATTERN 过滤后的文件
      权限。
    8. 如果不明确指定CMAKE_INSTALL_PREFIX,那么默认的值是/usr/local
    9. 编译静态/动态库的命令:
      ADD_LIBRARY(libname    [SHARED|STATIC|MODULE]
        [EXCLUDE_FROM_ALL]
              source1 source2 ... sourceN)
      EXCLUDE_FROM_ALL 参数的意思是这个库不会被默认构建,除非有其他的组件依赖或者手
      工构建。
      同时注意,一个target名(指用ADD_EXECUTABLE,ADD_LIBRARY的文件),不能够重复在ADD_命令中使用,否则cmake会忽略。
      如果需要同时添加同名的动态和静态库,那么可以通过下面的命令来实现:
      SET_TARGET_PROPERTIES(target1 target2 ...
                    PROPERTIES prop1 value1
                    prop2 value2 ...)

      对应的一个获取参数值的命令是:
      GET_TARGET_PROPERTY(VAR target property)
      比如:GET_TARGET_PROPERTY(OUTPUT_VALUE hello_static OUTPUT_NAME)
      就是获取target名为hello_static的里面的OUTPUT_NAME属性的值,并将其设置到OUTPUT_VALUE中。
    10. 当想要设置动态库的版本时候,使用如下命令:
      SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)
      其中VERSION是版本,SOVERSION是API版本。
    11. 当构建程序的时候,如果需要添加头文件搜索路径的话:
      INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)
      这条指令可以用来向工程添加多个特定的头文件搜索路径,路径之间用空格分割,如果路径
      中包含了空格,可以使用双引号将它括起来,默认的行为是追加到当前的头文件搜索路径的
      后面,你可以通过两种方式来进行控制搜索路径添加的方式:
      1,CMAKE_INCLUDE_DIRECTORIES_BEFORE,通过 SET 这个 cmake 变量为 on,可以
      将添加的头文件搜索路径放在已有路径的前面。
      2,通过 AFTER 或者 BEFORE 参数,也可以控制是追加还是置前。
    12. 为target添加链接共享库的路径:
      LINK_DIRECTORIES(directory1 directory2 ...)
      注意这个命令添加的目录只对在之后声明的target有效。如果给这个命令添加相对路径,该路径会原封不动的传递给ld。
      TARGET_LINK_LIBRARIES(target library1
                            <debug | optimized> library2
                            ...)
      这个命令可以做到单独为一个target指定链接库路径。
    13. CMAKE_INCLUDE_PATH 和 CMAKE_LIBRARY_PATH
      这两个环境变量是用来在cmake中的FIND_命令中设置默认的搜索路径,如果在cmake里面使用FIND而不设定路径,那么cmake就是会使用这两个变量的值,注意这两个变量并不是直接用在编译过程中的参数。
    14. 如果在一个模块里面有一个子库的话,可以使用TARGET_LINK_LIBRARIES来添加这些子模块。
      比如有下面的文件结构:
      top
        |---- sub1
                  |----- subsub1
                  |----- subsub2
      那么如果我们在subsub1和subsub2里面都有定义ADD_LIBRARY,而我们在使用sub1的时候需要隐藏里面的细节,也就是使用sub1自动会把subsub1和subsub2也包含进去的话,那么就是使用TARGET_LINK_LIBRARIES这个指令,如下:
      TARGET_LINK_LIBRARIES(sub1 subsub1 subsub2)
      这个命令并不会将subsub1和subsub2在创建sub1的时候将他们包含进去,而是在当其他库需要链接sub1的时候把这种依赖关系传递过去。这种性质在cmake里面transitive(传递性)。
    15. 注意在 TARGET_LINK_LIBRARIES的时候,里面添加的库之间如果有关系的话,那么使用某些函数的库必须在定义的库的前面。
      比如有如下的一个关系:
      ADD_EXECUTABLE(test test.cpp)
      TARGET_LINK_LIBRARIES(test A B)
      其中在A里面用到了B的函数foo,而B里面定义了函数foo。那么如果上面的A B的位置对调,在链接的时候就会出现undefined reference的错误,具体的原因和linker有关。
    • 0
      点赞
    • 2
      收藏
      觉得还不错? 一键收藏
    • 1
      评论

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

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

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

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

    余额充值