cmake命令选项及使用

VSCODE的配置

下载安装编译器和cmake工具

mingw下载地址

  • 解压到指定目录:C:/mingw64
  • 为其添加环境变量

cmake下载地址

  • 安装时,注意勾选添加到系统环境变量
  • vscode下载

为新工程配置编译、调试流程

在项目更目录下建立.vscode文件夹:
launch.json文件 F5启动它
注意文件中的gdb路径,修改成自己的。

{
    
    
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
    
    
            "name": "(gdb) 启动",                           //配置名称,将会在启动配置的下拉菜单中显示
            "type": "cppdbg",                               //配置类型,这里只能为cppdbg
            "request": "launch",                            //请求配置类型,可以为launch(启动)或attach(附加)
            // "targetArchitecture": "x64",                    //生成目标架构,一般为x86或x64
            "program": "${command:cmake.launchTargetPath}", //将要进行调试的程序的路径
            "args": [],                                     //程序调试时传递给程序的命令行参数,一般设为空即可
            "stopAtEntry": false,                           //设为true时程序将暂停在程序入口处,一般设置为false
            "cwd": "${workspaceFolder}",                    //调试程序时的工作目录,一般为${workspaceRoot}
            "environment": [],                              
            "externalConsole": true,                        //调试时是否显示控制台窗口,一般设置为true显示控制台
            "internalConsoleOptions": "neverOpen",          //如果不设为neverOpen,调试时会跳到“调试控制台”选项卡"
            "MIMode": "gdb",                                //指定连接的调试器
            "miDebuggerPath": "C:/mingw64/bin/gdb.exe",     //调试器路径
            "setupCommands": [
                {
    
    
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "Build"                        //执行调试前,先执行tasks.json中Build任务
        }
    ]
}

tasks.json这个被launch.json连带启动

{
    
    
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "options": {
    
    
        "cwd": "${workspaceFolder}/build"//进入cmake生成文件的build目录,里面有Makefile
    },
    "tasks": [
        {
    
    
            "label": "cmake",           //使用cmake ..  命令构建Makefile
            "type": "shell",
            "command": "cmake",
            "args": [
                ".."
            ],
        },
        {
    
    
            "label": "make",            //使用make命令编译
            "group": {
    
    
                "kind": "build",
                "isDefault": true       //按下 Ctrl + Shift + b 时将运行此任务
            },
            "command": "make",
            "args": [

            ]
        },
        {
    
    
            "label": "show_debug",      //调试用,打印环境变量
            "type": "shell",
            "command": "echo",
            "args": [
                "将要调试的程序路径:${command:cmake.launchTargetPath}"
            ],
        },
        {
    
    
            "label": "Build",           //Build任务,依赖于cmake,make任务执行完成
            "dependsOn":[
                "cmake",
                "make",
                "show_debug"
            ]
        }  
    ]
}

装一些语法提示插件

在这里插入图片描述

vscode上cmake路径配置

在这里插入图片描述
在选择cmake的编译工具,自动扫描(只要下载的编译工具链添加到环境变量中正确就可以扫描到)

记录vscode配置工程时生成的命令

一般刚安装CMake插件后 会自动提示你选择一个编译工具链,如果没有提示或者想更换其他编译工具链,那么可以通过ctrl+shifl+p,输入以下指令,然后在弹出框中选择自己安装的编译工具链

Ctrl+ Shift + P

CMake:Select a Kit

如果想重新配置本地的编译工具链的安装位置,那么可以打开如下配置

CMake:Edit user-local CMake kits

对于vscode找不到头文件问题

  • 方法1
    再下图中设置,随便修改下参数,会自动生成settings.json文件
    在这里插入图片描述
    在这里插入图片描述
    打开此文件,增加缺失的头文件路径信息,保存,关闭即可
    在这里插入图片描述
    快捷复制路径可按如下操作,鼠标右键头文件所在的文件夹
    在这里插入图片描述
  • 方法2
    直接在#incude中添加完整路径信息

cmake命令行选项

