CMake的简单使用


构建可执行程序

add_executable( [WIN32] [MACOSX_BUNDLE]
               [EXCLUDE_FROM_ALL]
               [source1] [source2 ...])

如:

add_executable(${PROJECT_NAME} main.cpp)

或者源码目录:

aux_source_directory(${CMAKE_CURRENT_LIST_DIR} DIR_SOURCES)
add_executable(${PROJECT_NAME} ${DIR_SOURCES})

构建动态链接库/静态库

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

STATIC:表示静态库,如libname.a

SHARED:表示动态链接库,如libname.dylib

MODULE:表示可以用类似dlopen得方法动态加载库,如libname.so

构建出来的库名字会自动加上lib前缀,如libname.a,libname.dylib,libname.so

如:

add_library(${PROJECT_NAME} SHARED main.cpp)

添加头文件

include_directories(include_dir)

include_dir.h文件所在的文件夹

添加源文件

aux_source_directory(./src DIR_SOURCES)

查找把./src下所有源文件,并保存到变量DIR_SOURCES中,后面可以使用${DIR_SOURCES}表示.

需要注意的地方是:

  • aux_source_directory不会递归包含子目录,仅包含指定的目录.
  • 当添加源文件时,如需重新编译,得重新运行cmake

还可以使用CMAKE_CURRENT_LIST_DIR内置变量:

aux_source_directory(${CMAKE_CURRENT_LIST_DIR} DIR_SOURCES)

添加子目录

add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

除了写helloworld,一般都需要配置多个源码目录,这个时候可以使用add_subdirectory命令,其中source_dir表示子目录中CMakeList.txt所在的路径,binary_dir表示输出目录.

查找依赖库

  • 通过link_directories (极少使用)

    link_directories([AFTER|BEFORE] directory1 [directory2 ...])

    linker会在这些定义的目录里查找依赖的库.如lib文件夹下放置一个libskia.so库文件:

    link_directories(${CMAKE_CURRENT_LIST_DIR}/lib)

    最后链接的时候:

    target_link_libraries(${PROJECT_NAME} skia)

    这个时候,会自动到上面包含的lib文件下去寻找libskia.so(或者libskia.a,libskia.dylib)文件.

    使用XCode等项目生成器需要根据架构动态切换依赖库,或者库本身依赖私库等情况会使用这个命令,一般使用find_library()替换.

  • 通过find_library

    find_library ( name1 [path1 path2 ...])

    如果库被找到,结果会被存储到变量VAR中.如果没有找到库文件,则结果会被存储到<VAR>-NOTFOUND.如:

    find_library(LIB_SKIA skia lib)
    if(LIB_SKIA-NOTFOUND)
        message("没有找到Skia")
    endif(LIB_SKIA-NOTFOUND)
    target_link_libraries(${PROJECT_NAME} ${LIB_SKIA})
  • 通过find_package

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

    cmake中自带了一些cmake脚本,通过cmake --help-module-list命令即可查看.拿libpng举例:

    add_executable(${PROJECT_NAME} ${DIR_SOURCES})
    
    find_package(PNG)
    if(PNG_FOUND)
        include_directories(${PNG_INCLUDE_DIR})
        target_link_libraries(${PROJECT_NAME} ${PNG_LIBRARY})
        message("找到了PNG")
    endif(PNG_FOUND)
    
    if(NOT PNG_FOUND)
        message("没有找到PNG")
    endif(NOT PNG_FOUND)

    如果遇到已有脚本存在,但是就是无法找到的情况,无需在此浪费时间,换一种查找方法即可.

链接库文件

target_link_libraries( ... ... ...)

这其中item可以是下面的任何一种:

  • 库名(不带lib前缀,不带后缀)

    target_link_libraries(${PROJECT_NAME} skia)
  • 库文件的完整路径

  • 表达式

自定义输出路径

  • 指定执行文件输出路径

    set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_LIST_DIR}/build)
    • 指定Debug/Release版本

      CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG
      CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE
  • 指定库文件输出路径

    LIBRARY_OUTPUT_PATH
    • 指定Debug/Release版本

      CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG
      CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE
    • 指定Debug/Release版本后缀名

      set(CMAKE_DEBUG_POSTFIX "_d")
      set(CMAKE_RELEASE_POSTFIX "_r")

内置变量

  • CMAKE_CURRENT_LIST_DIR

    当前CMakeList.txt所在目录

  • PROJECT_NAME

    项目名

  • PROJECT_SOURCE_DIR

    源码目录


文章作者: 姜康
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 姜康 !
评论
 上一篇
GN构建C++项目之HelloWorld GN构建C++项目之HelloWorld
使用Google的gn工具构建C++项目,但是官方的demo构建脚本还是不够简单,这里写一个最简单的构建结构. 目录结构 必要的几个文件 .gn 根目录下的BUIlD.gn BUILDCONFIG.gn .gn# gn help dotf
2020-05-29
下一篇 
ModernC++的一些特性 ModernC++的一些特性
Modern C++Modern C++指的是C++11/C++14/C++17/C++20等版本,新增和改进了C++语法,提升开发效率. nullptrnullptr是用来替换NULL的 constexpr常量表达式 constexpr
2020-05-23
  目录