找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 70|回复: 0

OLLVM学习之三 —— CMake学习

[复制链接]
发表于 2024-9-10 22:46:17 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×

写在前面

  因为有事在外地一周, 所以OLLVM学习耽搁了几天, 现在接着之前的研究继续. 为什么要研究CMake呢, 因为LLVM底层使用CMake编译, 且笔者将要作为测试基板的LLVM-Pass基于CMake也是最方便的, 虽然笔者在第一篇中也用过Makefile.

CMake版本历史

  • 2003-08   1.x
  • 2005-04   2.x
  • 2014-06   3.0     引入target_*/find_package
  • 2014-12   3.1     支持C++11/14, 引入CMake_build_type
  • 2015-03   3.2     支持UTF8, 引入CMake_language/CMake_policy
  • 2015-11   3.4     支持Swift, 支持CCache
  • 2016-03   3.5     支持ARM
  • 2016-11   3.7     支持交叉编译到Android, 支持服务器模式
  • 2017-04   3.8     支持C#, 支持CUDA, 支持C++17
  • 2017-11   3.10    支持CppCheck
  • 2018-07   3.12    支持cmake_minimum_required, 支持-j/--parallel并行构建, 支持C++20
  • 2018-11   3.13    支持target_link_options/add_link_options/target_link_directories
  • 2019-11   3.16    支持Objective-C/Objective-C++
  • 2021-03   3.20    支持C++23
  • 2021-07   3.21    支持MSYS
  • 2022-11   3.25    支持C++26

CMake语法

变量

  • 本地变量
set(<variable> <value>... [PARENT_SCOPE])
unset(<variable> [PARENT_SCOPE])
set(MY_VARIABLE "value")    # 声明变量
set(MY_LIST "one" "two")    # 列表
set(MY_LIST "one;two")      # 同上
  • 缓存变量
set(<variable> <value>... CACHE <type> <docstring> [FORCE])
unset(<variable> [CACHE])

预定义变量https://cmake.org/cmake/help/latest/manual/cmake-variables.7.html

set(MY_CACHE_VARIABLE "VALUE" CACHE STRING "Description")
set(MY_CACHE_VARIABLE "VALUE" CACHE STRING "" FORCE)    # 覆盖已有值
option(MY_OPTION "This is settable from the command line" OFF)  # BOOL型变量
  • 环境变量
set(ENV{<variable>} [<value>])
unset(ENV{<variable>})
set(ENV{MY_ENV} value)      # 设置
$ENV{MY_ENV}                # 读取
  • 属性
set_property(<GLOBAL                      |
              DIRECTORY [<dir>]           |
              TARGET    [<target1> ...]   |
              SOURCE    [<src1> ...]
                        [DIRECTORY <dirs> ...]
                        [TARGET_DIRECTORY <targets> ...] |
              INSTALL   [<file1> ...]     |
              TEST      [<test1> ...]
                        [DIRECTORY <dir>] |
              CACHE     [<entry1> ...]    >
             [APPEND] [APPEND_STRING]
             PROPERTY <name> [<value1> ...])

预定义属性https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html

set_property(TARGET TargetName PROPERTY CXX_STANDARD 11)  # 可设置多目标
set_target_properties(TargetName PROPERTIES CXX_STANDARD 11) # 设置一个目标多属性
get_property(ResultVariable TARGET TargetName PROPERTY CXX_STANDARD)

宏和函数

宏:

macro(<name> [<arg1> ...])
  <commands>
endmacro()

参数:
${ARGC}, ${ARGV0}, ${ARGV1}, ${ARGV2}, ...
${ARGN}

例:

macro(foo)
  <commands>
endmacro()
# 调用
foo()
Foo()
FOO()
cmake_language(CALL foo)

if(${ARGV1})
if(${ARGC} GREATER 2)
set(list_var "${ARGN}")
foreach(loop_var IN LISTS list_var)

函数:

function(<name> [<arg1> ...])
  <commands>
endfunction()

调用及参数同宏

function(SIMPLE REQUIRED_ARG)
    message(STATUS "Simple arguments: ${REQUIRED_ARG}, followed by ${ARGN}")
    set(${REQUIRED_ARG} "From SIMPLE" PARENT_SCOPE)
endfunction()

simple(This Foo Bar)
message("Output: ${This}")

输出:

-- Simple arguments: This, followed by Foo;Bar
Output: From SIMPLE

cmake_language

  • 动态调用
    cmake_language(CALL <command> [<arg>...])

禁止的命令:

  • if/elseif/else/endif
  • block/endblock
  • while/endwhile
  • foreach/endforeach
  • function/endfunction
  • macro/endmacro
set(message_command "message")
cmake_language(CALL ${message_command} STATUS "Hello World!")
# 等价于
message(STATUS "Hello World!")
  • 表达式计算

cmake_language(EVAL CODE <code>...)

set(A TRUE)
set(B TRUE)
set(C TRUE)
set(condition "(A AND B) OR C")
cmake_language(EVAL CODE "
  if (${condition})
    message(STATUS TRUE)
  else()
    message(STATUS FALSE)
  endif()"
)
# 等价于
set(A TRUE)
set(B TRUE)
set(C TRUE)
set(condition "(A AND B) OR C")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/eval.cmake "
  if (${condition})
    message(STATUS TRUE)
  else()
    message(STATUS FALSE)
  endif()"
)
include(${CMAKE_CURRENT_BINARY_DIR}/eval.cmake)
  • 延迟调用