cmake --no-warn-unused-cli \
-DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE \
-DCMAKE_BUILD_TYPE:STRING=Debug \
-DCMAKE_C_COMPILER:FILEPATH=C:\msys64\mingw64\bin\x86_64-w64-mingw32-gcc.exe \
-DCMAKE_CXX_COMPILER:FILEPATH=C:\msys64\mingw64\bin\x86_64-w64-mingw32-g++.exe \
-Hg:i1Protocol \
-Bg:i1Protocol/build \
-G Ninja
#-H定义home目录也就是主CMakeLists.txt所在目录
#-B定义build编译生成目录
#-G定义generator-name生成的编译规则文件类型
  -S <path-to-source>          = Explicitly specify a source directory.
  -B <path-to-build>           = Explicitly specify a build directory.
  -C <initial-cache>           = Pre-load a script to populate the cache.
  -D <var>[:<type>]=<value>    = Create or update a cmake cache entry.
  -U <globbing_expr>           = Remove matching entries from CMake cache.
  -G <generator-name>          = Specify a build system generator.
  -T <toolset-name>            = Specify toolset name if supported by

生成Make file

第一次需要输入"cmake -G"Unix Makefiles" …/",尤其是电脑装了Visual Studio如果直接"cmake …"会生成VS的工程文件,所以这里需要指定下,可以参考x265_3.2.1版本的编译方法

mkdir build
cd build
cmake -G "Unix Makefiles" ../
#还有MinGW Makefiles
cmake -G "MinGW Makefiles" ../

cmake可用变量

cmake_minimum_required(VERSION 3.2)
#(无) = 重要消息;
#STATUS = 非重要消息;
#WARNING = CMake 警告, 会继续执行;
#AUTHOR_WARNING = CMake 警告 (dev), 会继续执行;
#SEND_ERROR = CMake 错误, 继续执行,但是会跳过生成的步骤;
#FATAL_ERROR = CMake 错误, 终止所有处理过程;
message(STATUS "CMAKE_C_FLAGS = " ${CMAKE_C_FLAGS})
message(STATUS "CMAKE_C_FLAGS_DEBUG = " ${CMAKE_C_FLAGS_DEBUG})
message(STATUS "CMAKE_C_FLAGS_MINSIZEREL = " ${CMAKE_C_FLAGS_MINSIZEREL})
message(STATUS "CMAKE_C_FLAGS_RELEASE = " ${CMAKE_C_FLAGS_RELEASE})
message(STATUS "CMAKE_C_FLAGS_RELWITHDEBINFO = " ${CMAKE_C_FLAGS_RELWITHDEBINFO})

message(STATUS "CMAKE_CXX_FLAGS = " ${CMAKE_CXX_FLAGS})
message(STATUS "CMAKE_CXX_FLAGS_DEBUG = " ${CMAKE_CXX_FLAGS_DEBUG})
message(STATUS "CMAKE_CXX_FLAGS_MINSIZEREL = " ${CMAKE_CXX_FLAGS_MINSIZEREL})
message(STATUS "CMAKE_CXX_FLAGS_RELEASE = " ${CMAKE_CXX_FLAGS_RELEASE})
message(STATUS "CMAKE_CXX_FLAGS_RELWITHDEBINFO = " ${CMAKE_CXX_FLAGS_RELWITHDEBINFO})

message(STATUS "CMAKE_EXE_LINKER_FLAGS = " ${CMAKE_EXE_LINKER_FLAGS})
message(STATUS "CMAKE_EXE_LINKER_FLAGS_DEBUG = " ${CMAKE_EXE_LINKER_FLAGS_DEBUG})
message(STATUS "CMAKE_EXE_LINKER_FLAGS_MINSIZEREL = " ${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL})
message(STATUS "CMAKE_EXE_LINKER_FLAGS_RELEASE = " ${CMAKE_EXE_LINKER_FLAGS_RELEASE})
message(STATUS "CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO = " ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO})

