CMake语法复习

前言

此文总结了库的制作和一些CMake常用的一些语法。

一:创建静态库和动态库

静态库的生成和使用

 动态库的生成和使用

二:使用CMake来生成Makefile,生成可执行文件

顶层目录下的CMakeLists.txt

project(HELLO)
add_subdirectory(libhello)
add_subdirectory(src)

libhello目录下的CMakeLists.txt

set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
add_library(libhello hello.c)
set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello")

src目录下的CMakeLists.txt

include_directories(${PROJECT_SOURCE_DIR}/libhello)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
add_executable(helloApp main.c)
target_link_libraries(helloApp libhello)

最后进入到build目录下进行cmake ../,make之后,helloApp会在build/bin目录下,libhello.a会在/build/lib目录下

三:list相关操作

工程文件目录

对list进行一些操作

cmake_minimum_required(VERSION 3.22)
project(HELLO)
add_subdirectory(src)
add_subdirectory(libhello)

set(helloList "hello world")
message(${helloList})

aux_source_directory(src list1)
message("list1 = ${list1}")

aux_source_directory(libhello list2)
message("list2 = ${list2}")

list(LENGTH helloList helloListLength)
message("helloListLength = ${helloListLength}")

list(APPEND list1 ${list2})
message("after append list1 = ${list1}")

list(GET list1 0 VAR1)
message("var1 in list1 after append = ${VAR1}")

打印结果

 四:头文件和库

private、interface、public三个参数的区别

⚫ 当使用 PRIVATE 关键字修饰时,意味着 包含目录列表仅用于当前目标;
⚫ 当使用 INTERFACE 关键字修饰时,意味着 包含目录列表不用于当前目标、只能用于依赖该目标的其它目标,也就是说 cmake 会将 包含目录列表传递给当前目标的依赖目标;
⚫ 当使用 PUBLIC 关键字修饰时,这就是以上两个的集合, 包含目录列表既用于当前目标、也会传递给当前目标的依赖目标。

target_link_libraries(hello_world INTERFACE hello):表示目标 hello_world 不需要链接 hello 库,但是对于 hello_world 目标的依赖目标(依赖于 hello_world 的目标)它们需要链接 hello 库。

五:部分变量

在src目录下的CMakeLists.txt中添加PROJECT_SOURCE_DIR、PROJECT_BINARY_DIR、CMAKE_CURRENT_SOURCE_DIR、CMAKE_CURRENT_BINARY_DIR。在build目录下进行cmake ../编译。

打印结果

可执行程序和库文件的输出路径EXECUTABLE_OUTPUT_PATH、LIBRARY_OUTPUT_PATH

六:循环语句(foreach)

foreach语句

cmake_minimum_required(VERSION 3.22)
project(HELLO)
add_subdirectory(src)
add_subdirectory(libhello)

set(myList happy qixi festival lm)
foreach(temp ${myList})
    message("${temp}")
endforeach()

foreach(temp "${myList}")
    message("${temp}")
endforeach()

 打印结果

七:数学运算math

cmake_minimum_required(VERSION 3.22)
project(HELLO)
add_subdirectory(src)
add_subdirectory(libhello)

math(EXPR RET1 "100 + 200")
math(EXPR RET2 "100 * 200")
math(EXPR RET3 "1 & 0")
message("${RET1}, ${RET2}, ${RET3}")

打印结果

八:函数(function)

通过 function()定义的函数它的使用范围是全局的,并不局限于当前源码、可以在其子源码或者父源码中被使用

function(myprintf arg1 arg2)
    message("${arg1} ${arg2}")
endfunction()

myprintf(hello world)

打印结果

函数内的局部变量

ARGVXX 是一个数字,譬如 ARGV0、ARGV1,ARGV0 为第一个参数、ARGV1 位第二个参数
ARGV 实际调用时传入的参数会存放在 ARGV 变量中(如果是多个参数,那它就是一个参数列表)
ARGN 假如定义函数时参数为 2 个,实际调用时传入了 4 个,则 ARGN 存放了剩下的 2 个参数(如果是多个参数,那它也是一个参数列表)
ARGC调用函数时,实际传入的参数个数
cmake_minimum_required(VERSION 3.22)
project(HELLO)
add_subdirectory(src)
add_subdirectory(libhello)
 
function(myprintf arg1 arg2)
    message("ARGC = ${ARGC}")
    message("ARGV = ${ARGV}")
    message("ARGN = ${ARGN}")
    message("ARGV0 = ${ARGV0}")
 
    set(i 0)
    foreach(var ${ARGV})
        message("var${i} = ${var}")
        math(EXPR i "${i} + 1")
    endforeach()
    
endfunction()
 
myprintf(hello world impressive)

打印结果

九:文件操作(file)

WRITE文件不存在就新建一个文件,如果文件存在就覆盖写
APPEND在文件末追加
READ读取文件,可以以二进制的形式读(HEX)
GENERATE通过文件(INPUT)或内容(CONTENT)来生成新文件
STRINGS以字符串形式读取
RENAME重命名
REMOVE删除文件
cmake_minimum_required(VERSION 3.22)
project(HELLO)
add_subdirectory(src)
add_subdirectory(libhello)

file(WRITE test.txt "impressiv and attractive\n")
file(APPEND test.txt "ONU and OLT")

file(GENERATE OUTPUT out1.txt INPUT "${PROJECT_SOURCE_DIR}/test.txt")
file(GENERATE OUTPUT out2.txt CONTENT "hello world")

file(READ "${PROJECT_SOURCE_DIR}/test.txt" read_buf)
message("!!!read from test.txt: !!!\n" ${read_buf})
file(READ "${PROJECT_SOURCE_DIR}/test.txt" outvar1 OFFSET 0 LIMIT 6)
message("outvar1 OFFSET 0 LIMIT 6 is \n" ${outvar1})
file(READ "${PROJECT_SOURCE_DIR}/test.txt" outvar2 OFFSET 0 LIMIT 6 HEX)
message("outvar2 OFFSET 0 LIMIT 6 HEX is \n" ${outvar2})

file(STRINGS "${PROJECT_SOURCE_DIR}/test.txt" outvar3 LENGTH_MAXIMUM 6)
message("outvar3 LENGTH_MAXIMUM 6 is \n" "${outvar3}")
file(STRINGS "${PROJECT_SOURCE_DIR}/test.txt" outvar4 LENGTH_MINIMUM 4)
message("outvar4 LENGTH_MINIMUM 2 is \n" "${outvar4}")
file(STRINGS "${PROJECT_SOURCE_DIR}/test.txt" outvar5 LIMIT_COUNT 1)
message("outvar5 LIMIT_COUNT 1 is \n" "${outvar5}")

file(WRITE "${PROJECT_SOURCE_DIR}/temp.txt" "")
file(RENAME "${PROJECT_SOURCE_DIR}/temp.txt" "${PROJECT_SOURCE_DIR}/change.txt")
file(REMOVE "${PROJECT_SOURCE_DIR}/change.txt")

message打印内容

十:设置交叉编译链

总结

以上就是本文的全部内容了,希望可以帮到你。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

门牙会稍息

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值