cmake_language(DEFER <options>... CALL <command> [<arg>...])

cmake_language(DEFER CALL message "${deferred_message}")
cmake_language(DEFER ID_VAR id CALL message "Canceled Message")
cmake_language(DEFER CANCEL_CALL ${id})
message("Immediate Message")
set(deferred_message "Deferred Message")
# output
#Immediate Message
#Deferred Message
set(deferred_message "Deferred Message 1")
set(re_evaluated [[${deferred_message}]])
cmake_language(EVAL CODE "
  cmake_language(DEFER CALL message [[${deferred_message}]])
  cmake_language(DEFER CALL message \"${re_evaluated}\")
")
message("Immediate Message")
set(deferred_message "Deferred Message 2")
# output
#Immediate Message
#Deferred Message 1
#Deferred Message 2
  • 获取日志等级

cmake_language(GET_MESSAGE_LOG_LEVEL <output_variable>)

  • 终止脚本

cmake_language(EXIT <exit-code>)

控制流程

条件语法优先级

  • 括号
  • 一元操作符: EXISTS, COMMAND, DEFINED, NOT, TARGET
  • 二元操作符: EQUAL, LESS, LESS_EQUAL, GREATER, GREATER_EQUAL, STREQUAL, STRLESS, STRLESS_EQUAL, STRGREATER, STRGREATER_EQUAL, VERSION_EQUAL, VERSION_LESS, VERSION_LESS_EQUAL, VERSION_GREATER, VERSION_GREATER_EQUAL, PATH_EQUAL, MATCHESVERSION_LESS_EQUAL
  • 一元逻辑操作符: NOT
  • 二元逻辑操作符: AND, OR

if

语法

if(<condition>)
  <commands>
elseif(<condition>) # optional block, can be repeated
  <commands>
else()              # optional block
  <commands>
endif()
基本表达式
if(<constant>)      # True if the constant is 1, ON, YES, TRUE, Y, or a non-zero number, False if the constant is 0, OFF, NO, FALSE, N, IGNORE, NOTFOUND, the empty string, or ends in the suffix -NOTFOUND
if(<variable>)      # True if given a variable that is defined to a value that is not a false constant. False otherwise, including if the variable is undefined
if(<string>)        # A quoted string always evaluates to false unless the string's value is one of the true constants
逻辑操作
if(NOT <condition>)
if(<cond1> AND <cond2>)
if(<cond1> OR <cond2>)
if((condition) AND (condition OR (condition)))
存在性检测
if(COMMAND <command-name>)      # 若目标为命令/宏/函数则为真
if(POLICY <policy-id>)
if(TARGET <target-name>)        # 若目标为add_executable/add_library/add_custom_target创建则为真
if(TEST <test-name>)            # 若目标是add_test创建则为真
if(DEFINED <name>|CACHE{<name>}|ENV{<name>}) # 若目标是变量/缓存变量/环境变量则为真
if(<variable|string> IN_LIST <variable>)
文件操作
if(EXISTS <path-to-file-or-directory>)
if(IS_READABLE <path-to-file-or-directory>)
if(IS_WRITABLE <path-to-file-or-directory>)
if(IS_EXECUTABLE <path-to-file-or-directory>)
if(<file1> IS_NEWER_THAN <file2>)
if(IS_DIRECTORY <path>)
if(IS_SYMLINK <path>)
if(IS_ABSOLUTE <path>)
比较
if(<variable|string> MATCHES <regex>)
if(<variable|string> LESS <variable|string>)
if(<variable|string> GREATER <variable|string>)
if(<variable|string> EQUAL <variable|string>)
if(<variable|string> LESS_EQUAL <variable|string>)
if(<variable|string> GREATER_EQUAL <variable|string>)
if(<variable|string> STRLESS <variable|string>)
if(<variable|string> STRGREATER <variable|string>)
if(<variable|string> STREQUAL <variable|string>)
if(<variable|string> STRLESS_EQUAL <variable|string>)
if(<variable|string> STRGREATER_EQUAL <variable|string>)
版本比较
if(<variable|string> VERSION_LESS <variable|string>)
if(<variable|string> VERSION_GREATER <variable|string>)
if(<variable|string> VERSION_EQUAL <variable|string>)
if(<variable|string> VERSION_LESS_EQUAL <variable|string>)
if(<variable|string> VERSION_GREATER_EQUAL <variable|string>)
路径比较
if(<variable|string> PATH_EQUAL <variable|string>)
# comparison is TRUE
if ("/a//b/c" PATH_EQUAL "/a/b/c")
   ...
endif()

# comparison is FALSE
if ("/a//b/c" STREQUAL "/a/b/c")
   ...
endif()

while

while(<condition>)
  <commands>
endwhile()

foreach

foreach(<loop_var> <items>)
  <commands>
endforeach()

foreach(<loop_var> RANGE <stop>)
foreach(<loop_var> RANGE <start> <stop> [<step>])
foreach(<loop_var> IN [LISTS [<lists>]] [ITEMS [<items>]])

set(A 0;1)
set(B 2 3)
set(C "4 5")
set(D 6;7 8)
set(E "")
foreach(X IN LISTS A B C D E)
    message(STATUS "X=${X}")
endforeach()
foreach(<loop_var>... IN ZIP_LISTS <lists>)

list(APPEND English one two three four)
list(APPEND Bahasa satu dua tiga)

foreach(num IN ZIP_LISTS English Bahasa)
    message(STATUS "num_0=${num_0}, num_1=${num_1}")
endforeach()

foreach(en ba IN ZIP_LISTS English Bahasa)
    message(STATUS "en=${en}, ba=${ba}")
endforeach()

break/continue

生成器表达式

可用于配置/构建/安装阶段
配置表达式: $<CONFIG:cfg_lst>, CONFIG满足cfg_lst中一个则表达式为1, 否则为0
条件表达式: $<condition:true_string>, condition满足则表达式为true_string

# 在配置阶段的DEBUG模式下开启编译标志
target_compile_options(MyTarget PRIVATE "$<$<CONFIGebug>:--my-flag>")

# 编译阶段和安装阶段指定不同的目录
target_include_directories(
    MyTarget
  PUBLIC
    $<BUILD_INTERFACE{CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)

block

block([SCOPE_FOR [POLICIES] [VARIABLES] ] [PROPAGATE <var-name>...])
  <commands>
endblock()
set(var1 "INIT1")
set(var2 "INIT2")

block(PROPAGATE var1 var2)
  set(var1 "VALUE1")
  unset(var2)
endblock()

# Now var1 holds VALUE1, and var2 is unset

return

从文件/目录/函数返回

return([PROPAGATE <var-name>...])
function(multi_scopes result_var1 result_var2)
  block(SCOPE_FOR VARIABLES)
    # This would only propagate out of the immediate block, not to
    # the caller of the function.
    #set(${result_var1} "new-value" PARENT_SCOPE)
    #unset(${result_var2} PARENT_SCOPE)

    # This propagates the variables through the enclosing block and
    # out to the caller of the function.
    set(${result_var1} "new-value")
    unset(${result_var2})
    return(PROPAGATE ${result_var1} ${result_var2})
  endblock()
endfunction()

set(var1 "some-value")
set(var2 "another-value")

multi_scopes(var1 var2)
# Now var1 will hold "new-value" and var2 will be unset

block(SCOPE_FOR VARIABLES)
  # This return() will set var1 in the directory scope that included us
  # via add_subdirectory(). The surrounding block() here does not limit
  # propagation to the current file, but the block() in the parent
  # directory scope does prevent propagation going any further.
  set(var1 "block-nested")
  return(PROPAGATE var1)
endblock()

CMake命令

message

  • 通用消息 message([<mode>] "message text" ...)

mode: FATAL_ERROR/SEND_ERROR/WARNING/AUTHOR_WARNING/DEPRECATION
NOTICE/STATUS/VERBOSE/DEBUG/TRACE

  • 检测报告 message(<checkState> "message text" ...)

checkState: CHECK_START/CHECK_PASS/CHECK_FAIL

例:

message(CHECK_START "Finding my things")
list(APPEND CMAKE_MESSAGE_INDENT "  ")
unset(missingComponents)

message(CHECK_START "Finding partA")
# ... do check, assume we find A
message(CHECK_PASS "found")

message(CHECK_START "Finding partB")
# ... do check, assume we don't find B
list(APPEND missingComponents B)
message(CHECK_FAIL "not found")

list(POP_BACK CMAKE_MESSAGE_INDENT)
if(missingComponents)
  message(CHECK_FAIL "missing components: ${missingComponents}")
else()
  message(CHECK_PASS "all components found")
endif()
  • 配置日志 message(CONFIGURE_LOG <text>...)
if (NOT DEFINED MY_CHECK_RESULT)
  # Print check summary in configure output.
  message(CHECK_START "My Check")

  # ... perform system inspection, e.g., with execute_process ...

  # Cache the result so we do not run the check again.
  set(MY_CHECK_RESULT "${MY_CHECK_RESULT}" CACHE INTERNAL "My Check")

  # Record the check details in the cmake-configure-log.
  message(CONFIGURE_LOG
    "My Check Result: ${MY_CHECK_RESULT}\n"
    "${details}"
  )

  # Print check result in configure output.
  if(MY_CHECK_RESULT)
    message(CHECK_PASS "passed")
  else()
    message(CHECK_FAIL "failed")
  endif()
endif()

find_package

find_package(<ackageName> [<version>] [REQUIRED] [COMPONENTS <components>...])
find_package(<ackageName> [version] [EXACT] [QUIET] [MODULE]
             [REQUIRED] [[COMPONENTS] [components...]]
             [OPTIONAL_COMPONENTS components...]
             [REGISTRY_VIEW  (64|32|64_32|32_64|HOST|TARGET|BOTH)]
             [GLOBAL]
             [NO_POLICY_SCOPE]
             [BYPASS_PROVIDER])
find_package(<ackageName> [version] [EXACT] [QUIET]
             [REQUIRED] [[COMPONENTS] [components...]]
             [OPTIONAL_COMPONENTS components...]
             [CONFIG|NO_MODULE]
             [GLOBAL]
             [NO_POLICY_SCOPE]
             [BYPASS_PROVIDER]
             [NAMES name1 [name2 ...]]
             [CONFIGS config1 [config2 ...]]
             [HINTS path1 [path2 ... ]]
             [PATHS path1 [path2 ... ]]
             [REGISTRY_VIEW  (64|32|64_32|32_64|HOST|TARGET|BOTH)]
             [PATH_SUFFIXES suffix1 [suffix2 ...]]
             [NO_DEFAULT_PATH]
             [NO_PACKAGE_ROOT_PATH]
             [NO_CMAKE_PATH]
             [NO_CMAKE_ENVIRONMENT_PATH]
             [NO_SYSTEM_ENVIRONMENT_PATH]
             [NO_CMAKE_PACKAGE_REGISTRY]
             [NO_CMAKE_BUILDS_PATH] # Deprecated; does nothing.
             [NO_CMAKE_SYSTEM_PATH]
             [NO_CMAKE_INSTALL_PREFIX]
             [NO_CMAKE_SYSTEM_PACKAGE_REGISTRY]
             [CMAKE_FIND_ROOT_PATH_BOTH |
              ONLY_CMAKE_FIND_ROOT_PATH |
              NO_CMAKE_FIND_ROOT_PATH])

include

include(<file|module> [OPTIONAL] [RESULT_VARIABLE <var>] [NO_POLICY_SCOPE])

file

Reading
  file(READ <filename> <out-var> [...])
  file(STRINGS <filename> <out-var> [...])
  file(<HASH> <filename> <out-var>)
  file(TIMESTAMP <filename> <out-var> [...])

Writing
  file({WRITE | APPEND} <filename> <content>...)
  file({TOUCH | TOUCH_NOCREATE} <file>...)
  file(GENERATE OUTPUT <output-file> [...])
  file(CONFIGURE OUTPUT <output-file> CONTENT <content> [...])

Filesystem
  file({GLOB | GLOB_RECURSE} <out-var> [...] <globbing-expr>...)
  file(MAKE_DIRECTORY <directories>...)
  file({REMOVE | REMOVE_RECURSE } <files>...)
  file(RENAME <oldname> <newname> [...])
  file(COPY_FILE <oldname> <newname> [...])
  file({COPY | INSTALL} <file>... DESTINATION <dir> [...])
  file(SIZE <filename> <out-var>)
  file(READ_SYMLINK <linkname> <out-var>)
  file(CREATE_LINK <original> <linkname> [...])
  file(CHMOD <files>... <directories>... PERMISSIONS <permissions>... [...])
  file(CHMOD_RECURSE <files>... <directories>... PERMISSIONS <permissions>... [...])

Path Conversion
  file(REAL_PATH <path> <out-var> [BASE_DIRECTORY <dir>] [EXPAND_TILDE])
  file(RELATIVE_PATH <out-var> <directory> <file>)
  file({TO_CMAKE_PATH | TO_NATIVE_PATH} <path> <out-var>)

Transfer
  file(DOWNLOAD <url> [<file>] [...])
  file(UPLOAD <file> <url> [...])

Locking
  file(LOCK <path> [...])

Archiving
  file(ARCHIVE_CREATE OUTPUT <archive> PATHS <paths>... [...])
  file(ARCHIVE_EXTRACT INPUT <archive> [...])

Handling Runtime Binaries
  file(GET_RUNTIME_DEPENDENCIES [...])

list

Reading
  list(LENGTH <list> <out-var>)
  list(GET <list> <element index> [<index> ...] <out-var>)
  list(JOIN <list> <glue> <out-var>)
  list(SUBLIST <list> <begin> <length> <out-var>)

Search
  list(FIND <list> <value> <out-var>)

Modification
  list(APPEND <list> [<element>...])
  list(FILTER <list> {INCLUDE | EXCLUDE} REGEX <regex>)
  list(INSERT <list> <index> [<element>...])
  list(POP_BACK <list> [<out-var>...])
  list(POP_FRONT <list> [<out-var>...])
  list(PREPEND <list> [<element>...])
  list(REMOVE_ITEM <list> <value>...)
  list(REMOVE_AT <list> <index>...)
  list(REMOVE_DUPLICATES <list>)
  list(TRANSFORM <list> <ACTION> [...])

Ordering
  list(REVERSE <list>)
  list(SORT <list> [...])

string

Search and Replace
  string(FIND <string> <substring> <out-var> [...])
  string(REPLACE <match-string> <replace-string> <out-var> <input>...)
  string(REGEX MATCH <match-regex> <out-var> <input>...)
  string(REGEX MATCHALL <match-regex> <out-var> <input>...)
  string(REGEX REPLACE <match-regex> <replace-expr> <out-var> <input>...)

Manipulation
  string(APPEND <string-var> [<input>...])
  string(PREPEND <string-var> [<input>...])
  string(CONCAT <out-var> [<input>...])
  string(JOIN <glue> <out-var> [<input>...])
  string(TOLOWER <string> <out-var>)
  string(TOUPPER <string> <out-var>)
  string(LENGTH <string> <out-var>)
  string(SUBSTRING <string> <begin> <length> <out-var>)
  string(STRIP <string> <out-var>)
  string(GENEX_STRIP <string> <out-var>)
  string(REPEAT <string> <count> <out-var>)

Comparison
  string(COMPARE <op> <string1> <string2> <out-var>)

Hashing
  string(<HASH> <out-var> <input>)

Generation
  string(ASCII <number>... <out-var>)
  string(HEX <string> <out-var>)
  string(CONFIGURE <string> <out-var> [...])
  string(MAKE_C_IDENTIFIER <string> <out-var>)
  string(RANDOM [<option>...] <out-var>)
  string(TIMESTAMP <out-var> [<format string>] [UTC])
  string(UUID <out-var> ...)

JSON
  string(JSON <out-var> [ERROR_VARIABLE <error-var>]
         {GET | TYPE | LENGTH | REMOVE}
         <json-string> <member|index> [<member|index> ...])
  string(JSON <out-var> [ERROR_VARIABLE <error-var>]
         MEMBER <json-string>
         [<member|index> ...] <index>)
  string(JSON <out-var> [ERROR_VARIABLE <error-var>]
         SET <json-string>
         <member|index> [<member|index> ...] <value>)
  string(JSON <out-var> [ERROR_VARIABLE <error-var>]
         EQUAL <json-string1> <json-string2>)

find

find_file (<VAR> name1 [path1 path2 ...])
find_file (
          <VAR>
          name | NAMES name1 [name2 ...]
          [HINTS [path | ENV var]... ]
          [PATHS [path | ENV var]... ]
          [REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)]
          [PATH_SUFFIXES suffix1 [suffix2 ...]]
          [VALIDATOR function]
          [DOC "cache documentation string"]
          [NO_CACHE]
          [REQUIRED]
          [NO_DEFAULT_PATH]
          [NO_PACKAGE_ROOT_PATH]
          [NO_CMAKE_PATH]
          [NO_CMAKE_ENVIRONMENT_PATH]
          [NO_SYSTEM_ENVIRONMENT_PATH]
          [NO_CMAKE_SYSTEM_PATH]
          [NO_CMAKE_INSTALL_PREFIX]
          [CMAKE_FIND_ROOT_PATH_BOTH |
           ONLY_CMAKE_FIND_ROOT_PATH |
           NO_CMAKE_FIND_ROOT_PATH]
         )
find_library (<VAR> name1 [path1 path2 ...])
find_library (
          <VAR>
          name | NAMES name1 [name2 ...] [NAMES_PER_DIR]
          [HINTS [path | ENV var]... ]
          [PATHS [path | ENV var]... ]
          [REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)]
          [PATH_SUFFIXES suffix1 [suffix2 ...]]
          [VALIDATOR function]
          [DOC "cache documentation string"]
          [NO_CACHE]
          [REQUIRED]
          [NO_DEFAULT_PATH]
          [NO_PACKAGE_ROOT_PATH]
          [NO_CMAKE_PATH]
          [NO_CMAKE_ENVIRONMENT_PATH]
          [NO_SYSTEM_ENVIRONMENT_PATH]
          [NO_CMAKE_SYSTEM_PATH]
          [NO_CMAKE_INSTALL_PREFIX]
          [CMAKE_FIND_ROOT_PATH_BOTH |
           ONLY_CMAKE_FIND_ROOT_PATH |
           NO_CMAKE_FIND_ROOT_PATH]
         )
find_path (<VAR> name1 [path1 path2 ...])
find_path (
          <VAR>
          name | NAMES name1 [name2 ...]
          [HINTS [path | ENV var]... ]
          [PATHS [path | ENV var]... ]
          [REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)]
          [PATH_SUFFIXES suffix1 [suffix2 ...]]
          [VALIDATOR function]
          [DOC "cache documentation string"]
          [NO_CACHE]
          [REQUIRED]
          [NO_DEFAULT_PATH]
          [NO_PACKAGE_ROOT_PATH]
          [NO_CMAKE_PATH]
          [NO_CMAKE_ENVIRONMENT_PATH]
          [NO_SYSTEM_ENVIRONMENT_PATH]
          [NO_CMAKE_SYSTEM_PATH]
          [NO_CMAKE_INSTALL_PREFIX]
          [CMAKE_FIND_ROOT_PATH_BOTH |
           ONLY_CMAKE_FIND_ROOT_PATH |
           NO_CMAKE_FIND_ROOT_PATH]
         )
