hello-CMake

Hello, CMake#

CMake是一个用于构建C++项目的编译链工具。通过编写CMakeLists.txt文件,完成项目的构建。

一个基本的CMakeLists.txt需要有版本要求,项目名称,和项目目标(可执行文件或库文件)组成。

cmake_minimum_required(VERSION 3.20)

project(hello-CMake LANGUAGES CXX)

add_executable(hello main.cpp)

CMake语言不区分大小写,但是参数区分大小写。

CMake基本构建命令#

在源文件的根目录下,执行cmake -S. -Bbuild,会生成一个和源文件根目录同级的build目录,并在其中生成项目所需的CMake配置文件,这一步等于先mkdir -p build,然后进入build目录下执行cmake ..-B可以指定build目录的路径。
在构建好了项目树后,进入build目录下,执行cmake --build .生成项目的可执行文件或者生成库,这个.表示了当前的build目录,当然也可以不进入build目录,在外面用相对路径或绝对路径代替这个.
另外,在生成过程中可以使用cmake -D CMAKE_CXX_COMPILER=clang++ ..指定编译器。
使用-D CMAKE_BUILD_TYPE=Debug来切换构建类型,其中类型有Debug,Release,RelWithDebInfo,MinSizeRel四种。

生成库#

CMake生成库的命令是add_library,将项目中生成的库链接到目标上的命令是target_link_libraries

cmake_minimum_required(VERSION 3.20)

project(hello-CMake LANGUAGES CXX)

add_executable(hello main.cpp)

add_library(mylib STATIC some.hpp some.cpp)

target_link_libraries(hello mylib)

在执行完add_library后,会在linux平台生成一个.a文件或者在windows平台生成一个.lib文件,这就是静态库文件。第二个参数可以是STATIC,SHARED,OBJECT,MODULE的其中一个,分别代表着静态库、动态库、对象库和模组。动态库和静态库很好理解,对象库会使要编译的文件先存起来,既不生成静态库,也不允许链接,然后在需要的时候一次性创建成静态库和动态库。MODULE生成的目标对象是动态库类型,不会被链接到项目中的目标,但又可以进行动态加载,一般用于构建运行时插件。

add_library(objs OBJECT some.hpp some.cpp)

add_library(mylib-static STATIC $<TARGET_OBJECTS:objs>)

set_target_properties(mylib-static PROPERTIES OUTPUT_NAME "mylib")

add_library(mylib-shared SHARED $<TARGET_OBJECTS:objs>)

set_target_properties(mylib-shared PROPERTIES OUTPUT_NAME "mylib")

CMake文件中的目标名是不可以重复的,但可以指定目标的属性,来修改其最后输出的名称。

变量和条件控制#

CMake中使用set(name value)来定义一个全局变量name,其实际内容是value。
通过list(APPEND file.cpp)可以向变量中追加内容
CMake中使用if() ... else() ... endif()的方式书写条件控制语句,其中if()的括号中可以指定变量。
option命令可以指定一个开关,并且允许在构建的时候由外部来修改。
变量通过${}来读取内容。

set(use_lib OFF)

if(use_lib)
    add_library(mylib STATIC some.hpp some.cpp)
else()
    add_library(mylib SHARED some.hpp some.cpp)
endif()

list(APPEND src else.hpp else.cpp)

option(use_lib_flag "switch" OFF)
if(use_lib_flag)
    add_library(mylib STATIC some.hpp some.cpp)
endif()

编译器选项#

使用target_compile_options()设置目标的编译选项,或者在命令行中使用-D CMAKE_CXX_FLAGS="..."手动指定。

控制流#

使用foreach(val lists)的形式来执行循环控制。

target_compile_options(geometry PRIVATE -O3)

list(
APPEND sources_with_lower_optimization
geometry_circle.cpp
geometry_rhombus.cpp
)

foreach(_source IN LISTS sources_with_lower_optimization)
    set_source_files_properties(${_source} PROPERTIES COMPILE_FLAGS -O2)
endforeach()

foreach(_source ${sources_with_lower_optimization})
    get_source_file_property(_flags ${_source} COMPILE_FLAGS)
endforeach()

foreach()有四种使用方式:

  • foreach(loop_var arg1 arg2 ...) : 其中提供循环变量和显式项列表。当为sources_with_lower_optimization 中的项打印编译器标志集时,使用此表单。注意,如果项目列表位于变量中,则必须显式展开它;也就是说, ${sources_with_lower_optimization} 必须作为参数传递。
  • 通过指定一个范围,可以对整数进行循环,例如: foreach(loop_var rangetotal) 或 foreach(loop_var range start stop [step]) 。
  • 对列表值变量的循环,例如: foreach(loop_var IN LISTS [list1[...]]) 。参数解释为列表,其内容就会自动展开。
  • 对变量的循环,例如: foreach(loop_var IN ITEMS [item1 [...]]) 。参数的内容没有展开。

作者:cwtxx

出处:https://www.cnblogs.com/cwtxx/p/18718170

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   cwtxx  阅读(1)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示