当前位置: 首页 > news >正文

cmake:基础

        本文主要探讨cmake语法相关知识。

cmake(GUI)安装

apt install cmake-curses-gui cmake -y

cmake语法

cmake_minimum_required(VERSION 版本号)
设置cmake最低版本

project(工程名) <==> PROGECT_NAME/CMAKE_PROJECT_NAME
设置工程名字

add_library(库名 SHARED/STATIC 源码)
编译生成库文件,默认生成静态库

add_executable(程序名 源码)
生成可执行程序

include_directories(path)
添加头文件路径

message(mode "message")
打印编译信息
FATAL_ERROR:出错停止编译和生成
SEND_ERROR:出错继续编译和生成
WARNING:告警继续编译
AUTHOR_WARNING:开发者警告继续编译
DEPRECATION:设置CMAKE_ERROR_DEPRECATED为true编译出错
(none) or NOTICE:用于打印消息
STATUS:编译状态信息,默认消息显示级别
DEBUG:调试信息
TRACE:日志级临时信息(详细)
CHECK_START:开始记录检查消息
CHECK_PASS:记录检查的成功结果
CHECK_FAIL:记录检查的失败结果
--log-level 参数用于指定消息打印最低级别

set(VAR_NAME var)/unset(VAR__NAME)
设置/删除变量

CMake给c++传递变量
add_definitions(-D PARAM) 
PARAM默认值是1CMAKE_CURRENT_LIST_DIR                    当前CMakeList.txt完整路径
CMAKE_CURRENT_LIST_LINE                   当前所在行
CMAKE_C_FLAGS                             C编译参数
CMAKE_CXX_FLAGS                           C++编译参数
DCMAKE_BUILD_TYPE                         设置Debug/Release
BUILD_SHARED_LIBS                         动态启用库变量
CMAKE_SYSTEM_NAME                         系统名
PROJECT_SOURCE_DIR/CMAKE_SOURCE_DIR       顶层目录
PROJECT_BINARY_DIR/CMAKE_BINARY_DIR       顶层缓存目录
CMAKE_CURRENT_SOURCE_DIR                  当前源码所在路径
CMAKE_CURRENT_BINARY_DIR                  当前缓存目录
CMAKE_RUNTIME_OUTPUT_DIRECTOR             执行文件输出路径
EXECUTABLE_OUTPUT_PATH                    执行文件输出路径
LIBRARY_OUTPUT_PATH                       动态库文件输出路径
CMAKE_LIBRARY_OUTPUT_DIRECTORY            动态库文件输出路径
CMAKE_ARCHIVE_OUTPUT_DIRECTORY            静态态库文件输出路径
ARCHIVE_OUTPUT_DIRECTORY                  静态态库文件输出路径
CMAKE_C_COMPILTER                         C编译工具链
CMAKE_CXX_COMPILTER                       C++编译工具链
CMAKE_MAJOR_VERSION                       cmake主版本号
CMAKE_MINOR_VERSION                       cmake次版本号
CMAKE_VERSION                             cmake版本号(主次)
PROJECT_VERSION_MAJOR                     工程主版本号
PROJECT_VERSION_MINOR                     工程次版本号
PROJECT_VERSION                           工程版本号(主次)

include(file.cmake OPTIONAL RESULT_VARIABLE ret)
导入子cmake,OPTIONAL参数使文件不存在不出错
ret为NOTFOUND不存在文件,FOUND存在文件

aux_source_directory(目录 变量) 
将目录下的文件存入变量