find_program (<VAR> name1 [path1 path2 ...])
find_program (
          <VAR>
          name | NAMES name1 [name2 ...] [NAMES_PER_DIR]
          [HINTS [path | ENV var]... ]
          [PATHS [path | ENV var]... ]
          [REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)]
          [PATH_SUFFIXES suffix1 [suffix2 ...]]
          [VALIDATOR function]
          [DOC "cache documentation string"]
          [NO_CACHE]
          [REQUIRED]
          [NO_DEFAULT_PATH]
          [NO_PACKAGE_ROOT_PATH]
          [NO_CMAKE_PATH]
          [NO_CMAKE_ENVIRONMENT_PATH]
          [NO_SYSTEM_ENVIRONMENT_PATH]
          [NO_CMAKE_SYSTEM_PATH]
          [NO_CMAKE_INSTALL_PREFIX]
          [CMAKE_FIND_ROOT_PATH_BOTH |
           ONLY_CMAKE_FIND_ROOT_PATH |
           NO_CMAKE_FIND_ROOT_PATH]
         )

math

math(EXPR <variable> "<expression>" [OUTPUT_FORMAT <format>])

例:

math(EXPR value "100 * 0xA" OUTPUT_FORMAT DECIMAL)      # value is set to "1000"
math(EXPR value "100 * 0xA" OUTPUT_FORMAT HEXADECIMAL)  # value is set to "0x3e8"

