# 0.3 安装必要的软件
与在Docker中使用不同,另一种选择是直接在主机操作系统上安装依赖项。为此,我们概括了一个工具栈,可以作为示例的基础。您必须安装以下组件:
1. CMake
2. 编译器
3. 自动化构建工具
4. 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:
```shell
$ cmake_version="3.5.2"
$ target_path=$HOME/Deps/cmake/${cmake_version}
$ cmake_url="https://cmake.org/files/v${cmake_version%.*}/cmake-${cmake_version}-Linux-x86_64.tar.gz"
$ mkdir -p "${target_path}"
$ curl -Ls "${cmake_url}" | tar -xz -C "${target_path}" --strip-components=1
$ export PATH=$HOME/Deps/cmake/${cmake_version}/bin${PATH:+:$PATH}
$ cmake --version
```
macOS获取最新版本的CMake:
```shell
$ 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位版本:
```shell
$ pacman -S mingw64/mingw-w64-x86_64-cmake
```
对于32位版本,请使用以下代码(为了简单起见,我们以后只会提到64位版本):
```shell
$ pacman -S mingw64/mingw-w64-i686-cmake
```
MSYS2的另一个特性是在Windows上提供了一个终端,比较像Unix操作系统上的终端,提供可用的开发环境。
## 0.3.2 编译器
我们将需要C++、C和Fortran的编译器。编译器的版本需要比较新,因为我们需要在大多数示例中支持最新的语言标准。CMake为来自商业和非商业供应商的许多编译器,提供了非常好的支持。为了让示例始终能够跨平台,并尽可能独立于操作系统,我们使用了开源编译器:
* GNU/Linux上,GNU编译器集合(GCC)是直接的选择。它是免费的,适用于所有发行版。例如,在Ubuntu上,可以安装以下编译器:
```shell
$ sudo apt-get install g++ gcc gfortran
```
* 在LLVM家族中,Clang也是C++和C编译器的一个很好的选择:
```shell
$ sudo apt-get install clang clang++ gfortran
```
* macOS上,XCode附带的LLVM编译器适用于C++和C。我们在macOS测试中使用了GCC的Fortran编译器。GCC编译器必须使用包管理器单独安装:
```shell
$ brew install gcc
```
* Windows上,可以使用Visual Studio测试C++和C示例。或者,可以使用MSYS2安装程序,MSYS2环境中(对于64位版本)使用以下单个命令安装整个工具链,包括C++、C和Fortran编译器:
```shell
$ 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:
```shell
$ mkdir -p ninja
$ ninja_url="https://github.com/Kitware/ninja/releases/download/v1.8.2.g3bbbe.kitware.dyndep-1.jobserver-1/ninja-1.8.2.g3bbbe.kitware.dyndep-1.jobserver-1_x86_64-linux-gnu.tar.gz"
$ curl -Ls ${ninja_url} | tar -xz -C ninja --strip-components=1
$ export PATH=$HOME/Deps/ninja${PATH:+:$PATH}
```
Windows上,使用MSYS2环境(假设是64位版本)执行以下命令:
```shell
$ 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可以安装如下:
```shell
sudo apt-get install python3.5-dev
```
Windows可使用MSYS2环境,Python安装方法如下(假设是64位版本):
```shell
$ pacman -S mingw64/mingw-w64-x86_64-python3
$ pacman -S mingw64/mingw-w64-x86_64-python3-pip
$ python3 -m pip install pipenv
```
为了运行已经写好的测试机制,还需要一些特定的Python模块。可以使用包管理器在系统范围内安装这些包,也可以在隔离的环境中安装。建议采用后一种方法:
* 可以在不影响系统环境的情况下,将安装包进行清理/安装。
* 可以在没有管理员权限的情况下安装包。
* 可以降低软件版本和依赖项冲突的风险。
* 为了复现性,可以更好地控制包的依赖性。
为此,我们准备了一个`Pipfile`。结合`pipfile.lock`,可以使用`Pipenv`( http://pipenv.readthedocs )。创建一个独立的环境,并安装所有包。要为示例库创建此环境,可在库的顶层目录中运行以下命令:
```shell
$ pip install --user pip pipenv --upgrade
$ pipenv install --python python3.5
```
执行`pipenv shell`命令会进入一个命令行环境,其中包含特定版本的Python和可用的包。执行`exit`将退出当前环境。当然,还可以使用`pipenv run`在隔离的环境中直接执行命令。
或者,可以将库中的`requirements.txt`文件与`Virtualenv`( http://docs.pythonguide.org/en/latest/dev/virtualenvs/ )和`pip`结合使用,以达到相同的效果:
```shell
$ virtualenv --python=python3.5 venv
$ source venv/bin/activate
$ pip install -r requirements.txt
```
可以使用`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 下载):
```shell
$ curl -Ls https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh > miniconda.sh
$ bash miniconda.sh -b -p "$HOME"/Deps/conda &> /dev/null
$ touch "$HOME"/Deps/conda/conda-meta/pinned
$ export PATH=$HOME/Deps/conda/bin${PATH:+:$PATH}
$ conda config --set show_channel_urls True
$ conda config --set changeps1 no
$ conda update --all
$ conda clean -tipy
```
Windows上,可以从 https://repo.continuum.io/miniconda/Miniconda3-latest-Windows-x86_64.exe 下载最新的`Miniconda`。该软件包可以使用`PowerShell`安装,如下:
```shell
$basedir = $pwd.Path + "\"
$filepath = $basedir + "Miniconda3-latest-Windows-x86_64.exe"
$Anaconda_loc = "C:\Deps\conda"
$args = "/InstallationType=JustMe /AddToPath=0 /RegisterPython=0 /S /D=$Anaconda_loc"
Start-Process -FilePath $filepath -ArgumentList $args -Wait -Passthru
$conda_path = $Anaconda_loc + "\Scripts\conda.exe"
$args = "config --set show_channel_urls True"
Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru
$args = "config --set changeps1 no"
Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru
$args = "update --all"
Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru
$args = "clean -tipy"
Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru
```
安装了`Conda`后, Python模块可以按如下方式安装:
```shell
$ conda create -n cmake-cookbook python=3.5
$ conda activate cmake-cookbook
$ conda install --file requirements.txt
```
执行`conda deactivate`将退出`conda`的环境。
## 0.3.5 依赖软件
有些示例需要额外的依赖,这些软件将在这里介绍。
### 0.3.5.1 BLAS和LAPACK
大多数Linux发行版都为BLAS和LAPACK提供包。例如,在Ubuntu 14.04 LTS上,您可以运行以下命令:
```shell
$ sudo apt-get install libatlas-dev liblapack-dev liblapacke-dev
```
macOS上,XCode附带的加速库可以满足我们的需要。
Windows使用MSYS2环境,可以按如下方式安装这些库(假设是64位版本):
```shell
$ 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`。可使用以下命令安装:
```shell
$ sudo apt-get install openmpi-bin libopenmpi-dev
```
在macOS上,`Homebrew`发布了`MPICH`:
```shell
$ 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`目录:
```shell
$ eigen_version="3.3.4"
$ mkdir -p eigen
$ curl -Ls http://bitbucket.org/eigen/eigen/get/${eigen_version}.tar.gz | tar -xz -C eigen --strip-components=1
$ cd eigen
$ cmake -H. -Bbuild_eigen -
DCMAKE_INSTALL_PREFIX="$HOME/Deps/eigen" &> /dev/null
$ cmake --build build_eigen -- install &> /dev/null
```
### 0.3.5.4 Boost库
`Boost`库适用于各种操作系统,大多数Linux发行版都通过它们的包管理器提供该库的安装。例如,在Ubuntu 14.04 LTS上,`Boost`文件系统库、`Boost Python`库和`Boost`测试库可以通过以下命令安装:
```shell
$ sudo apt-get install libboost-filesystem-dev libboost-python-dev libboost-test-dev
```
对于macOS, `MacPorts`和自制程序都为最新版本的`Boost`提供了安装包。我们在macOS上的测试设置安装`Boost`如下:
```shell
$ brew cask uninstall --force oclint
$ brew uninstall --force --ignore-dependencies boost
$ brew install boost
$ brew install boost-python3
```
Windows的二进制发行版也可以从`Boost`网站 http://www.boost.org 下载。或者,可以从 https://www.boost.org 下载源代码,并自己编译`Boost`库。
#### 0.3.5.5 交叉编译器
在类Debian/Ubuntu系统上,可以使用以下命令安装交叉编译器:
```shell
$ sudo apt-get install gcc-mingw-w64 g++-mingw-w64 gfortran-mingw-w64
```
在macOS上,使用`Brew`,可以安装以下交叉编译器:
```shell
$ brew install mingw-w64
```
其他包管理器提供相应的包。使用打包的跨编译器的另一种方法,是使用M交叉环境( https://mxe.cc ),并从源代码对其进行构建。
#### 0.3.5.6 ZeroMQ, pkg-config, UUID和Doxygen
Ubuntu 14.04 LTS上,这些包可以安装如下:
```shell
$ sudo apt-get install pkg-config libzmq3-dev doxygen graphviz-dev uuid-dev
```
macOS上,我们建议使用`Brew`安装:
```shell
$ brew install ossp-uuid pkg-config zeromq doxygen
```
`pkg-config`程序和`UUID`库只在类Unix系统上可用。
Windows上使用MSYS2环境,可以按如下方式安装这些依赖项(假设是64位版本):
```shell
$ pacman -S mingw64/mingw-w64-x86_64-zeromq
$ pacman -S mingw64/mingw-w64-x86_64-pkg-config
$ pacman -S mingw64/mingw-w64-x86_64-doxygen
$ pacman -S mingw64/mingw-w64-x86_64-graphviz
```
#### 0.3.5.7 Conda的构建和部署
想要使用`Conda`打包的示例的话,需要`Miniconda`和`Conda`构建和部署工具。`Miniconda`的安装说明之前已经给出。要在GNU/Linux和macOS上安装`Conda`构建和部署工具,请运行以下命令:
```shell
$ conda install --yes --quiet conda-build anaconda-client jinja2 setuptools
$ conda clean -tipsy
$ conda info -a
```
这些工具也可以安装在Windows上:
```shell
$conda_path = "C:\Deps\conda\Scripts\conda.exe"
$args = "install --yes --quiet conda-build anaconda-client jinja2 setuptools"
Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru
$args = "clean -tipsy"
Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru
$args = "info -a"
Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru
```
- Introduction
- 前言
- 第0章 配置环境
- 0.1 获取代码
- 0.2 Docker镜像
- 0.3 安装必要的软件
- 0.4 测试环境
- 0.5 上报问题并提出改进建议
- 第1章 从可执行文件到库
- 1.1 将单个源文件编译为可执行文件
- 1.2 切换生成器
- 1.3 构建和链接静态库和动态库
- 1.4 用条件句控制编译
- 1.5 向用户显示选项
- 1.6 指定编译器
- 1.7 切换构建类型
- 1.8 设置编译器选项
- 1.9 为语言设定标准
- 1.10 使用控制流
- 第2章 检测环境
- 2.1 检测操作系统
- 2.2 处理与平台相关的源代码
- 2.3 处理与编译器相关的源代码
- 2.4 检测处理器体系结构
- 2.5 检测处理器指令集
- 2.6 为Eigen库使能向量化
- 第3章 检测外部库和程序
- 3.1 检测Python解释器
- 3.2 检测Python库
- 3.3 检测Python模块和包
- 3.4 检测BLAS和LAPACK数学库
- 3.5 检测OpenMP的并行环境
- 3.6 检测MPI的并行环境
- 3.7 检测Eigen库
- 3.8 检测Boost库
- 3.9 检测外部库:Ⅰ. 使用pkg-config
- 3.10 检测外部库:Ⅱ. 自定义find模块
- 第4章 创建和运行测试
- 4.1 创建一个简单的单元测试
- 4.2 使用Catch2库进行单元测试
- 4.3 使用Google Test库进行单元测试
- 4.4 使用Boost Test进行单元测试
- 4.5 使用动态分析来检测内存缺陷
- 4.6 预期测试失败
- 4.7 使用超时测试运行时间过长的测试
- 4.8 并行测试
- 4.9 运行测试子集
- 4.10 使用测试固件
- 第5章 配置时和构建时的操作
- 5.1 使用平台无关的文件操作
- 5.2 配置时运行自定义命令
- 5.3 构建时运行自定义命令:Ⅰ. 使用add_custom_command
- 5.4 构建时运行自定义命令:Ⅱ. 使用add_custom_target
- 5.5 构建时为特定目标运行自定义命令
- 5.6 探究编译和链接命令
- 5.7 探究编译器标志命令
- 5.8 探究可执行命令
- 5.9 使用生成器表达式微调配置和编译
- 第6章 生成源码
- 6.1 配置时生成源码
- 6.2 使用Python在配置时生成源码
- 6.3 构建时使用Python生成源码
- 6.4 记录项目版本信息以便报告
- 6.5 从文件中记录项目版本
- 6.6 配置时记录Git Hash值
- 6.7 构建时记录Git Hash值
- 第7章 构建项目
- 7.1 使用函数和宏重用代码
- 7.2 将CMake源代码分成模块
- 7.3 编写函数来测试和设置编译器标志
- 7.4 用指定参数定义函数或宏
- 7.5 重新定义函数和宏
- 7.6 使用废弃函数、宏和变量
- 7.7 add_subdirectory的限定范围
- 7.8 使用target_sources避免全局变量
- 7.9 组织Fortran项目
- 第8章 超级构建模式
- 8.1 使用超级构建模式
- 8.2 使用超级构建管理依赖项:Ⅰ.Boost库
- 8.3 使用超级构建管理依赖项:Ⅱ.FFTW库
- 8.4 使用超级构建管理依赖项:Ⅲ.Google Test框架
- 8.5 使用超级构建支持项目
- 第9章 语言混合项目
- 9.1 使用C/C++库构建Fortran项目
- 9.2 使用Fortran库构建C/C++项目
- 9.3 使用Cython构建C++和Python项目
- 9.4 使用Boost.Python构建C++和Python项目
- 9.5 使用pybind11构建C++和Python项目
- 9.6 使用Python CFFI混合C,C++,Fortran和Python
- 第10章 编写安装程序
- 10.1 安装项目
- 10.2 生成输出头文件
- 10.3 输出目标
- 10.4 安装超级构建
- 第11章 打包项目
- 11.1 生成源代码和二进制包
- 11.2 通过PyPI发布使用CMake/pybind11构建的C++/Python项目
- 11.3 通过PyPI发布使用CMake/CFFI构建C/Fortran/Python项目
- 11.4 以Conda包的形式发布一个简单的项目
- 11.5 将Conda包作为依赖项发布给项目
- 第12章 构建文档
- 12.1 使用Doxygen构建文档
- 12.2 使用Sphinx构建文档
- 12.3 结合Doxygen和Sphinx
- 第13章 选择生成器和交叉编译
- 13.1 使用CMake构建Visual Studio 2017项目
- 13.2 交叉编译hello world示例
- 13.3 使用OpenMP并行化交叉编译Windows二进制文件
- 第14章 测试面板
- 14.1 将测试部署到CDash
- 14.2 CDash显示测试覆盖率
- 14.3 使用AddressSanifier向CDash报告内存缺陷
- 14.4 使用ThreadSaniiser向CDash报告数据争用
- 第15章 使用CMake构建已有项目
- 15.1 如何开始迁移项目
- 15.2 生成文件并编写平台检查
- 15.3 检测所需的链接和依赖关系
- 15.4 复制编译标志
- 15.5 移植测试
- 15.6 移植安装目标
- 15.7 进一步迁移的措施
- 15.8 项目转换为CMake的常见问题
- 第16章 可能感兴趣的书
- 16.1 留下评论——让其他读者知道你的想法