message(STATUS "CMAKE_MODULE_LINKER_FLAGS = " ${CMAKE_MODULE_LINKER_FLAGS})
message(STATUS "CMAKE_MODULE_LINKER_FLAGS_DEBUG = " ${CMAKE_MODULE_LINKER_FLAGS_DEBUG})
message(STATUS "CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL = " ${CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL})
message(STATUS "CMAKE_MODULE_LINKER_FLAGS_RELEASE = " ${CMAKE_MODULE_LINKER_FLAGS_RELEASE})
message(STATUS "CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO = " ${CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO})

message(STATUS "CMAKE_SHARED_LINKER_FLAGS = " ${CMAKE_SHARED_LINKER_FLAGS})
message(STATUS "CMAKE_SHARED_LINKER_FLAGS_DEBUG = " ${CMAKE_SHARED_LINKER_FLAGS_DEBUG})
message(STATUS "CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL = " ${CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL})
message(STATUS "CMAKE_SHARED_LINKER_FLAGS_RELEASE = " ${CMAKE_SHARED_LINKER_FLAGS_RELEASE})
message(STATUS "CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO = " ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO})

message(STATUS "CMAKE_STATIC_LINKER_FLAGS = " ${CMAKE_STATIC_LINKER_FLAGS})
message(STATUS "CMAKE_STATIC_LINKER_FLAGS_DEBUG = " ${CMAKE_STATIC_LINKER_FLAGS_DEBUG})
message(STATUS "CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL = " ${CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL})
message(STATUS "CMAKE_STATIC_LINKER_FLAGS_RELEASE = " ${CMAKE_STATIC_LINKER_FLAGS_RELEASE})
message(STATUS "CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO = " ${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO})

#当前文件目录
message(STATUS "CMAKE_CURRENT_SOURCE_DIR = " ${CMAKE_CURRENT_SOURCE_DIR})

cmake编写生成目标的过程

依据CMakeLists.txt文件cmake执行后生成Makefile文件,依据Makefile可以使用make命令进行编译,最终编译结果就是我们在CMakeLists.txt中定义

Created with Raphaël 2.2.0 创建CMakeLists.txt 编写CMakeLists.txt cmake 已生成Makefile? make 编译无误? 生成目标文件:APP/SHARE-LIB/STATIC-LIB yes no yes no
  • 指定cmake版本号
#指定CMAKE最低版本要求
cmake_minimum_required(VERSION 3.0)
  • 指定项目名称
#设定项目名称
project(xxx_ProjectName)
  • cmake目标是为了生成appshare-libstatic-lib这三个或者某一个或者某两个

  • 为了生成这些目标,需要指定它们的源文件,找到它们通过以下方式

#方式1:查找指定目录下源文件到指定变量中
aux_source_directory(文件夹名称 源文件存放变量名)
#例子1,将driver目录下源文件(*.c或者*.cpp装载到SRC_LIST中)
aux_source_directory(driver SRC_LIST)
#例子2,将当前CMakeLists.txt目录下源文件(*.c或者*.cpp装载到SRC_LIST中)
aux_source_directory(. SRC_LIST)

#方式2:直接设置变量包含的源文件
set(变量名 变量需装载的内容)
#例子1,将原SRC_LIST变量中的内容和1.c 2.c 3.c源文件装载到SRC_LIST变量中去
set(SRC_LIST "${SRC_LIST} 1.c 2.c 3.c")

#方式3:批量添加源文件
#设置源文件目录集合
set(SRC_DIRS "src" "port" "plugins/flash" "plugins/file")
#轮询目录加入源文件到SRC_LIST(局部变量)
foreach(srcdir ${
    
    SRC_DIRS})
    aux_source_directory(${
    
    srcdir} SRC_LIST)
endforeach()
message("源文件有:${SRC_LIST}")

#方式4:通配符查找
file(GLOB_RECURSE SRC_LIST ${
    
    YOUR_PROJECT_SRC_DIR}/ *.c)
  • 有了源文件可能还不够,因为某些源文件中包含了头文件,编译时可能找不到它们,所以需要指定,当然如果源文件中对包含的头文件路径信息比较全,那就不需要了!
include_directories(路径信息1 路径信息2)
#例子1,将driver/include和lib/include两个路径加到源码搜索路径中去
include_directories("driver/include" "lib/include")

