CmakeList入门

Tips:需要对编译原理有一定了解,内容选自 github

===================================================

A-基础

1-CMakeLists.txt

  • 存储所有CMake命令的文件

2-Minimum CMake version

  • 指定支持的最低CMake版本
 cmake_minimum_required(VERSION 3.5)

3-Projects

  • 项目名称
project(hello_cmake)

4-Creating an Executable

  • 构建可执行文件,第一个参数是要生成的可执行文件的名称,第二个参数是要编译的源文件的列表。
add_executable(hello_cmake main.cpp)

===================================================

B-头文件

1-Directory Paths

  • CMake语法指定了许多变量 ,可用于帮助您在项目或源代码树中找到有用的目录
Variable Info(直译比较难以理解)
CMAKE_SOURCE_DIR The root source directory
CMAKE_CURRENT_SOURCE_DIR The current source directory if using sub-projects and directories.
PROJECT_SOURCE_DIR The source directory of the current cmake project.
CMAKE_BINARY_DIR The root binary / build directory. This is the directory where you ran the cmake command.
CMAKE_CURRENT_BINARY_DIR The build directory you are currently in.
PROJECT_BINARY_DIR The build directory for the current project.

2-Source Files Variable

  • 设置一些关于源文件的环境变量提高可读性
# Create a sources variable with a link to all cpp files to compile
set(SOURCES
    src/Hello.cpp
    src/main.cpp
)
add_executable(${PROJECT_NAME} ${SOURCES})
  • 另一种方法是使用GLOB命令使用通配符模式匹配来查找文件。
file(GLOB SOURCES "src/*.cpp")
  • 对于现代CMake,不建议对源使用变量。相反,通常直接在add_xxx函数中声明源

3-Including Directories

  • 使用target_include_directories()来包含头文件。编译此目标时,会通过-I标志将这些目录添加到编译器,例如-I /directory/path
target_include_directories(target
    PRIVATE   # PRIVATE/INTERFACE/PUBILC 指定包含的范围
        ${PROJECT_SOURCE_DIR}/include
)

===================================================

C-静态库

1-Adding a Static Library

  • add_library()函数用于从某些源文件创建一个库
add_library(hello_library STATIC
    src/Hello.cpp
)
  • 如前面的示例所述,我们将源文件直接传递给add_library调用,这是现代CMake的建议

2-Populating Including Directories

target_include_directories(hello_library
    PUBLIC
        ${PROJECT_SOURCE_DIR}/include
)

-cmake中的变量作用域

scopes meaning
PRIVATE the directory is added to this target’s include directories
INTERFACE the directory is added to the include directories for any targets that link this library.
PUBLIC As above, it is included in this library and also any targets that link this library.

3-Linking a Library

  • 创建可执行文件时,必须告知编译器使用了什么库。可以使用target_link_libraries()函数完成此操作。
add_executable(hello_binary
    src/main.cpp
)

target_link_libraries( hello_binary
    PRIVATE
        hello_library
)
#编译器实例 /usr/bin/c++ CMakeFiles/hello_binary.dir/src/main.cpp.o -o hello_binary -rdynamic libhello_library.a

===================================================

D-动态库

1-Adding a Shared Library-添加动态库

add_library(hello_library SHARED
    src/Hello.cpp
)

2-Alias Target-目标别名

  • 目标别名在只读上下文中可以代替真实目标名称(只读代表无法更改)
add_library(hello::library ALIAS hello_library)

3-Linking a Shared Library-链接动态库文件

add_executable(hello_binary
    src/main.cpp
)

target_link_libraries(hello_binary
    PRIVATE
        hello::library
)

===================================================

E-安装

1-Installing

  • 安装说白了是将编译好的文件复制到安装目录。
  • Cmake通过make install允许用户安装二进制文件,库和其他文件。安装位置由变量CMAKE_INSTALL_PREFIX控制。
  • make install跑完后,CMake的生成install_manifest.txt文件,其中包括所有已安装的文件的详细信息。
#二进制文件
install (TARGETS cmake_examples_inst_bin
    DESTINATION bin)
#库文件
install (TARGETS cmake_examples_inst
    LIBRARY DESTINATION lib)
#头文件
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/
    DESTINATION include)
#配置文件
install (FILES cmake-examples.conf
    DESTINATION etc)

===================================================

F-build-type

1-介绍

  • CMake具有许多内置的构建配置,可用于编译您的项目。这些指定了优化级别以及调试信息是否包含在二进制文件中
level meaning
Release Adds the -O3 -DNDEBUG(屏蔽assert) flags to the compiler
Debug Adds the -g flag
MinSizeRel Adds -Os -DNDEBUG
RelWithDebInfo Adds -O2 -g -DNDEBUG flags

2-设置构建类型

command line: cmake .. -DCMAKE_BUILD_TYPE=Release

3-设置默认构建类型 in CMakeLists.txt

if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  message("Setting build type to 'RelWithDebInfo' as none was specified.")
  set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
  # Set the possible values of build type for cmake-gui
  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
    "MinSizeRel" "RelWithDebInfo")
endif()

===================================================

G-编译标志

