Make (or rather a Makefile) is a buildsystem - it drives the compiler and other build tools to build your code. But cmake is a generator of buildsystems.
-
configure-
概念
- 是一个
shell script
- 是一个
-
作用
make sure all of the dependencies
produces a customised
Makefilespecific to your system from a template file calledMakefile.in -
configure script file来源run
autoconfto turnconfigure.acinto aconfigurescript
-
-
makeThis runs a series of tasks defined in a
Makefileto build the finished program from its source code.-
MakeFile.in来源Run
automaketo turnMakefile.aminto aMakefile.in
-
-
make installThe
make installcommand will copy the built program, and its libraries and documentation, to the correct locations.It does do nothing less than running the install function/task in
MakeFile
-
解释
CMake is a generator of buildsystems. It can produce Makefiles, it can produce Ninja build files, it can produce KDEvelop or Xcode projects, it can produce Visual Studio solutions.
-
cmake和make的区别Make (or rather a Makefile) is a buildsystem - it drives the compiler and other build tools to build your code. But cmake is a generator of buildsystems.
即make由cmake构建而来,cmake是构建工具的构建工具。make和nija是平级关系
-
经常使用的两个命令
cmake -S . -B ./build # -S <path-to-source> = Explicitly specify a source directory. # -B <path-to-build> = Explicitly specify a build directory. cmake --build ./build # --build <dir> = Build a CMake-generated project binary tree. # path = the path to be built cmake --install ./build # --install <dir> = Install a CMake-generated project binary tree. # path = the path to be installed
-
include_directories(/opt/homebrew/Cellar/glfw/3.4/include)-
标准格式
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
-
标准解释
Add the given directories to those the compiler uses to search for include files. Relative paths are interpreted as relative to the current source directory.
-
通俗示例
-
在CmakeLists.txt中加这样一句
include_directories(/opt/homebrew/Cellar/glfw/3.4/include)
-
等于如下效果
clang -cc1 -I /opt/homebrew/Cellar/glfw/3.4/include
-
-
-
add_execuable(main.out main.cpp other.cpp)-
标准格式
add_executable(<name> [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] [source1] [source2 ...])
-
标准解释
Add an executable to the project using the specified source files.
-
示范
add_executable(3_hello_triangle main.cpp ~/Environment/glad/src/glad.c) # glad.c文件不是链接库,不能用link_libraries # 这种方式本质是将glad.c编译成glad.o,最后链接 # 所以也可以执行下面两条执行 add_library(glad STATIC ~/Environment/glad/src/glad.c) link_libraries(glad) add_executable(3_hello_triangle main.cpp)
-
-
-
add_library(mainlib SHARED main.cpp other.cpp)-
标准格式
add_library(<name> [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] [<source>...])
-
标准解释
Add a library to the project using the specified source files.
-
通俗解释
将mian.cpp和other.cpp源文件编译成一个命名为mainlib的共享库
-
-
-
link_libraries(/opt/homebrew/Cellar/glfw/3.4/lib/libglfw.3.dylib)-
标准格式
link_libraries([item1 [item2 [...]]] [[debug|optimized|general] <item>] ...)
-
标准解释
Specify libraries or flags to use when linking any targets created later in the current directory or below by commands such as add_executable() or add_library().
-
通俗示例
-
在CmakeLists.txt中加这样一句
link_libraries(/opt/homebrew/Cellar/glfw/3.4/lib/libglfw.3.dylib)
-
等于如下效果
ld -o 1_create_a_window CMakeFiles/1_create_a_window.dir/main.cpp.o /opt/homebrew/Cellar/glfw/3.4/lib/libglfw.3.dylib
-
-
-
target_link_libraries(main.out PUBLIC hellolib)-
标准格式
target_link_libraries(<target> <PRIVATE|PUBLIC|INTERFACE> <item>... [<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
-
标准解释
Specify libraries or flags to use when linking a given target and/or its dependents.
-
示范
add_library(glad STATIC ~/Environment/glad/src/glad.c) add_executable(3_hello_triangle main.cpp) target_link_libraries(3_hello_triangle PUBLIC glad)
-
-
-
add_subdirectory(fmt)-
标准格式
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
-
标准解释
Add a subdirectory to the build.
-
-
target_include_directories(hellolib PUBLIC .)-
标准格式
target_include_directories(<target> [SYSTEM] [AFTER|BEFORE] <INTERFACE|PUBLIC|PRIVATE> [items1...] [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
-
标准解释
Add include directories to a target.
-
通俗解释
在构建hellolib搜索头文件时,将当前目录纳入头文件搜索目录,并且可以向下传递
-
-
[PRIVATE|PUBLIC]区别- 是否
link、include等操作时进行传染 - 如
target_link_libraries(myexec PRIVATE hellolib)表示另一个library在链接时需要myexec库时会自动可以添加hellolib进行链接,否则不能进行链接
- 是否
-
C++声明的必要性
- 声明即引入头文件或在顶部做一个函数等声明如
void hello(); - 不声明编译器无法知道名称的含义。如
vector<MyClass> a可能会把vector、MyClass看作是变量,把<、>看作时运算符
- 声明即引入头文件或在顶部做一个函数等声明如
-
递归引入头文件
-
当递归引入头文件时会报错无法通过编译
-
防止递归引入的两种办法
-
#pragma once -
宏定义
#ifndef INC_01_HEADER_NAME_H #define INC_01_HEADER_NAME_H #endif //INC_01_HEADER_NAME_H
-
-
-
第三方库引入
- 纯头文件引入
- 直接
target_include_directories()时将包含头文件的文件夹填入即可 - 通常
#include <xxx.h>时需要定义一个xxx.h定义的宏,因为要防止重复引入
- 直接
- 子模块引入
- 即作为
cmake的子模块引入,通过add_subdirectories()和target_link_libraries()即可
- 即作为
- 引用系统中预安装的第三方库
- 最麻烦,通常通过
find_package() - 不推荐使用
- 最麻烦,通常通过
- 纯头文件引入
-
包管理器
C++没有包管理器,vcpkg太多问题简直没法用
-
CMAKE_CXX_FLAGS
-
含义: 编译器执行时加的参数
-
用法:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -v") # 输出详细的编译日志
-
-
CMAKE_EXPORT_COMPILE_COMMANDS
- 将编译指令输出到compile_commands.json文件
-
CMAKE_VERBOSE_MAKEFILE
- 让编译日志尽可能详细