#例子2,将driver/include和lib/include两个路径加到源码搜索路径中去
set(INCDIRS "driver/include" "lib/include")
foreach(incdir ${
    
    INCDIRS})
    include_directories(${
    
    incdir})
endforeach()

其实例子1中执行了,Makefile中:gcc -Idriver/include -Ilib/include
  • 设置目标app生成的目录及名称
set(CMAKE_BUILD_TYPE "Release")   # Debug Release

add_executable(app ${
    
    SRC_LIST})

#PROJECT_SOURCE_DIR:工程的根目录
#EXECUTABLE_OUTPUT_PATH :目标二进制可执行文件的存放位置
set(EXECUTABLE_OUTPUT_PATH ${
    
    PROJECT_SOURCE_DIR}/build/bin)
  • 设置目标lib生成的目录及名称
set(CMAKE_BUILD_TYPE "Release")   # Debug Release
set(CMAKE_LIB_TYPE "STATIC")   # SHARED STATIC,如果不指定默认静态库

#add_library: 生成动态库或静态库(第1个参数指定库的名字;第2个参数决定是动态还是静态,如果没有就默认静态;第3个参数指定生成库的源文件)
add_library(share-lib SHARED ${
    
    SRC_LIST})

add_library(static-lib STATIC ${
    
    SRC_LIST})

#set_target_properties: 设置最终生成的库的名称,还有其它功能,如设置库的版本号等等
set_target_properties(share-lib PROPERTIES OUTPUT_NAME "share_lib")
set_target_properties(static-lib PROPERTIES OUTPUT_NAME "static_lib")

#PROJECT_SOURCE_DIR:工程的根目录
#LIBRARY_OUTPUT_PATH :lib库文件的存放位置
set(LIBRARY_OUTPUT_PATH ${
    
    PROJECT_SOURCE_DIR}/build/lib)
  • 为目标设置链接的库文件
#找${
    
    PROJECT_SOURCE_DIR}/lib目录下,libxxx.so,并把库的绝对路径存放到变量LINK_LIB_LIST里,简写库名默认找动态库
find_library(LINK_LIB_LIST xxx HINTS ${
    
    PROJECT_SOURCE_DIR}/lib)
#找静态库
find_library(LINK_LIB_LIST libxxx.a HINTS ${
    
    PROJECT_SOURCE_DIR}/lib)
#也可以这样找动态库
find_library(LINK_LIB_LIST libxxx.so HINTS ${
    
    PROJECT_SOURCE_DIR}/lib)
target_link_libraries(app ${
    
    LINK_LIB_LIST})

#也可以指定库的路径
link_directories("${PROJECT_SOURCE_DIR}/lib")

  • 设置宏定义
option(ENABLE_ORIGIN_PROTOCOL "use origin protocol" OFF)
if(ENABLE_ORIGIN_PROTOCOL)
    add_definitions(-DUSE_OLD_PROTOCL)
endif(ENABLE_ORIGIN_PROTOCOL)

#定义常量,相当于#define USE_OLD_PROTOCL 1
add_definitions(-DUSE_OLD_PROTOCL=1)

#定义文本,相当于#define USE_OLD_PROTOCL #define XXX ...
add_definitions(-DUSE_OLD_PROTOCL -DXXX -DCCC)
  • 设置编译选项
set(CMAKE_C_FLAGS "-Wall")
set(CMAKE_C_FLAGS "-lpthread")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -O0 -g -ggdb")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -O3 -DNDEBUG")

if(CMAKE_COMPILER_IS_GNUCXX)
    set(CMAKE_CXX_FLAGS "-std=c++11")
    set(CMAKE_CXX_FLAGS "-lpthread")
    set(CMAKE_CXX_FLAGS "-Wall")
    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -O0 -g -ggdb")
    set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3") 
endif(CMAKE_COMPILER_IS_GNUCXX)
  • 添加选项开关