file
file(WRITE/APPEND filename "message")
WRITE文件存在覆盖写入,文件不存在创建写入
APPEND追加吸入
file(READ filename var num offset HEX)
READ以HEX读文件从offset开始读num字节存储在var中file
file(GLOB VAR path/*.h)
读取path录下的.h文件列表存入VAR
file(GLOB_RECURSE VAR path *.c)
读取path及子目录下的.c文件列表存入VAR

逻辑比较:NOT,AND,OR
大小比较:EQUAL,LESS,LESS_EQUAL,GREATER,GREATER_EQUAL
字符串比较:STR_EQUAL...
版本比较:VERSION_EQUAL...
if(COMMAND name)name是命令,宏,函数为true
if(TEST test)add_test创建测试为true
if(DEFINED name)定义普通,缓存,环境变量为true
if(EXISTS file/directory)文件或目录(全路径)存在为true
if(file1 IS_NEWER_THAN file2)file1比file2新/两文件中一个不存在则为true
if(IS_DIRECTORY directory)是目录为true
if(IS_SYMLINK file)是符号链接为true
if(IS_ABSOLUTE path)是绝对路径为true

缓存
缓存可在构建中重新加载运行
set(VAR var CACHE BOOL "test_cache")
定义缓存变量
BOOL        存储布尔值
PATH         存储路径
STRING         存储字符串
FILEPATH     存储文件路径
INTERNAL    内部变量不在缓存显示

ccmake -B test(GUI) 
cmake -S . -B test -D VAR=new_var
修改缓存变量

属性 
set_property(GLOBAL|DIRECTORY|TARGET|SOURCE|INSTALL|TEST|CACHE PROPERTY name value)
get_property(var GLOBAL|DIRECTORY|TARGET|SOURCE|INSTALL|TEST|CACHE PROPERTY name)

数学运算
math(EXPR var "expression" OUTPUT_FORMAT format)
HEXADECIMAL 16进制
DECIMAL     10进制

字符串处理
string(FIND <string> <substring> <out-var> [...]) 
string(REPLACE <match-string> <replace-string> <out-var> <input>...)
string(REGEX MATCH <match-regex> <out-var> <input>...)
string(APPEND <string-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(ASCII <number>... <out-var>)
string(HEX <string> <out-var>)
string(TIMESTAMP <out-var> [<format string>] [UTC])


list
set(listName var1 var2 var3...)
list(APPEND listName element1 [element2 ...])        尾部追加
list(INSERT listName index element1 [element2 ...]) 指定位插入
list(REMOVE_ITEM listName element1 [element2 ...])  移除元素
list(REMOVE_AT listName index)                        移除指定位元素
list(LENGTH listName outputVariable)                获取列表长度
list(GET listName index outputVariable)                获取列表指定位元素
list(FIND listName value outputVariable)            查找列表首次出现该值的位置
list(REVERSE listName)                                反转列表

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

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


名称大小写不敏感
在调用处展开类似inline
macro(foo arg1 arg2) 
    <commands>
endmacro()
ARGC参数个数
ARGV0/ARGV1/ARGV2参数

函数
function(func arg1 arg2)
    <commands>
endfunction(func)

func(param1 param2)

表达式生成器
包含多参数时满足一个则成立
$<BOOL:string>
$<AND:{条件1}[,{条件2}]...>    
$<OR:{条件1}[,{条件2}]...>    
$<NOT:{条件}>
$<EQUAL:{数值1},{数值2}>
$<STREQUAL:{字符串1},{字符串2}>
$<IN_LIST:{字符串},{列表}>
$<VERSION_LESS:{版本号1},{版本号2}>    
$<VERSION_LESS_EQUAL:{版本号1},{版本号2}>    
$<VERSION_EQUAL:{版本号1},{版本号2}>    
$<VERSION_GREATER_EQUAL:{版本号1},{版本号2}>    
$<VERSION_GREATER:{版本号1},{版本号2}>    
$<TARGET_EXISTS:{构建目标}>
$<CONFIG:{构建模式1}[,{构建模式2}]...>
$<PLATFORM_ID:{操作系统1}[,{操作系统2}]...>
$<C_COMPILER_ID:{编译器1}[,{编译器2}]...>
$<CXX_COMPILER_VERSION:{版本号}...>
$<COMPILE_FEATURES:{编译特性1}[,{编译特性2}]...>
$<COMPILE_LANGUAGE:{编程语言1}[,{编程语言2}]...>
$<JOIN:{列表字符串},{分隔符}>
$<JOIN:1;2;3,$<COMMA>> ==> 1,2,3
$<ANGLE-R> 为">"
$<COMMA> 为","
$<SEMICOLON> 为";"
$<LOWER_CASE:{字符串}> 转小写
$<UPPER_CASE:{字符串}> 转大写
$<TARGET_NAME_IF_EXISTS:{目标}> 文件绝对路径
$<TARGET_FILE:{目标}> 二进制文件绝对路径
$<TARGET_FILE_BASE_NAME:{目标}>    基本名称    base
$<TARGET_FILE_PREFIX:{目标}>    前缀lib
$<TARGET_FILE_SUFFIX:{目标}>    后缀.so
$<TARGET_FILE_NAME:{目标}>    文件名称    libbase.so
$<TARGET_FILE_DIR:{目标}>    目录名称
$<TARGET_PROPERTY:{目标},{目标属性}> 属性值
$<TARGET_PROPERTY:{目标属性}> 目标属性

target_include_directories
target_include_directories(<target> [SYSTEM] [AFTER|BEFORE]
<INTERFACE|PUBLIC|PRIVATE> [items1...] [<INTERFACE|PUBLIC|PRIVATE>
[items2...] ...])
AFTER/BEFORE 添加目录追到头列表/尾列表
SYSTEM 添加到系统目录
INTERFACE 只有依赖者引用
PUBLIC 依赖者和自己都引用
PRIVATE 只有自己用

target_link_libraries
target_link_libraries(<target> <PRIVATE|PUBLIC|INTERFACE> <item>... )
INTERFACE 只有依赖者引用
PUBLIC 依赖者和自己都引用
PRIVATE 只有自己用

target_compile_definitions
编译传递宏
target_compile_definitions(<target> <INTERFACE|PUBLIC|PRIVATE> [items1...])
target_compile_definitions(test_cmake PUBLIC "-DPI=3.14")

target_compile_features
设置c/c++版本
target_compile_features(test_cmake PUBLIC cxx_std_11)

add_library
add_library(<name> [STATIC|SHARED|MODULE] [EXCLUDE_FROM_ALL] [source1] [source2] [...])

配置Debug/Release
set_target_properties(cmath PROPERTIES DEBUG_POSTFIX "d")
设置debug文件后缀

set(CMAKE_BUILD_TYPE Debug)

Debug: -g
Release: -O3
RelWithDebInfo: -O2 -g
MinSizeRel: -Os

cmake -S . -B test -D CMAKE_BUILD_TYPE=Release
cmake -S . -B test && ccmake -B test

install
install(DIRECTORY doc_src DESTINATION doc_dest FILES_MATCHING PATTERN "*.txt"  PATTERN "*.html" EXCLUDE "dir" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ)
install(CODE [=[ string(TIMESTAMP now "%Y-%m-%d %H:%M:%S") FILE(APPEND install.log "${now}\n")]=])
install(TARGETS cmake_bin DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ)
install(TARGETS cmake_lib LIBRARY DESTINATION lib PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ)
install(FILES logo.png DESTINATION ${CMAKE_INSTALL_DOCDIR}/pic PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ)
install(SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/cmake/install_script.cmake")

demo: 

        语法测试

文件结构

代码示例 

run.sh

#!/bin/bashcmake -S . -B test --log-level DEBUG -D CACHE_VAR=1 -D CMAKE_BUILD_TYPE=Debugcmake --build testcd test && make installcd ..$(pwd)/bin/test_cmake

clean.sh

#!/bin/bashrm -rf test install.log lib include config doc readme.txt bin

CMakeLists.txt

cmake_minimum_required(VERSION 3.0)project(test_cmake)message("================test message=============")message(DEBUG "projetc : ${PROJECT_NAME}")
set(PARAM "hello")
message(CHECK_START "find PARMA")
if(PARAM)message(CHECK_PASS "define PARAM")
else()message(CHECK_FAIL "not define PARAM")
endif()message("================test param=============")message("CMAKE_CURRENT_LIST_DIR : ${CMAKE_CURRENT_LIST_DIR}")
message("CMAKE_CURRENT_LIST_LINE : ${CMAKE_CURRENT_LIST_LINE}")
message("CMAKE_SYSTEM_NAME : ${CMAKE_SYSTEM_NAME}")
message("PROJECT_SOURCE_DIR : ${PROJECT_SOURCE_DIR}")
message("PROJECT_BINARY_DIR : ${PROJECT_BINARY_DIR}")
message("CMAKE_VERSION : ${CMAKE_VERSION}")add_definitions(-D TEST_PARAM)add_definitions(-D TEST_NUM=27)message("================test include=============")include(${PROJECT_SOURCE_DIR}/math/test.cmake OPTIONAL RESULT_VARIABLE ret)
if(ret)message("found , ret : ${ret}")
else()message("not found , ret : ${ret}")
endif()message("================test file=============")file(WRITE readme.txt [=[
##############CMAKE TESTAUTHOR :  cxb
]=])file(APPEND readme.txt [=[ TIME : 2025-06-26##############
]=])file(GLOB FILE_H ${PROJECT_SOURCE_DIR}/include/*.h)file(GLOB_RECURSE SRC_C ./ *.c)file(WRITE file.txt ${SRC_C})file(APPEND file.txt ${FILE_H})file(READ file.txt CONTEXT 1024 0)message("file.txt : ${CONTEXT}")file(REMOVE file.txt)message("================test cache=============")set(CACHE_VAR 0 CACHE BOOL "test_cache")
if(CACHE_VAR)message("CACHE_VAR : ${CACHE_VAR}")
else()message("CACHE_VAR : ${CACHE_VAR}")
endif()message("================test if=============")
if(NOT WIN32)message("system : LINUX")
endif()if(DEFINED CACHE_VAR)message("CACHE_VAR existed")
endif()if(EXISTS ./math/src/math.cpp)message("./math/src/math.cpp existed")
endif()message("================test math=============")math(EXPR test_all "1 + 1" OUTPUT_FORMAT  HEXADECIMAL)message("test_all : ${test_all}")message("================test lib=============")add_subdirectory(math)include_directories(include)set(EXEC_SRC ${PROJECT_NAME}.cpp)add_executable(${PROJECT_NAME} ${EXEC_SRC})set(CMAKE_PREFIX_PATH "${PROJECT_SOURCE_DIR}/math")find_package(math)message("math_FOUND = ${math_FOUND}")if(math_FOUND)message("find math success!")endif()target_link_libraries(${PROJECT_NAME} math)message("================test property=============")set_property(GLOBAL PROPERTY TEST_GLOBAL "test1")set_property(GLOBAL APPEND PROPERTY TEST_GLOBAL "test2")get_property(test_g GLOBAL PROPERTY TEST_GLOBAL)message("test_g : ${test_g}")set_property(DIRECTORY . PROPERTY SRC_DIR "${PROJECT_SOURCE_DIR}") get_property(cur_dir DIRECTORY . PROPERTY SRC_DIR)message("cur_dir : ${cur_dir}")set_property(SOURCE math.cpp PROPERTY SRC_NAME "math.cpp")get_property(src_name SOURCE math.cpp PROPERTY SRC_NAME)message("src_name : ${src_name}")set_property(TARGET ${PROJECT_NAME} PROPERTY OBJ_VAR "test_cmake")get_property(target_name TARGET ${PROJECT_NAME} PROPERTY OBJ_VAR)message("target_name : ${target_name}")message("================test install=============")install(TARGETS ${PROJECT_NAME} DESTINATION ${PROJECT_SOURCE_DIR}/bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_WRITE  GROUP_EXECUTE WORLD_READ  WORLD_WRITE  WORLD_EXECUTE)install(FILES readme.txt DESTINATION ${PROJECT_SOURCE_DIR}/doc PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_WRITE  GROUP_EXECUTE WORLD_READ  WORLD_WRITE  WORLD_EXECUTE)string(TIMESTAMP now "%Y-%m-%d %H:%M:%S") FILE(APPEND install.log "${now} build math project\n")

test_cmake.cpp

#include <iostream>#include "math.h"int main()
{#ifdef TEST_PARAMstd::cout << "TEST_PARAM : " << TEST_PARAM << std::endl;#endif#ifdef TEST_NUMstd::cout << "TEST_NUM : " << TEST_NUM << std::endl;#endifint all = add_num(1, 1);std::cout << "all : " << all << std::endl;std::cout << "test cmake" << std::endl;return 0;
}

math/CMakeLists.txt

cmake_minimum_required(VERSION 3.0)aux_source_directory(${CMAKE_CURRENT_LIST_DIR}/src MATH_SRCS)include_directories(include)option(BUILD_SHARED_LIBS "shared lib or static lib" OFF)add_library(math $<$<CONFIG:$<BOOL:${BUILD_SHARED_LIBS}>>:SHARED> ${MATH_SRCS})set_target_properties(math PROPERTIES PUBLIC_HEADER include/math.h)target_include_directories(math PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> #install时为空,只有编译时有值$<INSTALL_INTERFACE:include>                                               #只有install时有值
)install(TARGETS math EXPORT mathLIBRARY DESTINATION ${PROJECT_SOURCE_DIR}/libARCHIVE DESTINATION ${PROJECT_SOURCE_DIR}/libPUBLIC_HEADER DESTINATION ${PROJECT_SOURCE_DIR}/include
)install(EXPORT math FILE mathConfig.cmake DESTINATION ${PROJECT_SOURCE_DIR}/config)

math/mathConfig.cmake

set(HEADS_PATH ${PROJECT_SOURCE_DIR}/math/include)set(LIB_PATH ${PROJECT_SOURCE_DIR}/math)

math/test.cmake

message("in cmake/src")

include/math.h 

#ifndef __CAMTH_H__
#define __CAMTH_H__int add_num(int num1, int num2);#endif

src/math.cpp

#include "math.h"int add_num(int num1, int num2)
{return num1 + num2;
}

编译执行结果示例

 

 清理执行结果示例

相关文章:

  • WPF之TextBlock控件详解
  • docker拉取国内镜像
  • Spring中bean的生命周期(笔记)
  • UE调试相关
  • 入选ICLR 2025 Oral,清华AIR周浩团队提出蛋白质预训练新范式,解密蛋白质家族进化
  • 力扣面试150题--删除链表的倒数第 N 个结点
  • iOS签名的包支持推送功能吗?
  • 【东枫电子】AI-RAN:人工智能 - 无线接入网络
  • 国内外半导体行业在供应链数字化集成方式上的差异
  • 网络安全攻防演练实训室建设方案
  • GAEA商业前景和生态系统扩展
  • 蓝桥杯 11. 最大距离
  • 蓝桥杯 5. 拼数
  • 远程访问你的家庭NAS服务器:OpenMediaVault内网穿透配置教程
  • Kotlin和JavaScript的对比
  • INI配置文件格式详解与实战指南
  • 工程管理部绩效考核关键指标与项目评估
  • 力扣刷题总表
  • leetcode:3005. 最大频率元素计数(python3解法)
  • 百度「心响」:通用超级智能体,重新定义AI任务执行新范式
  • 上海科创的三种品格
  • 西湖大学本科招生新增三省两市,首次面向上海招生
  • 找化学的答案,解人类的命题:巴斯夫的“变革者”成长之道
  • 广州一季度GDP为7532.51亿元,同比增长3%
  • 王羲之《丧乱帖》在日本流传了1300年,将在大阪展23天
  • 三亚一景区发生游客溺亡事件,官方通报:排除他杀