美文网首页
CMake 基础学习

CMake 基础学习

作者: yanlong107 | 来源:发表于2020-07-15 19:45 被阅读0次

    CMake 常用变量

    使用 ${}进行变量的引用。例如:message(${Hello_VERSION}),
    Hello为工程名。CMake提供了很多有用的变量。以下仅列举常用的变量:

    CMAKE_BINARY_DIR:
    构建树的顶层路径

    CMAKE_COMMAND:
    指向CMake可执行文件的完整路径

    CMAKE_CURRENT_BINARY_DIR:
    当前正在被处理的二进制目录的路径。

    CMAKE_CURRENT_SOURCE_DIR:
    指向正在被处理的源码目录的路径。

    CMAKE_HOME_DIRECTORY:
    指向源码树顶层的路径。

    CMAKE_PROJECT_NAME:
    当前工程的工程名。

    CMAKE_ROOT:
    CMake的安装路径。

    CMAKE_SOURCE_DIR:
    源码树的顶层路径。

    CMAKE_VERSION:
    cmake的完整版本号。

    PROJECT_BINARY_DIR:
    指向当前编译工程构建的全路径。

    <PROJECT-NAME>_BINARY_DIR:
    指向当前编译工程构建的全路径。

    <PROJECT-NAME>_SOURCE_DIR:
    指向构建工程的全路径。

    PROJECT_SOURCE_DIR:
    指向构建工程的全路径。

    PROJECT_NAME:
    project命令传递的工程名参数。

    <PROJECT-NAME>_VERSION:
    项目的完整版本号。

    CMake常用命令

    cmake_minimum_required 和 project

    设置项目要求的CMake最低版本号 和 设置项目名称

    # 设置cmake 版本信息
    cmake_minimum_required(VERSION 3.16)
    
    # 设置 项目名称
    project(demo)
    

    add_library

    添加一个库文件

    add_library(<name> [STATIC | SHARED | MODULE]
                [EXCLUDE_FROM_ALL]
                [source1] [source2 ...])
    
    <name> : 表示库文件的名字
    [STATIC | SHARED | MODULE] : 生成的库文件类型
    STATIC 静态库,在链接其他目标时使用
    SHARED 动态链接库,运行时加载
    MODULE 不会被链接到其它目标中,但是可能会在运行时使用dlopen-系列的函数动态链接
    
    例:
    # create lib , 在当前cmake 中 创建一个lib,名称为model_login,SHARED 动态库 ,后面为源文件列表
    add_library(model_login SHARED
            lib_login_model/LoginService.cpp
            utils/common_utils.cpp)
    
    add_library(lib_model_a model_utils.cpp)
    // 设置别名
    add_library(sub::modelA ALIAS lib_model_a) 
    
    

    add_subdirectory

    向构建中添加子目录(子目录中可以包含另一个cMakeLists.txt)。命令格式为

    add_subdirectory(source_dir [binary_dir]
                     [EXCLUDE_FROM_ALL])
    
    
    source_dir 需要包含的子目录。
    binary_dir 指定中间二进制和目标二进制存放的位置
    EXCLUDE_FROM_ALL 编译过程中排除的文件
    
    

    aux_source_directory

    查找目录中的所有源文件

    aux_source_directory(<dir> <variable>)
    查找指定目录dir中所有源文件的名称,并将列表存储在提供的variable中
    例:
    aux_source_directory(. DIR_SRCS)
    add_executable(${APP_NAME} ${DIR_SRCS})
    

    target_link_directories

    target_link_directories(<target> [BEFORE]
      <INTERFACE|PUBLIC|PRIVATE> [items1...]
      [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
    
    指定链接器在链接给定目标时应在其中搜索库的路径
    
    <target>: add_library 创建的target名称 或者 add_executable 创建的target名称
    
    target_link_libraries([TARGET_NAME] [链接库名字])  # 按名字添加
    target_link_directories([链接库目录])  # 按目录添加
    
    

    target_include_directories

    target_include_directories(<target> [SYSTEM] [BEFORE]
      <INTERFACE|PUBLIC|PRIVATE> [items1...]
      [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
    
    指定在编译给定目标时要使用的包含目录
    # 添加头文件的路径,以便查找到头文件
    <target>: add_library 创建的target名称 或者 add_executable 创建的target名称
    例:
    target_include_directories(lib_model_a PUBLIC ${PROJECT_SOURCE_DIR})
    
    

    find_library

    查找一个库文件.
    该命令用来查找一个库文件。一个名为<VAR>的cache条目会被创建来存储该命令的结果。如果找到了该库文件,那么结果会存储在该变量里,并且搜索过程将不再重复,除非该变量被清空。如果没有找到,结果变量将会是<VAR>-NOTFOUND,并且在下次使用相同变量调用find_library命令时,搜索过程会再次尝试。

    find_library(<VAR> name1 [path1 path2 ...])
    
    例如:
    link_directories(....) // 动态链接库或静态链接库的搜索路径
    find_library(Foundation Foundation)
    
    

    add_definitions

    // 为源文件的编译添加由-D引入的宏定义。命令格式为:
    add_definitions(-DFOO -DBAR ...)
    

    add_dependencies

    使顶级目标依赖于其他顶级目标,以确保它们在该目标之前构建。这里的顶级目标是由add_executable,add_library或add_custom_target命令之一创建的目标
    
    add_library(model_login SHARED
            lib_login_model/LoginService.cpp
            utils/common_utils.cpp)
    add_executable(demo main.cpp config.h.in Simple.cpp)
    add_dependencies(demo model_login)
    

    add_executable

    添加一个可执行文件

    # create exe
    add_executable(demo main.cpp config.h.in Simple.cpp)
    

    target_link_libraries

    将给定的库链接到一个目标上

    target_link_libraries(<target> ... <item>... ...)
    
    例:
    target_link_libraries(demo
            model_login)
    
    

    include_directories

    将给定的目录添加到编译器用于搜索包含文件的目录。相对路径则相对于当前源目录。命令格式为:

    include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
    
    例:
    // 指定头文件的搜索路径
    include_directories(
      ${CMAKE_CURRENT_SOURCE_DIR}
      ${CMAKE_CURRENT_SOURCE_DIR}/cocos
      ${CMAKE_CURRENT_SOURCE_DIR}/cocos/platform
      ${CMAKE_CURRENT_SOURCE_DIR}/extensions
      ${CMAKE_CURRENT_SOURCE_DIR}/external
    )
    

    message

    向用户显示消息。命令格式为:

    message([<mode>] "message to display" ...)
    参数说明:
    mode:
    可选的值为none,STATUS,WARNING,AUTHOR_WARNING,SEND_ERROR,FATAL_ERROR,DEPRECATION。
    例:
    message(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})
    

    set

    将一个CMAKE变量设置为给定值。命令格式为:

    set(<variable> <value>... [PARENT_SCOPE])
    
    例:
    set(COCOS2D_ROOT ${CMAKE_SOURCE_DIR}/cocos2d)
    

    set(CMAKE_CXX_FLAGS)

    传递FLAGS给C++编译器:设置CMAKE_CXX_FLAGS变量

    set(CMAKE_CXX_COMPILER      "clang++" )         # 显示指定使用的C++编译器
    set(CMAKE_CXX_FLAGS   "-std=c++11")             # c++11
    set(CMAKE_CXX_FLAGS   "-g")                     # 调试信息
    set(CMAKE_CXX_FLAGS   "-Wall")                  # 开启所有警告
    set(CMAKE_CXX_FLAGS_DEBUG   "-O0" )             # 调试包不优化
    set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG " )   # release包优化
    
    
    CMAKE_CXX_FLAGS 是CMake传给C++编译器的编译选项,通过设置这个值就好比 g++ -std=c++11 -g -Wall
    CMAKE_CXX_FLAGS_DEBUG 是除了CMAKE_CXX_FLAGS外,在Debug配置下,额外的参数
    CMAKE_CXX_FLAGS_RELEASE 同理,是除了CMAKE_CXX_FLAGS外,在Release配置下,额外的参数
    
    
    

    configure_file

    将文件复制到其他位置并修改其内容。命令格式为

    configure_file(<input> <output>
                   [COPYONLY] [ESCAPE_QUOTES] [@ONLY]
                   [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
    
    
    例:
    # 添加config 配置文件 版本信息 
    set(demo_VERSION_MAJOR 1)
    set(demo_VERSION_MINOR 0)
    set(demo_VERSION_PATCH 10)
    set(demo_VERSION_BUILD 100)
    
    set(CONFIG_VERSION "${demo_VERSION_MAJOR}.${demo_VERSION_MINOR}.${demo_VERSION_PATCH}.${demo_VERSION_BUILD}")
    
    
    configure_file(${PROJECT_SOURCE_DIR}/config.h.in ${PROJECT_BINARY_DIR}/config.h)
    
    

    config.h.in 文件如下:

    
    #cmakedefine USE_MYMATH
    
    
    #ifndef DEMO_CONFIG_H
    #define DEMO_CONFIG_H
    
    
    
    
    const char* version = "${CONFIG_VERSION}";
    
    
    
    #endif //DEMO_CONFIG_H
    
    

    file

    文件操作相关的命令。命令格式为:

    file(WRITE <filename> <content>...)
    file(APPEND <filename> <content>...)
    file(READ <filename> <variable>
         [OFFSET <offset>] [LIMIT <max-in>] [HEX])
    file(STRINGS <filename> <variable> [<options>...])
    file(<MD5|SHA1|SHA224|SHA256|SHA384|SHA512> <filename> <variable>)
    file(GLOB <variable>
         [LIST_DIRECTORIES true|false] [RELATIVE <path>]
         [<globbing-expressions>...])
    file(GLOB_RECURSE <variable> [FOLLOW_SYMLINKS]
         [LIST_DIRECTORIES true|false] [RELATIVE <path>]
         [<globbing-expressions>...])
    file(RENAME <oldname> <newname>)
    file(REMOVE [<files>...])
    file(REMOVE_RECURSE [<files>...])
    file(MAKE_DIRECTORY [<directories>...])
    file(RELATIVE_PATH <variable> <directory> <file>)
    file(TO_CMAKE_PATH "<path>" <variable>)
    file(TO_NATIVE_PATH "<path>" <variable>)
    file(DOWNLOAD <url> <file> [<options>...])
    file(UPLOAD   <file> <url> [<options>...])
    file(TIMESTAMP <filename> <variable> [<format>] [UTC])
    file(GENERATE OUTPUT output-file
         <INPUT input-file|CONTENT content>
         [CONDITION expression])
    file(<COPY|INSTALL> <files>... DESTINATION <dir>
         [FILE_PERMISSIONS <permissions>...]
         [DIRECTORY_PERMISSIONS <permissions>...]
         [NO_SOURCE_PERMISSIONS] [USE_SOURCE_PERMISSIONS]
         [FILES_MATCHING]
         [[PATTERN <pattern> | REGEX <regex>]
          [EXCLUDE] [PERMISSIONS <permissions>...]] [...])
    file(LOCK <path> [DIRECTORY] [RELEASE]
         [GUARD <FUNCTION|FILE|PROCESS>]
         [RESULT_VARIABLE <variable>]
         [TIMEOUT <seconds>])
    
    例:
    # 查找src目录下所有以hello开头的文件并保存到SRC_FILES变量里
    file(GLOB SRC_FILES "src/hello*")
    # 递归查找
    file(GLOB_RECURSE SRC_FILES "src/hello*")
    

    完整CmakeList.txt 文件

    工程结构如下:

    ├── 
    ├── lib_login_model/
    │   ├── LoginService.cpp
    │   ├── LoginService.h
    ├── lib_modelA/
    │   ├── CMakeLists.txt
    │   ├── model_utils.cpp
    │   ├── model_utils.h
    ├── uils/
    │   ├── common_utils.cpp
    │   ├── common_utils.h
    ├── CMakeLists.txt
    ├── ServiceResult.h
    

    CmakeList配置文件如下:

    cmake_minimum_required(VERSION 3.16)
    
    # set the project name
    project(demo)
    
    # 设置 C++ 14
    set(CMAKE_CXX_STANDARD 14)
    
    
    # create lib , 在当前cmake 中 创建一个lib
    add_library(model_login SHARED
            lib_login_model/LoginService.cpp
            utils/common_utils.cpp)
    
    
    # 添加头文件的路径,以便查找到头文件
    target_include_directories(model_login PRIVATE ${PROJECT_SOURCE_DIR}/lib_login_model ${PROJECT_SOURCE_DIR}/utils)
    
    
    # 添加config 配置文件
    set(demo_VERSION_MAJOR 1)
    set(demo_VERSION_MINOR 0)
    set(demo_VERSION_PATCH 10)
    set(demo_VERSION_BUILD 100)
    
    set(CONFIG_VERSION "${demo_VERSION_MAJOR}.${demo_VERSION_MINOR}.${demo_VERSION_PATCH}.${demo_VERSION_BUILD}")
    
    
    configure_file(${PROJECT_SOURCE_DIR}/config.h.in ${PROJECT_BINARY_DIR}/config.h)
    
    
    # 添加子目录, 子目录中有另外一个cMakeLists.txt文件 lib_modelA
    #include_directories ("${PROJECT_SOURCE_DIR}/lib_modelA")
    add_subdirectory(lib_modelA)
    
    
    option (USE_MYMATH
            "Use tutorial provided math implementation" OFF)
    
    
    # ADD_DEFINITIONS 添加 编译宏
    
    ADD_DEFINITIONS(-DENABLE_REALEASE)
    
    
    
    # create exe
    add_executable(demo main.cpp config.h.in Simple.cpp)
    
    target_include_directories(demo PUBLIC ${PROJECT_BINARY_DIR})
    target_include_directories(demo PUBLIC ${PROJECT_SOURCE_DIR})
    
    target_link_libraries(demo
            model_login)
    
    target_link_libraries(demo
            sub::modelA)
      
    

    lib 库的配置文件

    cmake_minimum_required(VERSION 3.16)
    
    # project 貌似设置或者不设置都可以
    project(model_a)
    
    add_library(lib_model_a model_utils.cpp)
    add_library(sub::modelA ALIAS lib_model_a)
    
    
    target_include_directories(lib_model_a PUBLIC ${PROJECT_SOURCE_DIR})
    
    

    参考资料:
    CMake 官网

    CMake学习

    相关文章

      网友评论

          本文标题:CMake 基础学习

          本文链接:https://www.haomeiwen.com/subject/lppfhktx.html