#其第一个参数是这个option的名字,第二个参数是字符串,用来描述这个option是来干嘛的,第三个是option的值,ON或OFF,也可以不写,不写就是默认OFF
option(ENABLE_DEBUG "enable debug compilation" OFF)
if(ENABLE_DEBUG)
    add_compile_options(-DENABLE_DEBUG_FLAG) #相当于Makefile中:-DENABLE_DEBUG_FLAG,.c或者.h中就可以用预编译宏进行判断了:#ifdefine ENABLE_DEBUG_FLAG
else()
    message(STATUS "Currently is not in debug mode")    
endif()
  • 多个源文件在不同的目录情况,为每个目录源文件编译成静态库,最终的目标去链接它

在每个目录建立CMakeLists.txt文件,用于打包成静态库

#加入源文件到DIR_SRCS(局部变量)
aux_source_directory(. DIR_SRCS)

#依据文件夹名称获得库名
string(REGEX REPLACE ".*/(.*)" "\\1" LIB_NAME ${
    
    CMAKE_CURRENT_SOURCE_DIR}) 

#本文件夹存在源文件则将主CMkakeLists.txt中LIBNAMES进行比较
if (DIR_SRCS)
    foreach(libname ${
    
    LIBNAMES})

        #在主CMakeLists.txt中定义的所有的库名进行匹配
        if (${
    
    LIB_NAME} STREQUAL ${
    
    libname})

            #编译成库,库名为${
    
    LIB_NAME},类型为${
    
    CMAKE_LIB_TYPE}(SHARED、STATIC),源文件为${
    
    DIR_SRCS}
            add_library(${
    
    libname} ${
    
    CMAKE_LIB_TYPE} ${
    
    DIR_SRCS})

            #库需要链接的外部库为空
            # target_link_libraries(${libname} "")
        endif()
    endforeach()

else()
    message(WARNING "not find is src file!")
endif()

根目录下的CMakeLists.txt 去调用 子目录的CMakeLists.txt

#主CMakeLists.txt 设置一个存储所有子目录的变量
set(SUBDIRS "sub1" "sub2" "sub3")

#主CMakeLists.txt 设置一个存储所有子目录静态库名的变量
set(LIBNAMES "A" "B" "C")

#添加子目录CMakeLists.txt
foreach(subdir ${
    
    SUBDIRS})
    add_subdirectory(${
    
    PROJECT_SOURCE_DIR}/${
    
    subdir})
endforeach()

#库生成路径设置
link_directories("build/lib/")

需最终生成目标的子目录下的CMakeLists.txt 去链接所有的子目录静态库,就OK了

aux_source_directory(. DIR_SRCS)

set(INCDIRS ${
    
    CMAKE_CURRENT_SOURCE_DIR})

#生成app
add_executable(${
    
    TARGETS} ${
    
    DIR_SRCS})

foreach(findlib ${
    
    LIBNAMES})
    target_link_libraries(${
    
    TARGETS} ${
    
    findlib})
endforeach()

find_package("Threads")
target_link_libraries(${
    
    TARGETS} ${
    
    CMAKE_THREAD_LIBS_INIT})

cmake 宏macro与函数function及变量作用域

  • 总结1functionadd_subdirectory与主CMakeLists.txt都是调用关系
#创建normal变量
set(VAL "666")

#创建函数func
function(func myval)
	set(VAL ${
    
    myval})
	set(VAL "888" PARENT_SCOPE)
endfunction()

#调用函数
func("777")

#######运行结果########
在函数func内,第一次设置VAL变量为"777",是创建了局部变量
在函数func内,第二次设置VAL变量为"888",是修改了VAL全局变量
  • 总结2include命令类似于C中的#include造成的效果也相似,直接展开
list(APPEND CMAKE_MODULE_PATH ${
    
    PROJECT_SOURCE_DIR}/cmake_modules) 
#第一种
include(FindmoduleName) # 从 CMAKE_MODULE_PATH 包含的路径中搜索 FindmoduleName.cmake 文件

#第二种这样子找
find_package(moduleName REQUIRED) # 从 CMAKE_MODULE_PATH 包含的路径中搜索 FindmoduleName.cmake 文件 与 include () 两者的效果是一样的!
  • 总结3includemacro展开后可以直接对CMakeLists.txt文件中变量修改