其他脚本命令

cmake_minimum_required

指定CMake最小版本
cmake_minimum_required(VERSION <min>[...<policy_max>] [FATAL_ERROR])

cmake_host_system_information

  • 查询主机信息
    cmake_host_system_information(RESULT <variable> QUERY <key> ...)

key:

  • NUMBER_OF_LOGICAL_CORES

  • NUMBER_OF_PHYSICAL_CORES

  • HOSTNAME

  • FQDN      (Fully qualified domain name)

  • TOTAL_VIRTUAL_MEMORY

  • AVAILABLE_VIRTUAL_MEMORY

  • TOTAL_PHYSICAL_MEMORY

  • AVAILABLE_PHYSICAL_MEMORY

  • IS_64BIT

  • HAS_FPU

  • HAS_MMX

  • HAS_MMX_PLUS

  • HAS_SSE

  • HAS_SSE2

  • HAS_SSE_FP

  • HAS_SSE_MMX

  • HAS_AMD_3DNOW

  • HAS_AMD_3DNOW_PLUS

  • HAS_IA64

  • HAS_SERIAL_NUMBER

  • PROCESSOR_SERIAL_NUMBER

  • PROCESSOR_NAME

  • PROCESSOR_DESCRIPTION

  • OS_NAME

  • OS_RELEASE

  • OS_VERSION

  • OS_PLATFORM

  • OS_PLATFORM

  • DISTRIB_INFO

  • DISTRIB_<name>

  • 查询Windows注册表
    cmake_host_system_information(RESULT <variable> QUERY WINDOWS_REGISTRY <key> ...)

