CMakeLists个人学习部分总结

注:一般Cmake编译会用out-of-source,就是新建一个build文件

1. 预定义变量

PROJECT_SOURCE_DIR:工程的根目录
PROJECT_BINARY_DIR运行 cmake 命令的目录,通常是 ${PROJECT_SOURCE_DIR}/build
PROJECT_NAME:返回通过 project 命令定义的项目名称


CMAKE_CURRENT_SOURCE_DIR:当前处理的 CMakeLists.txt 所在的路径

就是source所在路径,以上都是基于out-of-source进行解释


CMAKE_CURRENT_BINARY_DIR:target 编译目录(build)
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:重新定义目标链接库文件的输出位置
例如:set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

4.生成库文件

add_library 默认生成静态库

aux_source_directory(dir VAR) 发现一个目录下所有的源代码文件并将列表存储在一个变量中。

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

5. 查找指定的库文件

        find_library(VAR name path)查找到指定的预编译库,并将它的路径存储在变量中。
默认的搜索路径为 cmake 包含的系统库,因此如果是 NDK 的公共库只需要指定库的 name 即可。

find_file()      重点:找到文件的全路径(包含文件名)(查找需要全称),默认路径是CMAKE_INCLUDE_PATH
find_path()      重点:找到文件的文件夹路径(查找需要全称),默认路径是CMAKE_INCLUDE_PATH
find_library()   重点:找到文件的全路径(包含文件名)(查找不需要全称),默认路径是CMAKE_LIBRARY_PATH
find_library(TESTFUNC_LIB testFunc HINTS ${PROJECT_SOURCE_DIR}/testFunc/lib)

        find_library: 在指定目录下查找指定库,并把库的绝对路径存放到变量里,其第一个参数是变量名称,第二个参数是库名称,第三个参数是HINTS,第4个参数是路径,其它用法可以参考cmake文档

HINTS表示在默认搜索路径之前搜索

注:HINTS 与 PATHS

        Long story short: Hints get searched before the system paths, and
should only be set by some source of knowledge (location of other
files, etc) and not populated with "guesses" or default locations.
Paths get searched after system locations, and is the place to put
default locations.

    find_library( # Sets the name of the path variable.
                  log-lib
     
                  # Specifies the name of the NDK library that
                  # you want CMake to locate.
                  log )

类似的命令还有 find_file()、find_path()、find_program()、find_package()。

6. 设置包含的目录

设置头文件的目录

相当于指定g++编译器的-I参数      是i

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

Linux 下还可以通过如下方式设置包含的目录

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_CURRENT_SOURCE_DIR}")

7. 设置链接库搜索目录         

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

相当于指定g++编译器的-L参数

link_directories(
    ${CMAKE_CURRENT_SOURCE_DIR}/libs
)

Linux 下还可以通过如下方式设置包含的目录

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_CURRENT_SOURCE_DIR}/libs")

8. 设置 target 需要链接的库

相同于指定g++编译器-l参数        target_link_libraries

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

 该指令的作用为将目标文件与库文件进行链接。该指令的语法如下:

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

        上述指令中的<target>是指通过add_executable()add_library()指令生成已经创建的目标文件。而[item]表示没有后缀的库文件名字。

注:为什么可以用于add_library(),也不是很明白,感觉add_library()就是生成库用的

主要用法:

        target_link_libraries(可执行文件,库名)

例子:

在 Windows 下,系统会根据链接库目录,搜索xxx.lib 文件,Linux 下会搜索 xxx.so 或者 xxx.a 文件,如果都存在会优先链接动态库(so 后缀)。

8.1 指定链接动态库或静态库

    target_link_libraries(demo libface.a) # 链接libface.a
    target_link_libraries(demo libface.so) # 链接libface.so

8.2 指定全路径

    target_link_libraries(demo ${CMAKE_CURRENT_SOURCE_DIR}/libs/libface.a)
    target_link_libraries(demo ${CMAKE_CURRENT_SOURCE_DIR}/libs/libface.so)

 8.3 指定链接多个库

      target_link_libraries(demo
        ${CMAKE_CURRENT_SOURCE_DIR}/libs/libface.a
        boost_system.a
        boost_thread
        pthread)

