# 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 留下評論——讓其他讀者知道你的想法