cmake_parse_arguments

cmake_parse_arguments(<prefix> <options> <one_value_keywords> <multi_value_keywords> <args>...)
cmake_parse_arguments(PARSE_ARGV <N> <prefix> <options> <one_value_keywords> <multi_value_keywords>)

macro(my_install)
    set(options OPTIONAL FAST)
    set(oneValueArgs DESTINATION RENAME)
    set(multiValueArgs TARGETS CONFIGURATIONS)
    cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}"
                          "${multiValueArgs}" ${ARGN} )

    # ...

my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub CONFIGURATIONS)

生成:

MY_INSTALL_OPTIONAL = TRUE
MY_INSTALL_FAST = FALSE # was not used in call to my_install
MY_INSTALL_DESTINATION = "bin"
MY_INSTALL_RENAME <UNDEFINED> # was not used
MY_INSTALL_TARGETS = "foo;bar"
MY_INSTALL_CONFIGURATIONS <UNDEFINED> # was not used
MY_INSTALL_UNPARSED_ARGUMENTS = "blub" # nothing expected after "OPTIONAL"
MY_INSTALL_KEYWORDS_MISSING_VALUES = "CONFIGURATIONS"
         # No value for "CONFIGURATIONS" given

separate_arguments

separate_arguments(<variable> <mode> [PROGRAM [SEPARATE_ARGS]] <args>)