#假设${
    
    PROJECT_SOURCE_DIR}/cmake_modules目录下有FindmoduleName.cmake文件,其内容如下
set(VAL "新值")

#假设${
    
    PROJECT_SOURCE_DIR}/CMakeLists.txt文件内容如下
set(VAL "原始值")

macro(macro_test MY_VA) # 定义一个宏!
 set(VAL "macro修改了VAL") # 直接修改的就是调用该宏所处的文件中的 Normal 变量
endmacro()
message("原始VAL值:${VAL}")
macro_test("测试宏")
message("宏修改后VAL值:${VAL}")
list(APPEND CMAKE_MODULE_PATH ${
    
    PROJECT_SOURCE_DIR}/cmake_modules) 
find_package(moduleName REQUIRED)
message("FindmoduleName.cmake展开后VAL值:${VAL}")

#######运行结果########
原始VAL值:原始值
宏修改后VAL值:macro修改了VAL
FindmoduleName.cmake展开后VAL值:新值

测试编译

这个用法比较高级一点了,目前在大项目中看到过比如opencv的编译,用来测试链接外部的库存不存在。
以下内容摘自CMakeTestCCompiler.cmake文件

#创建文件,写入内容
  file(WRITE ./testCCompiler.c
    "#ifdef __cplusplus\n"
    "# error \"The CMAKE_C_COMPILER is set to a C++ compiler\"\n"
    "#endif\n"
    "#if defined(__CLASSIC_C__)\n"
    "int main(argc, argv)\n"
    "  int argc;\n"
    "  char* argv[];\n"
    "#else\n"
    "int main(int argc, char* argv[])\n"
    "#endif\n"
    "{ (void)argv; return argc-1;}\n")
    
#测试编译,编译成功则CMAKE_C_COMPILER_WORKS为TRUE
  try_compile(CMAKE_C_COMPILER_WORKS ./testCCompiler.c
    OUTPUT_VARIABLE __CMAKE_C_COMPILER_OUTPUT)
  # Move result from cache to normal variable.
  set(CMAKE_C_COMPILER_WORKS ${
    
    CMAKE_C_COMPILER_WORKS})
  unset(CMAKE_C_COMPILER_WORKS CACHE)
  
#追加内容到文件
file(APPEND "文件路径及文件名"
    "追加内容1 "
    "追加内容2\n\n")

语法官网参考

#尝试编译整个项目
try_compile(<resultVar> <bindir> <srcdir>
            <projectName> [<targetName>] [CMAKE_FLAGS <flags>...]
            [OUTPUT_VARIABLE <var>])
尝试建立一个项目。的成功或失败try_compile,即TRUE或FALSE分别返回<resultVar>。

在这种形式下,<srcdir>应包含一个完整的CMake项目,以及一个 CMakeLists.txt文件和所有源代码。执行 此命令后,<bindir><srcdir>将不会被删除。指定<targetName>构建特定的目标,而不是allor ALL_BUILD目标

#尝试编译源文件
try_compile(<resultVar> <bindir> <srcfile|SOURCES srcfile...>
            [CMAKE_FLAGS <flags>...]
            [COMPILE_DEFINITIONS <defs>...]
            [LINK_OPTIONS <options>...]
            [LINK_LIBRARIES <libs>...]
            [OUTPUT_VARIABLE <var>]
            [COPY_FILE <fileName> [COPY_FILE_ERROR <var>]]
            [<LANG>_STANDARD <std>]
            [<LANG>_STANDARD_REQUIRED <bool>]
            [<LANG>_EXTENSIONS <bool>]
            )
尝试从一个或多个源文件(该文件是由 CMAKE_TRY_COMPILE_TARGET_TYPE 变量)。的成功或失败try_compile,即TRUE或 FALSE分别返回<resultVar>。

