CMakeLists.txt终极配置模版+超详细细节索引导航

727 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情。你可以简单浏览一下目录,有需要的阅读,写文章不易,阅读之前请给我点个赞吧~

一、官方cmake配置命令使用方法

授人以鱼不如授人以渔,大家可以在官网找到命令的更多细节,可以边用边找。 这里主要可以看到以下五个部分的命令,大家根据需求自行搜索

1. 脚本命令/Scripting Commands

这些命令总是可用的。

blockbreakcmake_host_system_informationcmake_language
cmake_minimum_requiredcmake_parse_argumentscmake_pathcmake_policy
configure_filecontinueelseelseif
endblockendforeachendfunctionendif
endmacroendwhileexecute_processfile
find_filefind_libraryfind_packagefind_path
find_programforeachfunctionget_cmake_property
get_directory_propertyget_filename_componentget_propertyif
includeinclude_guardlistmacro
mark_as_advancedmathmessageoption
returnseparate_argumentssetset_directory_properties
set_propertysite_namestringunset
variable_watchwhile

2. 工程命令/Project Commands

这些命令只在CMake项目中可用。

add_compile_definitionsadd_compile_optionsadd_custom_commandadd_custom_target
add_definitionsadd_dependenciesadd_executableadd_library
add_link_optionsadd_subdirectoryadd_testaux_source_directory
build_commandcreate_test_sourcelistdefine_propertyenable_language
enable_testingexportfltk_wrap_uiget_source_file_property
get_target_propertyget_test_propertyinclude_directoriesinclude_external_msproject
include_regular_expressioninstalllink_directorieslink_libraries
load_cacheprojectremove_definitionsset_source_files_properties
set_target_propertiesset_tests_propertiessource_grouptarget_compile_definitions
target_compile_featurestarget_compile_optionstarget_include_directoriestarget_link_directories
target_link_librariestarget_link_optionstarget_precompile_headerstarget_sources
try_compiletry_run

3. CTest脚本命令/CTest Commands

这些命令只在CTest脚本中可用。

4. Deprecated Commands

这些命令已被弃用,仅用于维护向后兼容性。每个命令的文档都说明了它被弃用的CMake版本。不要在新代码中使用这些命令。

5. CMake中预设的一些变量

例如,我们经常用到的 CMAKE_BINARY_DIRCMAKE_PROJECT_NAMECMAKE_PREFIX_PATH 等都可以在这里找到,可以根据我们的需求自行查询。

二、"CMakeLists.txt" 组织大型工程常用命令模板总结

1. cmake_minimum_required

# Setup the minimum version required of CMake to generate the Makefile
# 设置cmake最小版本号
cmake_minimum_required (VERSION 2.8)

# Raises a FATAL_ERROR if version < 2.8
#  不满足提示错误
cmake_minimum_required (VERSION 2.8 FATAL_ERROR)

2. project

# We define the name of our project, and this changes some directories
# naming convention generated by CMake. We can send the LANG of code
# as the second param
# 设置项目名称,指定语言(这里是CXX,也就是C++)
project (learncmake CXX)

3. set

# 给变量赋值
# Set the project source dir (just convention)
# 源码目录
set( LEARN_CMAKE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )
# 目标二进制文件的目录
set( LEARN_CMAKE_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} )

# 设置语义版本
# It's useful to set up the current version of our code in the build system
# using a `semver` style
set (LEARN_CMAKE_VERSION_MAJOR 1)
set (LEARN_CMAKE_VERSION_MINOR 0)
set (LEARN_CMAKE_VERSION_PATCH 0)

4. configure_file

# 将文件复制到另一个位置并修改其内容,比如管理版本号,打包管理等
# Send the variables (version number) to the source code header
configure_file (
  "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
  "${PROJECT_BINARY_DIR}/TutorialConfig.h"
)

5. include_directories

# 包含目录,指定目录,给预编译器做头文件搜索
# Include Directories
# In GCC, this will invoke the "-I" command
include_directories( include )
include_directories(./ ./hello ./world)

6. CMAKE_MODULE_PATH

# CMake的模块化,有多个模块;
# 通过 CMAKE_MODULE_PATH 配置寻找模块的路径,可以写CMake自带的,还可以添加自己的
# Where are the additional libraries installed? Note: provide includes
# path here, subsequent checks will resolve everything else
set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMake/modules/" )

7. Conditions

if ( CONDITION )
  # Output!

  # Incidental information
  message(STATUS "My message")

  # CMake Warning, continue processing
  message(WARNING "My message")

  # CMake Warning (dev), continue processing
  message(AUTHOR_WARNING "My message")

  # CMake Error, continue processing, but skip generation
  message(SEND_ERROR "My message")

  # CMake Error, stop processing and generation
  message(FATAL_ERROR "My message")
endif()

if( CONDITION )

elseif( CONDITION )

else( CONDITION )

endif( CONDITION )

8. 循环

8.1 foreach()...endforeach()

foreach(loop_var arg1 arg2 ...)
  COMMAND1(ARGS ...)
  COMMAND2(ARGS ...)
  ...
endforeach(loop_var)

foreach(loop_var RANGE total)
foreach(loop_var RANGE start stop [step])

foreach(loop_var IN [LISTS [list1 [...]]]
                    [ITEMS [item1 [...]]])

8.2 while()...endwhile()

while(condition)
  COMMAND1(ARGS ...)
  COMMAND2(ARGS ...)
  ...
endwhile(condition)

9. 逻辑运算:AND、OR

if(FALSE AND (FALSE OR TRUE))
  message("Don't display!")
endif()

# Set a regular, cache, or environment variable to a given value.
# If the PARENT_SCOPE option is given, the variable will be set in the scope
# above the current scope.
# `set(<variable> <value>... [PARENT_SCOPE])`

# How to reference variables inside quoted and unquoted arguments?
# A variable reference is replaced by either the variable value or by the 
# empty string if the variable is not set.
${variable_name}

10. Lists:使用 set 把多个文件赋值给列表型变量

# Setup the list of source files
set( LEARN_CMAKE_SOURCES 
  src/main.c
  src/imagem.c
  src/pather.c
)

11. add_executable

# 指定编译构建的可执行的目标
# Calls the compiler

# ${PROJECT_NAME} 指代项目名称 Learn_CMake 
add_executable( ${PROJECT_NAME} ${LEARN_CMAKE_SOURCES} )

12. add_library

# 添加库文件
add_library()

13. add_subdirectory

# 添加模块子目录
# Add block directories
add_subdirectory(hello)
add_subdirectory(world)

14. target_link_libraries

# 链接库
# Link the libraries
target_link_libraries( ${PROJECT_NAME} ${LIBS} m )

15. Compiler Condition (gcc ; g++)

if ( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" )
  message( STATUS "Setting the flags for ${CMAKE_C_COMPILER_ID} compiler" )
  add_definitions( --std=c99 )
endif()

16. 编译系统(OS)的判断

if( UNIX )
    set( LEARN_CMAKE_DEFINITIONS
        "${LEARN_CMAKE_DEFINITIONS} -Wall -Wextra -Werror -Wno-deprecated-declarations -Wno-unused-parameter -Wno-comment" )
endif()

三、区分

include_directoriesadd_subdirectoryadd_library
向构建中添加包含目录向构建添加子目录使用指定的源文件向项目添加库
正常库/对象库/接口库/导入库/别名库