CMake 入门

135 阅读2分钟

日新计划6月更文 Day 19

CMake is a tool to manage building of source code. Originally, CMake was designed as a generator for various dialects of Makefile, today CMake generates modern buildsystems such as Ninja as well as project files for IDEs such as Visual Studio and Xcode.

CMake is widely used for the C and C++ languages, but it may be used to build source code of other languages too.

  简单来说,CMake是一个开源的跨平台构建脚本生成工具,它可以通过CMakeList.txt生成Makefile或其他编译脚本,再通过相应的自动化编译工具编译源代码、链接库文件、生成程序并提供安装脚本。

cmake命令

具体可参阅CMake(1)manual

CMakeLists

  cmake 通过读取 CMakeLists.txt 文件来确定如何处理代码

CMakeLists 指令

cmake_minimum_required(VERSION 3.21)            # 所需最低cmake版本
project($projName)                              # 项目名称
#[[
    默认支持所有语言,否则可在括号内添加所支持的语言,如CXX、JAVA
    project()隐式声明了<projectname>_BINARY_DIR和<projectname>_SOURCE_DIR
    以及PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR
]]

set(CMAKE_CXX_STANDARD 14)                      # 用于设置变量
#[[
    常用的变量:
    
]]

message($type $str)                             # 向控制台发送的信息
#[[
    信息的等级有三种:
        SEND_ERROR:错误信息,会跳过生成过程
        SATUS:一般提示信息
        FATAL_ERROR:严重错误信息,会立刻终止cmake运行
]]

include_directories($headerPath)                # 头文件搜索路径

link_directories($libPath)                      # 非标准共享库搜索路径

target_linked_libraries($execName $libName)     # 添加标准共享库

add_executable($execName $(SRC_LIST))           # 生成可执行文件,SRC_LIST可不加扩展名

find_package($pkgName REQUIRED)                 # 所需要的库,REQUIRED表示此库是必需的

CMakeLists语法

  • 语法类似Shell(你这Win和Linux反复横跳呢),如$()和${}
  • 参数之间可用逗号或空格,因此含有空格的参数需要使用引号包围
  • 指令大小写不敏感

CMake项目

  为了让我们的代码看起来更像一个项目,我们可以整理一下:

.
├── build
├── CMakeLists.txt
├── doc
│   └── index.md
├── lib
│   └── CMakeLists.txt
├── README.md
└── src
    ├── CMakeLists.txt
    └── main.cpp

  ./CMakeLists.txt

project(myProj)
add_subdirectory(src bin)                       # 指定子cmake工程和编译目标目录

INSTALL($type $files DESTINATION $dir)          # 配置程序安装
#[[
    $type 包括以下几类:
        FILE:与程序运行无关的文档等,
        PROGRAMS:非目标程序的可执行文件(如脚本)
        DIRECTORY:目录
        TARGETS:编译目标产物,安装动态库时使用 LIBRARY DESTINATION,静态库使用ARCHIVE DESTINATION。
    $dir 使用相对路径时在 $CMAKE_INSTALL_PREFIX 下(默认为 /usr/local )寻找
]]

库文件

  静态库在编译链接时会整合进程序,文件名一般以a或lib结尾;动态库独立于程序存在,文件名一般以so或dll结尾。

add_library($libName $type $src)                # 编译库
#[[
    生成的库是文件名会添加 lib 前缀和扩展名
    $type 分为 SHARED(动态库)和 STATIC(静态库)
    不可同时构建 $libName 相同的静态库和动态库,以第一个出现的为准
]]

set_target_properties($libName PROPERTIES {$key $value})  # 设置目标文件属性
#[[
    常见的$key:
        OUTPUT_NAME:输出文件名
        CLEAN_DIRECT_OUTPUT:为1时清理已存在的文件
        VERSION:动态库版本
        SOVERSION:API版本
]]