CMAKE的学习

下面我们来介绍Cmake

Cmake

我们着重介绍一下CMAKE,是因为CMAKE现在用的人比MAKEFILE多一些,也更好理解,编写一些。

1 安装 cmake

1.1 卸载已经安装的旧版的CMAKE【非必需】

apt-get autoremove cmake

1.2 文件下载解压:

wget https://github.com/Kitware/CMake/releases/download/v3.24.2/cmake-3.24.2-linux-x86_64.tar.gz

解压:

 tar zxvf cmake-3.24.2-linux-x86_64.tar.gz

查看解压后目录:

tree -L 2 cmake-3.24.2-linux-x86_64

1.3 创建软链接

注:文件路径是可以指定的,一般选择/opt/user路径下,这里选择/opt

mv cmake-3.24.2-linux-x86_64 /opt/cmake-3.24.2
ln -sf /opt/cmake-3.24.2/bin/* /usr/bin

2 基本exe项目的编译

2.1 基本工程

first_cmake.cpp

#include<iostream>

int main(int argc ,char* argv[])
{
    std::cout<<"my first CmakeProject";
    return 0;
}

CMakeLists.txt


#单个目录实现
#CMAKE最低版本号要求
cmake_minimum_required(VERSION 2.8)
#工程名
PROJECT(GodDragon)
#手动加入文件
SET(SRC_LIST main.c)
MESSAGE(STATUS "THIS IS BINARY DIR"${PROJECT_BINARY_DIR})
MESSAGE(STATUS "THIS IS SOURCE DIR"${PROJECT_SOURCE_DIR})
ADD_EXECUTABLE(0voice ${SRC_LIST})

我们现在WINDOWS平台下,使用CMAKE编译一下我们的工程。

现在看看我们生成的文件是什么样的。

这样我们第一个cmake WINDOWS项目就这样完成了

我们现在linux平台下,使用CMAKE编译一下我们的工程。

我们可以看到我们生成了我们第一个linux项目。

3.编译动态库和静态库

编译静态库

xlog.h

//xlog.h
#ifndef XLOG_H
#define XLOG_H
class XLog
{
	public:
		XLog();
};
#endif

xlog.cpp

#include"xlog.h"
#include<iostream>
XLog::XLog()
{
	std::cout<<"XLog()"<<std::endl;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.20)
project(xlog)
add_library(xlog STATIC xlog.cpp xlog.h)

上面是在编译我们的动态库文件。

接下来是测试程序的编写
main.cpp

#include<iostream>
#include"xlog.h"
using namespace std;
int main(){
    XLog log;
    cout<<"test \n";
    return 0;
}

CMakeLists.txt

#CMakeLists.txt test_xlog 102
cmake_minimum_required(VERSION 3.20)
project(test_xlog)
# 制定头文件查找路径
include_directories("../xlog")

# 指定库查找路径
link_directories("../xlog/build")

add_executable(test_xlog main.cpp)
# 指定加载的库
target_link_libraries(test_xlog xlog)

这样我们就能调用我们编译的静态库了

编译动态库

直接修改一下我们的CMakeLists.txt,在我们的项目目录内生成

#CMakeLists.txt test_xlog xlog 102
cmake_minimum_required(VERSION 3.20)
project(xlog)
include_directories("xlog")
add_library(xlog SHARED ./xlog/xlog.cpp)
add_executable(xlog_test ./xlog_test/main.cpp)
target_link_libraries(xlog_test xlog)

以上就是我们CMAKE基础入门的知识了。

3. CMAKE提高

3.1 CMAKE的注释

3.1.1 在3.0以前的注释,都是#的行注释

CMakeLists.txt

#这是一条单行注释
3.1.1 在3.0以后,增加了多行注释#[[注释内容]]

CMakeLists.txt

#[[这是一条多行注释
Hello
]]

3.2 CMAKE的调试打印

3.2.1 基本使用方法

CMakeLists.txt

cmake_minimum_required(VERSION 3.20)
project(message)
message("参数1")
message("参数p1" "参数p2" "p3")
3.2.2 message的高级使用-指定日志级别 message([<mode>] "message")

它的级别有--log-level = <ERROR|WARNING|NOTICE|STATUS|VERBOSE|DEBUG|TRACE>
输出的方式 stdoutstderr

#这是一条单行注释

#[[这是一条多行注释
Hello
]]
cmake_minimum_required(VERSION 3.20)
project(message)
message("参数1")
message("参数p1" "参数p2" "p3")

# 进程退出,生成退出
message(FATAL_ERROR "TEST FATAL_ERROR")
# 进程继续 ,生成退出
message(SEND_ERROR "TEST SEND_ERROR")
#WARNING 打印代码路径和行号
message(WARNING "TEST WARNING")
#NOTICE等同于 none也就是不加 message("TEST NOTICE")
message(NOTICE "TEST NOTICE")
#STATUS 加前缀 -- 用户可能感兴趣
message(STATUS "TEST STATUS")
#VEBOSE 默认不显示 用户需要的详细信息

message(VERBOSE "TEST VERBOSE")

#设置日志显示级别
#cmake -S . -B build --log-level=VERBOSE

message(DEBUG "TEST DEBUG")

message(TRACE "TEST TRACE")

3.3 message模块查找日志和显示缩进 message (<checkstate> "msg")

#[[
CHECK_PASS
记录检查的成功结果
CHECK_FAIL
记录不成功的检查结果
CHECK_START
开始记录将要执行检查的结果
]]

#开始查找
message(CHECK_START "Find xcpp")
#查找库的代码

#嵌套查找
message(CHECK_START "Find xlog")
#查找XLOG代码
message(CHECK_PASS "successed!")


#结束查找 查找失败
message(CHECK_FAIL "Not Found")

3.2 set变量入门和示例

3.2.1 变量语法 set

将一个CMAKE变量设置为给定值
set(<variable> <value>)将变量<variable>的值设置为<value>
如果没有指定<value>,那么这个变量就会被撤销而不是被设置。
unset(<variable>)撤销变量

3.2.2 变量的使用
  • 变量引用是值替换,如果未设置变量,返回空字符串
  • 变量引用可以嵌套并从内向外求值
  • 变量名大小写敏感

CMakeLists.txt

cmake_minimum_required(VERSION 3.20)
project(test_ver)
set(VAR1 "测试变量VAR1的值")
message("VAR="${VAR1})
message("VAR1 in string ${VAR1}")
message("\${VAR1}=${VAR1}")

set(VAR2 "VAR1")
message("VAR2=" ${VAR2})
message("VAR2=" ${${VAR2}})

unset(VAR1)
message("\${VAR1}=${VAR1}")
3.2.3 变量让message输出不同的颜色
cmake_minimum_required(VERSION 3.20)
project(message_color)
#[[
033[1;31;40m    <!--1-高亮显示 31-前景色红色  40-背景色黑色-->
033[0m          <!--采用终端默认设置,即取消颜色设置-->
显示方式  
0                终端默认设置
1                高亮显示
4                使用下划线
5                闪烁
7                反白显示
8                不可见

前景色            背景色           颜色
---------------------------------------
30                40              黑色
31                41              红色
32                42              绿色
33                43              黃色
34                44              蓝色
35                45              紫红色
36                46              青蓝色
37                47              白色
]]

string(ASCII 27 Esc)

# Esc[0;31m
set(R "${Esc}[0;31m")   #红色
#Esc[0m 
set(E "${Esc}[m" )      #结束颜色设置
set(B "${Esc}[1;34m")   #蓝色高亮
set(RB "${Esc}[1;31;40m") #红色字体黑色背景
message("${R}红色内容${E} 默认颜色")
message("${B}蓝色内容${E} 默认颜色")
message("${RB}红色字体黑色背景${E} 默认颜色")

3.3 cmake内建变量

  • 提供信息的变量
  • 改变行为的变量
  • 描述系统的变量
  • 控制构建过程的变量

xlog.h

//xlog.h
#ifndef XLOG_H
#define XLOG_H
//__declspec(dllexport)
//__declspec(dllexport) 导出XLog类的函数到lib文件中
// xlog库文件调用 dllexport
// test_xlog 调用 dllimport
#ifndef _WIN32 //linux mac unix Android
    #define XCPP_API
#else //windows
    #ifdef xlog_STATIC  //静态库
        #define XCPP_API
    #else               //动态库
        #ifdef xlog_EXPORTS
            #define XCPP_API __declspec(dllexport) //库项目调用
        #else
            #define XCPP_API __declspec(dllimport) //调用库项目调用
        #endif
    #endif
#endif
class XCPP_API XLog
{
public:
	XLog();
};
#endif

xlog.cpp

#include "xlog.h"
#include <iostream>
using namespace std;
XLog::XLog()
{
	cout<<"Create XLog"<<endl;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.20)
project(xlog)
#1 提供信息的变量  项目名称 ${PROJECT_NAME}对应project的name
#2 改变行为的变量 BUILD_SHARED_LIBS ON 动态库 OFF静态库 默认OFF
#set(BUILD_SHARED_LIBS ON)
set(BUILD_SHARED_LIBS OFF) #静态库

#cmake传递变量给c++
add_definitions(-Dxlog_STATIC) #默认值1

#3 描述系统的变量
message("MSVC = " ${MSVC})
message("WIN32 = " ${WIN32})
message("UNIX = " ${UNIX})
message("CMAKE_SYSTEM_NAME = " ${CMAKE_SYSTEM_NAME})

# 4 控制构建过程的变量 输出路径控制 CMAKE_COLOR_MAKEFILE 是否生成makefile的颜色,默认是ON
set(CMAKE_COLOR_MAKEFILE OFF)

add_library(${PROJECT_NAME} xlog.cpp xlog.h)

3.4 include

从给定的文件中读取CMake的列表文件
include(file [OPTIONAL][RESULT_VARIABLE VAR])
从给定的文件中读取CMake的清单文件代码。在清单文件的命令会被立即处理。如果指定OPTIONAL选项,那么如果包含文件不存在的话,不会报错。如果指定了RESULT_VARIABLE选项,那么var或者会被设置被包含文件的完整路径,或是NOTFOUND,表示没有找到改文件

CMakeLists.txt

cmake_minimum_required(VERSION 3.20)
project("cmake_include")
message("begin include")
include("cmake/test_cmake.cmake")
include("cmake/test_cmake.cmake")
include("cmake/test_cmake1.cmake" OPTIONAL) #OPTIONAL 可选,文件不存在不报错
include("cmake/test_cmake1.cmake" OPTIONAL RESULT_VARIABLE ret) #OPTIONAL 返回值
message("RESULT_VARIABLE ret=${ret}")
message("end include")

cmake/test_cmake.cmake

message("cmake/test_cmake.make")

3.5 自动查找所有源码文件和头文件

增加头文件和代码后不用修改cmake
aux_source_directory ---- aux_source_directory("./src" LIB_SRCS)#当前路径下所有源码 存入 DIR_SRCS
file ---- FILE(GLOB H_FILE "${INCLUDE_PATH}/xcpp/*.h")
FILE(GLOB H_FILE "${INCLUDE_PATH}/*.h<details>

CMakeFileLists.txt

#108auto_src_h/CMakeLists.h
#[[
108auto_src_h
    CMakeLists.txt
    main.cpp
    src
        xlog.cpp
        xthread.cc
        xtest.c
    include
        xlog.h
        xthread.hpp
]]

cmake_minimum_required(VERSION 3.20)
project("auto_src_h")

#头文件加载路径
set(INCLUDE_PATH  "./include")
include_directories(${INCLUDE_PATH})

# 找到当前目录(.)下源码写入M_SRC变量中
aux_source_directory("." M_SRC)
aux_source_directory("./src" SRC)

#读取所有的头文件
file(GLOB H_FILE "${INCLUDE_PATH}/*.h*")

add_executable(${PROJECT_NAME} ${M_SRC} ${SRC} ${H_FILE})

3.6 cmake命令实现程序的分步生成。

从源码到执行程序

  • 预处理
  • 编译
  • 汇编
  • 链接
  • 运行---动态库加载路径
  • cmake程序分步生成、指定项目和清理

我们可以使用 cmake --build . --target help查看我们生成的目标文件
在linux中,预处理会生成.i文件,编译生成.s文件,然后就会生成.o文件,最后就是直接生成编译的文件。

3.7 cmake调试打印生成的具体指令

  • CMAKE_VERBOSE_MAKEFILE
  • cmake --build . -v

第一种方法

# CMakeLists.txt 文件名大小写不敏

#指定cmake最低版本
cmake_minimum_required(VERSION 3.20)

#构建项目的名称
project(first_example)

set(CMAKE_VERBOSE_MAKEFILE ON)
#构建执行程序
add_executable(first_cmake first_cmake.cpp)

第二种方法 cmake --build . -v

3.8 cmake设置输出路径add_subdirectory

3.8.1 库输出路径

通过设置CMAKE_LIBRARY_OUTPUT_DIRECTORY 这个变量

3.8.2 归档输出路径

通过设置CMAKE_ARCHIVE_OUTPUT_DIRECTORY 这个变量

3.8.3 执行程序输出路径

通过设置CMAKE_RUNTIME_OUTPUT_DIRECTORY 这个变量

CMakeLists.txt

#CMakeLists.txt test_xlog  xlog 109cmake_out
cmake_minimum_required(VERSION 3.20)
project(xlog)
include_directories("xlog")

#CMakeLists.txt路径
message("CMAKE_CURRENT_LIST_DIR = ${CMAKE_CURRENT_LIST_DIR}")
# .so库输出路径 默认路径在-B build目录下
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/lib")

#执行程序和dll 动态库pdb调试文件 输出路径
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/bin")

#归档输出路径 静态库 .lib 动态库.lib地址文件 linux静态库.a 静态库pdb调试文件
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/lib")

#添加xlog库编译 项目自带预处理变量 xlog_EXPORTS
#add_library(xlog SHARED xlog/xlog.cpp)

set(BUILD_SHARED_LIBS OFF) #静态库
#cmake传递变量给c++
add_definitions(-Dxlog_STATIC) #默认值1
add_library(xlog xlog/xlog.cpp)

# add_library(xlog_d SHARED xlog/xlog.cpp)

#执行文件
add_executable(test_xlog test_xlog/test_xlog.cpp)

#链接库
target_link_libraries(test_xlog xlog)

使用我们之前的2个代码的例子,现在还有几个遗留的问题

  • 多个项目不同输出路径
  • debug和release不同输出
  • 一个项目同时要设置静态库和动态库

3.9 cmake add_subdirectory

./CMakeFileLists.txt

#CMakeLists.txt test_xlog  xlog 109cmake_out
cmake_minimum_required(VERSION 3.20)
project(xlog)
include_directories("xlog")

#CMakeLists.txt路径
message("CMAKE_CURRENT_LIST_DIR = ${CMAKE_CURRENT_LIST_DIR}")
# .so库输出路径 默认路径在-B build目录下
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/lib")

#执行程序和dll 动态库pdb调试文件 输出路径
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/bin")

#归档输出路径 静态库 .lib 动态库.lib地址文件 linux静态库.a 静态库pdb调试文件
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/lib")

#set(BUILD_SHARED_LIBS OFF) #静态库
#cmake传递变量给c++
#add_definitions(-Dxlog_STATIC) #默认值1

set(BUILD_SHARED_LIBS ON) #动态库

add_subdirectory("xlog")
add_subdirectory("test_xlog")

./test_xlog/CMakeLists.txt

#CMakeLists.txt test_xlog 102
cmake_minimum_required(VERSION 3.20)
project(test_xlog)
#指定头文件查找路径 
include_directories("../xlog")

# 指定库查找路径  window自动找 ../xlog/build/Debug  ../xlog/build/Release
link_directories("../xlog/build")

add_executable(test_xlog test_xlog.cpp)

# 指定加载的库
target_link_libraries(test_xlog xlog)

./xlog/CMakeLists.txt

#106cmake_system_ver/CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(xlog)

#3 描述系统的变量
message("MSVC = " ${MSVC})
message("WIN32 = " ${WIN32})
message("UNIX = " ${UNIX})
message("CMAKE_SYSTEM_NAME = " ${CMAKE_SYSTEM_NAME})

# 4 控制构建过程的变量 输出路径控制 CMAKE_COLOR_MAKEFILE 是否生成makefile的颜色,默认是ON
set(CMAKE_COLOR_MAKEFILE OFF)
add_library(${PROJECT_NAME} xlog.cpp xlog.h)

4.Cmake常用语法

4.1 cmake if语法说明与常量判断代码演示

if基础表达式
常量
if()
1,ON,YES,TRUE,Y或非零数(包括浮点数),则为真。
0,OFF,FALSE,N,IGNORE,NOTFOUND,空字符串,或者以suffix结尾-NOTFOUND则为假

if(1)
    message("1 is true")
endif()

if(0)
    message("0 is true?")
else()
    message("0 is false")
endif()

if(OFF)
    message("OFF is true?")
elseif(NO)
    message("NO is true?")
else()
    message("OFF ON is False")
endif(OFF)

if()
   message("empty is true?")
else()
    message("empty is false?")
endif()

if(-1)
    message("-1 is true")
endif(-1)

if(123)
    message("123 is true")
endif(123)

if(0.1)
message("0.1 is true")
endif(0.1)

if(-NOTFOUND)
    message("-NOTFOUND is true")
else()
    message("-NOTFOUND is false")
endif(-NOTFOUND)

变量
if()
非假值常量为真。未定义和其他为假。
环境变量总为假
宏参数不是变量

if(VAR_NOT_DEF)
    message("VAR_NOT_DEF is true?")
else()
    message("VAR_NOT_DEF is false?")
endif(VAR_NOT_DEF)

set(VAR1_TRUE TRUE)
if(VAR1_TRUE)
   message("VAR1_TRUE is true!") 
endif(VAR1_TRUE)

if()
字符串
字符串的值时常量真则为真
其他带引号的字符串始终计算为false

if("TRUE")
    message("string TRUE is true!")
endif("TRUE")

if("ON")
    message("string ON is true!")
endif("ON")

if("test")
    message("string test is true!")
else()
    message("string test is false!")
endif("test")

if("1234")
message("string 1234 is true!")
endif("1234")

4.2 if逻辑操作符

NOT、AND、OR
逻辑运算符
if(NOT )
如果条件不为真,则为真。
if( AND )
如果两个条件都是真的,则为真。

if( OR )
如果任一条件是真的,则为真。

if((condition) AND (condition OR (condition)))
首先评估括号内的条件,然后评估其余条件。

set(VAR_OFF OFF)
if(NOT VAR_OFF)
    message("NOT VAR_OFF(true)")    
endif(NOT VAR_OFF)

if(TRUE AND ON)
    message("TRUE and ON is true")
endif(TRUE AND ON)

if(TRUE AND OFF)
    message("TRUE and OFF is true")
else()
    message("TRUE and OFF is false")
endif(TRUE AND OFF)

if(TRUE OR OFF)
    message("TRUE or OFF is true")
else()
    message("TRUE or OFF is false")
endif(TRUE OR OFF)

if(TRUE AND (OFF OR ON))
    message("TRUE AND (OFF OR ON) is true")
endif(TRUE AND (OFF OR ON))

4.3 一元判断、二元判断 、正则匹配

一元判断

  • EXISTS
  • COMMAND
  • DEFINED
set(VAR_DEF OFF)
if(DEFINED VAR_DEF)
    message("VAR_DEF is DEFINED")
endif(DEFINED VAR_DEF)

if(DEFINED VAR_NOT_DEF)
    message("VAR_NOT_DEF is DEFINED?")
else()
    message("VAR_NOT DEF not DEFINED?")
endif(DEFINED VAR_NOT_DEF)

二元判断

  • EQUAL
  • 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
set(VAR1 123)
if(VAR1 EQUAL "123")
    message("VAR1 EQUAL 123")    
endif(VAR1 EQUAL "123")

set(VAR2 "test")
if(VAR2 EQUAL "test")
    message("VAR2 EQUAL test")
else()
    message("VAR2 not EQUAL test")    
endif(VAR2 EQUAL "test")

set(VAR2 "test")
if(VAR2 STREQUAL "test")
    message("VAR2 STREQUAL test")
else()
    message("VAR2 not STREQUAL test")    
endif(VAR2 STREQUAL "test")

if(VAR1 STREQUAL 123)
    message("VAR1 STREQUAL 123")   
else()
    message("VAR1 not STREQUAL 123")  
endif(VAR1 STREQUAL 123)

正则匹配
MATCHES if(<variable|string> MATCHES regex)


if("abcd1234" MATCHES "[a-z]+")
    message(" \"abcd1234\" MATCHES \"[a-z]+\"")
endif("abcd1234" MATCHES "[a-z]+")

4.4 cmake cache缓存变量设置

设置公式set(<variable> <value>... CACHE <type> <docstring> [FORCE])

type

  • BOOL
    ON/OFF 选择框
  • FILEPATH 文件选择
  • PATH 目录选择
  • STRING 字符串
  • INTERNAL 内部变量

docstring 变量说明
FORCE 强制修改缓存,不设置第二次调用不改

cmake_minimum_required(VERSION 3.20)
project(cmake_cache)
#设置缓存变量
set(VAR1 "CACHE VAR1" CACHE STRING "cache doc")
#缓存变量第二修改不生效
set(VAR1 "CACHE VAR2" CACHE STRING "cache doc")
message("VAR1 = ${VAR1}")

#强制修改缓存
set(VAR1 "CACHE VAR3" CACHE STRING "cache doc" FORCE)

4.5 普通变量和全局CACHE变量的作用域

# CACHE变量作用域是全局的
# 普通变量的作用域自身和子模块

set(VAR2_NORMAL "test normal")
message("in main")
message("VAR2_NORMAL = ${VAR2_NORMAL}")

4.6 cmake-gui与CACHE缓存变量的各种类型

#BOOl勾选
set(VAR_BOOL1 "ON" CACHE BOOL "VAR bool 001")
set(VAR_BOOL2 "OFF" CACHE BOOL "VAR bool 002")
message("-------------------------------------------")
message("VAR_BOOL1 = ${VAR_BOOL1}")
message("VAR_BOOL2 = ${VAR_BOOL2}")
#选择文件
set(VAR_FILE "filepath" CACHE FILEPATH "var FILEPATH")
#选择文件夹
set(VAR_PATH "PATH" CACHE PATH "var PATH")
#内部缓存变量
set(VAR_INTERNAL "INTERNAL" CACHE INTERNAL "var INTERNAL")

4.7 cmake用户修改该配置和option


option(OPT1 "opt1 doc" OFF)
option(OPT2 "opt2 doc" ON)

在Linux下,我们先进行项目的生成,在用CCMAKE进行生成。

4.8 cmake CACHE覆盖策略设置

当次政策设置为NEW时,set(CACHE)命令不会从当前范围中删除任何同名的普通变量。在以下情况,该OLD行为会从当前作用域中删除任何同名的普通变量.
cmake_policy(SET CMP0126 NEW)
$CACHE{NVAR1}

cmakelists.txt

#普通变量
set(NVAR1 "normal var1")
#设置缓存变量覆盖同名普通变量的策略
# OLD 删除同名普通变量
# NEW 不删除普通变量,要访问cache要用 $CACHE{var_name}
cmake_policy(SET CMP0126 NEW)

#cache变量  
set(NVAR1 "cache var1" CACHE STRING "cache doc")

message("NVAR1 = \t ${NVAR1}")
message("CACHE{NVAR1} = \t $CACHE{NVAR1}") #直接查找缓存变量

4.9传递缓存变量

-D 传递缓存变量
cmake内置缓存变量

  • BUILD_SHARED_LIBS
  • set(BUILD_SHARED_LIBS OFF CACHE BOOL "lib")
  • message("BUILD_SHARED_LIB=${BUILD_SHARED_LIBS}")
#命令行传递缓存变量
#cmake -S . -B build -D PARA1=para001
message("PARA1 = ${PARA1}")
set(BUILD_SHARED_LIBS OFF CACHE BOOL "so or a")
message("BUILD_SHARED_LIBS = ${BUILD_SHARED_LIBS}")
message("\n=================")

4.10 cmake变量和属性有什么区别

属性类似为成员变量
变量类似为全局变量
属性的语法

set_property(<GLOBAL                      |
              DIRECTORY [<dir>]           |
              TARGET    [<target1> ...]   |
              SOURCE    [<src1> ...]
                        [DIRECTORY <dirs> ...]
                        [TARGET_DIRECTORY <targets> ...] |
              INSTALL   [<file1> ...]     |
              TEST      [<test1> ...]     |
              CACHE     [<entry1> ...]    >
             [APPEND] [APPEND_STRING]
             PROPERTY <name> [<value1> ...])
get_property(<variable>
             <GLOBAL             |
              DIRECTORY [<dir>]  |
              TARGET    <target> |
              SOURCE    <source>
                        [DIRECTORY <dir> | TARGET_DIRECTORY <target>] |
              INSTALL   <file>   |
              TEST      <test>   |
              CACHE     <entry>  |
              VARIABLE           >
             PROPERTY <name>
             [SET | DEFINED | BRIEF_DOCS | FULL_DOCS])
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>])  

例子

# 全局属性
#设置全局属性
set_property(GLOBAL PROPERTY TEST_GLOBAL "test global 001")

#获取全局属性
get_property(val GLOBAL PROPERTY TEST_GLOBAL)
message("TEST_GLOBAL = ${val}")

#访问子目录中的全局属性
add_subdirectory(sub1)
get_property(val GLOBAL PROPERTY SUB1_GLOBAL)
message("SUB1_GLOBAL = ${val}")


#APPEND APPEND_STRING
# APPEND 数组方式添加 TEST_APPEND = append 001;append 002;append 003 
set_property(GLOBAL APPEND PROPERTY TEST_APPEND "append 001")
set_property(GLOBAL APPEND PROPERTY TEST_APPEND "append 002")
set_property(GLOBAL APPEND PROPERTY TEST_APPEND "append 003")
get_property(val GLOBAL PROPERTY TEST_APPEND)
message("TEST_APPEND = ${val}")


# APPEND_STRING 字符串拼接 append string 001 append string 002 append string 003
set_property(GLOBAL APPEND_STRING PROPERTY TEST_APPEND_STRING "append string 001 ")
set_property(GLOBAL APPEND_STRING PROPERTY TEST_APPEND_STRING "append string 002 ")
set_property(GLOBAL APPEND_STRING PROPERTY TEST_APPEND_STRING "append string 003 ")
get_property(val GLOBAL PROPERTY TEST_APPEND_STRING)
message("TEST_APPEND_STRING = ${val}")

4.11 cmake define_property属性说明设置

#get_property SET | DEFINED 
set_property(GLOBAL PROPERTY P1 "p1")
get_property(var GLOBAL PROPERTY P1)
message("P1 SET = ${var}")
if(var)
    message("P1 is set")
else()
    message("P1 not set")
endif()
#只有调用define_property之后才会为1
get_property(var GLOBAL PROPERTY P1 DEFINED)
message("P1 DEFINED = ${var}")
if(NOT var)
    message("P1 not defined")
endif()

#定义属性 不需要赋值
define_property(GLOBAL PROPERTY TEST_DEF  BRIEF_DOCS "p1 brief docs")
get_property(var GLOBAL PROPERTY TEST_DEF DEFINED )
message("TEST_DEF DEFINED = ${var}")

4.12 cmake文件属性和给c++传递预处理变量

# cmake传递变量给c++
# cmake 预置属性 COMPILE_DEFINITIONS    传递预处理变量(宏变量) -DPARA1 1234
set_property(SOURCE main.cpp PROPERTY COMPILE_DEFINITIONS "PARA1=1234")
add_executable(${PROJECT_NAME} main.cpp)

4.13 cmake目标属性设置给c++传递多个宏

#cmake 目标属性 目标必须已经存在
set_property(TARGET ${PROJECT_NAME} PROPERTY TVAR "tval")
get_property(var TARGET ${PROJECT_NAME} PROPERTY TVAR)
message("TVAR= ${var}")
#给C++传递宏
set_property(TARGET ${PROJECT_NAME} PROPERTY COMPILE_DEFINITIONS "PARA2=\"test_para2\"")
#追加设置
set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY COMPILE_DEFINITIONS "PARA3=\"test_para3\"")


推荐一个零声学院免费教程,个人觉得老师讲得不错,
分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习:
服务器
音视频
dpdk
Linux内核

posted @ 2022-09-25 23:22  飘雨的河  阅读(350)  评论(0编辑  收藏  举报