1-介绍

  • CMake支持以多种不同方式设置编译标志:
  • using target_compile_definitions() function
  • using the CMAKE_C_FLAGS and CMAKE_CXX_FLAGS variables.

2-Set Per-Target C++ Flags-设置每个目标C ++标志

  • 在现代CMake中设置C ++标志的推荐方法是使用按目标标志,可以通过target_compile_definitions()将其填充到其他目标。
target_compile_definitions(cmake_examples_compile_flags
    PRIVATE EX3
)
# This will cause the compiler to add the definition -DEX3 when compiling the target.

3-Set Default C++ Flags-设置默认C ++标志

set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEX2" CACHE STRING "Set C++ Compiler Flags" FORCE)
  • CACHE STRING "Set C++ Compiler Flags" FORCE上面命令的值用于强制在CMakeCache.txt文件中设置此变量。
  • 设置后,CMAKE_C_FLAGS和CMAKE_CXX_FLAGS将为该目录或所有包含的子目录中的所有目标全局设置编译器标志/定义。现在不建议将该方法用于一般用途,并且首选使用target_compile_definitions函数。

4-设置CMake标志

command line:  cmake .. -DCMAKE_CXX_FLAGS = “ -DEX3”

===================================================

H-第三方库

1-介绍

  • 几乎所有不平凡的项目都将要求包含第三方库,头文件或程序。CMake支持使用该find_package()功能查找这些工具的路径。这将从中CMAKE_MODULE_PATH列表中搜索格式为“ FindXXX.cmake”的CMake模块。在Linux上,默认搜索路径将包括/usr/share/cmake/Modules。

2-Finding a Package-寻找第三方库

find_package(Boost 1.46.1 REQUIRED COMPONENTS filesystem system)
param meaning
Boost 库名称,用于查找模块文件FindBoost.cmake
1.46.1 查找的Boost的最低版本
REQUIRED 告诉模块这是必需的,如果失败,它将无法找到
COMPONENTS 要查找的库列表

3-Checking if the package is found-检查第三方库

  • 大多数随附的软件包将设置一个变量XXX_FOUND,该变量可用于检查该软件包在系统上是否可用。
if(Boost_FOUND)
    message ("boost found")
    include_directories(${Boost_INCLUDE_DIRS})
else()
    message (FATAL_ERROR "Cannot find Boost")
endif()

4-Exported Variables-第三方库导出变量

  • 找到软件包后,它通常会导出变量,这些变量可以通知用户在哪里可以找到库,标头或可执行文件。与XXX_FOUND 变量类似,它们是特定于软件包的,通常记录在FindXXX.cmake文件顶部 。例如
Boost_INCLUDE_DIRS - boost 头文件目录.

5-Alias / Imported targets

  • 大多数现代CMake库在其模块文件中导出ALIAS目标。导出目标的好处是它们也可以填充包含目录和链接的库。

  • 例如,从CMake v3.5 +开始,Boost模块支持此功能。与使用自己的ALIAS目标进行库释放相似,模块中的ALIAS可以使引用找到的目标更加容易。

  • 在Boost的情况下,所有目标均使用Boost::标识符然后使用子系统的名称导出

===================================================

I-compiling-with-clang

1-Compiler Option-编译器选项

  • CMake提供了一些选项来控制用于编译和链接代码的程序
  • CMAKE_C_COMPILER-用于编译c代码的程序。
  • CMAKE_CXX_COMPILER-用于编译c ++代码的程序。
  • CMAKE_LINKER-用于链接二进制文件的程序。

2-Setting Flags-设置标志

cmake .. -DCMAKE_C_COMPILER = clang-3.6 -DCMAKE_CXX_COMPILER = clang ++-3.6

===================================================

L-cpp-standard-C++标准

a.common-method

1-Checking Compile flags-检查编译标志

  • CMake支持尝试使用传递给函数的任何标志来编译程序CMAKE_CXX_COMPILER_FLAG。然后将结果存储在您传递的变量中
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
# 本示例将尝试使用标志编译程序-std=c++11并将结果存储在变量中COMPILER_SUPPORTS_CXX11。
# 该行include(CheckCXXCompilerFlag)告诉CMake包括此功能以使其可用

2-Adding the flag-添加标志

  • 一旦确定编译是否支持标志,就可以使用将此标志添加到目标中。在此示例中,我们使用CMAKE_CXX_FLAGS来将标志传播给所有目标
if(COMPILER_SUPPORTS_CXX11)#
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)#
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
    message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()

b-cxx-standard

1-Using CXX_STANDARD property

  • 设置[CMAKE_CXX_STANDARD]变量将导致CXX_STANDARD所有目标上的属性。这使CMake在编译时间设置适当的标志。

c-compile-features

1-Using target_compile_features-使用target_compile_features

  • 在目标上调用target_compile_features函数将查看传入的功能,并确定要用于目标的正确编译器标志。
target_compile_features(hello_cpp11 PUBLIC cxx_auto_type)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,923评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,154评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,775评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,960评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,976评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,972评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,893评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,709评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,159评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,400评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,552评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,265评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,876评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,528评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,701评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,552评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,451评论 2 352