---
# System prepended metadata

title: cmake make configure
tags: [cmake, configure, make]

---

# cmake make configure

:::danger
#### 本文中的表格圖片由chatGPT生成，內容可能錯誤。
:::

:::danger
### Cmake version problem(solved)
![image](https://hackmd.io/_uploads/H1vJIELtyg.png)
這份圖表是chatGPT生成的，但我和ai都沒能找到官方圖表。
`cmake-3.28`不支持我自己編譯的`gcc-11.4.0`，會出現以下錯誤。
```
cmake: /media/hlajungo/D/linux/opt/gcc/11.4.0/lib64/libstdc++.so.6: version `GLIBCXX_3.4.32' not found (required by cmake)
cmake: /media/hlajungo/D/linux/opt/gcc/11.4.0/lib64/libstdc++.so.6: version `GLIBCXX_3.4.30' not found (required by cmake)
cmake: /media/hlajungo/D/linux/opt/gcc/11.4.0/lib64/libstdc++.so.6: version `GLIBCXX_3.4.32' not found (required by /lib/x86_64-linux-gnu/libjsoncpp.so.25)
cmake: /media/hlajungo/D/linux/opt/gcc/11.4.0/lib64/libstdc++.so.6: version `GLIBCXX_3.4.30' not found (required by /lib/x86_64-linux-gnu/libicuuc.so.74)
```
但能支持ubuntu下載的`gcc-13.3.0`。
使用`gcc-11.4.0`去編譯`cmake-3.27`是可行的，大概`cmake-3.28`對gcc版本要求更高了。
`cmake --version`
```
cmake version 3.27.7

CMake suite maintained and supported by Kitware (kitware.com/cmake).
```
:::
```
cmake -S . -B ./build/UseCudaLib -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=./install -DCMAKE_BUILD_TYPE=Release
cmake --build build/UseCudaLib/ --parallel $(nproc)
cmake --install build/UseCudaLib/

cmake -S standalone/ -B ./build/standalone -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=./install -DCMAKE_BUILD_TYPE=Release
cmake --build build/standalone/ --parallel $(nproc)
cmake --install build/standalone/

cmake -S test -B ./build/test -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=./install -DCMAKE_BUILD_TYPE=Release
cmake --build build/test/ --parallel $(nproc)
cmake --install build/test/
```
:::info
### [(Book) Cmake key concepts](https://cmake.org/cmake/help/book/mastering-cmake/chapter/Key%20Concepts.html)
:::
:::info
### [(Book) Cmake reference](https://cmake.org/cmake/help/latest/index.html)
:::


## PUBLIC vs PRIVATE vs INTERFACE
這三者是在表達庫之間的依賴關係的關鍵詞。

前情提要，如果你不知道"庫"是什麼，庫是一群只有實現的函數的二進制版本，如果是運行時使用的稱為動態庫(`.so`(linux)/`.dll`(windows)), 如果是編譯時使用的稱為靜態庫(`.a`(linux)/`.lib`(windows))。靜態庫基本上就是一群綁在一起的`.o`檔。

繼續，
PUBLIC者，影響自身及自身依賴項。
PRIVATE者，影響自身。
INTERFACE者，影響依賴項。
例如，此處要表達myLib使用"PUBLIC依賴"於depLib
```
add_library(myLib STATIC myLib.cpp)
add_library(depLib STATIC depLib.cpp)

target_link_libraries(myLib
    PUBLIC depLib      # myLib 會連結 depLib，所有依賴 myLib 的目標 也會連結 depLib
    PRIVATE math       # 只有 myLib 連結 math，其他目標不會
    INTERFACE pthread  # 只有 依賴 myLib 的目標 會連結 pthread，而 myLib 本身不會
)
```
這樣做，是為了減少編譯量以提高效率。
從庫中取出`.o`檔字串
```
$<TARGET_OBJECTS:archive>
```





:::warning
### add_subdirectory() 和 include()
```
add_subdirectory(subdir)
include(file)
```
![image](https://hackmd.io/_uploads/rymNZ5Zcyl.png)
如果`subdir`目錄沒有`CMakeLists.txt`會報錯。
:::

:::warning
### cmake cli help
用於查看cmake函數，cmake變量。
有輸出全部的內容，以及針對單個目標查詢的指令。
![image](https://hackmd.io/_uploads/rylWlh5Z9kg.png)
:::


:::warning
### CMake 的 cli 基本使用
基本上，就是`1.使用生成器生成專案`，`2.進行編譯`，`3.進行安裝`
### 1. generate (configure)
```
cmake -S . -B ./build -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=/opt/dir -DCMAKE_BUILD_TYPE=Release
```
`-S` 指定`CMakeLists.txt`所在的目錄(輸入), s for source.
```
cmake -S . -B ./build
cmake  . -B ./build
```
 以上兩命令基本相同，但更推薦使用`-S`選項。
`-B` 指定中間件目錄(輸出), b for build.
`-G` 指定生成器, 如果沒有，會根據系統指定， g for Generator.
`-G` 可能的值
```
Ninja
Unix Makefiles
Visual Studio 17 2022
```
`-D` 設定變數，例如安裝位置, 編譯模式和啟動交叉編譯
```
-DCMAKE_INSTALL_PREFIX=/opt/dir
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_TOOLCHAIN_FILE=arm-toolchain.cmake
```
安裝位置設定 (`makefile` vs `autoconf` vs `cmake` )
```
make DESTDIR=/path/path install
./configure --prefix=/path/path
cmake -DCMAKE_INSTALL_PREFIX=/path/path .
```
### 2. build (compile)
```
cmake --build build --parallel $(nproc)
```
`--build` 說明開始編譯，並設定中間件放置目錄。
```
cmake --build build
make
```
以上兩命令基本相同(linux上)，但更推薦使用`--build`選項。這樣記單選項，各個平台的選項就不用管了。
```
cmake --build dir --target target
```
Targets represent executables, libraries, and utilities built by CMake. 你可以指定只編譯某個 target。
```
--parallal $(nproc)
```
指定使用幾個邏輯cpu來編譯，這是cmake的官方選項。make工具使用`-j$(nproc)`。
### 3. install
```
cmake --install build
```
`--install` 開始安裝，並指定中間件目錄。
安裝位置會在`-DCMAKE_INSTALL_PREFIX`。

:::

:::warning
### CMakeLists.txt 語法
此處使用 `VIS` 來簡化 `[PUBLIC | PRIVATE | INTERFACE]`

### 1. generate (configure)

### 2. build (compile)

大致上需要做這些事情。
以下有 `cmake` 和 `gcc` 的對比。
1. 產出`TARGET` (`ARCHIVE`靜態庫, `LIBRARY`動態庫, `RUNTIME`可執行檔)
```
add_library
add_executable
(cli) gcc -o xxx
```
2. 把 `source code` 添加到 `TARGET`
```
target_sources
(cli) gcc xxx.c xxx.h 
```
3. 使用`include path`找出需要的 `header files`
```
target_include_directories
(cli) gcc -I/path/path
```
4. 使用`link path`找出需要的 `ARCHIVE or LIBRARY files`
```
link_directories
(cli) gcc -L/path/path
```
4. 把 `ARCHIVE, LIBRARY` 連結到 `TARGET`
```
target_link_libraries
(cli) gcc -lm  # 假設存在 libm.a
```
6. 把產出來的中間件，生成真正的 `TARGET`，並安裝
```
install
```
0. 設定編譯選項
```
全局添加選項
add_compile_options(-Wall -Wextra -O2)
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-std=c++17>)
(cli) gcc -Wall -Wextra -O2 -std=c++17

針對 TARGET 添加選項
target_compile_options(MyTarget PRIVATE -Wall -Wextra -O2)

全局設定專門的環境變量
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)  # 強制使用
set(CMAKE_CXX_EXTENSIONS OFF)  # 禁用擴展，只用C++17

針對 TARGET 設定專門的環境變量
set_target_properties(MyTarget PROPERTIES CXX_STANDARD 17)

設定宏
target_compile_definitions(MyTarget PRIVATE DEBUG)
(cli) cmake -Dxxx
(cli) gcc -Dxxx
```
![image](https://hackmd.io/_uploads/ryKh4LEq1g.png)
![image](https://hackmd.io/_uploads/Bki0EI4ckx.png)

### 函數細節

- Define `TARGET`
```
add_library(xxx.a [STATIC(default) | SHARED | MODULE] src.c)
add_executable(xxx.bin src.c )
```
同名稱是唯一的，不可重複定義

- Append code to `TARGET`
```
target_sources(xxx.bin
  VIS src.c
)
```

- Set `link path`
```
link_directories(/path/path)
```

- link library to `TARGET`
```
target_link_libraries(xxx.bin
  lib.a
)
```

- Set `include path`
```
target_include_directories(exec.bin
  [SYSTEM | ] VIS ${CMAKE_CURRENT_SOURCE_DIR}/include
)
```
`SYSTEM`關鍵字會將頭文件視為系統目錄，`SYSTEM`必須與`VIS`一起用。

- Set macro define
```
target_compile_definitions(archive
  PRIVATE   BUILDING_WITH_LZMA
  INTERFACE USING_ARCHIVE_LIB
)
```
用於 `#define xxx`

### 3. install
你可以把 `install` 簡單的理解為 `把該有的東西，移動到正確的位置` 的過程。

`install` 函數只會在 `(cli) cmake --install build`時被觸發。

![image](https://hackmd.io/_uploads/rJunygz91g.png)

Some examples
* 1. 安裝 `TARGET`
```
add_executable(MyApp main.cpp)
install(TARGETS MyApp RUNTIME DESTINATION bin)
```
安裝位置: `${CMAKE_INSTALL_PREFIX}/bin`
安裝類型: `RUNTIME` (可執行檔)
* 2. 單純複製文件。
```
install(FILES myheader.h DESTINATION include)
```
安裝位置: `${CMAKE_INSTALL_PREFIX}/include`
安裝類型: header file
* 3. 複製但是添加可執行權限
```
install(PROGRAMS myscript.sh DESTINATION bin)
```
`PROGRAMS`會保證文件是可執行的。
安裝位置: `${CMAKE_INSTALL_PREFIX}/bin`
安裝類型: `.sh`腳本
* 4. 複製整個目錄及內容到目的地。
```
install(DIRECTORY include/ DESTINATION include)
```
安裝位置: `${CMAKE_INSTALL_PREFIX}/include`
安裝類型: dir

* 5. 執行腳本
```
install(SCRIPT myscript.cmake)
```
執行腳本 `myscript.cmake`。
安裝：無

* 6. 執行內嵌 cmake 指令
```
install(CODE "message(STATUS 'Installing...')")
```
這段會輸出資訊。
安裝：無
* 7. 安裝 CMake package（用於 find_package()）
```
install(TARGETS MyApp EXPORT MyLibConfig
RUNTIME DESTINATION bin
)
install(EXPORT MyLibConfig DESTINATION lib/cmake/MyLib)
```
第一條語句把資訊存入 `MyLibConfig`，第二條語句是實際安裝。
該文件用於讓其他專案使用 `find_package(MyLib)` 來讓其他專案快速使用該庫。
### 0. others (輔助性, 專案設定)
- 尋找文件

```
file(GLOB_RECURSE sources src/main/*.cpp src/main/*.h)
```
遞迴地尋找匹配規則的文件，並全存入 `sources` 變量中。

- 設定 `project`
```
project(<ProjectName> [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
                      [LANGUAGES <language1> <language2> ...])
```
用於設定專案名稱，版本與使用語言。會自動做一些事。
1. 設定變量`PROJECT_NAME`
2. 設定變量`PROJECT_VERSION`, `PROJECT_VERSION_MAJOR`, `PROJECT_VERSION_MINOR`和`PROJECT_VERSION_PATCH`
3. 嘗試尋找編譯器`CMAKE_C_COMPILER`，若無則報錯。

在一個專案有多個`project()`時，新的會覆蓋舊的。

![image](https://hackmd.io/_uploads/SyXw44wtye.png)

### 0. 生成額外的 `*.cmake` 文件
如果 `install` 出來的產物還會需要被別的 `CMakeLists.txt` 使用，那麼可以生成 `*.cmake` 來讓別的 CMakeLists.txt 自動添加 `include目錄`或定義`TARGET`。

0. 生成`.cmake`文件
有兩個工具，CMake內建的`CMakePackageConfigHelpers`，需要手動設定，以及`TheLartians/PackageProject.cmake@1.8.0`，更加的自動化，一個命令即可完成，本篇使用這個。

範例
```
include(cmake/CPM.cmake)
CPMAddPackage("gh:TheLartians/PackageProject.cmake@1.8.0")

...

packageProject(
  NAME ${PROJECT_NAME}
  VERSION ${PROJECT_VERSION}
  NAMESPACE ${PROJECT_NAME}
  BINARY_DIR ${PROJECT_BINARY_DIR}
  INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include
  INCLUDE_DESTINATION include/${PROJECT_NAME}-${PROJECT_VERSION}
  VERSION_HEADER "${VERSION_HEADER_LOCATION}"
  COMPATIBILITY SameMajorVersion
)
```
在CMakeLists.txt末尾添加這個指令，就會安裝以下文件。
```
./output/lib/cmake/UseCudaLib-1.0.0/UseCudaLibConfig.cmake
./output/lib/cmake/UseCudaLib-1.0.0/UseCudaLibConfigVersion.cmake
./output/lib/cmake/UseCudaLib-1.0.0/UseCudaLibTargets-release.cmake
./output/lib/cmake/UseCudaLib-1.0.0/UseCudaLibTargets.cmake
```



![image](https://hackmd.io/_uploads/B1VBt8451l.png)

1. 在別處使用。
```
find_package(UseCudaLib CONFIG REQUIRED)
target_link_libraries(MyExecutable PRIVATE UseCudaLib)
```
上述兩行相等於以下(有些東西會不同)，cmake會自動幫你設定`include PATH`, `TARGET`等。
```
include("${CMAKE_CURRENT_LIST_DIR}/MyLibTargets.cmake")
add_library(MyLib IMPORTED)
set_target_properties(MyLib PROPERTIES
  INTERFACE_INCLUDE_DIRECTORIES "/PATH/TO/LIB/include"
  IMPORTED_LOCATION "/usr/local/lib/libMyLib.so"
)
target_link_libraries(MyExecutable PRIVATE MyLib)
```

`find_package`會去尋找文件`UseCudaLibConfig.cmake`，該文件會再去執行`UseCudaLibTargets.cmake`。

:::



::: warning
### ctest
:::

:::warning
## CMake的內建變量
你可以運行此[CMakeLists.txt](/1YUq7lxrREmCzh5um9KP5g)來輸出大部分的內建變量。
CMake會動態的生成部份變量，根據`<LANG>`,`<PROJECT-NAME>`,`<PackageName>`

![image](https://hackmd.io/_uploads/HJRpD6_t1l.png)

## 內建變量和值簡要說明
下文中出現`CXX`的部份可替換成其他語言，詳情參考上圖。
```
第一種：可執行檔變量
-- CMAKE_AR: /usr/bin/ar
-- CMAKE_BUILD_TOOL: /usr/bin/gmake
-- CMAKE_MAKE_PROGRAM: /usr/bin/gmake
-- CMAKE_RANLIB: /usr/bin/ranlib
-- CMAKE_CXX_COMPILER_AR: /usr/bin/gcc-ar-13
-- CMAKE_CXX_COMPILER_FRONTEND_VARIANT: GNU
-- CMAKE_CXX_COMPILER_RANLIB: /usr/bin/gcc-ranlib-13


第二種：CMAKE本身資料
-- CMAKE_ROOT: /media/hlajungo/D/linux/opt/gcc-11.4.0/cmake/3.27/share/cmake-3.27
-- CMAKE_COMMAND: /media/hlajungo/D/linux/opt/gcc-11.4.0/cmake/3.27/bin/cmake
-- CMAKE_CPACK_COMMAND: /media/hlajungo/D/linux/opt/gcc-11.4.0/cmake/3.27/bin/cpack
-- CMAKE_CTEST_COMMAND: /media/hlajungo/D/linux/opt/gcc-11.4.0/cmake/3.27/bin/ctest

-- CMAKE_VERSION: 3.27.7
-- CMAKE_MAJOR_VERSION: 3
-- CMAKE_MINOR_VERSION: 27
-- CMAKE_PATCH_VERSION: 7
-- CMAKE_TWEAK_VERSION: 0
-- CMAKE_CACHE_MAJOR_VERSION: 3
-- CMAKE_CACHE_MINOR_VERSION: 27
-- CMAKE_CACHE_PATCH_VERSION: 7
-- CMAKE_MINIMUM_REQUIRED_VERSION: 3.10

第三種：專案的目錄
解釋：
遇到 add_subdirectory() 或 project() 覆蓋時，一些變量會改變。

最頂層的 CMakeLists.txt，不會改變。
-- CMAKE_CFG_INTDIR: .
-- CMAKE_BINARY_DIR: /media/hlajungo/D/linux/test_place/test_cmake
-- CMAKE_SOURCE_DIR: /media/hlajungo/D/linux/test_place/test_cmake
-- CMAKE_PARENT_LIST_FILE: /media/hlajungo/D/linux/test_place/test_cmake/CMakeLists.txt
-- CMAKE_CACHEFILE_DIR: /media/hlajungo/D/linux/test_place/test_cmake
-- CMAKE_FIND_PACKAGE_REDIRECTS_DIR: /media/hlajungo/D/linux/test_place/test_cmake/CMakeFiles/pkgRedirects

存在 project() 函數的 CMakeLists.txt
-- PROJECT_BINARY_DIR: /media/hlajungo/D/linux/test_place/test_cmake
-- PROJECT_SOURCE_DIR: /media/hlajungo/D/linux/test_place/test_cmake

當前的 CMakeLists.txt。
-- CMAKE_CURRENT_BINARY_DIR: /media/hlajungo/D/linux/test_place/test_cmake
-- CMAKE_CURRENT_SOURCE_DIR: /media/hlajungo/D/linux/test_place/test_cmake
-- CMAKE_CURRENT_LIST_DIR: /media/hlajungo/D/linux/test_place/test_cmake
-- CMAKE_CURRENT_LIST_FILE: /media/hlajungo/D/linux/test_place/test_cmake/CMakeLists.txt

第四種：基本不會更改的設定
-- CMAKE_STATIC_LIBRARY_PREFIX: lib
-- CMAKE_STATIC_LIBRARY_SUFFIX: .a
-- CMAKE_SHARED_LIBRARY_PREFIX: lib
-- CMAKE_SHARED_LIBRARY_SUFFIX: .so
-- CMAKE_SHARED_MODULE_PREFIX: lib
-- CMAKE_SHARED_MODULE_SUFFIX: .so
-- CMAKE_SIZEOF_VOID_P: 8
-- CMAKE_FIND_LIBRARY_PREFIXES: lib
-- CMAKE_FIND_LIBRARY_SUFFIXES: .so;.a
-- CMAKE_LIBRARY_PATH_FLAG: -L
-- CMAKE_LINK_LIBRARY_FLAG: -l

第五種：其他
-- CMAKE_CURRENT_LIST_LINE: 648
-- CMAKE_DL_LIBS: dl
-- CMAKE_MATCH_COUNT: 0
-- CMAKE_SKIP_RPATH: NO

第六種：用戶系統識別庫
-- LINUX: 1
-- UNIX: 1
-- CMAKE_HOST_LINUX: 1
-- CMAKE_HOST_UNIX: 1
-- CMAKE_SYSTEM_NAME: Linux
-- CMAKE_HOST_SYSTEM_NAME: Linux
-- CMAKE_SYSTEM_PROCESSOR: x86_64
-- CMAKE_HOST_SYSTEM_PROCESSOR: x86_64
-- CMAKE_SYSTEM: Linux-6.8.0-51-generic
-- CMAKE_HOST_SYSTEM: Linux-6.8.0-51-generic
-- CMAKE_SYSTEM_VERSION: 6.8.0-51-generic
-- CMAKE_HOST_SYSTEM_VERSION: 6.8.0-51-generic
-- CMAKE_LIBRARY_ARCHITECTURE: x86_64-linux-gnu
-- CMAKE_LIBRARY_ARCHITECTURE_REGEX: [a-z0-9_]+(-[a-z0-9_]+)?-linux-gnu[a-z0-9_]*

第七種：專案設定和資料
-- CMAKE_PROJECT_NAME: LearningCMake
-- PROJECT_NAME: LearningCMake
-- CMAKE_INSTALL_PREFIX: /media/hlajungo/D/linux/test_place/test_cmake

第八種：專案資料
-- CMAKE_GENERATOR: Unix Makefiles
-- CMAKE_VERBOSE_MAKEFILE: FALSE
-- PROJECT_IS_TOP_LEVEL: ON
-- CMAKE_CROSSCOMPILING: FALSE

第九種：編譯用目錄
-- CMAKE_SYSTEM_INCLUDE_PATH: /usr/include/X11
-- CMAKE_SYSTEM_LIBRARY_PATH: /usr/lib/X11
-- CMAKE_SYSTEM_PREFIX_PATH: /usr/local;/usr;/;/media/hlajungo/D/linux/opt/gcc-11.4.0/cmake/3.27;/media/hlajungo/D/linux/test_place/test_cmake;/usr/X11R6;/usr/pkg;/opt
-- CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES: /media/hlajungo/D/linux/opt/gcc/11.4.0/include;/media/hlajungo/D/linux/opt/mpc/1.3.1/include;/media/hlajungo/D/linux/opt/mpfr/4.2.1/include;/media/hlajungo/D/linux/opt/isl/0.27/include;/media/hlajungo/D/linux/opt/gmp/6.2.1/include;/usr/include/c++/13;/usr/include/x86_64-linux-gnu/c++/13;/usr/include/c++/13/backward;/usr/lib/gcc/x86_64-linux-gnu/13/include;/usr/local/include;/usr/include/x86_64-linux-gnu;/usr/include
-- CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES: /media/hlajungo/D/linux/opt/gcc/11.4.0/lib;/media/hlajungo/D/linux/opt/mpc/1.3.1/lib;/media/hlajungo/D/linux/opt/mpfr/4.2.1/lib;/media/hlajungo/D/linux/opt/isl/0.27/lib;/media/hlajungo/D/linux/opt/gmp/6.2.1/lib;/usr/lib/gcc/x86_64-linux-gnu/13;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib;/media/hlajungo/D/linux/opt/gcc/11.4.0/lib64;/media/hlajungo/D/linux/opt/gcc/11.4.0/libexec
-- CMAKE_CXX_IMPLICIT_LINK_LIBRARIES: stdc++;m;gcc_s;gcc;c;gcc_s;gcc

第八種：其他

-- CMAKE_COLOR_MAKEFILE: ON
-- CMAKE_INSTALL_DEFAULT_COMPONENT_NAME: Unspecified

-- CMAKE_AUTOGEN_ORIGIN_DEPENDS: ON
-- CMAKE_AUTOMOC_COMPILER_PREDEFINES: ON
-- CMAKE_AUTOMOC_MACRO_NAMES: Q_OBJECT;Q_GADGET;Q_NAMESPACE;Q_NAMESPACE_EXPORT
-- CMAKE_AUTOMOC_PATH_PREFIX: OFF
-- CMAKE_EXE_LINKER_FLAGS_INIT:   
-- CMAKE_CXX_LINK_WHAT_YOU_USE_FLAG: LINKER:--no-as-needed
-- CMAKE_LINK_DEPENDS_USE_LINKER: FALSE
-- CMAKE_LINK_WHAT_YOU_USE_CHECK: ldd;-u;-r
-- CMAKE_MODULE_LINKER_FLAGS_INIT:   
-- CMAKE_SHARED_LINKER_FLAGS_INIT:   
-- CMAKE_SKIP_INSTALL_RPATH: NO

第九種：語言資訊
-- CMAKE_CXX_COMPILER: /usr/bin/c++
-- CMAKE_CXX_COMPILER_ID: GNU
-- CMAKE_CXX_COMPILER_LOADED: 1
-- CMAKE_CXX_BYTE_ORDER: LITTLE_ENDIAN
-- CMAKE_CXX_COMPILER_PREDEFINES_COMMAND: /usr/bin/c++;-dM;-E;-c;/media/hlajungo/D/linux/opt/gcc-11.4.0/cmake/3.27/share/cmake-3.27/Modules/CMakeCXXCompilerABI.cpp
-- CMAKE_CXX_COMPILER_VERSION: 13.3.0

-- CMAKE_C_COMPILE_FEATURES: c_std_90;c_function_prototypes;c_std_99;c_restrict;c_variadic_macros;c_std_11;c_static_assert;c_std_17;c_std_23
-- CMAKE_CXX_COMPILE_FEATURES: cxx_std_98;cxx_template_template_parameters;cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates;cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates;cxx_std_17;cxx_std_20;cxx_std_23

-- CMAKE_CXX_ARCHIVE_APPEND: <CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>
-- CMAKE_CXX_ARCHIVE_CREATE: <CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>
-- CMAKE_CXX_ARCHIVE_FINISH: <CMAKE_RANLIB> <TARGET>
-- CMAKE_CXX_COMPILE_OBJECT: <CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>
-- CMAKE_CXX_CREATE_SHARED_LIBRARY: <CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>
-- CMAKE_CXX_CREATE_SHARED_MODULE: <CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>
-- CMAKE_CXX_LINK_EXECUTABLE: <CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>

-- CMAKE_CXX_FLAGS_DEBUG: -g
-- CMAKE_CXX_FLAGS_DEBUG_INIT:  -g
-- CMAKE_CXX_FLAGS_INIT:   
-- CMAKE_CXX_FLAGS_MINSIZEREL: -Os -DNDEBUG
-- CMAKE_CXX_FLAGS_MINSIZEREL_INIT:  -Os -DNDEBUG
-- CMAKE_CXX_FLAGS_RELEASE: -O3 -DNDEBUG
-- CMAKE_CXX_FLAGS_RELEASE_INIT:  -O3 -DNDEBUG
-- CMAKE_CXX_FLAGS_RELWITHDEBINFO: -O2 -g -DNDEBUG
-- CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT:  -O2 -g -DNDEBUG
-- CMAKE_CXX_EXTENSIONS_DEFAULT: ON
-- CMAKE_CXX_IGNORE_EXTENSIONS: inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC
-- CMAKE_CXX_OUTPUT_EXTENSION: .o
-- CMAKE_CXX_SOURCE_FILE_EXTENSIONS: C;M;c++;cc;cpp;cxx;mm;mpp;CPP;ixx;cppm;ccm;cxxm;c++m
-- CMAKE_CXX_LINKER_WRAPPER_FLAG: -Wl,
-- CMAKE_CXX_LINKER_WRAPPER_FLAG_SEP: ,
-- CMAKE_CXX_LIBRARY_ARCHITECTURE: x86_64-linux-gnu
-- CMAKE_CXX_SIZEOF_DATA_PTR: 8
-- CMAKE_CXX_STANDARD_DEFAULT: 17
```
:::



:::warning
### cpm-cmake
這是一個用於下載和管理第三方庫的工具，內建於cmake。
To use `cpm.cmake`, add this to CMakeLists.txt
```
include(cmake/CPM.cmake)
```
### download 1
cpm can install the repo on github by syntex below.
```
CPMAddPackage(
  NAME fmt
  GIT_TAG 10.2.1
  GITHUB_REPOSITORY fmtlib/fmt
  OPTIONS "FMT_INSTALL YES" # create an installable target
)
```
下載的倉庫最好有CMakeLists.txt，不然你得手動指定編譯。

### download 2
```
CPMAddPackage("gh:TheLartians/PackageProject.cmake@1.8.0")
```
:::




:::warning
我沒用過，但先紀錄。
### cmake presets 跨平台編譯
```
cmake --preset=linux-release
cmake --preset=windows-release
```
### `CMakePresets.json` 文件
```
{
  "version": 3,
  "configurePresets": [
    {
      "name": "linux-release",
      "generator": "Ninja",
      "binaryDir": "build/linux-release",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Release"
      }
    },
    {
      "name": "windows-release",
      "generator": "Ninja",
      "binaryDir": "build/windows-release",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Release"
      }
    }
  ]
}

```
:::