separate_arguments (out UNIX_COMMAND PROGRAM "cc -c main.c")
separate_arguments (out UNIX_COMMAND PROGRAM SEPARATE_ARGS "cc -c main.c")

cmake_path

路径处理

cmake_path(GET <path-var> ROOT_NAME <out-var>)
cmake_path(GET <path-var> ROOT_DIRECTORY <out-var>)
cmake_path(GET <path-var> ROOT_PATH <out-var>)
cmake_path(GET <path-var> FILENAME <out-var>)
cmake_path(GET <path-var> EXTENSION [LAST_ONLY] <out-var>)
cmake_path(GET <path-var> STEM [LAST_ONLY] <out-var>)
cmake_path(GET <path-var> RELATIVE_PART <out-var>)
cmake_path(GET <path-var> PARENT_PATH <out-var>)

cmake_path(HAS_ROOT_NAME <path-var> <out-var>)
cmake_path(HAS_ROOT_DIRECTORY <path-var> <out-var>)
cmake_path(HAS_ROOT_PATH <path-var> <out-var>)
cmake_path(HAS_FILENAME <path-var> <out-var>)
cmake_path(HAS_EXTENSION <path-var> <out-var>)
cmake_path(HAS_STEM <path-var> <out-var>)
cmake_path(HAS_RELATIVE_PART <path-var> <out-var>)
cmake_path(HAS_PARENT_PATH <path-var> <out-var>)
cmake_path(IS_ABSOLUTE <path-var> <out-var>)
cmake_path(IS_RELATIVE <path-var> <out-var>)
cmake_path(IS_PREFIX <path-var> <input> [NORMALIZE] <out-var>)
cmake_path(COMPARE <input1> <OP> <input2> <out-var>)

