CSDN复制进来的mk笔记很乱 可以看下面的pdf文档 比较清晰
https://download.csdn.net/download/qq_41537499/89512254
Cmake
apt install cmake
cmake --version
cmake version 3.22.1
vim main.cpp
main.cpp 代码:
#include
int main(int argc,char *argv[])
{
std::cout << “hello, world” << std::endl;
return(0);
}
#一般的单文件执行用g++
g++ main.cpp -o app
//生成了一个可执行的文件app
-rwxr-xr-x 1 root root 16528 7月 2 18:19 app*
执行这个文件
./app 输出:hello, world
换成Cmake执行
touch CMakeLists.txt
vim CMakeLists.txt
CMakeLists.txt 内容:
cmake_minimum_required(VERSION 3.15)
project(test)
add_executable(app main.cpp)
执行Cmake 此时的main.cpp与CMakeLists.txt在同一级目录 用 .
root@zyp:/opt/test_bazel/examples/cpp-tutorial/stage1# cmake .
– Configuring done
– Generating done
– Build files have been written to: /opt/test_bazel/examples/cpp-tutorial/stage1
执行完命令多了CMakeCache.txt、cmake_install.cmake、Makefile文件以及 CMakeFiles文件夹
然后我们创建一个build文件夹,存放Cmake生成的文件
cd build
cmake … #当前在build下 、main.cpp在上级 所以用cmake…
– The C compiler identification is GNU 11.4.0
– The CXX compiler identification is GNU 11.4.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: /opt/test_bazel/examples/cpp-tutorial/stage1/build
查看当前build下生成的目录结构
├── CMakeCache.txt
├── CMakeFiles
│ ├── 3.22.1
│ │ ├── CMakeCCompiler.cmake
│ │ ├── CMakeCXXCompiler.cmake
│ │ ├── CMakeDetermineCompilerABI_C.bin
│ │ ├── CMakeDetermineCompilerABI_CXX.bin
│ │ ├── CMakeSystem.cmake
│ │ ├── CompilerIdC
│ │ │ ├── a.out
│ │ │ ├── CMakeCCompilerId.c
│ │ │ └── tmp
│ │ └── CompilerIdCXX
│ │ ├── a.out
│ │ ├── CMakeCXXCompilerId.cpp
│ │ └── tmp
│ ├── app.dir
│ │ ├── build.make
│ │ ├── cmake_clean.cmake
│ │ ├── compiler_depend.make
│ │ ├── compiler_depend.ts
│ │ ├── DependInfo.cmake
│ │ ├── depend.make
│ │ ├── flags.make
│ │ ├── link.txt
│ │ └── progress.make
│ ├── cmake.check_cache
│ ├── CMakeDirectoryInformation.cmake
│ ├── CMakeOutput.log
│ ├── CMakeTmp
│ ├── Makefile2
│ ├── Makefile.cmake
│ ├── progress.marks
│ └── TargetDirectories.txt
├── cmake_install.cmake
└── Makefile
利用MakeFile文件生成可执行文件app
root@zyp:/opt/test_bazel/examples/cpp-tutorial/stage1/build# make
[ 50%] Building CXX object CMakeFiles/app.dir/main.cpp.o
[100%] Linking CXX executable app
[100%] Built target app
root@zyp:/opt/test_bazel/examples/cpp-tutorial/stage1/build# ./app
hello, world
set使用
CMakeLists.tst
cmake_minimum_required(VERSION 3.15)
project(test)
set(SRC main.cpp) #SRC是定义的一个变量
set(EXECUTABLE_OUTPUT_PATH /opt/test_Cmake/build) #设置一个生成的可执行程序的输出目录,没有这个文件夹会自动生成
set(CMAKE_CXX_STANDARD 11) #设置c++标准 是11
add_executable(app ${SRC})
root@zyp:/opt/test_bazel/examples/cpp-tutorial/stage1/build# cmake …
– Configuring done
– Generating done
– Build files have been written to: /opt/test_bazel/examples/cpp-tutorial/stage1/build
root@zyp:/opt/test_bazel/examples/cpp-tutorial/stage1/build# ll
总计 40
drwxr-xr-x 3 root root 4096 7月 3 11:20 ./
drwxr-xr-x 4 root root 4096 7月 3 11:20 …/
-rw-r–r-- 1 root root 13847 7月 3 11:19 CMakeCache.txt
drwxr-xr-x 5 root root 4096 7月 3 11:20 CMakeFiles/
-rw-r–r-- 1 root root 1664 7月 3 11:20 cmake_install.cmake
-rw-r–r-- 1 root root 5158 7月 3 11:20 Makefile
查看我们定义的输出目录 没有执行make之前是没有文件的
root@zyp:/opt/test_Cmake/build# ll
drwxr-xr-x 2 root root 4096 7月 3 11:20 ./
drwxr-xr-x 3 root root 4096 7月 3 11:20 …/
执行make
root@zyp:/opt/test_bazel/examples/cpp-tutorial/stage1/build# make
[ 50%] Building CXX object CMakeFiles/app.dir/main.cpp.o
[100%] Linking CXX executable /opt/test_Cmake/build/app
[100%] Built target app
发现在我们自定义文件夹下/opt/test_Cmake/build下生成了可执行程序app
root@zyp:/opt/test_Cmake/build# ls
app
root@zyp:/opt/test_Cmake/build# ./app
hello, world
CMakeLists.txt中主要的几个宏
aux_source_directory、CMAKE_CURRENT_SOURCE_DIR、PROJECT_SOURCE_DIR、file
CMAKE_CURRENT_SOURCE_DIR和PROJECT_SOURCE_DIR区别
CMAKE_CURRENT_SOURCE_DIR:当前正在处理的CMakeLists.txt
所在的源代码目录路径,它的值会随着CMake在不同目录下处理CMakeLists.txt
文件而变化
CMAKE_CURRENT_SOURCE_DIR
和PROJECT_SOURCE_DIR
是CMake构建系统中的两个常用变量,它们在定义、位置变化以及用途**等方面存在差异。具体分析如下:
定义
CMAKE_CURRENT_SOURCE_DIR:这是当前正在处理的CMakeLists.txt
所在的源代码目录路径。它的值会随着CMake在不同目录下处理CMakeLists.txt
文件而变化。
PROJECT_SOURCE_DIR:这个变量指向包含最近一次调用project()
命令的CMakeLists.txt
文件的目录。在多项目情况下,每个子项目(每次调用project()
命令)都会重新设置PROJECT_SOURCE_DIR
。
位置变化
CMAKE_CURRENT_SOURCE_DIR:由于它指向当前处理的CMakeLists.txt
所在目录,因此其值会在CMake处理不同目录下的文件时改变[4]。
PROJECT_SOURCE_DIR:相对固定,只有在新的project()
命令被执行时才会更新其值,指向该命令所在目录。
用途
CMAKE_CURRENT_SOURCE_DIR:当需要引用同级或子级目录下的文件时,应该使用CMAKE_CURRENT_SOURCE_DIR
[4]。它常用于指定当前目录下的资源文件或配置文件。
PROJECT_SOURCE_DIR:适用于多项目结构,每个子项目可以有自己的PROJECT_SOURCE_DIR
,使得每个子项目有独立的源代码目录路径。
综合对比分析,针对实际的项目结构和需求,以下是一些建议:
- 对于单一目录的项目,通常不需要频繁使用
PROJECT_SOURCE_DIR
,CMAKE_SOURCE_DIR
已足够。 - 在多层次、多项目结构中,合理使用
PROJECT_SOURCE_DIR
可以带来更好的灵活性和项目管理能力。 - 当在脚本中定义相对路径时,使用
CMAKE_CURRENT_SOURCE_DIR
能确保正确解析这些路径。 - 使用变量时,了解其作用域和适用场景可以避免常见错误,提升构建配置的可维护性。
总的来说,CMAKE_CURRENT_SOURCE_DIR
主要用于动态指示当前处理的源目录,而PROJECT_SOURCE_DIR
则用于指示最接近的project()
命令所在的目录,这在多项目和多层级项目中特别有用。正确使用这两个变量,可以帮助开发者更好地控制项目的构建过程和结构。
PROJECT_SOURCE_DIR、aux_source_directory
cmake_minimum_required(VERSION 3.15)
project(test)
set(SRC main.cpp)
aux_source_directory(${PROJECT_SOURCE_DIR} SRC)
#PROJECT_SOURCE_DIR这个宏的意思是执行Cmake命令后面的路径 如.或则…后 可以理解为根目录
set(EXECUTABLE_OUTPUT_PATH /opt/test_Cmake/build) #设置一个生成的可执行程序的输出目录,没有这个文件夹会自动生成
set(CMAKE_CXX_STANDARD 11) #设置c++标准 是11
add_executable(app ${SRC})
file、CMAKE_CURRENT_SOURCE_DIR
cmake_minimum_required(VERSION 3.15)
project(test)
set(SRC main.cpp)
aux_source_directory(${PROJECT_SOURCE_DIR} SRC)
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
#CMAKE_CURRENT_SOURCE_DIR这个宏是指CMakeists.txt所在的路径
set(EXECUTABLE_OUTPUT_PATH /opt/test_Cmake/build) #设置一个生成的可执行程序的输出目录,没有这个文件夹会自动生成
set(CMAKE_CXX_STANDARD 11) #设置c++标准 是11
add_executable(app ${SRC})
头文件、源文件
假设我们有一个程序,它有一个用于计算的功能。我们可以将这个功能分成两部分组成:声明(在头文件中)和实现(在源文件中)。
目录结构
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ ├── cmake_install.cmake
│ └── Makefile
├── CMakeLists.txt
├── include
│ └── calculate.h
├── src
│ ├── calculate.cpp
│ └── main.cpp
└──
头文件.h
// calculate.h
#ifndef CALCULATE_H
#define CALCULATE_H
// 函数声明
int add(int a, int b);
#endif // CALCULATE_H
相应的实现在文件calculate.cpp中
// calculate.cpp
#include “calculate.h”
// 函数实现
int add(int a, int b) {
return a + b;
}
主程序main.cpp
// main.cpp
#include
#include “calculate.h”
int main() {
int sum = add(3, 4);
std::cout << "The sum is: " << sum << std::endl;
return 0;
}
CMakeLists.txt变化为
cmake_minimum_required(VERSION 3.15)
project(test)
set(SRC main.cpp)
aux_source_directory(${PROJECT_SOURCE_DIR} SRC)
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
#CMAKE_CURRENT_SOURCE_DIR这个宏是指CMakeists.txt所在的路径
set(EXECUTABLE_OUTPUT_PATH /opt/test_Cmake/build)
#设置一个生成的可执行程序的输出目录,没有这个文件夹会自动生成
set(CMAKE_CXX_STANDARD 11)
#设置c++标准 是11
add_executable(app KaTeX parse error: Expected 'EOF', got '#' at position 144: …al/stage1/build#̲ make [ 33%] Bu…{CMAKE_CURRENT_SOURCE_DIR}/include)
cmake_minimum_required(VERSION 3.15)
project(test)
file(GLOB SRC C M A K E C U R R E N T S O U R C E D I R / s r c / ∗ . c p p ) s e t ( E X E C U T A B L E O U T P U T P A T H / o p t / t e s t C m a k e / b u i l d ) i n c l u d e d i r e c t o r i e s ( {CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) set(EXECUTABLE_OUTPUT_PATH /opt/test_Cmake/build) include_directories( CMAKECURRENTSOURCEDIR/src/∗.cpp)set(EXECUTABLEOUTPUTPATH/opt/testCmake/build)includedirectories({CMAKE_CURRENT_SOURCE_DIR}/include)
set(CMAKE_CXX_STANDARD 11)
add_executable(app ${SRC})
编译成功
root@zyp:/opt/test_bazel/examples/cpp-tutorial/stage1/build# cmake …
– Configuring done
– Generating done
– Build files have been written to: /opt/test_bazel/examples/cpp-tutorial/stage1/build
root@zyp:/opt/test_bazel/examples/cpp-tutorial/stage1/build# make
Consolidate compiler generated dependencies of target app
[ 33%] Building CXX object CMakeFiles/app.dir/src/calculate.cpp.o
[ 66%] Building CXX object CMakeFiles/app.dir/src/main.cpp.o
[100%] Linking CXX executable /opt/test_Cmake/build/app
[100%] Built target app
root@zyp:/opt/test_Cmake/build# ./app
The sum is: 7
制作静态动态库
静态库STATIC
动态库SHARED
当前目录结构:
root@zyp:/opt/test_Cmake/lib# tree -L 2
.
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ ├── cmake_install.cmake
│ └── Makefile
├── CMakeLists.txt
├── include
│ └── calculate.h
└── src
├── calculate.cpp
└── main.cpp
动态库 SHARED
cmake_minimum_required(VERSION 3.15)
project(test)
file(GLOB SRC C M A K E C U R R E N T S O U R C E D I R / s r c / ∗ . c p p ) i n c l u d e d i r e c t o r i e s ( {CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) include_directories( CMAKECURRENTSOURCEDIR/src/∗.cpp)includedirectories({CMAKE_CURRENT_SOURCE_DIR}/include)
add_library(calc SHARED ${SRC})
编译动态库
oot@zyp:/opt/test_Cmake/lib/build# cmake …
– The C compiler identification is GNU 11.4.0
– The CXX compiler identification is GNU 11.4.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: /opt/test_Cmake/lib/build
root@zyp:/opt/test_Cmake/lib/build# make
[ 33%] Building CXX object CMakeFiles/calc.dir/src/calculate.cpp.o
[ 66%] Building CXX object CMakeFiles/calc.dir/src/main.cpp.o
[100%] Linking CXX shared library libcalc.so
[100%] Built target calc
执行make在当前目录build下面生成了一个动态库libcalc.so
root@zyp:/opt/test_Cmake/lib/build# ls
CMakeCache.txt CMakeFiles cmake_install.cmake libcalc.so Makefile
静态库 STATIC
cmake_minimum_required(VERSION 3.15)
project(test)
file(GLOB SRC C M A K E C U R R E N T S O U R C E D I R / s r c / ∗ . c p p ) i n c l u d e d i r e c t o r i e s ( {CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) include_directories( CMAKECURRENTSOURCEDIR/src/∗.cpp)includedirectories({CMAKE_CURRENT_SOURCE_DIR}/include)
add_library(calc STATIC ${SRC})
编译静态库
root@zyp:/opt/test_Cmake/lib# vim CMakeLists.txt
root@zyp:/opt/test_Cmake/lib# cd build/
root@zyp:/opt/test_Cmake/lib/build# cmake …
– Configuring done
– Generating done
– Build files have been written to: /opt/test_Cmake/lib/build
root@zyp:/opt/test_Cmake/lib/build# make
Consolidate compiler generated dependencies of target calc
[ 33%] Building CXX object CMakeFiles/calc.dir/src/calculate.cpp.o
[ 66%] Building CXX object CMakeFiles/calc.dir/src/main.cpp.o
[100%] Linking CXX static library libcalc.a
[100%] Built target calc
root@zyp:/opt/test_Cmake/lib/build# ls
CMakeCache.txt CMakeFiles cmake_install.cmake libcalc.a libcalc.so Makefile
root@zyp:/opt/test_Cmake/lib/build#
执行make在当前目录build下面生成了一个静态库libcalc.a
LIBRARY_OUTPUT_PATH
指定动态或者静态库生成的文件位置
类似与 set(EXECUTABLE_OUTPUT_PATH /opt/test_Cmake/build) #设置一个生成的可执行程序的输出目录,
cmake_minimum_required(VERSION 3.15)
project(test)
file(GLOB SRC C M A K E C U R R E N T S O U R C E D I R / s r c / ∗ . c p p ) i n c l u d e d i r e c t o r i e s ( {CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) include_directories( CMAKECURRENTSOURCEDIR/src/∗.cpp)includedirectories({CMAKE_CURRENT_SOURCE_DIR}/include)
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/testlib)
add_library(calc STATIC ${SRC})
编译生成
root@zyp:/opt/test_Cmake/lib/build# make
[ 33%] Building CXX object CMakeFiles/calc.dir/src/calculate.cpp.o
[ 66%] Building CXX object CMakeFiles/calc.dir/src/main.cpp.o
[100%] Linking CXX static library …/testlib/libcalc.a
[100%] Built target calc
生成的文件目录是
${PROJECT_SOURCE_DIR}/testlib
root@zyp:/opt/test_Cmake/lib# ls
build CMakeLists.txt include src testlib
调用库
创建两个目录
root@zyp:/opt/test_Cmake/lib# mkdir staticLib sharedLi
#将静态库、动态库文件复制到对应目录下
root@zyp:/opt/test_Cmake/lib/testlib# cp libcalc.a …/staticLib/
root@zyp:/opt/test_Cmake/lib/testlib# cp libcalc.so …/sharedLib/
root@zyp:/opt/test_Cmake/lib# tree -L 2
.
├── CMakeLists.txt
├── include
│ └── calculate.h
├── sharedLib
│ └── libcalc.so
├── staticLib
│ └── libcalc.a
└── testlib
├── libcalc.a
└── libcalc.so
创建一个测试文件test.cpp 调用动态库
#include
#include “calculate.h”
int main() {
int sum = add(3, 4);
std::cout << "The sum is: " << sum << std::endl;
return 0;
}
注意当前目录写的src已经删除 src下的功能实现文件calculate.cpp与主程序main.cpp都被删除了,所以
注意删除CMakeLists.txt中的file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)中的src
├── CMakeLists.txt
├── include
│ └── calculate.h
├── sharedLib
│ └── libcalc.so
├── staticLib
│ └── libcalc.a
├── test.cpp
└── testlib
├── libcalc.a
└── libcalc.so
此时的CMakeLists.txt :
cmake_minimum_required(VERSION 3.15)
project(test)
#追踪源文件test.app
file(GLOB SRC C M A K E C U R R E N T S O U R C E D I R / ∗ . c p p ) i n c l u d e d i r e c t o r i e s ( {CMAKE_CURRENT_SOURCE_DIR}/*.cpp) include_directories( CMAKECURRENTSOURCEDIR/∗.cpp)includedirectories({CMAKE_CURRENT_SOURCE_DIR}/include)
link_libraries(calc) #链接到库文件
#因为库文件不是系统的,需要指定库文件位置
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/staticLib)
add_executable(app1 ${SRC})
编译
root@zyp:/opt/test_Cmake/lib/build# cmake …
– Configuring done
– Generating done
– Build files have been written to: /opt/test_Cmake/lib/build
root@zyp:/opt/test_Cmake/lib/build# make
[ 50%] Building CXX object CMakeFiles/app1.dir/test.cpp.o
[100%] Linking CXX executable app1
[100%] Built target app1
#生成了可执行文件app1
root@zyp:/opt/test_Cmake/lib/build# ls
app1 CMakeCache.txt CMakeFiles cmake_install.cmake Makefile
root@zyp:/opt/test_Cmake/lib/build# ./app1
The sum is: 7