CMake教程(二)——基本操作
通常情况下,使用CMake的目的是为了构建比较大一些的项目,有很多文件需要处理,还要引用一些第三方库,接下来我来讲解在CMakeLists.txt下的基本操作。
本文是我自己整理的,没有按照官方教程进行翻译。
如果想要学习官方教程,请点击这里
开始
一般使用
示例目录结构如图
helloworld
├── CMakeLists.txt
├── README.md
├── main.c
└── main.h
最基础最简单的CMakeLists.txt写法,应该像这样:
# 最低要求版本
cmake_minimum_required(VERSION 3.10)
# 设置项目名
project(HelloWorld)
# 添加可执行目标
add_executable(hello main.c main.h)
注意,CMake不区分大小写,但这里采用最流行现代的写法,小写为主,部分采用大写。
然后按照标准方式编译构建
mkdir build
cd build
cmake ..
cmake --build .
编译完成后,目录结构大概就成了这样
helloworld
├── CMakeLists.txt
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ ├── Makefile
│ ├── cmake_install.cmake
│ └── hello
├── main.c
└── main.h
这样,你就会在build目录下看到编译好的可执行文件
更好的例子
如果你不喜欢这样的工程模式,可以采用更科学的目录结构,例如:
helloworld
├── CMakeLists.txt
├── inc
│ └── hello.h
└── src
├── hello.c
└── main.c
参考文件内容
- main.c
#include "../inc/hello.h"
int main(void)
{
hello();
return 0;
}
- hello.c
#include "../inc/hello.h"
void hello()
{
printf("hello, world!\n");
}
- hello.h
#include <stdio.h>
void hello();
只需要把CMakeLists.txt改为
# 最低要求版本
cmake_minimum_required(VERSION 3.10)
# 设置项目名
project(HelloWorld)
# 将目录下所有文件添加到变量
file(GLOB all_SRCS
# C项目
"${PROJECT_SOURCE_DIR}/inc/*.h"
"${PROJECT_SOURCE_DIR}/src/*.c"
# C++项目
# "${PROJECT_SOURCE_DIR}/inc/*.hpp"
# "${PROJECT_SOURCE_DIR}/src/*.cpp"
)
# 添加可执行目标
add_executable(hello ${all_SRCS})
选择构建工具,配合IDE或编辑器
大多数时候,你可能需要和你的IDE一起工作,此时你只需要指定构建工具,在生成构建时添加-G <Generators>
查看当前系统所支持的IDE,你只需要
cmake --help
在输出最后类似是这样
Generators
The following generators are available on this platform (* marks default):
* Unix Makefiles = Generates standard UNIX makefiles.
Green Hills MULTI = Generates Green Hills MULTI files
(experimental, work-in-progress).
Ninja = Generates build.ninja files.
Watcom WMake = Generates Watcom WMake makefiles.
CodeBlocks - Ninja = Generates CodeBlocks project files.
CodeBlocks - Unix Makefiles = Generates CodeBlocks project files.
CodeLite - Ninja = Generates CodeLite project files.
CodeLite - Unix Makefiles = Generates CodeLite project files.
Sublime Text 2 - Ninja = Generates Sublime Text 2 project files.
Sublime Text 2 - Unix Makefiles
= Generates Sublime Text 2 project files.
Kate - Ninja = Generates Kate project files.
Kate - Unix Makefiles = Generates Kate project files.
Eclipse CDT4 - Ninja = Generates Eclipse CDT 4.0 project files.
Eclipse CDT4 - Unix Makefiles= Generates Eclipse CDT 4.0 project files.
如果选择使用Ninja,你只需要在生成构建时添加选项,如:
cmake .. -G Ninja
引用第三方库
关于第三方库的使用,网上有很多过时的文章,这里根据最新的文档整理过来的。
引用第三方库主要有三种方法:
- 使用Pkg查找第三方库(推荐)
- 使用CMake自带的查找模块
- 手动指定库目录(不推荐)
使用Pkg查找第三方库(推荐)
很多时候,自带的查找模块并不好用,经常找不到第三方库。因此,PkgConfig是个不错的选择。
通常情况下,pkgconfig的查找模块在/usr/lib/x86_64-linux-gnu/pkgconfig/
下,你可以查看是否有你需要的库,这里以GTK为例
ls /usr/lib/x86_64-linux-gnu/pkgconfig/ | grep -i gtk
输出
gtk+-2.0.pc
gtk+-3.0.pc
gtk+-broadway-3.0.pc
gtkmm-3.0.pc
gtk+-unix-print-2.0.pc
gtk+-unix-print-3.0.pc
gtk+-wayland-3.0.pc
gtk+-x11-2.0.pc
gtk+-x11-3.0.pc
我们需要gtk3的库,因此,
你只需要在CMakeLists.txt需要库的语句前,添加
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
CMake会将查找到的库相关内容存储在相应的变量之中,我们只需要
include_directories(${GTK3_INCLUDE_DIRS}) # 添加头文件目录
link_directories(${GTK3_LIBRARY_DIRS}) # 添加链接目录
set(CMAKE_ENABLE_EXPORTS TRUE) # 允许CMake为你添加编译器选项
add_compile_options(${GTK3_CFLAGS_OTHER}) # 添加编译器选项
add_executable(<可执行程序名> <头文件和源文件>)
target_link_libraries(<可执行程序名> ${GTK3_LIBRARIES}) # 链接到第三方库
这里到的GTK3是可以任意替换的,包括变量名,pkg_check_modules
生成对应的变量名。
使用CMake自带的查找模块
如果你用的是arch或openSUSE的风滚草,软件源中就有额外的查找模块,安装和使用都十分方便。
如果你使用的是openSUSE,可以用以下命令安装额外的查找模块
sudo zypper install extra-cmake-modules
如果你是Ubuntu用户,应该优先考虑pkg查找。
你可以在/usr/share/cmake-<版本号>/Modules/
中找到你需要的库的查找模块。
例如,我的cmake版本是3.22,可以这样查看Qt库。
ls /usr/share/cmake-3.22/Modules/ | grep -i Qt
输出
DeployQt4.cmake
FindosgQt.cmake
FindQt3.cmake
FindQt4.cmake
FindQt.cmake
Qt4ConfigDependentSettings.cmake
Qt4Macros.cmake
UseQt4.cmake
下面是我qtCaller的示例:
cmake_minimum_required(VERSION 3.10)
project(qt-caller)
find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets REQUIRED) # 调用查找模块,查找Qt5或Qt6库
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets REQUIRED) # 这句应该是确定当前系统Qt库的版本
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # 允许CMake为你添加编译器选项
add_executable(qtCaller
main.cpp
widget.cpp
widget.h)
target_link_libraries(qtCaller
PRIVATE Qt${QT_VERSION_MAJOR}::Widgets) # 链接到第三方库
手动指定库目录(不推荐)
我是看了一些CSDN的文章,才了解到这个方法的。
如果你的系统是Windows,用CMake就是好奇想了解一下,这个方法比较适合你。
include_directories(<头文件路径>)
link_directories(<链接文件路径>)
add_executable(<可执行程序名> <头文件和源文件>)
target_link_libraries(<可执行程序名> <链接选项>)
没什么系统性,无法跨平台,直接去CSDN里找示例就可以了,但是会比较直观,容易理解。
还有其他需求的,推荐查看官方文档。
如果还需要另外的功能,请查看下一篇CMake教程(三)——配置完善
点击这里返回目录
参考链接:
- https://blog.csdn.net/weixin_43669941/article/details/112913301
- https://cmake.org/cmake/help/latest/
- https://stackoverflow.com/questions/8304190/cmake-with-include-and-source-paths-basic-setup
- https://blog.51cto.com/u_15127539/3336648
- https://cmake.org/cmake/help/latest/guide/using-dependencies/index.html#guide:Using Dependencies Guide