cmake_path(SET <path-var> [NORMALIZE] <input>)
cmake_path(APPEND <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>])
cmake_path(APPEND_STRING <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>])
cmake_path(REMOVE_FILENAME <path-var> [OUTPUT_VARIABLE <out-var>])
cmake_path(REPLACE_FILENAME <path-var> <input> [OUTPUT_VARIABLE <out-var>])
cmake_path(REMOVE_EXTENSION <path-var> [LAST_ONLY] [OUTPUT_VARIABLE <out-var>])
cmake_path(REPLACE_EXTENSION <path-var> [LAST_ONLY] <input> [OUTPUT_VARIABLE <out-var>])

cmake_path(NORMAL_PATH <path-var> [OUTPUT_VARIABLE <out-var>])
cmake_path(RELATIVE_PATH <path-var> [BASE_DIRECTORY <input>] [OUTPUT_VARIABLE <out-var>])
cmake_path(ABSOLUTE_PATH <path-var> [BASE_DIRECTORY <input>] [NORMALIZE] [OUTPUT_VARIABLE <out-var>])

cmake_path(NATIVE_PATH <path-var> [NORMALIZE] <out-var>)
cmake_path(CONVERT <input> TO_CMAKE_PATH_LIST <out-var> [NORMALIZE])
cmake_path(CONVERT <input> TO_NATIVE_PATH_LIST <out-var> [NORMALIZE])

cmake_path(HASH <path-var> <out-var>)

configure_file

configure_file(<input> <output>
               [NO_SOURCE_PERMISSIONS | USE_SOURCE_PERMISSIONS |
                FILE_PERMISSIONS <permissions>...]
               [COPYONLY] [ESCAPE_QUOTES] [@ONLY]
               [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
# foo.h.in
#cmakedefine FOO_ENABLE
#cmakedefine FOO_STRING "@FOO_STRING@"

# CMakeLists.txt
option(FOO_ENABLE "Enable Foo" ON)
if(FOO_ENABLE)
  set(FOO_STRING "foo")
endif()
configure_file(foo.h.in foo.h @ONLY)

# output -> foo.h
#define FOO_ENABLE
#define FOO_STRING "foo"

execute_process

execute_process(COMMAND <cmd1> [<arguments>]
                [COMMAND <cmd2> [<arguments>]]...
                [WORKING_DIRECTORY <directory>]
                [TIMEOUT <seconds>]
                [RESULT_VARIABLE <variable>]
                [RESULTS_VARIABLE <variable>]
                [OUTPUT_VARIABLE <variable>]
                [ERROR_VARIABLE <variable>]
                [INPUT_FILE <file>]
                [OUTPUT_FILE <file>]
                [ERROR_FILE <file>]
                [OUTPUT_QUIET]
                [ERROR_QUIET]
                [COMMAND_ECHO <where>]
                [OUTPUT_STRIP_TRAILING_WHITESPACE]
                [ERROR_STRIP_TRAILING_WHITESPACE]
                [ENCODING <name>]
                [ECHO_OUTPUT_VARIABLE]
                [ECHO_ERROR_VARIABLE]
                [COMMAND_ERROR_IS_FATAL <ANY|LAST>])

variable_watch

variable_watch(<variable> [<command>])

COMMAND(<variable> <access> <value> <current_list_file> <stack>)

项目命令

add_compile_definitions

添加预定义宏
add_compile_definitions(<definition> ...)

add_compile_options

add_compile_options(<option> ...)

if (MSVC)
    # warning level 4
    add_compile_options(/W4)
else()
    # additional warnings
    add_compile_options(-Wall -Wextra -Wpedantic)
endif()

add_definitions

add_definitions(-DFOO -DBAR ...)
remove_definitions(-DFOO -DBAR ...)

add_dependencies

add_dependencies(<target> [<target-dependency>]...)

add_executable

add_executable(<name> <options>... <sources>...)

add_link_options(<option> ...)

add_custom_target

add_custom_target(Name [ALL] [command1 [args1...]]
                  [COMMAND command2 [args2...] ...]
                  [DEPENDS depend depend depend ... ]
                  [BYPRODUCTS [files...]]
                  [WORKING_DIRECTORY dir]
                  [COMMENT comment]
                  [JOB_POOL job_pool]
                  [JOB_SERVER_AWARE <bool>]
                  [VERBATIM] [USES_TERMINAL]
                  [COMMAND_EXPAND_LISTS]
                  [SOURCES src1 [src2...]])

add_custom_command

add_custom_command(OUTPUT output1 [output2 ...]
                   COMMAND command1 [ARGS] [args1...]
                   [COMMAND command2 [ARGS] [args2...] ...]
                   [MAIN_DEPENDENCY depend]
                   [DEPENDS [depends...]]
                   [BYPRODUCTS [files...]]
                   [IMPLICIT_DEPENDS <lang1> depend1
                                    [<lang2> depend2] ...]
                   [WORKING_DIRECTORY dir]
                   [COMMENT comment]
                   [DEPFILE depfile]
                   [JOB_POOL job_pool]
                   [JOB_SERVER_AWARE <bool>]
                   [VERBATIM] [APPEND] [USES_TERMINAL]
                   [COMMAND_EXPAND_LISTS]
                   [DEPENDS_EXPLICIT_ONLY])
add_custom_command(
  OUTPUT out.c
  COMMAND someTool -i ${CMAKE_CURRENT_SOURCE_DIR}/in.txt
                   -o out.c
  DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/in.txt
  VERBATIM)
add_library(myLib out.c)

add_subdirectory

add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL] [SYSTEM])

