ubuntu安装cmake – 从入门到精通:了解、获取、安装、配置与使用CMake的完整教程
在Ubuntu系统上进行软件开发,尤其是涉及C++等编译型语言的项目时,一套强大的构建系统管理工具是必不可少的。CMake正是这样一款跨平台的开源工具,它能够帮助开发者管理复杂的编译流程,生成各种原生构建工具(如Makefile、Ninja、Visual Studio项目文件等)的配置文件。本篇文章将详细探讨在Ubuntu系统上安装、配置及使用CMake的方方面面。
一、CMake是什么?为什么需要在Ubuntu上安装它?
什么是CMake?它与构建系统有何关系?
CMake是一个“跨平台自动化构建系统”生成工具。它本身不直接编译代码,而是读取名为CMakeLists.txt的配置文件,然后根据该文件生成特定平台或IDE所需的构建脚本(例如,在Linux上生成Makefile文件,在Windows上生成Visual Studio项目文件)。开发人员随后可以使用这些生成的脚本通过原生的构建工具(如make)来编译项目。
简而言之:
- CMake:负责生成构建脚本(如Makefile)。它定义了项目的结构、依赖和构建规则。
- Make/Ninja等:负责根据CMake生成的脚本实际执行编译、链接等操作。它们是真正的构建执行者。
为什么要在Ubuntu上安装CMake?它的核心价值是什么?
在Ubuntu上安装CMake的主要原因和核心价值在于:
- 跨平台兼容性:您的项目只需要一份
CMakeLists.txt文件,就可以在Linux (Ubuntu)、Windows、macOS等不同操作系统上使用CMake生成各自平台的构建文件,极大地简化了项目迁移和协作。 - 简化复杂项目构建:对于包含多个源文件、库依赖、模块化组件的大型项目,手动编写Makefile会非常复杂且易出错。CMake提供了一套简洁且功能强大的语法来管理这些复杂性。
- 依赖管理:CMake可以方便地查找和链接系统上安装的库,或指定项目内部的依赖关系,大大简化了库的集成过程。
- 现代化构建实践:许多现代的C++项目和开源库都选择使用CMake作为其主要的构建系统,如Qt、OpenCV、Boost、LLVM等。为了编译和使用这些项目,CMake是必需的工具。
- 自动化流程:除了编译,CMake还可以用于生成安装包、运行测试、生成文档等,实现更全面的自动化。
CMake在Ubuntu系统中的常见应用场景有哪些?
- 编译从GitHub等代码托管平台下载的C/C++开源项目。
- 开发自己的C/C++应用程序,并希望在不同操作系统上都能轻松编译。
- 集成第三方库到您的项目中,CMake可以帮助您管理这些库的查找和链接。
- 进行软件测试、打包或部署,CMake提供相应的指令支持。
二、Ubuntu上获取CMake的多种途径与版本选择
从哪里可以获取CMake安装包或源代码?
在Ubuntu上,获取CMake有以下几种主要途径:
- Ubuntu官方软件源(APT):这是最推荐和最简单的途径。Ubuntu的仓库中通常包含了稳定版本的CMake。
- Kitware官方PPA(Personal Package Archive):如果需要最新版本的CMake,而官方软件源中的版本不够新,Kitware维护的PPA是一个很好的选择。
- CMake官方网站:您可以从 cmake.org/download/ 下载预编译的二进制文件(通常是AppImage格式)或源代码包进行手动编译。
- Snap Store:Ubuntu也支持Snap包管理器,可以通过Snap安装CMake。
Ubuntu官方软件源中的CMake版本通常是多少?
Ubuntu官方软件源中的CMake版本通常是一个稳定且经过测试的版本,但它可能不是最新的。例如,Ubuntu 20.04 LTS可能包含CMake 3.16或3.17,而Ubuntu 22.04 LTS可能包含CMake 3.22或3.23。这些版本通常足以满足大多数日常开发需求,但如果您正在处理需要特定最新CMake功能或修复的项目,官方软件源的版本可能不足以满足需求。
通过官方源安装的CMake通常占用几十MB的磁盘空间,安装过程通常只需要几秒到一分钟。
为什么有些项目需要特定版本的CMake?
一些大型或前沿的项目可能会利用CMake的最新功能、语法改进或bug修复。CMake每隔几个月就会发布新版本,带来大量新特性。如果您的CMake版本过旧,可能会导致以下问题:
- 编译错误,提示某些CMake命令或变量未定义。
- 新特性无法使用,例如对C++20模块的支持、新的语言标准检测或更先进的依赖查找功能。
- 项目构建脚本(
CMakeLists.txt)中的某些指令可能无法被旧版本解析,导致配置失败。 - 在某些情况下,旧版本可能存在影响特定项目构建的bug。
因此,了解并能够安装特定或最新版本的CMake是十分重要的。
三、如何在Ubuntu上安装CMake?(详细步骤与多种方法)
本节将详细介绍在Ubuntu系统上安装CMake的多种方法,包括推荐的标准方法、获取最新版本的PPA方法以及从源代码编译安装的高级方法。
方法一:使用APT包管理器(推荐的标准安装方式)
这是在Ubuntu上安装CMake最简单、最常见且最推荐的方法,它能安装一个稳定且与您的Ubuntu系统版本兼容的CMake版本。这种方法安装的CMake版本通常足够用于大多数项目。
安装步骤:
-
更新APT包索引:
在安装任何新软件包之前,始终建议更新您的本地软件包列表,以确保您能获取到最新可用的软件包信息。
sudo apt update -
安装CMake:
执行以下命令来安装CMake及其相关的依赖。
sudo apt install cmake系统可能会提示您确认安装,输入
Y并按回车即可。 -
验证安装:
安装完成后,您可以通过查询CMake的版本号来确认它是否已成功安装。
cmake --version如果成功,您将看到类似
cmake version 3.16.3或更高版本的输出,表明安装成功。
优点:
- 简单快捷:只需几个命令即可完成安装过程。
- 稳定兼容:安装的版本经过Ubuntu团队的测试,与系统其他组件的兼容性良好,不易出现问题。
- 自动依赖处理:APT会自动处理所有必要的依赖,无需手动操作。
- 易于维护:可以通过
sudo apt upgrade命令方便地更新到Ubuntu仓库中的最新稳定版本。
缺点:
- 版本可能不是最新的:官方软件源中的CMake版本通常不是最新发布的版本,对于需要最新功能的项目可能不适用。
方法二:使用Kitware官方PPA安装最新版本的CMake
如果您需要比Ubuntu官方仓库提供的更新的CMake版本,使用Kitware官方提供的PPA是一个很好的选择。这种方法比从源代码编译更简单,并且能提供最新的稳定版本。
安装步骤:
-
添加Kitware官方PPA:
首先,您需要添加Kitware的PPA到您的系统。这个PPA提供了最新的CMake二进制包。
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc | sudo apt-key add -sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main'第一行命令导入Kitware的GPG密钥,第二行命令添加PPA仓库到APT源列表。
$(lsb_release -cs)会自动替换为您的Ubuntu版本代号(如focalfor 20.04,jammyfor 22.04)。重要提示: 自Ubuntu 20.04 LTS起,
apt-key add已被弃用并可能产生警告。更现代且推荐的方法是将GPG密钥文件直接放入/etc/apt/trusted.gpg.d/目录。如果您遇到apt-key add相关的警告或错误,可以尝试以下更现代的方法:sudo apt update
sudo apt install ca-certificates curl gnupg lsb-release
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://apt.kitware.com/keys/kitware-archive-latest.asc | sudo gpg --dearmor -o /etc/apt/keyrings/kitware.gpg
echo "deb [signed-by=/etc/apt/keyrings/kitware.gpg] https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/kitware.list > /dev/null -
更新APT包索引:
添加PPA后,需要再次更新您的软件包列表,以让系统识别新添加的仓库中的软件包。
sudo apt update -
安装CMake:
现在,您可以使用APT来安装CMake。由于PPA提供了更新版本,此命令将会安装PPA中的最新版本。
sudo apt install cmake如果系统提示您确认,输入
Y并按回车。此时安装的版本将比官方源中的新。 -
验证安装:
再次检查CMake版本,确认安装的是最新版本。
cmake --version您应该会看到一个比之前官方源中更高版本的CMake。
优点:
- 获取最新稳定版:能够安装最新的CMake稳定版本,满足对新功能的需求。
- 仍然方便管理:通过APT安装,易于更新和卸载,与系统其他软件包管理方式保持一致。
缺点:
- 对系统源有修改:添加第三方PPA可能略微增加系统维护的复杂性(尽管Kitware PPA非常可靠)。
方法三:从源代码编译安装CMake(获取最新或特定版本)
当您需要安装一个尚未在PPA中提供的最新开发版本,或者需要特定的小版本号,或者希望对CMake的编译选项有完全的控制时,从源代码编译安装是最佳选择。这种方法相对复杂,但提供了最大的灵活性。
安装前准备:所需依赖
在编译CMake之前,您需要安装一些必要的构建工具和库。这些通常包括C++编译器、make工具以及SSL开发库等。
-
安装构建工具和开发库:
sudo apt update
sudo apt install build-essential libssl-devbuild-essential软件包包含了GCC/G++编译器、make等核心构建工具。libssl-dev提供了OpenSSL开发库,CMake在一些网络操作(如下载外部模块)时可能会用到。
安装步骤:
-
下载CMake源代码:
访问CMake官方网站 cmake.org/download/,下载您需要的最新稳定版或特定版本的源代码压缩包(通常是
.tar.gz格式)。您也可以使用
wget命令直接下载,例如下载3.28.1版本:wget https://github.com/Kitware/CMake/releases/download/v3.28.1/cmake-3.28.1.tar.gz(请根据实际需要替换版本号和下载链接,通常Kitware的GitHub发布页面是最可靠的下载源)。
-
解压源代码:
将下载的压缩包解压到一个您喜欢的位置。通常,建议在用户主目录下创建一个专门用于编译软件的目录,例如
~/sources。tar -zxvf cmake-3.28.1.tar.gz
cd cmake-3.28.1 -
配置、编译和安装:
进入解压后的源代码目录,然后执行以下步骤:
-
创建构建目录(推荐):
为了保持源代码目录的整洁,通常在源代码目录内部创建一个独立的
build目录进行编译。这是CMake的推荐做法,称为“out-of-source”构建。mkdir build
cd build -
运行配置脚本:
使用CMake的配置命令来生成Makefile。您可以通过
--prefix参数指定安装路径。将其安装到/usr/local是一个常见且推荐的做法,这与系统APT管理的软件包区分开来,有助于避免冲突。../bootstrap --prefix=/usr/localbootstrap脚本会首先构建一个简单的CMake来完成后续的配置工作。这个方法在系统没有CMake或CMake版本过旧时特别有用。或者,如果您已经安装了旧版本的CMake(例如通过APT安装的),您也可以使用它来配置新版本的CMake:
cmake ../ -DCMAKE_INSTALL_PREFIX=/usr/local这两种方法都可以,但使用
bootstrap更具通用性,因为它不依赖于系统上预先存在的CMake。 -
编译:
执行编译命令。
-jN参数可以指定并行编译的线程数,通常设置为CPU核心数(通过$(nproc)获取),可以显著加快编译速度。make -j$(nproc)此步骤可能需要几分钟到十几分钟不等,具体取决于您的CPU性能。
-
安装:
将编译好的CMake安装到之前指定的
--prefix目录。此步骤需要管理员权限。sudo make install
-
创建构建目录(推荐):
-
验证安装与更新PATH环境变量:
安装完成后,新编译的CMake可执行文件默认会安装到
/usr/local/bin。如果您的系统PATH环境变量中没有这个路径,或者/usr/bin(APT安装的CMake通常在这里)的优先级更高,系统可能仍然会找到旧版本的CMake(如果存在的话)。-
检查PATH:
echo $PATH确认
/usr/local/bin是否在输出中。如果不在,或者在/usr/bin之前,您可能需要手动调整。通常,/usr/local/bin应该在/usr/bin之前,以确保优先使用您手动安装的版本。 -
更新PATH(如果需要):
编辑您的shell配置文件(例如
~/.bashrc或~/.zshrc),添加或修改以下行:export PATH="/usr/local/bin:$PATH"然后使更改生效:
source ~/.bashrc(或source ~/.zshrc,根据您使用的shell) -
验证版本:
cmake --version现在应该显示您刚刚编译安装的最新版本。
-
检查PATH:
优点:
- 版本控制最灵活:可以安装任意特定版本,包括最新的开发版本。
- 完全定制化:可以在编译时设置各种编译选项,以满足特定需求。
- 独立性:通常安装到
/usr/local,不会与APT管理的系统软件包冲突。
缺点:
- 过程复杂:需要手动处理依赖、下载、解压、配置、编译和安装步骤。
- 耗时:编译过程可能需要较长时间,尤其是在性能较低的机器上。
- 手动维护:更新和卸载不如APT管理方便,需要手动跟踪安装文件。
方法四:使用Snap安装CMake
Snap是一种通用Linux软件包格式,它将应用程序及其所有依赖项打包到一个隔离的容器中。在Ubuntu上,Snap是预装的,因此也是一个方便的选择,尤其是在您不希望修改系统APT源或编译源代码的情况下。
安装步骤:
-
安装Snap版本的CMake:
执行以下命令即可安装最新的稳定版CMake。
sudo snap install cmake --classic--classic参数是必需的,因为CMake需要访问系统文件,而不是局限在沙盒环境中。 -
验证安装:
由于Snap安装的程序通常会将其可执行文件链接到
/snap/bin或类似的路径,并自动添加到PATH中,您可以直接验证。cmake --version如果系统同时存在APT安装的CMake,您可能需要指定Snap的路径,或者确保Snap的路径在PATH中优先级更高。
通常Snap安装的程序会有一个特殊的别名,或者你可能需要这样执行:
/snap/bin/cmake --version
优点:
- 简单易用:与APT类似,一条命令即可安装。
- 获取最新版本:Snap上的CMake通常是最新的稳定版本。
- 隔离性:Snap包与系统其他部分相对隔离,减少潜在冲突。
缺点:
- 占用空间:Snap包通常比APT包更大,因为它包含了所有依赖,可能占用数百MB的磁盘空间。
- 运行效率:理论上,Snap应用在某些情况下可能比原生安装的应用略慢(虽然对CMake这种工具来说影响不大)。
- 集成度:在某些特定场景下,Snap应用的集成度可能不如原生安装的高。
四、CMake的卸载、更新与多版本管理
如何卸载CMake?
卸载CMake的方法取决于您当初的安装方式。
APT安装的CMake:
如果您通过sudo apt install cmake安装,可以使用以下命令卸载:
sudo apt remove cmake
如果想清除所有相关的配置文件,可以使用:
sudo apt purge cmake
之后,您还可以清除不再需要的依赖包:
sudo apt autoremove
PPA安装的CMake:
与APT安装类似,使用相同的remove或purge命令。在卸载之后,如果您不再需要PPA,也可以将其从系统中移除:
sudo apt-add-repository --remove 'deb https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main'
sudo apt update
源代码编译安装的CMake:
如果您的安装目录是/usr/local,您需要手动删除相关文件。由于没有一个简单的make uninstall命令(除非源代码提供了),这通常意味着:
- 删除安装目录:
sudo rm -rf /usr/local/bin/cmake /usr/local/share/cmake-... /usr/local/doc/cmake-...等。这需要您清楚知道当时安装了哪些文件。 - 更安全的做法:在编译安装时的
build目录中,如果当时运行了sudo make install,那么通常会有一些日志或文件列表。最理想的卸载方式是回到当时的构建目录,执行sudo make uninstall(如果目标提供了这个选项)。如果不支持,则需要手动移除。
鉴于手动卸载的复杂性,这就是为什么将编译安装的软件安装到/opt/或/usr/local/stow/cmake-X.Y/等特定目录并使用GNU Stow进行管理可能是一个更好的实践。
Snap安装的CMake:
sudo snap remove cmake
如何更新CMake?
更新CMake也取决于安装方式。
- APT或PPA安装:只需运行常规的系统更新命令:
sudo apt update
sudo apt upgrade如果APT仓库或PPA中发布了新版本,
apt upgrade会将其更新。 - 源代码编译安装:需要重复编译安装的步骤:下载最新源代码,解压,编译,然后
sudo make install。新版本会覆盖旧版本,确保在执行sudo make install之前,您的PATH环境变量已经配置正确,指向了您希望更新的安装目录。 - Snap安装:Snap包管理器会自动在后台更新应用程序,或您可以使用:
sudo snap refresh cmake
如何管理多个CMake版本或指定特定版本?
在某些情况下,您可能需要在同一系统上拥有多个CMake版本。例如,一个项目需要CMake 3.10,而另一个需要最新的3.28。
-
通过PATH环境变量控制优先级:
这是最常见的方法。当您执行
cmake命令时,系统会按照PATH环境变量中目录的顺序查找可执行文件。因此,您可以将您希望优先使用的CMake版本所在的目录放在PATH的前面。例如,如果您编译安装了一个新版本到
/usr/local/bin,并希望优先使用它,而系统同时有APT安装的旧版本在/usr/bin,您可以在~/.bashrc中添加:export PATH="/usr/local/bin:$PATH"这会确保
/usr/local/bin/cmake被首先找到。 -
使用符号链接或别名:
您可以创建符号链接或shell别名来指向特定版本的CMake。
例如,如果您有
/opt/cmake-3.10/bin/cmake和/opt/cmake-3.28/bin/cmake:alias cmake310="/opt/cmake-3.10/bin/cmake"
alias cmake328="/opt/cmake-3.28/bin/cmake"然后您就可以使用
cmake310或cmake328来调用特定版本。 -
使用
update-alternatives(不推荐用于CMake):虽然
update-alternatives工具可以管理系统中多个同名命令的不同版本,但它主要用于系统级工具。对于开发者工具如CMake,通过修改PATH或别名通常更灵活且不易导致系统问题。
最佳实践:对于特定项目,可以在项目的构建脚本或环境变量中明确指定
CMAKE_COMMAND来确保使用了预期的CMake版本。例如,在CI/CD环境中,这尤为重要。
export PATH="/opt/cmake-3.28/bin:$PATH" && cmake ..或者直接指定可执行文件的完整路径:
/opt/cmake-3.28/bin/cmake ..
五、CMake的基本使用示例
安装好CMake之后,下一步就是如何在您的项目中使用它。这里提供一个最简单的C++项目示例,帮助您快速上手。
示例项目结构:
我们将在一个名为my_project的目录中创建以下结构:
my_project/
├── main.cpp
└── CMakeLists.txt
main.cpp 文件内容:
这是一个简单的“Hello, CMake!”程序,用于输出一行文字。
#include <iostream>
int main() {
std::cout << "Hello, CMake!" << std::endl;
return 0;
}
CMakeLists.txt 文件内容:
这是CMake的核心配置文件,它告诉CMake如何构建您的项目。
# 指定项目所需的最低CMake版本
cmake_minimum_required(VERSION 3.10)
# 定义项目名称
project(MyAwesomeProject VERSION 1.0)
# 启用C++11标准(可选,根据项目需求)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
# 添加一个可执行文件
# MyAwesomeProject是目标名称,main.cpp是源文件
add_executable(MyAwesomeProject main.cpp)
构建项目步骤:
-
创建构建目录并进入:
在项目根目录(
my_project)中创建一个build目录。这是CMake推荐的“out-of-source”构建方式,能保持源代码目录的整洁。mkdir my_project/build
cd my_project/build -
运行CMake配置:
在
build目录中,执行cmake ..。..表示CMakeLists.txt文件位于当前目录的上一级。cmake ..这将根据
CMakeLists.txt文件生成默认的构建系统文件(在Linux上通常是Makefile)。您会看到CMake输出一些配置信息,例如检测编译器、设置变量等。 -
编译项目:
生成构建文件后,使用您的原生构建工具(如
make)来编译项目。make或者,如果您在
cmake ..时指定了不同的生成器(例如通过cmake -G Ninja ..),则使用相应的构建工具,如ninja。编译成功后,您会在
build目录下找到一个名为MyAwesomeProject的可执行文件。 -
运行程序:
执行编译生成的可执行文件。
./MyAwesomeProject您应该会看到输出:
Hello, CMake!
六、常见问题与疑难解答
Q1: 为什么我安装了CMake,但是执行 cmake --version 仍然显示旧版本?
A1: 这通常是由于PATH环境变量配置问题。系统会按照PATH中的目录顺序查找可执行文件。如果您通过编译安装或Snap安装了新版本,但其安装路径在PATH中的优先级低于旧版本(例如APT安装在/usr/bin),系统就会优先找到旧版本。
解决方案:
- 确保您新安装的CMake路径(例如
/usr/local/bin,或Snap安装的/snap/bin)在~/.bashrc或~/.zshrc中被添加到PATH环境变量的开头。例如:export PATH="/usr/local/bin:$PATH"。 - 执行
source ~/.bashrc(或相应的shell配置文件,如source ~/.zshrc)使更改生效。 - 如果通过Snap安装,尝试使用
/snap/bin/cmake --version来明确调用Snap版本,以确认其存在和版本。
Q2: 编译安装CMake时提示缺少依赖,例如libssl-dev或build-essential,怎么办?
A2: 这意味着您的系统缺少编译CMake所需的开发库或工具。在尝试编译之前,请确保已安装所有必要的预设工具包。
解决方案:
- 使用APT安装缺失的依赖:
sudo apt update
sudo apt install build-essential libssl-dev根据具体的报错信息,可能还需要安装其他开发库,例如
libcurl4-openssl-dev等。
Q3: CMake配置时报错 CMake Error: CMAKE_CXX_COMPILER not found,或者找不到C++编译器。
A3: 这表明CMake无法找到合适的C++编译器(如g++)。这通常是build-essential包没有正确安装或配置的问题,或者您的系统上没有可用的C++编译器。
解决方案:
- 确保
build-essential包已安装,此包包含了GCC/G++编译器:sudo apt update
sudo apt install build-essential - 检查
g++是否可执行并正常工作:g++ --version如果此命令不起作用或显示错误,则编译器本身存在问题,需要进一步排查GCC/G++的安装。
- 在CMake命令中明确指定编译器(如果系统有多个编译器版本,或CMake未能自动检测到):
cmake .. -DCMAKE_CXX_COMPILER=/usr/bin/g++-11(请根据实际情况调整路径和版本,例如g++-9、clang++等)
Q4: 我想在Ubuntu上卸载APT安装的CMake,然后重新编译安装一个最新版本,如何操作?
A4:
- 卸载APT版本:
sudo apt purge cmake
sudo apt autoremove - 移除PPA(如果之前通过PPA安装):
sudo apt-add-repository --remove 'deb https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main'
sudo apt update - 按照“方法三:从源代码编译安装CMake”的步骤进行操作。确保在编译安装完成后,更新您的
PATH环境变量,使其优先指向新安装的CMake路径。
Q5: 如何查看CMake的详细帮助文档?
A5: CMake提供了丰富的在线文档和本地帮助,是学习和解决问题的重要资源。
- 在线文档:访问 cmake.org/documentation/ 获取最全面、最新的文档,包括命令、模块、变量和属性的详细说明。
- 本地帮助(通过命令行):
- 查看所有可用的CMake模块:
cmake --help-modules - 查看特定模块的帮助信息:
cmake --help-module [ModuleName](例如cmake --help-module FindPackageHandleStandardArgs) - 查看CMake命令的帮助:
cmake --help-command [CommandName](例如cmake --help-command add_executable) - 查看所有变量的帮助:
cmake --help-variables - 查看所有属性的帮助:
cmake --help-properties - 获取简要帮助信息:
cmake --help
这些本地帮助对于快速查询特定语法或概念非常有用。
- 查看所有可用的CMake模块:
通过这篇详细的指南,您应该已经全面了解了在Ubuntu系统上安装、配置、管理和使用CMake的各种方法和技巧。无论您是CMake的新手还是需要处理特定版本需求的高级用户,本文都希望能为您提供有价值的参考。