目次
2.12.3 ルートディレクトリの CMakeLists.txt
2.12.4 calFunc ディレクトリ内の CMakeLists.txt
2.12.5 sotrFunc ディレクトリ内の CMakeLists.txt
2.12.6 test1 ディレクトリ内の CMakeLists.txt
2.12.7 test2 ディレクトリ内の CMakeLists.txt
CMake コンパイル ツール
1.CMakeの概要
CMake はプロジェクト構築ツールであり、クロスプラットフォームです。プロジェクトの構築に関しては、Makefile (make コマンドによるプロジェクトの構築) にも精通しています。ほとんどの IDE ソフトウェアは、VS の nmake、Linux 上の GNU make、Qt の qmake など、make を統合しています。自分で Makefile を作成する場合は、通常、makefile は現在のコンパイル プラットフォームに依存しており、makefile を作成する作業負荷は比較的大きく、依存関係を解決するときに間違いを犯しやすいことがわかります。
CMake は上記の問題を正確に解決します. 開発者がプロジェクト全体のコンパイルプロセスを指定できるようにします. コンパイルプラットフォームによれば、最終的にはユーザーは自动生成本地化的Makefile和工程文件
コンパイルするだけで済みますmake
. したがって、CMake は Makefile を自動的に生成するツールとみなすことができますコンパイルプロセスは次のようになります。
-
青い点線は、メイクファイルを使用してプロジェクトをビルドするプロセスを示します。
-
赤い実線は、cmake を使用してプロジェクトをビルドするプロセスを示します。
CMake の機能を紹介した後、その利点をまとめてみましょう。
-
クロスプラットフォーム。
-
大規模なプロジェクトを管理する能力。
-
コンパイルのビルド プロセスとコンパイル プロセスを簡素化します。
-
拡張可能: 特定の関数を備えたモジュールを cmake 用に作成して cmake の関数を拡張できます。
2.CMakeの使用
CMake は、大文字、小文字、および大文字と小文字の混合コマンドをサポートします。CMakeLists.txtファイルの作成時に使用したツールに対応するコマンド プロンプトがある場合は、あまり気にせずにケースに従ってください。
2.1 注意事項
2.1.1 コメント行
CMake は行コメントに # を使用し、どこにでも配置できます。
# 这是一个 CMakeLists.txt 文件
cmake_minimum_required(VERSION 3.0.0)
2.1.2 コメントブロック
#[[ 这是一个 CMakeLists.txt 文件。
这是一个 CMakeLists.txt 文件
这是一个 CMakeLists.txt 文件]]
cmake_minimum_required(VERSION 3.0.0)
2.2 ソースファイル
2.1.1 同じ部屋に住む
-
準備作業: テストを容易にするために、ローカル コンピューター上にいくつかのテスト ファイルを準備しました。
-
【add.cpp】
#include "head.h"
int Add(int x, int y) { return x + y; }
-
【サブCPP】
#include "head.h"
int Sub(int x, int y) { return x - y; }
-
【マルチcpp】
#include "head.h"
int Mul(int x, int y) { return x * y; }
-
【div.cpp】
#include "head.h"
int Div(int x, int y) { return x / y; }
-
【head.h】
#pragma once
#include <iostream>
using namespace std;
int Add(int x, int y);
int Sub(int x, int y);
int Mul(int x, int y);
int Div(int x, int y);
-
【main.cpp】
#include "head.h"
int main()
{
int a = 10;
int b = 2;
cout << a << "+" << b << "=" << Add(a, b) << endl;
cout << a << "-" << b << "=" << Sub(a, b) << endl;
cout << a << "*" << b << "=" << Mul(a, b) << endl;
cout << a << "/" << b << "=" << Div(a, b) << endl;
return 0;
}
-
【ディレクトリ構造】
[shaxiang@VM-8-14-centos data_structure_algorithm]$ tree .
.
|-- add.cpp
|-- CMakeLists.txt
|-- div.cpp
|-- head.h
|-- main.cpp
|-- mul.cpp
`-- sub.cpp
0 directories, 7 files
-
CMakeLists.txtファイルを追加します
上記のソース ファイルが配置されているディレクトリに新しいファイルCMakeLists.txtを追加します。ファイルの内容は次のとおりです。
# 指定使用的 cmake 的最低版本,可选,非必须,如果不加可能会有警告。
cmake_minimum_required(2.8)
# 定义工程名称,并可指定工程的版本、工程描述、web主页地址、支持的语言(默认情况支持所有语言),如果不需要这些都是可以忽略的,只需要指定出工程名字即可。
project(test)
# 定义工程会生成一个可执行程序。
add_executable(app main.cpp add.cpp sub.cpp div.cpp mul.cpp)
次に、 CMakeLists.txtファイルに追加された 3 つのコマンドを順番に紹介します。
-
cmake_minimum_required : 使用する cmake の最小バージョンを指定します。オプション、必須ではありません。追加しない場合は、警告が表示される可能性があります。
-
project : プロジェクト名を定義し、プロジェクトのバージョン、プロジェクトの説明、Web ホームページのアドレス、およびサポートされている言語を指定します (デフォルトではすべての言語がサポートされています)。これらが必要ない場合は、無視して指定するだけで問題ありません。プロジェクト名。
-
add_executable : プロジェクトを定義すると、実行可能プログラムが生成されます。
add_executable(可执行程序名 源文件名称)
-
ここでの実行可能プログラム名は、project内のプロジェクト名とは関係ありません。
-
使用可能なスペースまたは;間隔が複数ある場合、ソース ファイル名は 1 つまたは複数にすることができます。
# 样式1
add_executable(app add.c div.c main.c mult.c sub.c)
# 样式2
add_executable(app add.c;div.c;main.c;mult.c;sub.c)
-
CMakeコマンドを実行する
CMakeLists.txtファイルを編集した後、 cmakeコマンドを実行できます。
[shaxiang@VM-8-14-centos data_structure_algorithm]$ tree .
.
|-- add.cpp
|-- CMakeLists.txt
|-- div.cpp
|-- head.h
|-- main.cpp
|-- mul.cpp
`-- sub.cpp
0 directories, 7 files
cmakeコマンドを実行すると、CMakeLists.txt内のコマンドが実行されるため、cmake コマンドへのパスの指定に誤りがないか必ず確認してください。
コマンドを実行した後、ソース ファイルが配置されているディレクトリにさらにファイルがあるかどうかを確認します。
[shaxiang@VM-8-14-centos data_structure_algorithm]$ tree -L 1
.
|-- add.cpp
|-- CMakeCache.txt
|-- CMakeFiles
|-- CMakeLists.txt
|-- div.cpp
|-- head.h
|-- main.cpp
|-- mul.cpp
`-- sub.cpp
対応するディレクトリにmakefile が生成されていることが確認できたので、makeコマンドを実行してプロジェクトをビルドし、必要な実行可能プログラムを取得します。
$ make
Scanning dependencies of target app
[ 16%] Building C object CMakeFiles/app.dir/add.c.o
[ 33%] Building C object CMakeFiles/app.dir/div.c.o
[ 50%] Building C object CMakeFiles/app.dir/main.c.o
[ 66%] Building C object CMakeFiles/app.dir/mult.c.o
[ 83%] Building C object CMakeFiles/app.dir/sub.c.o
[100%] Linking C executable app
[100%] Built target app
# 查看可执行程序是否已经生成
$ tree -L 1
.
├── add.c
├── app # 生成的可执行程序
├── CMakeCache.txt
├── CMakeFiles
├── cmake_install.cmake
├── CMakeLists.txt
├── div.c
├── head.h
├── main.c
├── Makefile
├── mult.c
└── sub.c
最後に、実行可能プログラムアプリがコンパイルされます (名前はCMakeLists.txtで指定されます)。
2.1.2 VIPルーム
上記の例からわかるように、CMakeLists.txtファイルが配置されているディレクトリで cmake コマンドが実行されると、いくつかのディレクトリとファイル (メイクファイルファイルを含む) が生成されます。ファイル , プログラムはコンパイル プロセス中にも生成されます。いくつかの中間ファイルと実行可能ファイルを生成すると、プロジェクト ディレクトリ全体が乱雑に見え、管理と保守が難しくなります。この時点では、何も含まれていない生成されたファイルを置くことができます。プロジェクトのソース コードを対応するディレクトリに格納します。たとえば、このディレクトリにbuildという名前を付けます。
[shaxiang@VM-8-14-centos build]$ cmake ../
-- The C compiler identification is GNU 7.3.1
-- The CXX compiler identification is GNU 7.3.1
-- Check for working C compiler: /opt/rh/devtoolset-7/root/usr/bin/cc
-- Check for working C compiler: /opt/rh/devtoolset-7/root/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /opt/rh/devtoolset-7/root/usr/bin/c++
-- Check for working CXX compiler: /opt/rh/devtoolset-7/root/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/shaxiang/data_structure_algorithm/build
ここで、cmakeコマンドはビルド ディレクトリで実行されますが、CMakeLists.txtファイルはビルドディレクトリの 1 レベル上のディレクトリにあるため、cmake コマンドの後に指定されるパスは... (現在のディレクトリの 1 レベル上のディレクトリ) になります。ディレクトリ。
コマンドを実行すると、ビルドディレクトリにメイクファイルが生成されます。
$ tree build -L 1
build
├── CMakeCache.txt
├── CMakeFiles
├── cmake_install.cmake
└── Makefile
1 directory, 3 files
このように、ビルドディレクトリでmakeコマンドを実行してプロジェクトをコンパイルすると、生成された関連ファイルが自然にビルドディレクトリに保存されます。このようにして、cmakeとmakeによって生成されたすべてのファイルはプロジェクトのソース ファイルから完全に分離され、それぞれが自分の家に戻って自分の母親を探します。
[shaxiang@VM-8-14-centos build]$ make
Scanning dependencies of target app
[ 20%] Building CXX object CMakeFiles/app.dir/main.cpp.o
[ 40%] Building CXX object CMakeFiles/app.dir/add.cpp.o
[ 60%] Building CXX object CMakeFiles/app.dir/sub.cpp.o
[ 80%] Building CXX object CMakeFiles/app.dir/div.cpp.o
[100%] Building CXX object CMakeFiles/app.dir/mul.cpp.o
Linking CXX executable app
[100%] Built target app
[shaxiang@VM-8-14-centos build]$ ls
app CMakeCache.txt CMakeFiles cmake_install.cmake Makefile
2.3 個人的なカスタマイズ
2.2.1 変数の定義
上記の例では、合計5つのソースファイルが用意されていますが、これら5つのソースファイルを繰り返し利用することを想定すると、その都度名前を直接書き出すのは非常に面倒なので、このとき変数を定義する必要があります。ファイルを参照すると、名前に対応する文字列が保存されており、 cmake で変数を定義するにはset。
# SET 指令的语法是:
# [] 中的参数为可选项, 如不需要可以不写
SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
-
VAR : 変数名
-
VALUE : 変数値
# 方式1: 各个源文件之间使用空格间隔
# set(SRC_LIST add.c div.c main.c mult.c sub.c)
# 方式2: 各个源文件之间使用分号 ; 间隔
set(SRC_LIST add.c;div.c;main.c;mult.c;sub.c)
add_executable(app ${SRC_LIST})
2.2.2 使用する C++ 標準を指定する
C++ プログラムを作成する場合、C++11、C++14、C++17、C++20 などの新機能を使用する場合があります。その場合、コンパイル時にコンパイル コマンドでどれを使用するかを決定する必要があります。 .標準:
$ g++ *.cpp -std=c++11 -o app
上の例では、パラメータ-std=c++11を使用して、c++11 標準コンパイラを使用することを指定しています。C++ 標準は、DCMAKE_CXX_STANDARDというマクロに対応します。CMake で C++ 標準を指定するには 2 つの方法があります。
-
CMakeLists.txt の set コマンドを通じて指定します。
#增加-std=c++11
set(CMAKE_CXX_STANDARD 11)
#增加-std=c++14
set(CMAKE_CXX_STANDARD 14)
#增加-std=c++17
set(CMAKE_CXX_STANDARD 17)
2. cmake コマンドを実行するときに、このマクロの値を指定します。
#增加-std=c++11
cmake CMakeLists.txt文件路径 -DCMAKE_CXX_STANDARD=11
#增加-std=c++14
cmake CMakeLists.txt文件路径 -DCMAKE_CXX_STANDARD=14
#增加-std=c++17
cmake CMakeLists.txt文件路径 -DCMAKE_CXX_STANDARD=17
上記例では、CMake以降のパスは実際の状況に応じて適宜変更する必要があります。
2.2.3 出力パスの指定
CMake での実行可能プログラム出力のパスの指定は、 EXECUTABLE_OUTPUT_PATHというマクロにも対応しており、その値は引き続きsetコマンドによって設定されます。
set(HOME /home/robin/Linux/Sort)
set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)
-
1行目: 絶対パスを格納する変数を定義します。
-
2 行目: スプライスされたパスの値をEXECUTABLE_OUTPUT_PATHマクロに設定します。このパスにサブディレクトリが存在しない場合は、手動で作成する必要がなく、自動的に生成されます。
cmakeコマンドで生成したmakefileを元に実行プログラムを取得し、makeコマンドで実行するため、ここで実行プログラムの生成パスを指定する際に相対パス./xxx/xxxを使用した場合、このパス内の./はmakefile ファイルが配置されているディレクトリに対応します。
[上記を踏まえてコンパイルしたプロジェクトを書く]
# 指定使用的 cmake 的最低版本,可选,非必须,如果不加可能会有警告。
cmake_minimum_required(VERSION 2.8.12.2)
# 定义工程名称,并可指定工程的版本、工程描述、web主页地址、支持的语言(默认情况支持所有语言),如果不需要这些都是可以忽略的,只需要指定出工程名字即可。
project(test)
# 设置源文件为变量值SRC需要被执行调用
set(SRC main.cpp add.cpp sub.cpp div.cpp mul.cpp)
# 设置编译标准
set(CMAKE_CXX_STANDARD 98)
# 设置编译输出路径
set(EXECUTABLE_OUTPUT_PATH /home/shaxiang/data_structure_algorithm/build/A/B/C)
# 定义工程会生成一个可执行程序。
add_executable(app ${SRC})
2.4 ファイルの検索
プロジェクト内にソースファイルが多数ある場合、CMakeLists.txtファイルを記述する際に、プロジェクトディレクトリ内のファイルを一つ一つ列挙することは不可能であり、非常に面倒で現実的ではありません。したがって、CMake にはファイルを検索するためのコマンドが用意されており、aux_source_directoryコマンドまたはfileコマンドを使用できます。
2.3.1 方法 1
CMake でaux_source_directoryコマンドを使用して、特定のパスにあるすべてのソース ファイルを検索します。コマンドの形式は次のとおりです。
aux_source_directory(< dir > < variable >)
-
dir : 検索するディレクトリ。
-
変数: dirディレクトリから検索したソースファイルのリストをこの変数に格納します。
// 测试
# 指定使用的 cmake 的最低版本,可选,非必须,如果不加可能会有警告。
cmake_minimum_required(VERSION 2.8.12.2)
# 定义工程名称,并可指定工程的版本、工程描述、web主页地址、支持的语言(默认情况支持所有语言),如果不需要这些都是可以忽略的,只需要指定出工程名字即可。
project(test)
# 设置源文件为变量值SRC需要被执行调用
# 方法一:路径宏:PROJECT_BINARY_DIR 代表cmake..
aux_source_directory(${PROJECT_SOURCE_DIR} SRC)
# 设置编译标准
set(CMAKE_CXX_STANDARD 98)
# 设置编译输出路径
set(EXECUTABLE_OUTPUT_PATH /home/shaxiang/data_structure_algorithm/build/A/B/C)
# 定义工程会生成一个可执行程序。
add_executable(app ${SRC})
2.3.2 方法 2
プロジェクト内にソースファイルが多数ある場合、CMakeLists.txtファイルを記述する際に、プロジェクトディレクトリ内のファイルを一つ一つ列挙することは不可能であり、非常に面倒です。したがって、CMake は、ファイルを検索するためのコマンド、file を提供します (もちろん、検索に加えて、 file を使用して他のことを行うこともできます)。
file(GLOB/GLOB_RECURSE 变量名 要搜索的文件路径和文件类型)
-
GLOB : 指定したディレクトリ内で検索した条件を満たすすべてのファイル名のリストを生成し、変数に格納します。
-
GLOB_RECURSE : 指定したディレクトリを再帰的に検索し、検索された条件を満たすファイル名のリストを生成し、変数に格納します。
カレントディレクトリのsrcディレクトリ内のすべてのソースファイルを検索し、変数に格納します。
file(GLOB MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
file(GLOB MAIN_HEAD ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h)
CMAKE_CURRENT_SOURCE_DIR マクロは、現在アクセスされている CMakeLists.txt ファイルが配置されているパスを示します。
検索するファイル パスとタイプには二重引用符を追加するかどうかを指定できます。
// 测试
# 指定使用的 cmake 的最低版本,可选,非必须,如果不加可能会有警告。
cmake_minimum_required(VERSION 2.8.12.2)
# 定义工程名称,并可指定工程的版本、工程描述、web主页地址、支持的语言(默认情况支持所有语言),如果不需要这些都是可以忽略的,只需要指定出工程名字即可。
project(test)
# 设置源文件为变量值SRC需要被执行调用
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
# 设置编译标准
set(CMAKE_CXX_STANDARD 98)
# 设置编译输出路径
set(EXECUTABLE_OUTPUT_PATH /home/shaxiang/data_structure_algorithm/build/A/B/C)
# 定义工程会生成一个可执行程序。
add_executable(app ${SRC})
2.5 ヘッダー ファイルをインクルードする
プロジェクトのソース ファイルをコンパイルする場合、コンパイラがコンパイル プロセス中にこれらのヘッダー ファイルを見つけてコンパイルを正常に通過できるようにするために、ソース ファイルに対応するヘッダー ファイルのパスを指定することが必要になることがよくあります。CMake に含めるディレクトリの設定も非常に簡単で、 include_directoriesという 1 つのコマンドで実行できます。
include_directories(headpath)
たとえば、ソース ファイルがいくつかあり、それらのディレクトリ構造は次のとおりです。
[shaxiang@VM-8-14-centos data_structure_algorithm]$ tree
.
|-- build
|-- CMakeLists.txt
|-- include
| `-- head.h
`-- src
|-- add.cpp
|-- div.cpp
|-- main.cpp
|-- mul.cpp
`-- sub.cpp
CMakeLists.txt ファイルの内容は次のとおりです。
# 指定使用的 cmake 的最低版本,可选,非必须,如果不加可能会有警告。
cmake_minimum_required(VERSION 2.8.12.2)
# 定义工程名称,并可指定工程的版本、工程描述、web主页地址、支持的语言(默认情况支持所有语言),如果不需要这些都是可以忽略的,只需要指定出工程名字即可。
project(test)
# 设置头文件编译路径
include_directories(${PROJECT_SOURCE_DIR}/include)
# 设置源文件编译路径
# set(SRC main.cpp add.cpp sub.cpp div.cpp mul.cpp)
# 方法一:路径宏:PROJECT_BINARY_DIR 代表cmake..
# aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC)
# 方法二:
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
# 设置编译标准
set(CMAKE_CXX_STANDARD 98)
# 设置编译输出路径
set(EXECUTABLE_OUTPUT_PATH /home/shaxiang/data_structure_algorithm/build/A/B/C)
# 定义工程会生成一个可执行程序。
add_executable(app ${SRC})
このうち、6 行目はヘッダー ファイルへのパスを指定しており、PROJECT_SOURCE_DIRマクロに対応する値はcmake コマンドを使用するときに続くディレクトリ (通常はプロジェクトのルート ディレクトリ) です。
2.6 動的ライブラリまたは静的ライブラリの作成
作成したソース コードを実行可能プログラムにコンパイルする必要がない場合もありますが、一部の静的ライブラリまたは動的ライブラリはサードパーティが使用できるように生成されます。以下では、cmake でこれら 2 種類のライブラリ ファイルを生成する方法について説明します。
説明: Linux の場合は静的ライブラリ [libxxx.so]、Windows の場合は [libxxx.dll]、Linux の場合は動的ライブラリ [libxxx.lib]、Windows の場合は [libxxx.a]
// 准备生成东静态库的文件
[shaxiang@VM-8-14-centos v2]$ tree
.
|-- build
|-- CMakeLists.txt
|-- include
| `-- head.h
`-- src
|-- add.cpp
|-- div.cpp
|-- mul.cpp
`-- sub.cpp
3 directories, 6 files
2.6.1 静的ライブラリの作成
cmake で静的ライブラリを作成する場合、使用する必要があるコマンドは次のとおりです。
add_library(库名称 STATIC 源文件1 [源文件2] ...)
Linux では、静的ライブラリ名はlib +ライブラリ名+ .aの 3 つの部分に分かれています。ここでは、ライブラリの名前を指定するだけで済みます。他の 2 つの部分は、ファイルの生成時に自動的に入力されます。
上記のディレクトリ構造に従って、CMakeLists.txtファイルは次のように記述できます。
# 指定使用的 cmake 的最低版本,可选,非必须,如果不加可能会有警告。
cmake_minimum_required(VERSION 2.8.12.2)
# 定义工程名称,并可指定工程的版本、工程描述、web主页地址、支持的语言(默认情况支持所有语言),如果不需要这些都是可以忽略的,只需要指定出工程名字即可。
project(test)
# 设置头文件编译路径
include_directories(${PROJECT_SOURCE_DIR}/include)
# 设置源文件编译路径
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
# 设置编译标准
set(CMAKE_CXX_STANDARD 98)
# 编译静态库
add_library(cal STATIC ${SRC})
これにより、最終的に、対応する静的ライブラリ ファイルlibcal.aが生成されます。
2.6.2 静的ライブラリの作成
cmake でダイナミック ライブラリを作成する場合、使用する必要があるコマンドは次のとおりです。
add_library(库名称 SHARED 源文件1 [源文件2] ...)
Linux では、ダイナミック ライブラリ名はlib +ライブラリ名+ .soの 3 つの部分に分かれています。ここでは、ライブラリの名前を指定するだけで済みます。他の 2 つの部分は、ファイルの生成時に自動的に入力されます。
上記のディレクトリ構造に従って、CMakeLists.txtファイルは次のように記述できます。
# 指定使用的 cmake 的最低版本,可选,非必须,如果不加可能会有警告。
cmake_minimum_required(VERSION 2.8.12.2)
# 定义工程名称,并可指定工程的版本、工程描述、web主页地址、支持的语言(默认情况支持所有语言),如果不需要这些都是可以忽略的,只需要指定出工程名字即可。
project(test)
# 设置头文件编译路径
include_directories(${PROJECT_SOURCE_DIR}/include)
# 设置源文件编译路径
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
# 设置编译标准
set(CMAKE_CXX_STANDARD 98)
# 编译静态库
add_library(cal SHARED ${SRC})
これにより、最終的に、対応するダイナミック ライブラリ ファイルlibcal.soが生成されます。
2.6.3 出力パスの指定
2.6.3.1 動的ライブラリに適用可能
生成されたライブラリファイルは、実行可能プログラムと同様に出力パスを指定できます。Linux で生成されるダイナミック ライブラリにはデフォルトで実行権限があるため、実行可能プログラムを生成する場合と同じ方法で生成するディレクトリを指定できます。
# 指定使用的 cmake 的最低版本,可选,非必须,如果不加可能会有警告。
cmake_minimum_required(VERSION 2.8.12.2)
# 定义工程名称,并可指定工程的版本、工程描述、web主页地址、支持的语言(默认情况支持所有语言),如果不需要这些都是可以忽略的,只需要指定出工程名字即可。
project(test)
# 设置头文件编译路径
include_directories(${PROJECT_SOURCE_DIR}/include)
# 设置源文件编译路径
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
# 设置编译标准
set(CMAKE_CXX_STANDARD 98)
# 设置生成东静态库的文件路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
add_library(cal SHARED ${SRC_LIST})
この方法では、実際にsetコマンドでEXECUTABLE_OUTPUT_PATHマクロへのパスを設定しますが、このパスが実行可能ファイルが生成されるパスになります。
2.6.3.2 動的ライブラリと静的ライブラリに適用可能
Linux で生成された静的ライブラリには、デフォルトでは実行権限がないため、静的ライブラリを生成するパスを指定するときにEXECUTABLE_OUTPUT_PATHマクロを使用できません。代わりに、 LIBRARY_OUTPUT_PATHを使用する必要があります。このマクロは、静的ライブラリ ファイルと動的ライブラリ ファイルの両方に適用できます。
# 指定使用的 cmake 的最低版本,可选,非必须,如果不加可能会有警告。
cmake_minimum_required(VERSION 2.8.12.2)
# 定义工程名称,并可指定工程的版本、工程描述、web主页地址、支持的语言(默认情况支持所有语言),如果不需要这些都是可以忽略的,只需要指定出工程名字即可。
project(test)
# 设置头文件编译路径
include_directories(${PROJECT_SOURCE_DIR}/include)
# 设置源文件编译路径
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
# 设置编译标准
set(CMAKE_CXX_STANDARD 98)
# 设置生成东静态库的文件路径
set(LIBRARY_OUTPUT_PATH /home/shaxiang/data_structure_algorithm/v2/lib)
# 编译静态库
# add_library(cal SHARED ${SRC})
# add_library(cal STATIC ${SRC})
2.7 ライブラリファイルをインクルードする
プログラムを作成するプロセスでは、システムによって提供されるいくつかの動的ライブラリ、または自分で作成した動的ライブラリまたは静的ライブラリ ファイルを使用できます。また、cmake は動的ライブラリをロードするための関連コマンドも提供します。
2.7.1 リンク静的ライブラリ
テストのディレクトリ構造は次のとおりです。
[shaxiang@VM-8-14-centos v3]$ tree
.
|-- build
|-- CMakeLists.txt
|-- include
| `-- head.h
|-- lib
| |-- libcal.a // 静态库
| `-- libcal.so // 动态库
`-- src
`-- main.cpp
4 directories, 5 files
cmake で静的ライブラリをリンクするコマンドは次のとおりです。
link_libraries(<static lib> [<static lib>...])
-
パラメータ 1: リンクする静的ライブラリの名前を指定します。フルネームlibxxx.aにすることも、先頭(lib)をつまんで末尾(.a)を削除した後の名前xxxにすることもできます。
-
パラメータ 2: リンクされる他の静的ライブラリの名前。
静的ライブラリがシステムによって提供されていない場合 (自分で作成するか、サードパーティが提供する静的ライブラリを使用する)、静的ライブラリが見つからない可能性があります。この場合、静的ライブラリのパスを指定することもできます。
link_directories(<lib path>)
このようにして、変更されたCMakeLists.txtファイルの内容は次のようになります。
# 指定使用的 cmake 的最低版本,可选,非必须,如果不加可能会有警告。
cmake_minimum_required(VERSION 2.8.12.2)
# 定义工程名称,并可指定工程的版本、工程描述、web主页地址、支持的语言(默认情况支持所有语言),如果不需要这些都是可以忽略的,只需要指定出工程名字即可。
project(test)
# 设置头文件编译路径
include_directories(${PROJECT_SOURCE_DIR}/include)
# 设置源文件编译路径
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
# 设置编译标准
set(CMAKE_CXX_STANDARD 11)
# 设置包含静态库路径
link_directories(${PROJECT_SOURCE_DIR}/lib)
# 连接静态库
link_libraries(cal)
# 生成可执行程序
add_executable(app ${SRC})
コードの 8 行目を追加すると、パラメーターで指定されたパスに従って静的ライブラリを見つけることができます。
2.7.2 リンクダイナミックライブラリ
テストのディレクトリ構造は次のとおりです。
[shaxiang@VM-8-14-centos v3]$ tree
.
|-- build
|-- CMakeLists.txt
|-- include
| `-- head.h
|-- lib
| |-- libcal.a // 静态库
| `-- libcal.so // 动态库
`-- src
`-- main.cpp
4 directories, 5 files
cmake でダイナミック ライブラリをリンクするコマンドは次のとおりです。
target_link_libraries(
<target>
<PRIVATE|PUBLIC|INTERFACE> <item>...
[<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
-
target : ダイナミック ライブラリをロードするファイルの名前を指定します。
-
ファイルはソース ファイルである可能性があります
-
このファイルはダイナミック ライブラリ ファイルである可能性があります
-
ファイルは実行可能ファイルである可能性があります
-
-
PRIVATE|PUBLIC|INTERFACE : 動的ライブラリのアクセス権限。デフォルトはPUBLICです。
-
さまざまな動的ライブラリ間に依存関係がない場合は、設定を行う必要はありません。これら 3 つに違いはありません。通常、指定する必要はなく、デフォルトの PUBLIC を使用します。
-
ダイナミック ライブラリのリンクは推移的です。ダイナミック ライブラリ A がダイナミック ライブラリ B および C にリンクし、ダイナミック ライブラリ D がダイナミック ライブラリ A にリンクする場合、ダイナミック ライブラリ D はダイナミック ライブラリ B および C にリンクすることと同等であり、ダイナミック ライブラリを使用できます。ライブラリ。B および C で定義されたメソッド。
-
target_link_libraries(A B C) target_link_libraries(D A)
-
PUBLIC : public の背後にあるライブラリは前のターゲットにリンクされ、内部のシンボルもエクスポートされてサードパーティに提供されます。PRIVATE : private の背後にあるライブラリは前のターゲットにリンクされるだけで終了します。サードパーティはどのライブラリを調整したかを検出できません。 INTERFACE : インターフェイスの後に導入されたライブラリは前のターゲットにリンクされず、エクスポートされるだけです。シンボル。
-
2.7.2.1 リンクシステムダイナミックライブラリ
動的ライブラリのリンクは、静的ライブラリのリンクとはまったく異なります。
-
静的ライブラリは、実行可能プログラムを生成するリンク段階で実行可能プログラムにパッケージ化されるため、実行可能プログラムが開始されると、静的ライブラリはメモリにロードされます。
-
動的ライブラリは、実行可能プログラム生成のリンク段階では実行可能プログラムにパッケージ化されません。実行可能プログラムが開始され、動的ライブラリ内の関数が呼び出されるまで、動的ライブラリはメモリにロードされません。
したがって、cmakeでリンクするダイナミック ライブラリを指定する場合は、実行可能ファイルが生成された後にコマンドを記述する必要があります。
cmake_minimum_required(VERSION 3.0)
project(TEST)
file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
# 添加并指定最终生成的可执行程序名
add_executable(app ${SRC_LIST})
# 指定可执行程序要链接的动态库名字
target_link_libraries(app pthread)
target_link_libraries(app pthread)内:
-
app : 最終的に生成された実行可能プログラムの名前に対応します。
-
pthread : 実行可能プログラムによってロードされる動的ライブラリです。このライブラリはシステムによって提供されるスレッド ライブラリです。完全名は libpthread.so です。指定される場合、通常、先頭(lib) と末尾 (.so) はつままれた。
2.7.2.2 サードパーティの動的ライブラリのリンク
テストファイルmain.cpp が自作ダイナミックライブラリlibcalc.soとシステム提供のスレッドライブラリの両方を使用する 場合、 CMakeLists.txtファイルは次のように記述できます。
cmake_minimum_required(VERSION 3.0)
project(TEST)
file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
include_directories(${PROJECT_SOURCE_DIR}/include)
add_executable(app ${SRC_LIST})
target_link_libraries(app pthread calc)
6 行目のpthread と calc は、実行可能プログラムappがリンクする動的ライブラリの名前です。実行可能プログラムアプリが生成され、ファイルが実行されると、次のエラー メッセージが表示されます。
$ ./app
./app: error while loading shared libraries: libcalc.so: cannot open shared object file: No such file or directory
これは、実行可能プログラムの起動後にダイナミック ライブラリcalcがロードされますが、ダイナミック ライブラリがどこに配置されているかが不明であるためです。リンクするダイナミック ライブラリの場所はコマンドで指定されます。このコマンドは、次の目的にも使用されます。静的ライブラリの場所を指定します。
link_directories(path)
したがって、変更されたCMakeLists.txtファイルは次のようになります。
cmake_minimum_required(VERSION 3.0)
project(TEST)
file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
# 指定源文件或者动态库对应的头文件路径
include_directories(${PROJECT_SOURCE_DIR}/include)
# 指定要链接的动态库的路径
link_directories(${PROJECT_SOURCE_DIR}/lib)
# 添加并生成一个可执行程序
add_executable(app ${SRC_LIST})
# 指定要链接的动态库
target_link_libraries(app pthread calc)
link_directories でダイナミック ライブラリのパスを指定した後、生成された実行可能プログラムを実行するときに、ダイナミック ライブラリが見つからないという問題は発生しません。
注意: 動的ライブラリまたは静的ライブラリ ファイルにリンクするには、target_link_libraries コマンドを使用します。
2.8 ログ
CMake では、ユーザーを使用してメッセージを表示できます。コマンドの名前はmessageです。
message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR] "message to display" ...)
-
(なし) : 重要なお知らせ
-
STATUS : 重要ではないメッセージ
-
警告: CMake 警告、実行は続行されます
-
AUTHOR_WARNING : CMake 警告 (開発)、実行は続行されます
-
SEND_ERROR : CMake エラー。実行は続行しますが、生成ステップはスキップします
-
FATAL_ERROR : CMake エラー、すべての処理を終了します
CMake のコマンド ライン ツールは、 STATUSメッセージを stdout に表示し、他のすべてのメッセージを stderr に表示します。CMake の GUI は、ログ領域にすべてのメッセージを表示します。
CMake の警告メッセージとエラー メッセージのテキストは、単純なマークアップ言語を使用して表示されます。テキストはインデントされず、長さを超える行は折り返され、段落間の区切り文字として新しい行が使用されます。
# 输出一般日志信息
message(STATUS "source path: ${PROJECT_SOURCE_DIR}")
# 输出警告信息
message(WARNING "source path: ${PROJECT_SOURCE_DIR}")
# 输出错误信息
message(FATAL_ERROR "source path: ${PROJECT_SOURCE_DIR}")
2.9 変数の操作
2.9.1 セットスプライシングを使用する
プロジェクト内のソース ファイルが必ずしも同じディレクトリにあるとは限りませんが、これらのソース ファイルは最終的に一緒にコンパイルして、最終的な実行可能ファイルまたはライブラリ ファイルを生成する必要があります。fileコマンドを使用して各ディレクトリ内のソース ファイルを検索する場合、最後に文字列の結合操作を実行する必要がありますが、文字列の結合には setコマンドまたはlistコマンドを使用できます。
文字列のスプライシングに set を使用する場合、対応するコマンド形式は次のとおりです。
set(变量名1 ${变量名1} ${变量名2} ...)
上記のコマンドは、実際には第 2 パラメータからすべての文字列を連結し、最終的にその結果を第 1 パラメータに格納しますが、第 1 パラメータに元のデータがある場合、元のデータは上書きされます。
# 指定使用的 cmake 的最低版本,可选,非必须,如果不加可能会有警告。
cmake_minimum_required(VERSION 2.8.12.2)
# 定义工程名称,并可指定工程的版本、工程描述、web主页地址、支持的语言(默认情况支持所有语言),如果不需要这些都是可以忽略的,只需要指定出工程名字即可。
project(test)
# 设置头文件编译路径
include_directories(${PROJECT_SOURCE_DIR}/include)
# 设置源文件编译路径
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
# 设置编译标准
set(CMAKE_CXX_STANDARD 11)
# 设置包含静态库路径
link_directories(${PROJECT_SOURCE_DIR}/lib)
# 连接静态库
link_libraries(cal)
# 拼接字符串练习
set(sTemp Hello_World)
set(strTemp ${sTemp} ${SRC})
message(${sTemp}) # 打印结果:Hello_World
message(${strTemp}) # 打印结果:Hello_World/home/shaxiang/test_cmake/v4/src/main.cpp
# 生成可执行程序
add_executable(app ${SRC})
2.9.2 リストのスプライシングを使用する
文字列の結合に list を使用する場合、対応するコマンド形式は次のとおりです。
list(APPEND <list> [<element> ...])
listコマンドの機能はsetよりも強力です。文字列の結合はその機能の 1 つにすぎません。そのため、最初のパラメータの位置で実行したい操作を指定する必要があります。APPEND はデータを追加することを意味し、次のパラメータはセット
# 指定使用的 cmake 的最低版本,可选,非必须,如果不加可能会有警告。
cmake_minimum_required(VERSION 2.8.12.2)
# 定义工程名称,并可指定工程的版本、工程描述、web主页地址、支持的语言(默认情况支持所有语言),如果不需要这些都是可以忽略的,只需要指定出工程名字即可。
project(test)
# 设置头文件编译路径
include_directories(${PROJECT_SOURCE_DIR}/include)
# 设置源文件编译路径
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
# 设置编译标准
set(CMAKE_CXX_STANDARD 11)
# 设置包含静态库路径
link_directories(${PROJECT_SOURCE_DIR}/lib)
# 连接静态库
link_libraries(cal)
# 拼接字符串练习
set(sTemp Hello_World )
set(strTemp ${sTemp} ${SRC})
message(${sTemp}) # 打印结果:Hello_World
message(${strTemp}) # 打印结果:Hello_World/home/shaxiang/test_cmake/v4/src/main.cpp
list(APPEND sTemp "XXX" "AAA" "QQQ")
message(${sTemp}) # 打印结果:Hello_WorldXXXAAAQQQ
# 生成可执行程序
add_executable(app ${SRC})
CMake で、setコマンドを使用してlistを作成します。リスト内には、セミコロンで区切られた一連の文字列が含まれます。たとえば、set(var abcde)コマンドはlist:a;b;c;d;eを作成しますが、変数値が出力されるときはabcdeが取得されます。
2.9.3 文字列の削除
file を通じてディレクトリを検索すると、ディレクトリ内のすべてのソース ファイルが取得されますが、次のようなソース ファイルの一部は必要なものではありません。
$ tree
.
├── add.cpp
├── div.cpp
├── main.cpp
├── mult.cpp
└── sub.cpp
0 directories, 5 files
現在のディレクトリには 5 つのソース ファイルがあり、そのうちのmain.cppはテスト ファイルです。他の人が使用できるように電卓関連のソース ファイルからダイナミック ライブラリを生成する場合、必要なソース ファイルはadd.cpp、div.cp、mult.cpp、および sub.cpp の4 つだけです。このとき、検索データからmain.cpp を削除する必要がありますが、この機能を実現したい場合はlistを使用することもできます。
list(REMOVE_ITEM <list> <value> [<value> ...])
上記のコマンド プロトタイプから、最初のパラメーターがREMOVE_ITEM になることを除いて、データの削除と追加は似ていることがわかります。
# 指定使用的 cmake 的最低版本,可选,非必须,如果不加可能会有警告。
cmake_minimum_required(VERSION 2.8.12.2)
# 定义工程名称,并可指定工程的版本、工程描述、web主页地址、支持的语言(默认情况支持所有语言),如果不需要这些都是可以忽略的,只需要指定出工程名字即可。
project(test)
# 设置编译标准
set(CMAKE_CXX_STANDARD 98)
# 设置头文件编译路径
include_directories(${PROJECT_SOURCE_DIR}/include)
# 设置源文件编译路径
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
# 字符串移除练习
# 打印未移除前的字符串
message("删除前:"${SRC})
list(REMOVE_ITEM SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp)
message("删除后:"${SRC})
# 打印结果:
# 删除前:/home/shaxiang/test_cmake/v5/src/main.cpp/home/shaxiang/test_cmake/v5/src/mul.cpp/home/shaxiang/test_cmake/v5/src/sub.cpp/home/shaxiang/test_cmake/v5/src/add.cpp/home/shaxiang/test_cmake/v5/src/div.cpp
# 删除后:/home/shaxiang/test_cmake/v5/src/mul.cpp/home/shaxiang/test_cmake/v5/src/sub.cpp/home/shaxiang/test_cmake/v5/src/add.cpp/home/shaxiang/test_cmake/v5/src/div.cpp
# 定义工程会生成一个可执行程序。
add_executable(app ${SRC})
ご覧のとおり、8 行目のリストに削除するファイルの名前を割り当てるだけです。ただし、file コマンドを使用してソース ファイルを検索すると、ファイルの絶対パスが取得されることに注意してください (リスト内の各ファイルに対応するパスは項目であり、それらはすべて絶対パスです)。削除するときに削除します。 ファイルの絶対パスを指定する必要があります。指定しない場合、削除操作は成功しません。
listコマンドには他にも機能がありますが、一般的に使用されるものではないため、ここでは 1 つずつ例を示します。
-
リストの長さを取得します。
list(LENGTH <list> <output variable>)
-
LENGTH : サブコマンド LENGTH は、リストの長さを読み取るために使用されます。
-
list : 現在の操作のリスト。
-
出力変数: リストの長さを格納するために使用される新しく作成された変数。
-
リスト内の指定したインデックスにある要素を読み取ります。インデックスは複数指定できます。
list(GET <list> <element index> [<element index> ...] <output variable>)
-
list : 現在の操作のリスト。
-
element Index : リスト要素のインデックス。
-
番号付けは 0 から始まり、インデックス 0 の要素がリストの最初の要素になります。
-
インデックスは負の値にすることもできます。-1 はリストの最後の要素を表し、-2 はリストの最後から 2 番目の要素を表します。
-
インデックス (正または負に関係なく) がリストの長さを超えると、エラーが報告されます。
-
-
出力変数: 指定されたインデックス要素の戻り結果を格納する、新しく作成された変数であり、リストでもあります。
-
コネクタ (文字列) を使用してリスト内の要素を連結し、文字列を形成します
list (JOIN <list> <glue> <output variable>)
-
list : 現在の操作のリスト。
-
グルー: 指定されたコネクタ (文字列)。
-
出力変数: 返された文字列を格納する新しく作成された変数
-
指定された要素がリスト内に存在するかどうかを調べます。見つからない場合は、-1 を返します。
list(FIND <list> <value> <output variable>)
-
list: 現在の操作のリスト。
-
value: リスト内で検索される要素。
-
出力変数: 新しく作成された変数。
-
<value> がリスト<list>に存在する場合、リスト内の<value>のインデックスを返します。
-
見つからない場合は -1 を返します。
-
-
リストに要素を追加する
list (APPEND <list> [<element> ...])
-
リストのインデックス 0 に要素を挿入します。
list(INSERT <list> <element_index> <element> [<element> ...])
-
リストのインデックス 0 に要素を挿入します。
list (PREPEND <list> [<element> ...])
-
リストから最後の要素を削除します
list (POP_BACK <list> [<out-var>...])
-
リストから最初の要素を削除します
list (POP_FRONT <list> [<out-var>...])
-
指定された要素をリストから削除します
list (REMOVE_ITEM <list> <value> [<value> ...])
-
指定されたインデックスにある要素をリストから削除します
list (REMOVE_AT <list> <index> [<index> ...])
-
重複した要素をリストから削除する
list (REMOVE_DUPLICATES <list>)
-
リストの反転
list(REVERSE <list>)
-
リストの並べ替え
list (SORT <list> [COMPARE <compare>] [CASE <case>] [ORDER <order>])
-
COMPARE : ソート方法を指定します。次の値が利用可能です。
-
STRING : アルファベット順に並べ替えます。これがデフォルトの並べ替え方法です。
-
FILE_BASENAME : 一連のパス名の場合、basename がソートに使用されます。
-
NATURAL : 自然数順にソートします。
-
-
CASE : 大文字と小文字を区別するかどうかを示します。次の値が利用可能です。
-
SENSITIVE : 大文字と小文字を区別して並べ替えます (デフォルト値)。
-
INSENSITIVE : 大文字と小文字を区別しない方法で並べ替えます。
-
-
ORDER : ソート順を指定します。次の値が利用可能です。
-
ASCENDING : 昇順で並べ替えます (デフォルト値)。DESCENDING : 降順に並べ替えます。
-
2.10 マクロ定義
プログラムをテストするときは、以下に示すように、コードにいくつかのマクロ定義を追加し、これらのマクロを使用してコードが有効になるかどうかを制御できます。
#include "head.h"
#define NUM 10
int main()
{
int a = 10;
int b = 2;
for(int i = 0; i < NUM; i++)
{
cout << a << "+" << b << "=" << Add(a, b) << endl;
cout << a << "-" << b << "=" << Sub(a, b) << endl;
cout << a << "*" << b << "=" << Mul(a, b) << endl;
cout << a << "/" << b << "=" << Div(a, b) << endl;
}
#ifdef DEBUG
cout << "我是一个程序源哦!" << endl;
#endif
return 0;
}
DEBUGマクロの判定はプログラムの7行目で行いますマクロが定義されている場合は8行目でログ出力されます マクロが定義されていない場合は8行目はコメントアウトに相当するため出力できませんログ出力を参照してください (このマクロは上記のコードでは定義されていません)。
テストをより柔軟にするために、このマクロをコード内で定義するのではなく、テスト中に定義することができます。1 つの方法は、次のようにgcc/g++コマンドで指定することです。
$ gcc test.c -DDEBUG -o app
gcc/g++コマンドのパラメーター-Dを使用して、定義するマクロの名前を指定します。これは、コード内でDEBUGという名前のマクロを定義するのと同じです。
CMakeでも同様のことを行うことができ、対応するコマンドはadd_settingsと呼ばれます。
add_definitions(-D宏名称)
上記のソース ファイルのCMakeLists.txt を次の内容で作成します。
# 指定使用的 cmake 的最低版本,可选,非必须,如果不加可能会有警告。
cmake_minimum_required(VERSION 2.8.12.2)
# 定义工程名称,并可指定工程的版本、工程描述、web主页地址、支持的语言(默认情况支持所有语言),如果不需要这些都是可以忽略的,只需要指定出工程名字即可。
project(test)
# 设置编译标准
set(CMAKE_CXX_STANDARD 98)
# 设置头文件编译路径
include_directories(${PROJECT_SOURCE_DIR}/include)
# 设置源文件编译路径
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
# 自定义的宏
add_definitions(-DDEBUG)
# 定义工程会生成一个可执行程序。
add_executable(app ${SRC})
2.11 定義済みマクロ
次のリストは、CMake で一般的に使用されるいくつかのマクロをまとめたものです。
大きい | 関数 |
---|---|
PROJECT_SOURCE_DIR | cmake コマンドの直後のディレクトリは、通常、プロジェクトのルート ディレクトリです。 |
PROJECT_BINARY_DIR | cmakeコマンドが実行されるディレクトリ |
CMAKE_CURRENT_SOURCE_DIR | 現在処理されている CMakeLists.txt が配置されているパス |
CMAKE_CURRENT_BINARY_DIR | ターゲットコンパイルディレクトリ |
EXECUTABLE_OUTPUT_PATH | ターゲットのバイナリ実行可能ファイルの場所を再定義します |
ライブラリ_出力_パス | ターゲットリンクライブラリファイルの格納場所を再定義する |
PROJECT_NAME | PROJECT ディレクティブを通じて定義されたプロジェクト名を返します。 |
CMAKE_BINARY_DIR | プロジェクトの実際のビルド パス。ビルドがビルド ディレクトリで実行されると仮定すると、取得されるパスはこのディレクトリのパスになります。 |
2.12 入れ子になった CMake
プロジェクトが大きい場合、またはプロジェクト内に多くのソース コード ディレクトリがある場合、CMakeを通じてプロジェクトを管理するときにCMakeLists.txt を1 つだけ使用すると、このファイルは比較的複雑になります。ソース コードCMakeLists.txtファイルを各ディレクトリに追加します (ヘッダー ファイル ディレクトリには必要ありません)。これにより、各ファイルが複雑になりすぎず、より柔軟で保守が容易になります。
まず、以下のディレクトリ構造を見てみましょう。
[shaxiang@VM-8-14-centos v6]$ tree
.
|-- bin
|-- calFunc
| |-- add.cpp
| |-- CMakeLists.txt
| |-- div.cpp
| |-- mul.cpp
| `-- sub.cpp
|-- CMakeLists.txt
|-- include
| `-- head.h
|-- lib
|-- sortFunc
| |-- bubbleSort.cpp
| `-- CMakeLists.txt
|-- test1
| |-- CMakeLists.txt
| `-- sort.cpp
`-- test2
|-- cal.cpp
`-- CMakeLists.txt
7 directories, 13 files
2.12.1 ノード関係
ご存知のとおり、Linux ディレクトリはツリー構造であるため、入れ子になった CMake もツリー構造であり、最上位のCMakeLists.txtがルート ノードであり、その後に子ノードが続きます。したがって、CMakeLists.txt ファイルの変数スコープに関するいくつかの情報を知っておく必要があります。
-
ルート ノードCMakeLists.txtの変数はグローバルに有効です。
-
親ノードCMakeLists.txtの変数は、子ノードで使用できます。
-
サブノードCMakeLists.txtの変数は、現在のノードでのみ使用できます。
2.12.2 サブディレクトリの追加
次に、親ノードと子ノード間の関係が CMake でどのように確立されるかを知る必要があります。ここでは、CMake コマンドを使用する必要があります。
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
-
source_dir : CMakeLists.txt ソース ファイルとコード ファイルの場所を指定します。これは、実際にはサブディレクトリを指定することを意味します。
-
binary_dir : 出力ファイルのパスを指定します。通常は指定する必要はなく、無視しても問題ありません。
-
EXCLUDE_FROM_ALL : サブパス内のターゲットは、デフォルトでは親パスの ALL ターゲットに含まれず、IDE プロジェクト ファイルからも除外されます。ユーザーはサブパスの下にターゲットを明示的に構築する必要があります。
このようにして、CMakeLists.txt ファイル間の親子関係が構築されます。
2.12.3 ルートディレクトリの CMakeLists.txt
# 指定CMake版本的最低版本
cmake_minimum_required(VERSION 2.8.12.2)
# 指定项目名称
project(TestDeme)
# 指定头文件路径
set(HEADPATH ${PROJECT_SOURCE_DIR}/include)
# 指定静态库生成的路径
set(LIBPATH ${PROJECT_SOURCE_DIR}/lib)
# 指定可执行生成的路径
set(EXEPATH ${PROJECT_SOURCE_DIR}/bin)
# 指定库文件名称
set(CALCLIB calc)
set(SORTLIB sort)
# 指定可执行程序名称
set(APPNAME1 app1)
set(APPNAME2 app2)
# 给当前节点添加子目录
add_subdirectory(calFunc)
add_subdirectory(sortFunc)
add_subdirectory(test1)
add_subdirectory(test2)
2.12.4 calFunc ディレクトリ内の CMakeLists.txt
# 指定CMake版本的最低版本
cmake_minimum_required(VERSION 2.8.12.2)
# 指定项目名称
project(Calc)
# 指定头文件目录
include_directories(${HEADPATH})
# 搜索源文件
aux_source_directory(./ SRC)
# 指定静态库生成路径
set(LIBRARY_OUTPUT_PATH ${LIBPATH})
# 生成静态库
add_library(${CALCLIB} STATIC ${SRC})
2.12.5 sotrFunc ディレクトリ内の CMakeLists.txt
# 指定CMake版本的最低版本
cmake_minimum_required(VERSION 2.8.12.2)
# 指定项目名称
project(Sort)
# 指定头文件目录
include_directories(${HEADPATH})
# 搜索源文件
aux_source_directory(./ SRC)
# 指定静态库生成路径
set(LIBRARY_OUTPUT_PATH ${LIBPATH})
# 生成静态库
add_library(${SORTLIB} STATIC ${SRC})
2.12.6 test1 ディレクトリ内の CMakeLists.txt
# 指定CMake版本的最低版本
cmake_minimum_required(VERSION 2.8.12.2)
# 指定项目名称
project(Test1)
# 指定头文件路径
include_directories(${HEADPATH})
# 搜索源文件
aux_source_directory(./ SRC)
# 指定连接静态库的路径
link_directories(${LIBPATH})
# 连接静态库
link_libraries(${SORTLIB})
# 设置生成可执行文件的路径
set(EXECUTABLE_OUTPUT_PATH ${EXEPATH})
# 生成可执行文件
add_executable(${APPNAME1} ${SRC})
2.12.7 test2 ディレクトリ内の CMakeLists.txt
# 指定CMake版本的最低版本
cmake_minimum_required(VERSION 2.8.12.2)
# 指定项目名称
project(Test2)
# 指定头文件路径
include_directories(${HEADPATH})
# 搜索源文件
aux_source_directory(./ SRC)
# 指定连接静态库的路径
link_directories(${LIBPATH})
# 连接静态库
link_libraries(${CALCLIB})
# 设置生成可执行文件的路径
set(EXECUTABLE_OUTPUT_PATH ${EXEPATH})
# 生成可执行文件
add_executable(${APPNAME2} ${SRC})
2.12.8 プロジェクトをビルドする
[shaxiang@VM-8-14-centos v6]$ cd build/
[shaxiang@VM-8-14-centos build]$ cmake ..
-- The C compiler identification is GNU 7.3.1
-- The CXX compiler identification is GNU 7.3.1
-- Check for working C compiler: /opt/rh/devtoolset-7/root/usr/bin/cc
-- Check for working C compiler: /opt/rh/devtoolset-7/root/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /opt/rh/devtoolset-7/root/usr/bin/c++
-- Check for working CXX compiler: /opt/rh/devtoolset-7/root/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/shaxiang/test_cmake/v6/build
[shaxiang@VM-8-14-centos build]$ make
Scanning dependencies of target calc
[ 14%] Building CXX object calFunc/CMakeFiles/calc.dir/mul.cpp.o
[ 28%] Building CXX object calFunc/CMakeFiles/calc.dir/sub.cpp.o
[ 42%] Building CXX object calFunc/CMakeFiles/calc.dir/add.cpp.o
[ 57%] Building CXX object calFunc/CMakeFiles/calc.dir/div.cpp.o
Linking CXX static library ../../lib/libcalc.a
[ 57%] Built target calc
Scanning dependencies of target sort
[ 71%] Building CXX object sortFunc/CMakeFiles/sort.dir/bubbleSort.cpp.o
Linking CXX static library ../../lib/libsort.a
[ 71%] Built target sort
Scanning dependencies of target app1
[ 85%] Building CXX object test1/CMakeFiles/app1.dir/sort.cpp.o
Linking CXX executable ../../bin/app1
[ 85%] Built target app1
Scanning dependencies of target app2
[100%] Building CXX object test2/CMakeFiles/app2.dir/cal.cpp.o
Linking CXX executable ../../bin/app2
[100%] Built target app2
[shaxiang@VM-8-14-centos v6]$ tree -L 2
.
|-- bin
| |-- app1
| `-- app2
|-- build
| |-- calFunc
| |-- CMakeCache.txt
| |-- CMakeFiles
| |-- cmake_install.cmake
| |-- Makefile
| |-- sortFunc
| |-- test1
| `-- test2
|-- calFunc
| |-- add.cpp
| |-- CMakeLists.txt
| |-- div.cpp
| |-- mul.cpp
| `-- sub.cpp
|-- CMakeLists.txt
|-- include
| `-- head.h
|-- lib
| |-- libcalc.a
| `-- libsort.a
|-- sortFunc
| |-- bubbleSort.cpp
| `-- CMakeLists.txt
|-- test1
| |-- CMakeLists.txt
| `-- sort.cpp
`-- test2
|-- cal.cpp
`-- CMakeLists.txt
13 directories, 20 files