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>
输出的方式 stdout
、stderr
#这是一条单行注释
#[[这是一条多行注释
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内核
CMAKE的学习的更多相关文章
- CMAKE工具学习
最近在学习各大物联网平台的SDK包,发现其工程都使用了一种叫cmake的工具在管理代码.于是花了一天时间简单学习了解了cmake工具,其目的是让自己能读懂使用该工具管理的代码,并能简单使用该工具管理我 ...
- 【ESP32学习】CMake学习
在之前的博客中提到,ESP-IDF采用的是CMake来构建项目,因此需要学习一下CMake,以对ESP32的开发有更好的把握 参考: Windows下CMake安装教程 从零开始详细介绍CMake C ...
- linux 下cmake 编译 ,调用,调试 poco 1.6.0 小记
上篇文章 小记了: 关于 Poco::TCPServer框架 (windows 下使用的是 select模型) 学习笔记. http://www.cnblogs.com/bleachli/p/4352 ...
- [C] c99int(让VC等编译器自动兼容C99的整数类型)V1.02。源码托管到github、添加CMake编译配置文件、使用doxygen规范注释
新版本—— http://www.cnblogs.com/zyl910/p/zlstdint_v100.html[C] zlstdint(让VC.TC等编译器自动兼容C99的整数类型)V1.0.支持T ...
- CMake使用教程
转自 RichardXG 原文 CMake使用教程 CMake是一个比make更高级的编译配置工具,它可以根据不同平台.不同的编译器,生成相应的Makefile或者vcproj项目. 通过编写CMak ...
- CMake入门指南-编译教程
CMake是一个比make更高级的编译配置工具,它可以根据不同平台.不同的编译器,生成相应的Makefile或者vcproj项目.通过编写CMakeLists.txt,可以控制生成的Makefile, ...
- CMake入门指南
原文地址:http://www.cnblogs.com/sinojelly/archive/2010/05/22/1741337.html CMake是一个比make更高级的编译配置工具,它可以根据不 ...
- Linux下CMake简明教程
转载地址:https://blog.csdn.net/whahu1989/article/details/82078563 CMake是开源.跨平台的构建工具,可以让我们通过编写简单的配置文件去生成本 ...
- cmake和make
学计算机的,在写代码的时候,IDE安装好,环境按着教程配置好,就直接代码了,编辑器的具体原理只是一知半解,现在来系统学习一下,为了方便以后学习HElib! make和cmake 写程序大体步骤为: 1 ...
- 【精解】EOS智能合约演练
EOS,智能合约,abi,wasm,cleos,eosiocpp,开发调试,钱包,账户,签名权限 热身 本文旨在针对EOS智能合约进行一个完整的实操演练,过程中深入熟悉掌握整个EOS智能合约的流程,过 ...
随机推荐
- centos离线安装mongodb-database-tools
mongodb-database-tools是MongoDB数据库工具的命令行的工具,用于工作与MongoDB部署.可以使用mongodump和mongoimport很方便的导入导出备份数据. 该数据 ...
- 【算法】【动态规划】动规dp解决不同路径两道经典OJ笔试题【力扣62-力扣63】超详细的动态规划入门详解,掌握动态规划的解题方法
[算法][动态规划]动规dp解决不同路径两道经典OJ笔试题[力扣62-力扣63]超详细的动态规划入门详解,掌握动态规划的解题方法 作者: @小小Programmer 这是我的主页:@小小Program ...
- Python中的UnboundLocalError是什么错误?如何解决?
在一个月黑风高的夜晚,我们满心欢喜地写出以下代码: money = 10000 # 当前的财产,单位为元 def add_money(value): money += value print('当 ...
- java bean 慎用 is开头isXxx开头的属性,若必须得用,那么一定要记得 idea自动生成的 setter 和 getter会不标准,从而会引起问题,他自动生成后,需要手工再次进行修改,才可使用,要不然有可能引起各种问题
直接上例子: 然后用 Idea 自动生成 getter 和 setter public class XyzBean { //最普通的 private String name; //Boolean类型, ...
- Pandas—to_csv()写入函数参数详解
1. to_csv函数的参数 DataFrame.to_csv(path_or_buf=None, sep=',', na_rep='', float_format=None, columns=Non ...
- Blazor OIDC 单点登录授权实例5 - 独立SSR App (net8 webapp ) 端授权
目录: OpenID 与 OAuth2 基础知识 Blazor wasm Google 登录 Blazor wasm Gitee 码云登录 Blazor OIDC 单点登录授权实例1-建立和配置IDS ...
- USB至串口TTL转接设备及Console线
USB转串口常见芯片方案 FT232, FTDI(英国) 公认稳定可靠, 传输速率3Mbps, 功能最强, 单芯片内置SPI,TWI,JTAG,GPIO等功能. FT232BM为较早型号, FT232 ...
- 【Unity3D】Tank大战
1 需求实现 项目代码见→坦克大战1.1.0 1)人机交互 玩家通过 ↑ ↓ ← → 键(或 W.S.A.D)键控制己方坦克平移: 玩家通过滑动鼠标右键控制己方坦克左右旋转: 玩家通过鼠标左键 ...
- python中矩阵切片维数微秒变化
1 前言 使用切片访问矩阵的部分数据(特别是一行或一列数据)时,通常会出现切片维数怎么在瞎变化,以致于不得不用reshape()强制改变维数.在深度学习中,网络对矩阵维数的要求是非常严格的,往往就是这 ...
- Jsp+Servlet实现文件上传下载(一)--文件上传
文件上传和下载功能是Java Web必备技能,很实用. 本文使用的是Apache下的著名的文件上传组件 org.apache.commons.fileupload 实现 下面结合最近看到的一些资料以及 ...