9. 设置变量

9.1 set 直接设置变量的值

set(SRC_LIST main.cpp test.cpp)
add_executable(demo ${SRC_LIST})

9.2 set 追加设置变量的值

    set(SRC_LIST main.cpp)
    set(SRC_LIST ${SRC_LIST} test.cpp)
    add_executable(demo ${SRC_LIST})

9.3 list 追加或者删除变量的值

    set(SRC_LIST main.cpp)
    list(APPEND SRC_LIST test.cpp)
    list(REMOVE_ITEM SRC_LIST main.cpp)
    add_executable(demo ${SRC_LIST})

10. 条件控制

10.1 if…elseif…else…endif

逻辑判断和比较:
if (expression):expression 不为空(0,N,NO,OFF,FALSE,NOTFOUND)时为真
if (not exp):与上面相反
if (var1 AND var2)
if (var1 OR var2)
if (COMMAND cmd):
如果 cmd 确实是命令并可调用为真
if (EXISTS dir) if (EXISTS file):如果目录或文件存在为真
if (file1 IS_NEWER_THAN file2):当 file1 比 file2 新,或 file1/file2 中有一个不存在时为真,文件名需使用全路径
if (IS_DIRECTORY dir):当 dir 是目录时为真
if (DEFINED var):如果变量被定义为真
if (var MATCHES regex):给定的变量或者字符串能够匹配正则表达式 regex 时为真,此处 var 可以用 var 名,也可以用 ${var}
if (string MATCHES regex)

数字比较:

if (variable LESS number):LESS 小于
if (string LESS number)
if (variable GREATER number):
GREATER 大于
if (string GREATER number)
if (variable EQUAL number):
EQUAL 等于
if (string EQUAL number)

字母表顺序比较:
if (variable STRLESS string)
if (string STRLESS string)
if (variable STRGREATER string)
if (string STRGREATER string)
if (variable STREQUAL string)
if (string STREQUAL string)

 示例:

if(MSVC)
    set(LINK_LIBS common)
else()
    set(boost_thread boost_log.a boost_system.a)
endif()
target_link_libraries(demo ${LINK_LIBS})
# 或者
if(UNIX)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fpermissive -g")
else()
    add_definitions(-D_SCL_SECURE_NO_WARNINGS
    D_CRT_SECURE_NO_WARNINGS
    -D_WIN32_WINNT=0x601
    -D_WINSOCK_DEPRECATED_NO_WARNINGS)
endif()
 
if(${CMAKE_BUILD_TYPE} MATCHES "debug")
    ...
else()
    ...
endif()

10.2 while…endwhile

while(condition)
    ...
endwhile()

 10.3 foreach…endforeach

foreach(loop_var RANGE start stop [step])
    ...
endforeach(loop_var)

start 表示起始数,stop 表示终止数,step 表示步长,示例:

    foreach(i RANGE 1 9 2)
        message(${i})
    endforeach(i)
    # 输出:13579

11. 打印信息

message(${PROJECT_SOURCE_DIR})
message("build with debug mode")
message(WARNING "this is warnning message")
message(FATAL_ERROR "this build has many error") # FATAL_ERROR 会导致编译失败

12 主要开关选项

可以参考文档

BUILD_SHARED_LIBS:这个开关用来控制默认的库编译方式,如果不进行设置,使用 add_library 又没有指定库类型的情况下,默认编译生成的库都是静态库。如果 set(BUILD_SHARED_LIBS ON) 后,默认生成的为动态库
CMAKE_C_FLAGS:设置 C 编译选项,也可以通过指令 add_definitions() 添加
CMAKE_CXX_FLAGS:设置 C++ 编译选项,也可以通过指令 add_definitions() 添加
 

参考博客

https://www.cnblogs.com/coderfenghc/archive/2012/06/23/2559603.html

CMakeLists.txt 语法介绍与实例演练_阿飞的博客-CSDN博客_cmakelist

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值