enable_language

enable_language(<lang>... [OPTIONAL])

export

export(TARGETS <target>... [...])
export(EXPORT <export-name> [...])
export(PACKAGE <ackageName>)
export(SETUP <export-name> [...])

export(TARGETS <target>... [...])
export(TARGETS <target>... [NAMESPACE <namespace>]
       [APPEND] FILE <filename> [EXPORT_LINK_INTERFACE_LIBRARIES]
       [CXX_MODULES_DIRECTORY <directory>])

build_command

build_command(<variable>
              [CONFIGURATION <config>]
              [PARALLEL_LEVEL <parallel>]
              [TARGET <target>]
              [PROJECT_NAME <projname>] # legacy, causes warning
             )

cmake_file_api

cmake_file_api(
  QUERY
  API_VERSION <version>
  [CODEMODEL <versions>...]
  [CACHE <versions>...]
  [CMAKEFILES <versions>...]
  [TOOLCHAINS <versions>...]
)

define_property

define_property(<GLOBAL | DIRECTORY | TARGET | SOURCE |
                 TEST | VARIABLE | CACHED_VARIABLE>
                 PROPERTY <name> [INHERITED]
                 [BRIEF_DOCS <brief-doc> [docs...]]
                 [FULL_DOCS <full-doc> [docs...]]
                 [INITIALIZE_FROM_VARIABLE <variable>])

get_target_property

get_target_property(<variable> <target> <property>)

include_directories

include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])

include_regular_expression

include_regular_expression(regex_match [regex_complain])

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

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

load_cache

load_cache(pathToBuildDirectory READ_WITH_PREFIX prefix entry1...)
load_cache(pathToBuildDirectory [EXCLUDE entry1...] [INCLUDE_INTERNALS entry1...])

set_target_properties

set_target_properties(<targets> ... PROPERTIES <prop1> <value1> [<prop2> <value2>] ...)

target_compile_definitions

target_compile_definitions(<target>
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])

target_compile_features

target_compile_features(<target> <RIVATE|PUBLIC|INTERFACE> <feature> [...])

target_compile_options

target_compile_options(<target> [BEFORE] <INTERFACE|PUBLIC|PRIVATE> [items1...] [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])

target_include_directories

target_include_directories(<target> [SYSTEM] [AFTER|BEFORE]
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
target_link_directories(<target> [BEFORE]
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
target_link_libraries(<target> ... <item>... ...)
# 目标和/或其依赖
target_link_libraries(<target>
                      <RIVATE|PUBLIC|INTERFACE> <item>...
                     [<RIVATE|PUBLIC|INTERFACE> <item>...]...)
# 目标及其依赖
target_link_libraries(<target> <item>...)
target_link_options(<target> [BEFORE]
  <INTERFACE|PUBLIC|PRIVATE> [items1...]
  [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])

target_precompile_headers

target_precompile_headers(<target>
  <INTERFACE|PUBLIC|PRIVATE> [header1...]
  [<INTERFACE|PUBLIC|PRIVATE> [header2...] ...])

target_sources

target_sources(<target> <INTERFACE|PUBLIC|PRIVATE> [items1...] [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])

add_library

普通库:
add_library(<name> [<type>] [EXCLUDE_FROM_ALL] <sources>...)

type: STATIC/SHARED/MODULE/EXCLUDE_FROM_ALL

目标库:
add_library(<name> OBJECT <sources>...)
add_library(... $<TARGET_OBJECTSbjlib> ...)
add_executable(... $<TARGET_OBJECTSbjlib> ...)   

接口库:
add_library(<name> INTERFACE)
add_library(<name> INTERFACE [EXCLUDE_FROM_ALL] <sources>...)   

导入库:
add_library(<name> <type> IMPORTED [GLOBAL])   

别名库:
add_library(<name> ALIAS <target>)

install

install(TARGETS <target>... [...])
install(IMPORTED_RUNTIME_ARTIFACTS <target>... [...])
install({FILES | PROGRAMS} <file>... [...])
install(DIRECTORY <dir>... [...])
install(SCRIPT <file> [...])
install(CODE <code> [...])
install(EXPORT <export-name> [...])
install(RUNTIME_DEPENDENCY_SET <set-name> [...])

project

project(<ROJECT-NAME> [<language-name>...])
project(<ROJECT-NAME>
        [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
        [DESCRIPTION <project-description-string>]
        [HOMEPAGE_URL <url-string>]
        [LANGUAGES <language-name>...])
回复

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-9-21 11:28 , Processed in 0.038145 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表