# 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" } } ] } ``` :::