CMake构建项目的方式
直接写入源码路径
add_executable
中直接写入相对路径- 在源码中引入头文件时需要写相对路径
直接测试
现在有以下目录结构及代码环境
shell
$ tree
.
├── CMakeLists.txt
├── animal
│ ├── dog.cpp
│ └── dog.h
└── main.cpp
2 directories, 4 files
cpp
#pragma once
#include <string>
class Dog {
private:
std::string name_;
std::string bark_;
public:
Dog(std::string name, std::string bark = "Wang! Wang wang wang");
void barking();
};
cpp
#include "dog.h"
#include <iostream>
Dog::Dog(std::string name, std::string bark) : name_(name), bark_(bark) {}
void Dog::barking() {
std::cout << bark_ << std::endl;
}
cpp
#include "./animal/dog.h"
#include <iostream>
int main(int argc, char *argv[]) {
Dog dog("旺财");
dog.barking();
return 0;
}
cmake
# 配置CMake的最小版本
cmake_minimum_required(VERSION 3.20.0)
# 配置项目名称
project(test)
# 配置生成和可执行程序名称和依赖的源文件
add_executable(test main.cpp animal/dog.cpp)
使用CMake进行构建并运行
shell
$ cmake -B build
-- The C compiler identification is GNU 12.3.0
-- The CXX compiler identification is GNU 12.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/zm/code/cmake/projects/test01/build
$ cmake --build build
[ 33%] Building CXX object CMakeFiles/test.dir/main.cpp.o
[ 66%] Building CXX object CMakeFiles/test.dir/animal/dog.cpp.o
[100%] Linking CXX executable test
[100%] Built target test
$ ./build/test
Wang! Wang wang wang
调用CMake脚本的方式
- include方法可以引入子目录中的CMake后缀的配置文件
- 将配置加入
add_executable
中
直接测试
现在有以下目录结构及代码环境
shell
$ tree
.
├── CMakeLists.txt
├── animal
│ ├── animal.cmake
│ ├── cat.cpp
│ ├── cat.h
│ ├── dog.cpp
│ └── dog.h
└── main.cpp
2 directories, 7 files
cpp
#pragma once
#include <string>
class Cat {
private:
std::string name_;
std::string bark_;
public:
Cat(std::string name, std::string bark = "Miao~ miao~");
void bark();
};
cpp
#include "cat.h"
#include <iostream>
Cat::Cat(std::string name, std::string bark) : name_(name), bark_(bark) {}
void Cat::bark() {
std::cout << bark_ << std::endl;
}
cpp
#pragma once
#include <string>
class Dog {
private:
std::string name_;
std::string bark_;
public:
Dog(std::string name, std::string bark = "Wang! Wang wang wang");
void barking();
};
cpp
#include "dog.h"
#include <iostream>
Dog::Dog(std::string name, std::string bark) : name_(name), bark_(bark) {}
void Dog::barking() {
std::cout << bark_ << std::endl;
}
cmake
# 设置变量
set(animal_source animal/dog.cpp animal/cat.cpp)
cpp
#include "./animal/cat.h"
#include "./animal/dog.h"
int main(int argc, char *argv[]) {
Dog dog("旺财");
dog.barking();
Cat cat("小橘");
cat.bark();
return 0;
}
cmake
# 配置CMake的最小版本
cmake_minimum_required(VERSION 3.20.0)
# 配置项目名称
project(test)
# 引入配置文件
include(animal/animal.cmake)
# 配置生成和可执行程序名称和依赖的源文件
add_executable(test
main.cpp
${animal_source}
)
使用CMake进行构建并运行
shell
$ cmake -B build
-- The C compiler identification is GNU 12.3.0
-- The CXX compiler identification is GNU 12.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/zm/code/cmake/projects/test02/build
$ cmake --build build
[ 25%] Building CXX object CMakeFiles/test.dir/main.cpp.o
[ 50%] Building CXX object CMakeFiles/test.dir/animal/dog.cpp.o
[ 75%] Building CXX object CMakeFiles/test.dir/animal/cat.cpp.o
[100%] Linking CXX executable test
[100%] Built target test
$ ./build/test
Wang! Wang wang wang
Miao~ miao~
CMakeLists嵌套
使用CMake最常见的一种方式,也是用的最多的一种方式
target_include_directories()
:头文件目录的声明target_link_libraries()
:链接库文件add_subdirectory()
:添加子目录add_library()
:生成库文件- 默认STATIC library
直接测试
现在有以下目录结构及代码环境
除了
CMakelists.txt
和main.cpp
有变动,其余与上个案例一致
shell
$ tree
.
├── CMakeLists.txt
├── animal
│ ├── CMakeLists.txt
│ ├── cat.cpp
│ ├── cat.h
│ ├── dog.cpp
│ └── dog.h
└── main.cpp
2 directories, 7 files
cpp
#pragma once
#include <string>
class Cat {
private:
std::string name_;
std::string bark_;
public:
Cat(std::string name, std::string bark = "Miao~ miao~");
void bark();
};
cpp
#include "cat.h"
#include <iostream>
Cat::Cat(std::string name, std::string bark) : name_(name), bark_(bark) {}
void Cat::bark() {
std::cout << bark_ << std::endl;
}
cpp
#pragma once
#include <string>
class Dog {
private:
std::string name_;
std::string bark_;
public:
Dog(std::string name, std::string bark = "Wang! Wang wang wang");
void barking();
};
cpp
#include "dog.h"
#include <iostream>
Dog::Dog(std::string name, std::string bark) : name_(name), bark_(bark) {}
void Dog::barking() {
std::cout << bark_ << std::endl;
}
cmake
add_library(AnimalLib cat.cpp dog.cpp)
cpp
#include "cat.h"
#include "dog.h"
int main(int argc, char *argv[]) {
Dog dog("旺财");
dog.barking();
Cat cat("小橘");
cat.bark();
return 0;
}
cmake
# 配置CMake的最小版本
cmake_minimum_required(VERSION 3.20.0)
# 配置项目名称
project(test)
# 添加子目录
add_subdirectory(animal)
# 配置生成和可执行程序名称和依赖的源文件
add_executable(test
main.cpp
)
# 在子目录中生成静态库,在该文件中引入子目录中生成的静态库
target_link_libraries(test PUBLIC AnimalLib)
# 添加了头文件引入目录,编写代码的时间可以省略目录前缀了
target_include_directories(test PUBLIC ${PROJECT_SOURCE_DIR}/animal)
使用CMake进行构建并运行
shell
$ cmake -B build
-- The C compiler identification is GNU 12.3.0
-- The CXX compiler identification is GNU 12.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/zm/code/cmake/projects/test03/build
$ cmake --build build
[ 20%] Building CXX object animal/CMakeFiles/AnimalLib.dir/cat.cpp.o
[ 40%] Building CXX object animal/CMakeFiles/AnimalLib.dir/dog.cpp.o
[ 60%] Linking CXX static library libAnimalLib.a
[ 60%] Built target AnimalLib
[ 80%] Building CXX object CMakeFiles/test.dir/main.cpp.o
[100%] Linking CXX executable test
[100%] Built target test
$ ./build/test
Wang! Wang wang wang
Miao~ miao~
Object Libraries
add_library OBJECT
Object Library是一个特殊的库类型,它将目标文件编译成一个库,但不会生成最终的链接文件。这意味着你可以在后续的
add_library()
或add_executable()
命令中,将Object Library做为源文件进行链接,从而生成最终的可执行文件或库文件。使用它的最低版本是3.12
将
target_include_directories
移入到CMakeLists.txt中
直接测试
现在有以下目录结构及代码环境
除了
CMakelists.txt
有变动,其余与上个案例一致
shell
$ tree
.
├── CMakeLists.txt
├── animal
│ ├── CMakeLists.txt
│ ├── cat.cpp
│ ├── cat.h
│ ├── dog.cpp
│ └── dog.h
└── main.cpp
2 directories, 7 files
cpp
#pragma once
#include <string>
class Cat {
private:
std::string name_;
std::string bark_;
public:
Cat(std::string name, std::string bark = "Miao~ miao~");
void bark();
};
cpp
#include "cat.h"
#include <iostream>
Cat::Cat(std::string name, std::string bark) : name_(name), bark_(bark) {}
void Cat::bark() {
std::cout << bark_ << std::endl;
}
cpp
#pragma once
#include <string>
class Dog {
private:
std::string name_;
std::string bark_;
public:
Dog(std::string name, std::string bark = "Wang! Wang wang wang");
void barking();
};
cpp
#include "dog.h"
#include <iostream>
Dog::Dog(std::string name, std::string bark) : name_(name), bark_(bark) {}
void Dog::barking() {
std::cout << bark_ << std::endl;
}
cmake
# 方式一 生成一个target
# add_library(AnimalLib OBJECT cat.cpp dog.cpp)
# target_include_directories(AnimalLib PUBLIC .)
# 方式二 生成两个target
add_library(cat OBJECT cat.cpp)
target_include_directories(cat PUBLIC .)
add_library(dog OBJECT dog.cpp)
target_include_directories(dog PUBLIC .)
cpp
#include "cat.h"
#include "dog.h"
int main(int argc, char *argv[]) {
Dog dog("旺财");
dog.barking();
Cat cat("小橘");
cat.bark();
return 0;
}
cmake
# 配置CMake的最小版本
cmake_minimum_required(VERSION 3.20.0)
# 配置项目名称
project(test)
# 添加子目录
add_subdirectory(animal)
# 配置生成和可执行程序名称和依赖的源文件
add_executable(test
main.cpp
)
# 在子目录中生成静态库,在该文件中引入子目录中生成的静态库
# 方式一 生成一个target
# target_link_libraries(test PUBLIC AnimalLib)
# 方式二 生成两个target
target_link_libraries(test PUBLIC cat dog)
使用CMake进行构建并运行
shell
$ cmake -B build
-- The C compiler identification is GNU 12.3.0
-- The CXX compiler identification is GNU 12.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/zm/code/cmake/projects/test04/build
$ cmake --build build
[ 25%] Building CXX object animal/CMakeFiles/dog.dir/dog.cpp.o
[ 25%] Built target dog
[ 50%] Building CXX object animal/CMakeFiles/cat.dir/cat.cpp.o
[ 50%] Built target cat
[ 75%] Building CXX object CMakeFiles/test.dir/main.cpp.o
[100%] Linking CXX executable test
[100%] Built target test
$ ./build/test
Wang! Wang wang wang
Miao~ miao~