CMake 完整使用教程 之一 配置环境
本文于1450天之前发表,文中内容可能已经过时。
学习CMake之前,需要对系统进行设置,这样才能运行所有示例。
本章的主要内容有:
- 如何获取代码
- 如何在GNU/Linux、macOS和Windows上安装运行示例所需的所有工具
- 自动化测试如何工作
- 如何报告问题,并提出改进建议
我们会尽可能让初学者看懂本书的内容。不过,这本书并非完全适合零基础人士。我们假设,您对构建目标平台上可用的软件,及本地工具有基本的了解。有Git版本控制的经验,可与源码库进行“互动”(不是必需)。
0.1 获取代码
本书的源代码可以在GitHub上找到,网址是 https://github.com/dev-cafe/cmake-cookbook 。开源代码遵循MIT许可:只要原始版权和许可声明包含在软件/源代码的任何副本中,可以以任何方式重用和重新混合代码。许可的全文可以在 https://opensource.org/licenses/MIT 中看到。
为了测试源码,需要使用Git获取代码:
- 主要的GNU/Linux发行版都可以通过包管理器安装Git。也可以从Git项目网站 https://git-scm.com 下载二进制发行版,进行安装。
- MacOS上,可以使用自制或MacPorts安装Git。
- Windows上,可以从Git项目网站( https://git-scm.com )下载Git可执行安装文件。
可以通过GitHub桌面客户端访问这些示例,网址为 https://desktop.github.com 。
另一种选择是从 https://github.com/dev-cafe/cmake-cookbook 下载zip文件。
安装Git后,可以将远程库克隆到本地计算机,如下所示:
1 | $ git clone https://github.com/dev-cafe/cmake-cookbook.git |
这将创建一个名为cmake-cookbook
的文件夹。本书内容与源码的章节对应,书中章节的编号和源码的顺序相同。
在GNU/Linux、MacOS和Windows上,使用最新的持续集成进行测试。我们会在之后讨论测试的设置。
我们用标签v1.0标记了与本书中打印的示例相对应的版本。为了与书中内容对应,可以如下获取此特定版本:
1 | $ git clone --single-branch -b v1.0 https://github.com/dev-cafe/cmake-cookbook.git |
我们希望收到Bug修复,并且GitHub库将继续发展。要获取更新,可以选择库的master分支。
0.2 Docker镜像
在Docker中进行环境搭建,无疑是非常方便的(依赖项都已经安装好了)。我们的Docker镜像是基于Ubuntu 18.04的镜像制作,您可以按照官方文档https://docs.docker.com 在您的操作系统上安装Docker。
Docker安装好后,您可以下载并运行我们的镜像,然后可以对本书示例进行测试:
1 | docker run -it devcafe/cmake-cookbook_ubuntu-18.04 |
0.3 安装必要的软件
与在Docker中使用不同,另一种选择是直接在主机操作系统上安装依赖项。为此,我们概括了一个工具栈,可以作为示例的基础。您必须安装以下组件:
- CMake
- 编译器
- 自动化构建工具
- Python
我们还会详细介绍,如何安装所需的某些依赖项。
0.3.1 获取CMake
本书要使用的CMake最低需要为3.5。只有少数示例,演示了3.5版之后引入的新功能。每个示例都有提示,指出示例代码在哪里可用,以及所需的CMake的最低版本。提示信息如下:
NOTE:这个示例的代码可以在 https://github.com/dev-cafe/cmake-cookbook/tree/v1.0/chapter-03/recipe10 中找到,其中包括一个C示例。该示例在CMake 3.5版(或更高版本)中是有效的,并且已经在GNU/Linux、macOS和Windows上进行了测试。
有些(如果不是大多数)示例仍然适用于较低版本的CMake。但是,我们没有测试过这个。我们认为CMake 3.5是大多数系统和发行版的默认软件,而且升级CMake也没什么难度。
CMake可以以多种方式安装。下载并提取由Kitware维护的二进制发行版,可以在所有平台上运行,下载页面位于 https://cmake.org/download/ 。
大多数GNU/Linux发行版都在包管理器中提供了CMake。然而,在一些发行版中,版本可能比较旧,因此下载由Kitware提供的二进制文件当然是首选。下面的命令将从CMake打包的版本中下载并安装在$HOME/Deps/CMake
(根据您的偏好调整此路径)下的CMake 3.5.2:
1 | cmake_version="3.5.2" |
macOS获取最新版本的CMake:
1 | $ brew upgrade cmake |
Windows上,可以使用Visual Studio 2017,它提供了CMake支持。Visual Studio 2017的安装记录在第13章,可选生成器和交叉编译,示例技巧1,使用Visual Studio 2017构建CMake项目。
或者,可以从 https://www.msys2.org 下载MSYS2安装程序,按照其中给出的说明更新包列表,然后使用包管理器pacman
安装CMake。下面的代码正在构建64位版本:
1 | pacman -S mingw64/mingw-w64-x86_64-cmake |
对于32位版本,请使用以下代码(为了简单起见,我们以后只会提到64位版本):
1 | pacman -S mingw64/mingw-w64-i686-cmake |
MSYS2的另一个特性是在Windows上提供了一个终端,比较像Unix操作系统上的终端,提供可用的开发环境。
0.3.2 编译器
我们将需要C++、C和Fortran的编译器。编译器的版本需要比较新,因为我们需要在大多数示例中支持最新的语言标准。CMake为来自商业和非商业供应商的许多编译器,提供了非常好的支持。为了让示例始终能够跨平台,并尽可能独立于操作系统,我们使用了开源编译器:
GNU/Linux上,GNU编译器集合(GCC)是直接的选择。它是免费的,适用于所有发行版。例如,在Ubuntu上,可以安装以下编译器:
1
$ sudo apt-get install g++ gcc gfortran
在LLVM家族中,Clang也是C++和C编译器的一个很好的选择:
1
$ sudo apt-get install clang clang++ gfortran
macOS上,XCode附带的LLVM编译器适用于C++和C。我们在macOS测试中使用了GCC的Fortran编译器。GCC编译器必须使用包管理器单独安装:
1
$ brew install gcc
Windows上,可以使用Visual Studio测试C++和C示例。或者,可以使用MSYS2安装程序,MSYS2环境中(对于64位版本)使用以下单个命令安装整个工具链,包括C++、C和Fortran编译器:
1
pacman -S mingw64/mingw-w64-x86_64-toolchain
0.3.3 自动化构建工具
自动化构建工具为示例中的项目提供构建和链接的基础设施,最终会安装和使用什么,很大程度上取决于操作系统:
- GNU/Linux上,GNU Make(很可能)在安装编译器时自动安装。
- macOS上,XCode将提供GNU Make。
- Windows上,Visual Studio提供了完整的基础设施。MSYS2环境中,GNU Make作为mingw64/mingw-w64-x86_64工具链包的一部分,进行安装。
为了获得最大的可移植性,我们尽可能使示例不受这些系统相关细节的影响。这种方法的优点是配置、构建和链接,是每个编译器的固有特性。
Ninja是一个不错的自动化构建工具,适用于GNU/Linux、macOS和Windows。Ninja注重速度,特别是增量重构。为GNU/Linux、macOS和Windows预先打包的二进制文件可以在GitHub库中找到,网址是 https://github.com/ninja-build/ninja/releases 。
Fortran项目中使用CMake和Ninja需要注意。使用CMake 3.7.2或更高版本是必要的,Kitware还有维护Ninja,相关包可以在 https://github.com/Kitware/ninja/releases 上找到。
在GNU/Linux上,可以使用以下一系列命令安装Ninja:
1 | $ mkdir -p ninja |
Windows上,使用MSYS2环境(假设是64位版本)执行以下命令:
1 | pacman -S mingw64/mingw-w64-x86_64-ninja |
NOTE:我们建议阅读这篇文章 http://www.aosabook.org/en/posa/ninja.html ,里面是对NInja编译器的历史和设计的选择,进行启发性的讨论。
0.3.4 Python
本书主要关于CMake,但是其中的一些方法,需要使用Python。因此,也需要对Python进行安装:解释器、头文件和库。Python 2.7的生命周期结束于2020年,因此我们将使用Python 3.5。
在Ubuntu 14.04 LTS上(这是Travis CI使用的环境,我们后面会讨论),Python 3.5可以安装如下:
1 | sudo apt-get install python3.5-dev |
Windows可使用MSYS2环境,Python安装方法如下(假设是64位版本):
1 | pacman -S mingw64/mingw-w64-x86_64-python3 |
为了运行已经写好的测试机制,还需要一些特定的Python模块。可以使用包管理器在系统范围内安装这些包,也可以在隔离的环境中安装。建议采用后一种方法:
- 可以在不影响系统环境的情况下,将安装包进行清理/安装。
- 可以在没有管理员权限的情况下安装包。
- 可以降低软件版本和依赖项冲突的风险。
- 为了复现性,可以更好地控制包的依赖性。
为此,我们准备了一个Pipfile
。结合pipfile.lock
,可以使用Pipenv
( http://pipenv.readthedocs )。创建一个独立的环境,并安装所有包。要为示例库创建此环境,可在库的顶层目录中运行以下命令:
1 | $ pip install --user pip pipenv --upgrade |
执行pipenv shell
命令会进入一个命令行环境,其中包含特定版本的Python和可用的包。执行exit
将退出当前环境。当然,还可以使用pipenv run
在隔离的环境中直接执行命令。
或者,可以将库中的requirements.txt
文件与Virtualenv
( http://docs.pythonguide.org/en/latest/dev/virtualenvs/ )和pip
结合使用,以达到相同的效果:
1 | virtualenv --python=python3.5 venv |
可以使用deactivate
命令退出虚拟环境。
另一种选择是使用Conda
环境,我们建议安装Miniconda
。将把最新的Miniconda
安装到GNU/Linux的$HOME/Deps/conda
目录(从 https://repo.continuum.io/miniconda/miniconda3-latestlinux-x86_64.sh 下载)或macOS(从 https://repo.continuum.io/miniconda/miniconda3-latestmacosx-x86_64.sh 下载):
1 | curl -Ls https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh > miniconda.sh |
Windows上,可以从 https://repo.continuum.io/miniconda/Miniconda3-latest-Windows-x86_64.exe 下载最新的Miniconda
。该软件包可以使用PowerShell
安装,如下:
1 | $basedir = $pwd.Path + "\" |
安装了Conda
后, Python模块可以按如下方式安装:
1 | $ conda create -n cmake-cookbook python=3.5 |
执行conda deactivate
将退出conda
的环境。
0.3.5 依赖软件
有些示例需要额外的依赖,这些软件将在这里介绍。
0.3.5.1 BLAS和LAPACK
大多数Linux发行版都为BLAS和LAPACK提供包。例如,在Ubuntu 14.04 LTS上,您可以运行以下命令:
1 | $ sudo apt-get install libatlas-dev liblapack-dev liblapacke-dev |
macOS上,XCode附带的加速库可以满足我们的需要。
Windows使用MSYS2环境,可以按如下方式安装这些库(假设是64位版本):
1 | pacman -S mingw64/mingw-w64-x86_64-openblas |
或者,可以从GitHub ( https://github.com/referlapack/lapack )下载BLAS和LAPACK的参考实现,并从源代码编译库。商业供应商为平台提供安装程序,安装包中有BLAS和LAPACK相关的API。
0.3.5.2 消息传递接口(MPI)
MPI有许多商业和非商业实现。这里,安装免费的非商业实现就足够了。在Ubuntu 14.04 LTS上,我们推荐OpenMPI
。可使用以下命令安装:
1 | $ sudo apt-get install openmpi-bin libopenmpi-dev |
在macOS上,Homebrew
发布了MPICH
:
1 | $ brew install mpich |
还可以从 https://www.open-mpi.org/software/ 上获取源代码,编译OpenMPI
。 对于Windows,Microsoft MPI可以通过 https://msdn.microsoft.com/en-us/library/bb524831(v=vs.85).aspx 下载安装。
0.3.5.3 线性代数模板库
一些示例需要线性代数模板库,版本为3.3或更高。如果包管理器不提供Eigen
,可以使用在线打包源(http://eigen.tuxfamily.org )安装它。例如,在GNU/Linux和macOS上,可以将Eigen
安装到$HOME/Deps/Eigen
目录:
1 | $ eigen_version="3.3.4" |
0.3.5.4 Boost库
Boost
库适用于各种操作系统,大多数Linux发行版都通过它们的包管理器提供该库的安装。例如,在Ubuntu 14.04 LTS上,Boost
文件系统库、Boost Python
库和Boost
测试库可以通过以下命令安装:
1 | $ sudo apt-get install libboost-filesystem-dev libboost-python-dev libboost-test-dev |
对于macOS, MacPorts
和自制程序都为最新版本的Boost
提供了安装包。我们在macOS上的测试设置安装Boost
如下:
1 | $ brew cask uninstall --force oclint |
Windows的二进制发行版也可以从Boost
网站 http://www.boost.org 下载。或者,可以从 https://www.boost.org 下载源代码,并自己编译Boost
库。
0.3.5.5 交叉编译器
在类Debian/Ubuntu系统上,可以使用以下命令安装交叉编译器:
1 | $ sudo apt-get install gcc-mingw-w64 g++-mingw-w64 gfortran-mingw-w64 |
在macOS上,使用Brew
,可以安装以下交叉编译器:
1 | $ brew install mingw-w64 |
其他包管理器提供相应的包。使用打包的跨编译器的另一种方法,是使用M交叉环境( https://mxe.cc ),并从源代码对其进行构建。
0.3.5.6 ZeroMQ, pkg-config, UUID和Doxygen
Ubuntu 14.04 LTS上,这些包可以安装如下:
1 | $ sudo apt-get install pkg-config libzmq3-dev doxygen graphviz-dev uuid-dev |
macOS上,我们建议使用Brew
安装:
1 | $ brew install ossp-uuid pkg-config zeromq doxygen |
pkg-config
程序和UUID
库只在类Unix系统上可用。 Windows上使用MSYS2环境,可以按如下方式安装这些依赖项(假设是64位版本):
1 | pacman -S mingw64/mingw-w64-x86_64-zeromq |
0.3.5.7 Conda的构建和部署
想要使用Conda
打包的示例的话,需要Miniconda
和Conda
构建和部署工具。Miniconda
的安装说明之前已经给出。要在GNU/Linux和macOS上安装Conda
构建和部署工具,请运行以下命令:
1 | $ conda install --yes --quiet conda-build anaconda-client jinja2 setuptools |
这些工具也可以安装在Windows上:
1 | $conda_path = "C:\Deps\conda\Scripts\conda.exe" |
0.4 测试环境
示例在下列持续集成(CI)上进行过测试:
- Travis( https://travis-ci.org )用于GNU/Linux和macOS
- Appveyor( https://www.appveyor.com )用于Windows
- CircleCI ( https://circleci.com )用于附加的GNU/Linux测试和商业编译器
CI服务的配置文件可以在示例库中找到( https://github.com/dev-cafe/cmake-cookbook/ ):
- Travis的配置文件为
travis.yml
- Appveyor的配置文件为
.appveyor.yml
- CircleCI的配置文件为
.circleci/config.yml
- Travis和Appveyor的其他安装脚本,可以在
testing/dependencies
文件夹中找到。
NOTE:GNU/Linux系统上,Travis使用CMake 3.5.2和CMake 3.12.1对实例进行测试。macOS系统上用CMake 3.12.1进行测试。Appveyor使用CMake 3.11.3进行测试。Circle使用CMake 3.12.1进行测试。
测试机制是一组Python脚本,包含在testing
文件夹中。脚本collect_tests.py
将运行测试并报告它们的状态。示例也可以单独测试,也可以批量测试; collect_tests.py
接受正则表达式作为命令行输入,例如:
1 | $ pipenv run python testing/collect_tests.py 'chapter-0[1,7]/recipe-0[1,2,5]' |
该命令将对第1章和第7章的示例1、2和5进行测试。
要获得更详细的输出,可以设置环境变量VERBOSE_OUTPUT=ON
:
1 | $ env VERBOSE_OUTPUT=ON pipenv run python testing/collect_tests.py 'chapter-*/recipe-*' |