以这种形式,必须提供一个或多个源文件。如果 CMAKE_TRY_COMPILE_TARGET_TYPE如果未设置或设置为EXECUTABLE,则源必须包含的定义,main并且CMake将创建一个 CMakeLists.txt文件来将源构建为可执行文件。如果CMAKE_TRY_COMPILE_TARGET_TYPE设置为STATIC_LIBRARY,则将构建静态库,并且不需要定义main。对于可执行文件,生成的CMakeLists.txt文件将包含以下内容:

add_definitions(<expanded COMPILE_DEFINITIONS from caller>)
include_directories(${
    
    INCLUDE_DIRECTORIES})
link_directories(${
    
    LINK_DIRECTORIES})
add_executable(cmTryCompileExec <srcfile>...)
target_link_options(cmTryCompileExec PRIVATE <LINK_OPTIONS from caller>)
target_link_libraries(cmTryCompileExec ${
    
    LINK_LIBRARIES})
选项包括:

CMAKE_FLAGS <flags>...
指定-DVAR:TYPE=VALUE要传递给cmake用于驱动测试版本的命令行的表单的标志。上面的例子说明了如何变量值 INCLUDE_DIRECTORIES,LINK_DIRECTORIES和LINK_LIBRARIES 被使用。

COMPILE_DEFINITIONS <defs>...
指定-Ddefinition要传递给的参数add_definitions() 在生成的测试项目中。

COPY_FILE <fileName>
将构建的可执行文件或静态库复制到给定的<fileName>。

COPY_FILE_ERROR <var>
使用after COPY_FILE将<var>试图复制文件时遇到的任何错误消息捕获到变量中。

LINK_LIBRARIES <libs>...
指定要在生成的项目中链接的库。库列表可以引用系统库以及 从调用项目中导入的目标。

如果指定了此选项,则将忽略-DLINK_LIBRARIES=...赋予该CMAKE_FLAGS选项的任何值。

LINK_OPTIONS <options>...
指定要传递给的链接步骤选项 target_link_options() 或设置 STATIC_LIBRARY_OPTIONS 生成的项目中的目标属性,具体取决于 CMAKE_TRY_COMPILE_TARGET_TYPE 变量。

OUTPUT_VARIABLE <var>
将构建过程的输出存储在给定的变量中。

<LANG>_STANDARD <std>
指定 C_STANDARD, CXX_STANDARD, OBJC_STANDARD, OBJCXX_STANDARD, 要么 CUDA_STANDARD 生成项目的目标属性。

<LANG>_STANDARD_REQUIRED <bool>
指定 C_STANDARD_REQUIRED, CXX_STANDARD_REQUIRED, OBJC_STANDARD_REQUIRED, OBJCXX_STANDARD_REQUIRED,要么 CUDA_STANDARD_REQUIRED 生成项目的目标属性。

<LANG>_EXTENSIONS <bool>
指定 C_EXTENSIONS, CXX_EXTENSIONS, OBJC_EXTENSIONS, OBJCXX_EXTENSIONS, 要么 CUDA_EXTENSIONS 生成项目的目标属性。

在3.18.2版本中,<bindir>/CMakeFiles/CMakeTmp将自动清除其中的所有文件。对于调试,--debug-trycompile可以通过传递cmake来避免这种清理。但是,多个顺序 try_compile操作将重用此单个输出目录。如果使用 --debug-trycompile,则一次只能调试一个try_compile呼叫。推荐的过程是try_compile通过逻辑保护项目中的所有调用,使用cmake进行一次完整配置,然后删除与感兴趣的try_compile调用关联的缓存条目,然后使用再次重新运行cmake 。if(NOT DEFINED <resultVar>)--debug-trycompile

获取目录名

#获取上上级目录名
get_filename_component(PARENT_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
string(REGEX REPLACE ".*/(.*)" "\\1" NAME ${PARENT_DIR}) 

#获取本级目录名
string(REGEX REPLACE ".*/(.*)" "\\1" NAME ${CMAKE_CURRENT_SOURCE_DIR}) 

参考博客地址
作用域博客参考地址
find_package博客参考

猜你喜欢

转载自blog.csdn.net/weixin_42892101/article/details/108527143