報錯
target include libraries 應(yīng)當(dāng)在add_executable(cmake cmake.cpp)后面
cmakei下載
https://cmake.org/download/
我下載了 zip版本的,直接解壓縮就行。
解壓縮的步驟如下:
-
首先,你需要將下載好的 ZIP 壓縮包解壓縮到你想要存放 CMake 可執(zhí)行文件和相關(guān)資源的目錄中。這個目錄可以任意選定,只要有足夠的空間存放 CMake 文件即可。
-
解壓后,你可以在目錄中看到一個名為 “cmake-x.x.x-win64-x64” 的文件夾(其中“x.x.x”代表 CMake 的版本號),打開該文件夾即可看到 CMake 的可執(zhí)行文件和其他必需的資源文件,如下所示:
bin/
doc/
share/
LICENSE.txt
README.html
-
如果你希望在命令行中使用 CMake 命令,那么你需要將解壓縮后的 “bin” 目錄添加到系統(tǒng)環(huán)境變量的 Path 中。具體操作方法可以參考以下步驟:
-
右鍵點擊桌面左下角的“開始”按鈕,選擇“系統(tǒng)”。
-
在系統(tǒng)設(shè)置面板上,選擇“關(guān)于”選項卡,并記錄下自己的電腦名稱和系統(tǒng)版本號。
-
在搜索框中輸入“環(huán)境變量”并選擇“編輯系統(tǒng)環(huán)境變量”命令。
-
在彈出的“系統(tǒng)屬性”對話框中,選擇“高級”選項卡,然后點擊下方的“環(huán)境變量”按鈕。
-
在環(huán)境變量對話框中,找到“Path”變量并雙擊打開編輯對話框。
-
點擊“新建”按鈕,然后輸入剛才解壓縮出來的 CMake 可執(zhí)行文件所在的完整路徑,例如:C:\Program Files\cmake-x.x.x-win64-x64\bin
-
點擊“確定”按鈕,保存設(shè)置并關(guān)閉所有對話框。
-
至此,你已經(jīng)成功地將 CMake 安裝到了你的 Windows 操作系統(tǒng)中,并且可以在命令行中使用 CMake 命令進行項目構(gòu)建管理等操作。
cmake 官方教程
https://cmake.org/documentation/
教程1
step1
創(chuàng)建一個cmakelists.txt文件,最基本的,需要三個命令
add_executable()
cmake_minimum_required(VERSION 2.4)
project()
完善后直接執(zhí)行以下指令
mkdir Step1_build
cd Step1_build
cmake ../Step1 到上一級目錄的 step1目錄下查找cmakelists文件,然后使用 cmake 命令來執(zhí)行 CMakeLists.txt 中的構(gòu)建腳本,并將生成的構(gòu)建系統(tǒng)文件(如 Makefile 或 Ninja 構(gòu)建文件)保存到當(dāng)前目錄中。執(zhí)行完這個指令后,可以使用 make 或 ninja 命令來對代碼進行編譯和構(gòu)建。具體的構(gòu)建流程和命令可能會因項目而異,但一般情況下,上述步驟就可以讓我們成功地使用 CMake 來管理和構(gòu)建項目了。
cmake --build . 在當(dāng)前目錄下編譯
`cmake --build .` 是一個在命令行中使用 CMake 構(gòu)建系統(tǒng)進行構(gòu)建的指令。它會自動識別當(dāng)前目錄下的構(gòu)建系統(tǒng)文件(如 Makefile 或 Ninja 構(gòu)建文件),并執(zhí)行相應(yīng)的構(gòu)建過程來生成可執(zhí)行文件或庫文件等。
具體來說,`.` 表示當(dāng)前目錄,也就是 CMake 構(gòu)建腳本所在的目錄。執(zhí)行 `cmake --build .` 后,CMake 會查找當(dāng)前目錄下的構(gòu)建系統(tǒng)文件,并使用默認的構(gòu)建方式,例如 Makefile 時就會使用 `make` 命令進行構(gòu)建,Ninja 時則會使用 `ninja` 命令進行構(gòu)建。
需要注意的是,執(zhí)行 `cmake --build .` 前,需要先使用 `cmake` 命令來生成構(gòu)建系統(tǒng)文件。如果沒有在當(dāng)前目錄下生成構(gòu)建系統(tǒng)文件,則會出現(xiàn)構(gòu)建失敗的情況。
此外,在構(gòu)建過程中,還可以通過添加一些參數(shù)來指定編譯選項、目標(biāo)類型、生成路徑等信息。例如,可以使用 `-j` 參數(shù)來指定構(gòu)建線程數(shù),同時也可以使用 `--target` 參數(shù)來指定要構(gòu)建的目標(biāo)類型,以及使用 `-DCMAKE_BUILD_TYPE` 參數(shù)來指定構(gòu)建類型等。
總之,`cmake --build .` 可以幫助我們自動執(zhí)行構(gòu)建過程,而不需要手動執(zhí)行 Makefile 或其他構(gòu)建系統(tǒng)文件。但是,在使用這個命令前,需要確保當(dāng)前目錄下已經(jīng)存在構(gòu)建系統(tǒng)文件,并且可以進行正確的編譯和構(gòu)建。
`--build` 是 CMake 命令行工具中的一個參數(shù),用于在構(gòu)建系統(tǒng)中進行構(gòu)建和生成輸出文件。
這個參數(shù)可以讓 CMake 自動識別當(dāng)前目錄下的構(gòu)建系統(tǒng)文件(如 Makefile 或 Ninja 構(gòu)建文件),并執(zhí)行相應(yīng)的構(gòu)建操作。
當(dāng)使用 `cmake` 命令創(chuàng)建構(gòu)建系統(tǒng)文件后,我們可以執(zhí)行 `cmake --build` 命令來直接進行編譯、鏈接和打包等操作。例如,可以使用以下命令來進行構(gòu)建:
cmake --build . 在當(dāng)前目錄下編譯 鏈接 操作 相當(dāng)于mingw
上述命令中的 `.` 表示當(dāng)前目錄,CMake 會自動根據(jù)當(dāng)前目錄中的 CMakeLists.txt 文件生成對應(yīng)的構(gòu)建系統(tǒng)文件,然后執(zhí)行默認的構(gòu)建方式(如 Makefile 時就會執(zhí)行 make 命令)。
除了指定目錄外,`--build` 還支持其他一些可選參數(shù),例如:
- `--target`: 指定要構(gòu)建的目標(biāo)名稱。
- `--config`: 指定要構(gòu)建的配置類型(如 Debug 或 Release)。
- `--clean-first`: 在構(gòu)建之前首先清除輸出目錄。
- `-j`: 指定多線程構(gòu)建時使用的線程數(shù)等。
總之,`--build` 參數(shù)可以讓我們更便捷地執(zhí)行構(gòu)建操作,并且可以快速的在命令行中生成可執(zhí)行文件或庫文件等輸出結(jié)果。
最低版本
這里的 <min>
指的是在 cmake_minimum_required()
命令中指定的最低 CMake 版本號。當(dāng) <min>
的值大于 2.4 時,cmake_minimum_required()
命令會隱式地調(diào)用 cmake_policy(VERSION <min>[...<max>])
命令,以根據(jù)指定的版本范圍設(shè)置 CMake 策略(policies)。
反之,當(dāng) <min>
的值小于或等于 2.4 時,cmake_minimum_required()
命令會隱式地調(diào)用 cmake_policy(VERSION 2.4[...<max>])
命令,以啟用與 CMake 2.4 及以下版本的兼容性特性。
因此,這段話的意思是:當(dāng)在 cmake_minimum_required()
命令中指定的最低 CMake 版本號 <min>
大于 2.4 時,cmake_minimum_required()
命令會隱式地調(diào)用 cmake_policy(VERSION <min>[...<max>])
命令;而當(dāng) <min>
小于或等于 2.4 時,cmake_minimum_required()
命令會隱式地調(diào)用 cmake_policy(VERSION 2.4[...<max>])
命令。
最低為2.4, 如果低于2.4,比方說你給了個2.3,他會隱式的調(diào)用2.4.
報錯
具體為cmake configuration報錯
"D:\Microsoft VS Code\mingw64\bin\gcc.exe" 命令未找到
mingw32-make 命令未找到
首先,關(guān)于第一個問題,它表示你的系統(tǒng)缺少 GCC 編譯器或者它的路徑未正確添加到 PATH 環(huán)境變量中。你需要確認你的系統(tǒng)上已安裝了 GCC 編譯器,并且它的路徑被正確地添加到 PATH 環(huán)境變量中。你可以在終端中運行 gcc --version 命令來驗證 GCC 是否正確安裝并設(shè)置好了環(huán)境變量。
其次,關(guān)于第二個問題,它表示你的系統(tǒng)缺少 mingw32-make 工具或者它的路徑未正確添加到 PATH 環(huán)境變量中。你需要確認你的系統(tǒng)上已經(jīng)安裝了 MinGW 并且它的路徑被正確地添加到 PATH 環(huán)境變量中。你可以在終端中運行 mingw32-make --version 命令來驗證 MingGW 是否正確安裝并設(shè)置好了環(huán)境變量
兩個都是存在的
系統(tǒng)已經(jīng)正確安裝了 GCC 編譯器和 MinGW 并且它們的路徑也被正確地添加到 PATH 環(huán)境變量中。因此出現(xiàn)報錯的原因就不是因為缺少這兩個組件。
你可以嘗試在 VS Code 中打開終端窗口,進入到 CMakeLists.txt 所在的目錄下,然后執(zhí)行以下命令來進行編譯:
cmake -G "MinGW Makefiles" .
mingw32-make
第一條命令 cmake -G "MinGW Makefiles" . 是用來生成 Makefile 文件,并指定了使用 MinGW 生成器,同時“.”表示當(dāng)前目錄,即 CMakeLists.txt 所在的目錄。
第二條命令 mingw32-make 是用來執(zhí)行編譯操作的,它會根據(jù) Makefile 文件中的指令進行編譯。需要注意的是,在使用 mingw32-make 命令之前,你需要確保當(dāng)前工作目錄已經(jīng)是包含 Makefile 文件的目錄。因此,. 表示當(dāng)前目錄,也就是 Makefile 文件所在的目錄。
總而言之,這兩條命令的組合就是先通過 CMake 生成 Makefile 文件,然后再使用 mingw32-make 命令進行編譯。
報錯2 vscode 路徑?jīng)]有配置好
到這里再次 cmake configuration
[proc] Executing command: "D:\Microsoft VS Code\mingw64\bin\gcc.exe" -v
[proc] The command: "D:\Microsoft VS Code\mingw64\bin\gcc.exe" -v failed with error: Error: spawn D:\Microsoft VS Code\mingw64\bin\gcc.exe ENOENT
[proc] The command: mingw32-make --version failed with error: Error: spawn mingw32-make ENOENT
[main] Unable to determine what CMake generator to use. Please install or configure a preferred generator, or update settings.json, your Kit configuration or PATH variable. Error: No usable generator found.
[main] Configuring project: cmake
vscode沒有配置好
根據(jù)你提供的信息,報錯信息顯示 CMake 在執(zhí)行命令行時無法找到對應(yīng)的程序,可能是因為 GCC 或者 MinGW 沒有正確安裝或者其路徑?jīng)]有被正確地添加到環(huán)境變量中。具體來說,ENOENT
錯誤代碼表示系統(tǒng)找不到指定文件路徑的程序。
你可以嘗試按照以下步驟進行排查:
-
確認 GCC 和 MinGW 已經(jīng)成功安裝在你的電腦上,且安裝路徑已經(jīng)添加到 PATH 環(huán)境變量中。可以在終端中分別執(zhí)行
gcc --version
和mingw32-make --version
命令來檢查 GCC 和 MinGW 的版本信息。 -
如果你使用的是 VS Code,可以在 VS Code 的“設(shè)置”中搜索“Path”關(guān)鍵字,然后在“Terminal > Integrated > Env: Path”選項中添加 GCC 和 MinGW 的安裝路徑。這樣做可以確保終端窗口能夠正確識別到 GCC 和 MinGW 的安裝路徑。
-
如果你使用的是其他 IDE 或編輯器,可以查看對應(yīng)軟件的文檔,了解如何添加環(huán)境變量或者指定 GCC 和 MinGW 的路徑。
如果上述方法仍然不能解決問題,可以重新安裝 GCC 和 MinGW 并確保其正確添加到 PATH 環(huán)境變量中。
Unable to determine what CMake generator to use. Please install or configure a preferred generator, or update settings.json, your Kit configuration or PATH variable. 是不是跟這個有關(guān),我需要配置相關(guān)文件
是的,這個錯誤提示與 CMake 的生成器配置有關(guān)。通過這個錯誤提示,我們可以得知 CMake 無法自動識別所使用的生成器,需要手動進行配置。
你可以嘗試更改 CMakeLists.txt 文件中的 project()
命令后面所跟隨的參數(shù),以指定所需要的 CMake 生成器。例如,以下命令將指定使用 MinGW 作為代碼編譯器:
project(MyProject CXX)
set(CMAKE_C_COMPILER "D:/mingw64/bin/gcc.exe")
set(CMAKE_CXX_COMPILER "D:/mingw64/bin/g++.exe")
其中,CMAKE_C_COMPILER
和 CMAKE_CXX_COMPILER
是用來指定 GCC 和 G++ 編譯器路徑的變量,你需要將其指定為你所使用的編譯器的實際路徑。在這個示例中,我們將編譯器安裝在 D:/mingw64/bin/
目錄下,因此需要指定相應(yīng)的路徑。
另外,還可以通過修改 VS Code 的 settings.json
文件來指定所使用的 CMake 生成器。你可以在該文件中添加以下設(shè)置:
{
"cmake.generator": "MinGW Makefiles"
}
這里,“MinGW Makefiles”表示使用 MinGW 作為 CMake 生成器。你也可以根據(jù)實際情況選擇其他合適的生成器類型。
setting.json
另外,還可以通過修改 VS Code 的 settings.json 文件來指定所使用的 CMake 生成器。如何調(diào)出setting.json,ctrl+shift+p嗎
是的,您可以使用快捷鍵 Ctrl + Shift + P
來打開 VS Code 的命令面板,然后輸入 “Open Settings (JSON)” 或者 “打開設(shè)置(JSON文件)” 來打開 settings.json 文件。
在打開的 JSON 配置文件中添加以下內(nèi)容,就可以指定 CMake 使用 MinGW 作為生成器:
{
"cmake.generator": "MinGW Makefiles"
}
保存文件后,關(guān)閉并重新打開 VS Code,CMake 就會自動識別并使用 MinGW 作為默認的生成器來構(gòu)建項目。請注意,如果您在 CMakeLists.txt 中明確指定了其他的生成器,那么這個設(shè)置將被覆蓋。
通過該方式打開的似乎是一個全局的文件,可以為本工作文件夾下設(shè)置一個本地的嗎
是的,您可以設(shè)置一個本地的 Workspace 設(shè)置來覆蓋全局設(shè)置,這樣就只會影響當(dāng)前工作區(qū)域中的所有文件。以下是具體步驟:
-
在 VS Code 中打開您的工作文件夾,并右鍵單擊左側(cè)的資源管理器窗口中的
.vscode
文件夾。 -
在彈出的上下文菜單中,選擇 “新建文件”(New File) 選項,創(chuàng)建一個名為
settings.json
的新文件。 -
在新文件中添加以下內(nèi)容:
{
"cmake.generator": "MinGW Makefiles"
}
- 保存文件后,關(guān)閉并重新打開 VS Code。
現(xiàn)在,VS Code 將會使用您在本地設(shè)置文件中指定的 CMake 生成器。如果您想要清除本地設(shè)置并恢復(fù)全局設(shè)置,只需要刪除 .vscode
文件夾下的 settings.json
文件即可。
報錯3
你上面讓我cmake -G “MinGW Makefiles” . 相當(dāng)于避開了這個問題嗎,他是怎么做到的
是的,使用 cmake -G "MinGW Makefiles" .
命令可以直接指定使用 MinGW 作為 CMake 的生成器,從而避免了無法確定生成器的問題。
這個命令通過 -G
參數(shù)指定了生成器類型,后面的參數(shù) .
表示當(dāng)前目錄。執(zhí)行這個命令之后,CMake 就會自動在當(dāng)前目錄下生成適合 MinGW 編譯器的 Makefile 文件,并以此來進行代碼的編譯和構(gòu)建。
相比于手動修改 CMakeLists.txt 文件或者 VS Code 的 settings.json
文件來設(shè)置生成器,使用命令行指定生成器可以更加簡單快捷,不需要修改配置文件。只要保證 MinGW 的安裝路徑已經(jīng)添加到 PATH 環(huán)境變量中,就可以直接在終端中運行上述命令,完成編譯工作。
配置cmake工具鏈
The kit “GCC 8.1.0 x86_64-w64-mingw32” references a non-existent compiler binary [D:\Microsoft VS Code\mingw64\bin\gcc.exe]. What would you like to do?這什么意思
這意味著您使用的 CMake 工具鏈中指定了一個不存在的編譯器二進制文件 “D:\Microsoft VS Code\mingw64\bin\gcc.exe”。
您需要檢查該路徑下是否存在 “gcc.exe” 可執(zhí)行文件,如果沒有,可能是由于 MinGW 工具鏈未正確安裝或配置所致。請嘗試重新安裝 MinGW 工具鏈,并確保將其添加到 PATH 環(huán)境變量中。
如果 “gcc.exe” 文件存在,但仍然無法被找到,請檢查 CMake 工具鏈文件是否正確配置。您可以在 CMake 插件的設(shè)置頁面中檢查和修改 CMake 工具鏈配置。
如果還有其他問題,請?zhí)峁└嘈畔⒁员阄夷軌驇椭鉀Q問題。
配置 CMake 工具鏈的方法如下:
-
打開 VS Code 中的 CMake 工具鏈設(shè)置頁面。您可以通過側(cè)邊欄中的 “CMake” 圖標(biāo)打開,或者在 VS Code 菜單中選擇 “File” -> “Preferences” -> “Settings”,然后搜索 “cmake.toolchain”。
-
找到 “cmake.toolchain” 設(shè)置項,并點擊 “Edit in settings.json” 按鈕進行編輯。
-
在 “cmake.toolchain” 的值域中添加工具鏈文件的路徑和名稱,例如:
"cmake.toolchain": "/path/to/mytoolchain.cmake"
- 打開指定的工具鏈文件(如上例中的 mytoolchain.cmake),并按照需要配置編譯器和相關(guān)工具的路徑、編譯選項、鏈接選項等信息。例如:
SET(CMAKE_C_COMPILER /path/to/gcc)
SET(CMAKE_CXX_COMPILER /path/to/g++)
SET(CMAKE_AR /path/to/ar)
SET(CMAKE_RANLIB /path/to/ranlib)
SET(CMAKE_C_FLAGS "-Wall -O2")
SET(CMAKE_CXX_FLAGS "-Wall -O2")
SET(CMAKE_EXE_LINKER_FLAGS "-L/path/to/libs -lmylib")
- 配置完畢后,保存工具鏈文件并重新打開 CMake 插件的界面,讓插件重新掃描項目并嘗試使用指定的生成器和編譯器來構(gòu)建項目。
如果您遇到任何問題,請告訴我。
如果您在 VS Code 的設(shè)置中沒有找到 “cmake.toolchain” 配置項,可能是因為您當(dāng)前沒有打開 CMake 項目或者缺少必要的擴展插件。
請確保您已經(jīng)安裝了 CMake Tools 擴展插件,該插件提供了 CMake 項目的關(guān)鍵功能,并且支持用戶配置 CMake 工具鏈。
如果您已經(jīng)安裝了 CMake Tools 插件,但仍然無法找到 “cmake.toolchain” 配置項,請嘗試使用以下方法進行配置:
- 在 CMake 項目文件夾下創(chuàng)建一個名為 “toolchain.cmake” 的文件,用于指定特定的編譯器、鏈接器和其他構(gòu)建工具的路徑、選項等信息。例如:
SET(CMAKE_C_COMPILER /path/to/gcc)
SET(CMAKE_CXX_COMPILER /path/to/g++)
SET(CMAKE_AR /path/to/ar)
SET(CMAKE_RANLIB /path/to/ranlib)
SET(CMAKE_C_FLAGS "-Wall -O2")
SET(CMAKE_CXX_FLAGS "-Wall -O2")
SET(CMAKE_EXE_LINKER_FLAGS "-L/path/to/libs -lmylib")
-
在 VS Code 中打開 CMake 項目文件夾,然后在狀態(tài)欄中單擊 “Configure” 按鈕。如果狀態(tài)欄中沒有 “Configure” 按鈕,則可以通過菜單 “View” -> “Command Palette” -> “CMake: Configure” 來達到同樣的效果。
-
在彈出的 “Configure” 對話框中,選擇 “Advanced” 選項卡,并在 “CMake toolchain file” 選項中指定工具鏈文件的路徑,例如:
-D CMAKE_TOOLCHAIN_FILE=/path/to/toolchain.cmake
-
點擊 “Configure” 按鈕,進行 CMake 配置。
-
在配置完成后,您可以在狀態(tài)欄中單擊 “Build” 按鈕開始構(gòu)建項目。如果狀態(tài)欄中沒有 “Build” 按鈕,則可以通過菜單 “View” -> “Command Palette” -> “CMake: Build” 來達到同樣的效果。
如果您仍然遇到問題,請?zhí)峁└嘣敿毿畔⒁员阄夷軌蚋玫貛椭鉀Q問題。
準確的流程
在build文件夾下
PS F:\cmake\steo1_build> cmake -G "MinGW Makefiles" ..
PS F:\cmake\steo1_build> mingw32-make
[ 50%] Building CXX object CMakeFiles/cmake.dir/cmake.cpp.obj
[100%] Linking CXX executable cmake.exe
[100%] Built target cmake
PS F:\cmake\steo1_build> cd ..
PS F:\cmake> ./cmake
1000
報錯4 cpp中main函數(shù)返回值
cpp中main函數(shù)必要要有一個返回值
是的,C++ 中程序的入口函數(shù) main()
必須要有一個 int
類型的返回值。這個返回值指示程序的運行狀態(tài),可以用來告訴操作系統(tǒng)程序是否正常結(jié)束。
在 C++ 標(biāo)準中規(guī)定,main()
函數(shù)的返回類型必須是 int
,不能是其他類型。一般情況下,如果程序正常運行并且沒有出現(xiàn)錯誤,我們可以將返回值設(shè)置為 0,表示程序正常結(jié)束。如果程序出現(xiàn)了某些錯誤,可以返回其他非零的整數(shù)值,以便向操作系統(tǒng)表明程序發(fā)生了錯誤并且退出了。
所以在您的代碼中,如果 main()
函數(shù)沒有返回任何值,或者返回了一個非整數(shù)值,都會導(dǎo)致編譯錯誤。要解決這個問題,只需要將 main()
函數(shù)的返回類型改為 int
,并在函數(shù)末尾添加 return 0;
即可。
問題結(jié)果
一開始進去 會提示你來自cmake tool的配置cmake 工程
這個時候點擊配置 就會報錯,因為他默認會有一個錯誤的路徑,他會到這個錯誤的路徑下查找什么 gcc,它上面也告訴你了,
The kit “GCC 8.1.0 x86_64-w64-mingw32” references a non-existent compiler binary [D:\Microsoft VS Code\mingw64\bin\gcc.exe]. What would you like to do?
這個時候點擊 remove去除,再次配置就成功了,他會默認生成build文件夾。
這個時候 單純的cmake什么的命令就沒問題了
官方教程2 specifying the c++ standard
cmake有一些特殊的變量,都各自有意義,通常以CMAKE_ 開頭,這里介紹兩個
CMAKE_CXX_STANDARD
CMAKE_CXX_STANDARD_REQUIRED
set()
需要編輯兩個文件:
CMakeLists.txt
tutorial.cxx
在cpp文件中添加了c++11所需要的特征指令
// TODO 4: Replace atof(argv[1]) with std::stod(argv[1])
const double inputValue = atof(argv[1]);
#include <cstdlib> // TODO 5: Remove this line
# TODO 6: Set the variable CMAKE_CXX_STANDARD to 11
# and the variable CMAKE_CXX_STANDARD_REQUIRED to True
// TODO 6: Replace sqrt with mathfunctions::sqrt
// calculate square root
const double outputValue = sqrt(inputValue);
cmakelists
確保 cmake cxx standard聲明在 add executable() 前面
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
atof stod
atof()
和 std::stod()
都是將字符串轉(zhuǎn)換成浮點數(shù)的函數(shù)。但它們有以下不同:
-
標(biāo)準庫函數(shù)
std::stod()
是 C++11 引入的,而atof()
則是 C 標(biāo)準庫里的函數(shù),它們所屬的語言和標(biāo)準不同。 -
atof()
只能將字符串轉(zhuǎn)換成double
類型的浮點數(shù),而std::stod()
可以將字符串轉(zhuǎn)換成任意精度的浮點數(shù)類型(如float
、double
、long double
等)。 -
atof()
和std::stod()
對于不合法的輸入字符串的處理方式不同。atof()
無法檢測輸入字符串是否合法,如果輸入字符串不是有效的浮點數(shù)格式,則會返回一個未定義值。而std::stod()
會拋出std::invalid_argument
異?;?std::out_of_range
異常,以指示輸入字符串無效。 -
std::stod()
支持多種進制的浮點數(shù)轉(zhuǎn)換,可以指定參數(shù) base 來指定轉(zhuǎn)換進制。而atof()
僅支持十進制的浮點數(shù)轉(zhuǎn)換。 -
std::stod()
能夠?qū)崿F(xiàn)更好的精度控制,例如可以設(shè)置輸出精度和舍入模式等。而atof()
無法進行更細致的精度控制。
總之,在 C++11 及以上版本的項目中,推薦使用 std::stod()
函數(shù)來進行浮點數(shù)字符串轉(zhuǎn)換操作,因為它更加安全、靈活和易于維護。如果您在 C 語言項目中使用,則只能使用 atof()
或者自行實現(xiàn)一個浮點數(shù)字符串轉(zhuǎn)換函數(shù)。
sqrt
sqrt()
函數(shù)是標(biāo)準 C++ 庫定義的一個函數(shù),用于計算一個 double 類型數(shù)的平方根。而 mathfunctions::sqrt()
是一個自定義的命名空間 mathfunctions 中定義的函數(shù),也是用于計算 double 類型數(shù)的平方根。
兩者在功能上并沒有本質(zhì)上的差別,都可以進行浮點數(shù)的開根運算。但是 mathfunctions::sqrt()
是由用戶自定義的函數(shù),可以自行實現(xiàn)和修改,比如可以添加更多的參數(shù)檢查、異常處理等功能。而標(biāo)準庫函數(shù) sqrt()
則是由 C++ 標(biāo)準委員會制定的規(guī)范,具有較高的通用性和可移植性。
此外,如果您使用了命名空間 using namespace std;
,則可以直接調(diào)用標(biāo)準庫函數(shù) sqrt()
,而省略前綴 std::。但是如果您的代碼中使用了其他自定義的函數(shù)或變量,可能會出現(xiàn)名字沖突的問題,建議使用 namespace 前綴來明確指定函數(shù)的來源。
cstdlib
cstdlib
是 C++ 標(biāo)準庫中的一個頭文件,其中定義了一些與標(biāo)準 C 庫函數(shù)相關(guān)的常量、類型、函數(shù)等。該頭文件在 C 和 C++ 中都可以使用。
其中包含的一些常用函數(shù)有:
-
std::atoi()
:將字符串轉(zhuǎn)換為整型數(shù),其功能與 C 標(biāo)準庫的atoi()
函數(shù)相同。 -
std::atof()
:將字符串轉(zhuǎn)換為浮點型數(shù),其功能與 C 標(biāo)準庫的atof()
函數(shù)相同。 -
std::rand()
:生成一個隨機數(shù),其功能與 C 標(biāo)準庫的rand()
函數(shù)相同。 -
std::exit()
:結(jié)束程序,并返回一個指定的退出碼,其功能與 C 標(biāo)準庫的exit()
函數(shù)相同。 -
std::system()
:調(diào)用系統(tǒng)命令,其功能與 C 標(biāo)準庫的system()
函數(shù)相同。
此外,cstdlib
還定義了一些常量,例如 EXIT_SUCCESS
和 EXIT_FAILURE
表示程序正常執(zhí)行和執(zhí)行失敗時的退出碼。
總之,cstdlib
頭文件提供了一些實用的 C 標(biāo)準庫函數(shù)和常量,方便我們在 C++ 程序中進行系統(tǒng)調(diào)用、字符串處理、數(shù)字轉(zhuǎn)換等操作。
exercise 3 Adding a Version Number and Configured Header File
在你的源代碼文件中有一個你在cmakelists里定義的變量,該做法優(yōu)勢會很有用。
一個做法是使用一個配置的 header 文件。 創(chuàng)建一個輸入文件,里面包含多個用于替換的變量。
這些變量有特別的語法,看起來像 @VAR@
使用 configure_file()命令來將輸入文件拷貝至一個給定的輸出文件,并替換這些變量在cmakelist文件里的值
雖然我們可以直接在源代碼中編輯版本,但使用這個特性更加推薦,因為它可以創(chuàng)建一個單一的真相源,避免重復(fù)。
編輯的文件
CMakeLists.txt
tutorial.cxx
<PROJECT-NAME>_VERSION_MAJOR
<PROJECT-NAME>_VERSION_MINOR
configure_file()
target_include_directories()
創(chuàng)建1個頭文件 xxx.h 定義了版本數(shù)字,他會接收由configure file傳遞過來的變量
project(Tutorial VERSION 1.0) CMake defines Tutorial_VERSION_MAJOR and Tutorial_VERSION_MINOR behind the scenes.
configure_file(TutorialConfig.h.in TutorialConfig.h) 通過· 來分隔數(shù)字
target_include_directories(Tutorial PUBLIC
"${PROJECT_BINARY_DIR}"
)
在示例中,Tutorial 是指示要創(chuàng)建的目標(biāo)名稱,PUBLIC 則指示這個搜索路徑將作為其接口的一部分公開,即在編譯目標(biāo)時需要包括此目錄。 public是默認的可以省略
創(chuàng)建 頭文件
引入頭文件
#include "TutorialConfig.h"
增加代碼直接使用變量
if (argc < 2) {
// report version
std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
<< Tutorial_VERSION_MINOR << std::endl;
std::cout << "Usage: " << argv[0] << " number" << std::endl;
return 1;
}
創(chuàng)建一個 xxx.h.in作為輸入文件,輸出文件會根據(jù)你的路徑創(chuàng)建出
輸出文件里 @ @中的變量被替代了
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
總結(jié)
相當(dāng)于設(shè)置變量 讓cmakelist里的變量傳入 代碼文件
解釋
是的,CMake 在定義 project(Tutorial VERSION 1.0)
的同時,會根據(jù)版本號自動定義兩個變量 Tutorial_VERSION_MAJOR
和 Tutorial_VERSION_MINOR
,其值分別為版本號中的主版本號和次版本號。
例如,如果設(shè)置 project(Tutorial VERSION 1.2.3)
,則會自動生成下面兩個變量:
set(Tutorial_VERSION_MAJOR 1)
set(Tutorial_VERSION_MINOR 2)
這些自動生成的變量可以在 CMakeLists.txt 文件中使用,比如生成一個帶有版本號的頭文件。通常做法是使用 configure_file()
函數(shù),將一個包含 ${Tutorial_VERSION_MAJOR}
和 ${Tutorial_VERSION_MINOR}
的頭文件模板復(fù)制到構(gòu)建目錄,并將其中的變量替換為實際的版本號,然后將生成的頭文件添加到源代碼中。
例如,假設(shè)我們有一個包含版本號的頭文件模板 version.h.in:
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
然后可以在 CMakeLists.txt 文件中添加以下語句:
configure_file(version.h.in ${PROJECT_BINARY_DIR}/version.h)
include_directories(${PROJECT_BINARY_DIR})
這段代碼會將 version.h.in 復(fù)制到構(gòu)建目錄中的 version.h,并將其中的變量替換為實際的版本號。然后通過將 ${PROJECT_BINARY_DIR}
添加到 include_directories() 中,可以確保頭文件能夠被正確地包含在項目中。
是的,您說得對,我犯了一個錯誤。project(Tutorial VERSION 1.2.3)
定義的不僅僅是一個版本號,而是一個包含三個數(shù)字的完整版本號,其中 1
是主版本號,2
是次版本號,3
是修訂號。
CMake 在定義 project()
的同時,自動為項目定義了以下變量:
-
ProjectName_VERSION
:等于指定的版本號,即 “1.2.3”。 -
ProjectName_VERSION_MAJOR
:等于指定的主版本號,即 “1”。 -
ProjectName_VERSION_MINOR
:等于指定的次版本號,即 “2”。 -
ProjectName_VERSION_PATCH
:等于指定的修訂號,即 “3”。 -
ProjectName_VERSION_TWEAK
:如果指定了第四個數(shù)字,則等于該數(shù)字,否則沒有定義(也就是說,該變量只有當(dāng)版本號中包含四個數(shù)字時才會被定義)。
需要注意的是,這些變量的名稱始終是全部大寫的,并且是自動生成的,因此在 CMakeLists.txt 文件中無需手動定義它們。我們可以在項目中使用這些變量來包含版本信息、生成帶版本號的文件名等。
示例:
# 指定項目名稱和版本號
project(Tutorial VERSION 1.2.3)
# 生成帶版本號的可執(zhí)行文件
add_executable(MyApp_${PROJECT_NAME}_${PROJECT_VERSION} main.cpp)
# 輸出項目版本信息
message("MyApp version: ${PROJECT_VERSION}")
解釋2
在 CMake 中,可以使用 configure_file()
命令將一個輸入文件中的內(nèi)容復(fù)制到另一個輸出文件中,并且可以根據(jù)變量的值修改輸入文件中的內(nèi)容。在 configure_file()
命令中,@
符號和 ${}
語法用于引用 CMake 變量。而 .in
則是作為輸入文件的后綴名稱。
以 configure_file(version.h.in ${PROJECT_BINARY_DIR}/version.h)
為例,version.h.in
是一個輸入文件,其中包含了一些占位符,例如:
#define PROJECT_VERSION "@PROJECT_VERSION@"
在運行 configure_file()
命令時,CMake 會讀取 version.h.in
文件的內(nèi)容,并將 @PROJECT_VERSION@
替換為實際的項目版本號。然后,CMake 會將修改后的內(nèi)容寫入 ${PROJECT_BINARY_DIR}/version.h
文件中。
因此,version.h.in
的 .in
后綴只是為了表示這是一個輸入文件,以便 CMake 正確地處理它。在實際使用中,我們可以將輸入文件命名為任何字符串,只要在調(diào)用 configure_file()
命令時正確指定即可。例如,您也可以將 version.h.in
改為 version_template.h
,并使用以下命令進行配置:
configure_file(version_template.h ${PROJECT_BINARY_DIR}/version.h)
這樣也是可以的。
是的,在運行 configure_file()
命令時,CMake 會自動創(chuàng)建輸出文件 ${PROJECT_BINARY_DIR}/version.h
并將修改后的內(nèi)容寫入其中。${PROJECT_BINARY_DIR}
是 CMake 內(nèi)置的變量,表示構(gòu)建目錄的絕對路徑。
需要注意的是,如果輸出文件所在的目錄不存在,則 CMake 會自動創(chuàng)建該目錄。如果您希望輸出文件的目錄與輸入文件的目錄結(jié)構(gòu)相同,則可以在命令中使用 ${CMAKE_CURRENT_SOURCE_DIR}
變量,該變量表示當(dāng)前正在處理的 CMakeLists.txt 所在的目錄。例如:
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h)
這樣,CMake 將根據(jù) version.h.in
文件在 ${CMAKE_CURRENT_BINARY_DIR}
目錄下創(chuàng)建一個名為 version.h
的文件,并將修改后的內(nèi)容寫入其中。
總之,在運行 configure_file()
命令時,CMake 會自動創(chuàng)建輸出文件并寫入其中,不需要用戶手動創(chuàng)建。
解釋3
include_directories()
命令用于向 CMake 項目中添加包含文件的搜索路徑。${PROJECT_BINARY_DIR}
是 CMake 內(nèi)置的變量,表示構(gòu)建目錄的絕對路徑。因此,這個命令可以將 ${PROJECT_BINARY_DIR}
目錄添加到包含文件的搜索路徑中,以便在源代碼中引用生成的 version.h
文件。
具體來說,如果在 CMakeLists.txt 文件中添加了以下代碼:
project(MyProject VERSION 1.0)
configure_file(version.h.in ${PROJECT_BINARY_DIR}/version.h)
include_directories(${PROJECT_BINARY_DIR})
則 CMake 將處理 version.h.in
文件并生成 ${PROJECT_BINARY_DIR}/version.h
文件,并將 ${PROJECT_BINARY_DIR}
目錄添加到包含文件的搜索路徑中。在源代碼中,可以使用 #include "version.h"
來引用 version.h
文件中定義的宏 PROJECT_VERSION
。
例如,在一個名為 main.c
的源代碼文件中,可以編寫以下代碼來使用 PROJECT_VERSION
宏:
#include <stdio.h>
#include "version.h"
int main()
{
printf("Project version: %s\n", PROJECT_VERSION);
return 0;
}
這樣,CMake 將自動在構(gòu)建期間為該項目生成版本號,并將其定義為 PROJECT_VERSION
宏,供源代碼中的其他部分使用。然后,當(dāng)您構(gòu)建項目并運行生成的可執(zhí)行文件時,它將輸出您在 CMakeLists.txt 文件中指定的項目版本號。
因此,include_directories(${PROJECT_BINARY_DIR})
命令實際上將 ${PROJECT_BINARY_DIR}
目錄添加到包含文件的搜索路徑中,以便在源代碼中引用生成的 version.h
文件。
step2 adding a library
exercise 1 creating a library
怎么在工程中使用庫
使用 add library()并確認加入什么代碼文件
可以增加一個cmakelist并增加多個代碼文件
并在頂層的cmakelist里面使用add subdirectory增加子目錄
一旦庫被建立,可以通過target include directories 和 target link libraries來連接可執(zhí)行的目標(biāo)文件
可以看他的文件目錄結(jié)構(gòu)
add_library()
add_subdirectory()
target_include_directories()
target_link_libraries()
PROJECT_SOURCE_DIR
add_library(MathFunctions MathFunctions.cxx mysqrt.cxx) 在里面的cmakelist里面添加
第一個參數(shù)是庫的名稱
add_subdirectory(MathFunctions) 在外層的cmakelist添加
target_link_libraries(Tutorial PUBLIC MathFunctions) 連接庫與可執(zhí)行文件
target_include_directories(Tutorial PUBLIC 確認庫的頭文件的位置
"${PROJECT_BINARY_DIR}"
"${PROJECT_SOURCE_DIR}/MathFunctions"
)
在mian.cpp中加入
#include "MathFunctions.h"
文件如下:
#pragma once
namespace mathfunctions {
double sqrt(double x);
}
最后修改參數(shù)
const double outputValue = mathfunctions::sqrt(inputValue);
PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR都指向當(dāng)前工程目錄嗎
PROJECT_BINARY_DIR
和 PROJECT_SOURCE_DIR
變量分別指向當(dāng)前 CMake 工程的構(gòu)建目錄和源代碼目錄。
其中,PROJECT_BINARY_DIR
是構(gòu)建目錄,指編譯產(chǎn)生的二進制文件、庫文件等輸出目錄。而 PROJECT_SOURCE_DIR
則是源代碼目錄,通常包含了 CMakeLists.txt 文件、頭文件、源文件等等。
需要注意的是,PROJECT_BINARY_DIR
和 PROJECT_SOURCE_DIR
可能不總是指向當(dāng)前工程的根目錄。這兩個變量的值是由 project()
命令的第一個參數(shù)指定的項目名稱得出的。如果在 project()
命令中指定了項目子目錄,那么 PROJECT_BINARY_DIR
和 PROJECT_SOURCE_DIR
就會相應(yīng)地指向子目錄。
例如,在以下工程結(jié)構(gòu)中,
MyProject/
├── CMakeLists.txt
├── build/
│ ├── CMakeFiles/
│ └── Makefile
└── src/
├── CMakeLists.txt
├── main.cpp
└── sub/
├── CMakeLists.txt
├── lib.cpp
└── lib.h
當(dāng)我們在 MyProject/CMakeLists.txt
中調(diào)用 project(MyProject)
命令時,PROJECT_BINARY_DIR
和 PROJECT_SOURCE_DIR
分別指向 MyProject/build
和 MyProject/src
目錄。
如果我們在 MyProject/src/CMakeLists.txt
中再次調(diào)用 project(SubProject)
命令并添加一個子目錄 sub
,那么 PROJECT_BINARY_DIR
和 PROJECT_SOURCE_DIR
就會相應(yīng)地指向 MyProject/build/sub
和 MyProject/src
目錄。
因此,需要根據(jù)具體情況來使用 PROJECT_BINARY_DIR
和 PROJECT_SOURCE_DIR
變量。
add library
add_library()
是 CMake 中的一個命令,用于向項目中添加一個庫文件。它的語法如下:
add_library(<name> [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL]
source1 [source2 ...])
其中,<name>
是要創(chuàng)建的庫文件的名稱,STATIC
、SHARED
和 MODULE
是可選的構(gòu)建類型,其意義分別是創(chuàng)建靜態(tài)庫、共享庫和模塊庫。EXCLUDE_FROM_ALL
用于將這個庫從默認的構(gòu)建目標(biāo)列表中排除。source1
、source2
等參數(shù)則是編譯庫文件所需的源代碼文件。
add_library()
命令可以創(chuàng)建多種類型的庫文件,具體取決于使用的構(gòu)建類型。使用 STATIC
構(gòu)建類型創(chuàng)建的庫文件是靜態(tài)庫(也稱為歸檔庫),它將在鏈接時與應(yīng)用程序一起鏈接。使用 SHARED
構(gòu)建類型創(chuàng)建的庫文件是共享庫(也稱為動態(tài)庫),它將在應(yīng)用程序運行時加載。而使用 MODULE
構(gòu)建類型創(chuàng)建的庫文件是模塊庫,它通常用于插件式架構(gòu),可在運行時動態(tài)加載和卸載。
CMake 在生成構(gòu)建系統(tǒng)時會自動根據(jù)操作系統(tǒng)和編譯器等信息選擇庫文件的適當(dāng)構(gòu)建類型和后綴名,例如 .a
、.lib
或 .so
。
使用 add_library()
命令可以將多個源文件合并為一個庫文件。這種庫文件通常包含一組相關(guān)的類、函數(shù)或?qū)ο螅部梢詫⑵溆米髌渌创a文件的依賴項。
總之,add_library()
命令是 CMake 中用于創(chuàng)建庫文件的命令,它允許將多個源代碼文件合并成一個庫文件,并可選擇不同的構(gòu)建類型,例如靜態(tài)庫、共享庫或模塊庫等。
add subdirectory
add_subdirectory()
和 target_link_libraries()
都是 CMake 中與庫文件相關(guān)的命令,但它們的作用是不同的。
add_subdirectory(MathFunctions)
命令用于向 CMake 項目中添加一個子目錄,并在該目錄中構(gòu)建一個新的 CMake 項目。這個子目錄中的 CMakeLists.txt 文件可以包含一些其他的 add_library()
、add_executable()
等命令來定義新的庫或可執(zhí)行文件。當(dāng)使用 add_subdirectory()
命令添加一個子目錄后,CMake 將會為這個子目錄構(gòu)建一個新的 Makefile 或者其他生成方法所需的構(gòu)建系統(tǒng)。
target_link_libraries(Tutorial PUBLIC MathFunctions)
命令則是用于將目標(biāo)文件與一個或多個庫文件進行鏈接。在本例中,Tutorial
是由 add_executable()
命令創(chuàng)建的可執(zhí)行文件的名稱。PUBLIC
關(guān)鍵字告訴 CMake 該鏈接庫應(yīng)該同時應(yīng)用于 Tutorial
及其公共依賴關(guān)系。MathFunctions
則是指用于鏈接的庫文件名。
這兩個命令通常在不同的 CMakeLists.txt 文件中使用,它們的作用也是不同的。add_subdirectory()
用于在一個 CMake 項目中添加一個子目錄,并構(gòu)建其中定義的新的庫或可執(zhí)行文件。而 target_link_libraries()
則用于將一個或多個庫文件鏈接到一個目標(biāo)文件中(例如可執(zhí)行文件或者其他庫文件)。
因此,在一個 CMake 項目的根目錄中,我們可以使用 add_subdirectory()
命令添加子目錄,并在這些子目錄的 CMakeLists.txt 文件中使用 add_library()
命令創(chuàng)建庫文件。然后我們可以在需要使用這些庫文件的目標(biāo)文件(例如可執(zhí)行文件)的 CMakeLists.txt 文件中使用 target_link_libraries()
命令將這些庫文件鏈接起來。這樣就可以方便地管理和構(gòu)建整個項目。
指定路徑
注意,在使用 add_subdirectory() 命令添加子目錄時,CMake 會自動將子目錄中定義的庫文件添加到當(dāng)前項目中,并將其編譯成為共享庫或靜態(tài)庫,具體取決于 add_library() 命令中的參數(shù)。因此,在使用 target_link_libraries() 命令時,可以直接將庫文件名作為參數(shù)傳遞給該命令,而不需要指定庫文件的路徑。如果需要指定庫文件的位置信息,可以使用變量來表示路徑等信息。
在使用 target_link_libraries()
命令時,可以通過指定庫文件的路徑或者使用變量來表示庫文件的位置信息。下面分別介紹這兩種方式:
- 指定庫文件的路徑
如果庫文件位于當(dāng)前目錄下的子目錄中,可以使用相對路徑來指定庫文件的位置。例如,如果要將名為 libMyLib.a
的靜態(tài)庫文件鏈接到當(dāng)前目標(biāo)文件中,可以使用以下命令:
target_link_libraries(MyTarget PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/libs/libMyLib.a)
其中 ${CMAKE_CURRENT_SOURCE_DIR}
是一個 CMake 變量,表示當(dāng)前 CMakeLists.txt 文件所在的目錄。${CMAKE_CURRENT_SOURCE_DIR}/libs/libMyLib.a
表示該庫文件所在的目錄為 libs
目錄,文件名為 libMyLib.a
。
如果庫文件位于外部目錄中,可以使用絕對路徑或者相對路徑來指定庫文件的位置。例如,如果要鏈接 /home/user/mylibs/libMyLib.so
動態(tài)庫文件,可以使用以下命令:
target_link_libraries(MyTarget PUBLIC /home/user/mylibs/libMyLib.so)
- 使用變量來表示庫文件的位置信息
除了使用絕對路徑、相對路徑來指定庫文件的位置信息外,還可以使用變量來表示庫文件的位置信息。例如,可以使用 set()
命令來定義一個變量,并在 target_link_libraries()
命令中使用該變量來表示庫文件的位置信息。示例如下:
set(MY_LIBS_DIR /home/user/mylibs)
target_link_libraries(MyTarget PUBLIC ${MY_LIBS_DIR}/libMyLib.so)
在這個示例中,我們使用 set()
命令定義了一個名為 MY_LIBS_DIR
的變量,并給它賦值 /home/user/mylibs
。然后,在 target_link_libraries()
命令中使用 ${MY_LIBS_DIR}
變量來表示庫文件的位置信息。這樣做的好處是,如果將來庫文件位置發(fā)生變化,只需要修改變量的值即可,而不需要修改多次出現(xiàn)在 target_link_libraries()
命令中的路徑信息。
.so .a .lib
是的,動態(tài)庫通常使用 .so
(Shared Object)擴展名,靜態(tài)庫通常使用 .a
(Archive)擴展名。這是因為在大多數(shù) Unix 系統(tǒng)中,動態(tài)庫使用的擴展名為 .so
,而靜態(tài)庫使用的擴展名為 .a
。
.a
文件實際上就是一個簡單的歸檔文件,可以將多個目標(biāo)文件打包成一個文件供鏈接器使用,以便生成可執(zhí)行程序。當(dāng)創(chuàng)建一個靜態(tài)庫時,編譯器會將所有的源文件編譯成目標(biāo)文件(.o
),然后使用 ar
命令將它們打包成一個 .a
文件。靜態(tài)庫在鏈接時會被完整地復(fù)制到可執(zhí)行文件中,因此可執(zhí)行文件運行時與靜態(tài)庫沒有任何關(guān)系。
.so
文件是一種共享庫,它涵蓋了許多不同的功能,并且可以在多個應(yīng)用程序之間共享使用。動態(tài)庫在鏈接時不會被完全復(fù)制到可執(zhí)行文件中,而是在運行時動態(tài)加載到內(nèi)存中。這意味著多個程序可以共享同一個庫,從而節(jié)省系統(tǒng)資源并簡化程序的管理和維護。
需要注意的是,不同的操作系統(tǒng)、編譯器和開發(fā)環(huán)境可能會使用不同的擴展名來表示庫文件,例如 Windows 系統(tǒng)下的動態(tài)庫通常使用 .dll
擴展名,而靜態(tài)庫通常使用 .lib
擴展名。
總之,.so
通常指動態(tài)庫,.a
通常指靜態(tài)庫,它們是不同類型的庫文件,具有不同的用途和鏈接方式。
.lib
是在 Windows 操作系統(tǒng)下表示靜態(tài)庫文件的擴展名,與在 Unix/Linux 系統(tǒng)下使用的 .a
擴展名類似。它是 Microsoft Visual Studio 編譯器生成的靜態(tài)庫文件的標(biāo)準擴展名。
在 Visual Studio 中,靜態(tài)庫文件可以使用命令行工具 LIB.EXE
或在 IDE 中的屬性頁中進行創(chuàng)建。與 Unix/Linux 系統(tǒng)下的靜態(tài)庫一樣,.lib
文件實際上也是一個歸檔文件,其中包含了一個或多個目標(biāo)文件(即編譯后的代碼)。在鏈接可執(zhí)行程序時,鏈接器會將需要的目標(biāo)文件從庫文件中提取出來,并將其復(fù)制到可執(zhí)行文件中。
在 Windows 平臺上,.dll
文件是動態(tài)庫文件的標(biāo)準擴展名,和在 Unix/Linux 平臺上使用的 .so
擴展名相當(dāng)。.dll
文件和 .lib
文件是不同類型的文件,.dll
文件常用于動態(tài)鏈接,而.lib
文件則常用于靜態(tài)鏈接。
總之,在 Windows 操作系統(tǒng)中,.lib
擴展名通常表示靜態(tài)庫文件,其中包含了目標(biāo)文件,可以通過鏈接器靜態(tài)地將其連接到可執(zhí)行程序中。
step2 exercise2 adding an option
https://cmake.org/cmake/help/latest/guide/tutorial/Adding%20a%20Library.html
在MathFunctions庫中添加一個選項,允許開發(fā)人員選擇自定義平方根實現(xiàn)或內(nèi)置標(biāo)準實現(xiàn)。雖然對于教程來說,確實沒有必要這樣做,但對于較大的項目來說,這是常見的情況。
CMake可以使用option()命令執(zhí)行此操作。這為用戶提供了一個變量,用戶可以在配置cmake構(gòu)建時更改該變量。此設(shè)置將存儲在緩存中,這樣用戶就不需要每次在構(gòu)建目錄上運行CMake時都設(shè)置該值。
if()
option()
target_compile_definitions()
cmake ../Step2 -DUSE_MYMATH=OFF
cmake --build .
步驟如下:
MathFunctions/CMakeLists.txt. This option will be displayed in the cmake-gui and ccmake with a default value of ON that can be changed by the user.
option(USE_MYMATH "Use tutorial provided math implementation" ON) 第二個為說明信息
if (USE_MYMATH)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
endif()
ON的話就會設(shè)置是否編譯
然后再 mathfunctions.cxx中定義
#ifdef USE_MYMATH
return detail::mysqrt(x);
#else
return std::sqrt(x);
#endif Next, we need to include mysqrt.h if USE_MYMATH is defined.加入頭文件
#ifdef USE_MYMATH 頭文件也要看情況加入
# include "mysqrt.h"
#endif
#include <cmath> 如果為off, mysqrt.cxx文件不會被用到,但仍然會被編譯,因為 MathFunctions target has mysqrt.cxx listed under sources.
There are a few ways to fix this. The first option is to use target_sources() to add mysqrt.cxx from within the USE_MYMATH block. Another option is to create an additional library within the USE_MYMATH block which is responsible for compiling mysqrt.cxx. For the sake of this tutorial, we are going to create an additional library.
他這里選了第二種
內(nèi)部的cmakelist
add_library(SqrtLibrary STATIC
mysqrt.cxx
)
target_link_libraries(MathFunctions PUBLIC SqrtLibrary)
上面這兩個都是要在if() endif中
add_library(MathFunctions MathFunctions.cxx) 從一開始的刪掉mysrt.cpp
外部的
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
target_include_directories(Tutorial PUBLIC
"${PROJECT_BINARY_DIR}"
)
-D option -d 小d是調(diào)試工具選項,輸出詳細調(diào)試信息
-D
是 CMake 工具的一個選項,用于定義一個 CMake 變量,并為其指定一個值。
在 CMake 中,變量可用于存儲和傳遞信息,比如控制編譯選項、設(shè)置版本號、指定構(gòu)建路徑等等。在 CMakeLists.txt 文件中使用 -D
選項可以方便地在命令行上設(shè)置變量值,避免了手動編輯 CMakeLists.txt 文件的麻煩。
例如,以下是一個簡單的 CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
project(MyProject)
option(USE_MYMATH "use my math library" ON)
if(USE_MYMATH)
add_subdirectory(mymath)
list(APPEND EXTRA_LIBS mymath)
endif()
add_executable(MyApp main.cpp)
target_link_libraries(MyApp ${EXTRA_LIBS})
其中,option()
命令會定義一個名為 USE_MYMATH
的選項變量,初始值為 ON
。如果 -DUSE_MYMATH=OFF
被傳給 cmake 命令,那么 CMake 會將 USE_MYMATH
變量的值設(shè)置為 OFF
,從而跳過構(gòu)建 mymath
庫并且不鏈接 mymath
庫到 MyApp
可執(zhí)行文件中。這樣,我們就可以在命令行上方便地修改相應(yīng)的選項。
因此,-D
選項是非常有用的,它方便開發(fā)者在命令行上動態(tài)地設(shè)置 CMake 變量,從而輕松控制編譯選項,增強 CMake 的靈活性。
target source
CMake 中沒有 target_source()
命令,可能您想問的是 target_sources()
命令。
target_sources()
是 CMake 提供的一個命令,用于向指定的一個或多個目標(biāo)添加源文件。其常見語法如下:
target_sources(<target> [PRIVATE|PUBLIC|INTERFACE] [items1...]
[PRIVATE|PUBLIC|INTERFACE] [items2...] ...)
其中,<target>
表示添加源文件的目標(biāo)名稱,可以是庫或可執(zhí)行文件。
[PRIVATE|PUBLIC|INTERFACE]
是可選的關(guān)鍵字,用于指定后面的源文件列表是屬于 PRIVATE
、PUBLIC
還是 INTERFACE
。具體含義如下:
-
PRIVATE
表示僅對當(dāng)前目標(biāo)可見的源文件,不會被鏈接到依賴該目標(biāo)的其他目標(biāo)中; -
PUBLIC
表示既對當(dāng)前目標(biāo)可見,也會被鏈接到依賴該目標(biāo)的其他目標(biāo)中; -
INTERFACE
表示不對當(dāng)前目標(biāo)可見,只會被鏈接到依賴該目標(biāo)的其他目標(biāo)中。
[items1...]
、[items2...]
等表示要添加的源文件列表,可以是相對于當(dāng)前 CMakeLists.txt 文件的路徑或者源文件名。
例如,以下是一個簡單的例子:
add_library(MyLib STATIC)
target_sources(MyLib PRIVATE src/foo.cpp)
首先,我們創(chuàng)建了一個名為 MyLib
的靜態(tài)庫,然后使用 target_sources()
命令向它添加了 src/foo.cpp
源文件。由于使用了 PRIVATE
關(guān)鍵字,因此該源文件只會對 MyLib
目標(biāo)可見,不會被鏈接到依賴該目標(biāo)的其他目標(biāo)中。
使用 target_sources()
命令可以方便地管理源文件,避免了手動編寫鏈接器腳本的繁瑣操作,并且提高了 CMake 項目的可維護性。
cmake -
-build 和 mingwcmake --build .
和 make
命令類似,都是用于執(zhí)行編譯和鏈接操作的命令。不過它們之間還是有一些區(qū)別的。
make
是一個獨立的構(gòu)建工具,它使用 Makefile 文件來描述項目的組織結(jié)構(gòu)以及如何進行編譯、鏈接和安裝等操作。
cmake
則是一個跨平臺的構(gòu)建系統(tǒng)生成器,它可以根據(jù)不同操作系統(tǒng)和編譯器生成對應(yīng)的構(gòu)建系統(tǒng)文件(如 Makefile 或 Ninja 構(gòu)建文件),提供相應(yīng)的接口和API來進行項目的編譯、測試、打包和安裝等操作。
執(zhí)行 cmake --build .
命令時,CMake 會自動識別當(dāng)前目錄下的構(gòu)建系統(tǒng)文件,并執(zhí)行默認的構(gòu)建方式(如 Makefile 時就會執(zhí)行 make 命令)來進行編譯和鏈接操作。
與 make
相比,cmake --build .
可以自動進行一些跨平臺的處理,例如在 Windows 平臺中會自動使用 MSVC 編譯器,而在 Linux 平臺則會自動使用 GCC 或 Clang 等編譯器。
總之,cmake --build .
命令可以讓我們更方便地執(zhí)行 CMake 構(gòu)建系統(tǒng),自動生成構(gòu)建文件和進行編譯、鏈接和打包等操作。而 make
則是常用的 Linux 系統(tǒng)中的構(gòu)建工具,用于編譯、鏈接和構(gòu)建 Makefile 構(gòu)建文件所描述的項目。
compiler 和kit
在 Windows 和 Linux 中,Compiler 和 Kit 都是關(guān)鍵的概念,用于構(gòu)建和編譯應(yīng)用程序。下面我會逐一介紹這兩個概念的具體內(nèi)容:
- Compiler(編譯器)
編譯器是將源代碼轉(zhuǎn)換為可執(zhí)行文件或庫文件的工具。在編譯過程中,編譯器會將源代碼翻譯成計算機可以理解的機器碼,然后生成可執(zhí)行文件或庫文件。在 Windows 中,常見的編譯器包括 Visual Studio 的 MSVC 編譯器和 MinGW 編譯器;而在 Linux 中,則常見的編譯器有 GCC 和 Clang。
- Kit(構(gòu)建工具鏈)
Kit 是 CMake 中的一個重要概念,表示一組用于構(gòu)建和編譯應(yīng)用程序的工具集合。在 Windows 上,一個 Kit 可以包括 C++ 編譯器、構(gòu)建工具(如 Ninja 或 Visual Studio)、調(diào)試器和其他相關(guān)的工具;在 Linux 上,一個 Kit 則可以包括 C++ 編譯器、構(gòu)建工具(如 Makefile 或 Ninja)、調(diào)試器和其他相關(guān)的工具。
Kit 對于交叉編譯非常有用。例如,在 Windows 系統(tǒng)上開發(fā)嵌入式 Linux 應(yīng)用程序時,我們需要使用一個 Linux 交叉編譯工具鏈,這樣才能將應(yīng)用程序編譯為 Linux 可執(zhí)行文件。使用 CMake 的 Kit 功能,我們可以輕松切換不同的工具鏈(如 Linux 交叉編譯工具鏈或本地編譯工具鏈),從而為我們提供了一個可靠的交叉編譯環(huán)境。
總之,編譯器和 Kit 是 CMake 中非常重要的概念,通過它們可以構(gòu)建和編譯不同平臺的應(yīng)用程序。無論是 Windows 還是 Linux 系統(tǒng)下,都需要選擇合適的編譯器和 Kit 來滿足不同的需求。
在 CMake 中,Kit 是一組參數(shù)的集合,它描述了如何為不同的目標(biāo)平臺編譯和構(gòu)建項目。一個 Kit 是由一組工具鏈、編譯器、構(gòu)建器、環(huán)境變量等參數(shù)組成的。
具體來說,Kit 是一個用于定義構(gòu)建環(huán)境的抽象概念,包括了編譯器、構(gòu)建器、調(diào)試工具、部署工具以及相關(guān)的路徑、變量、選項等等。通常情況下,一個 Kit 會對應(yīng)一個特定的編譯器和一些相關(guān)的構(gòu)建、編譯和部署工具。
在使用 CMake 進行交叉編譯時,通過創(chuàng)建不同的 Kit,可以為不同的目標(biāo)平臺選擇不同的編譯器、工具鏈和構(gòu)建選項等。這樣可以使得我們的項目能夠在不同的平臺上進行編譯和構(gòu)建,并生成相應(yīng)的可執(zhí)行文件或庫文件。
總之,CMake 中的 Kit 是一個非常重要的概念,通過它可以指定編譯器、構(gòu)建工具等參數(shù),從而為不同的目標(biāo)平臺定制構(gòu)建環(huán)境。
kit
在 CMake 中,Kit 是一組工具集合,用于指定構(gòu)建和編譯應(yīng)用程序的工具鏈。使用 Kit 功能的主要優(yōu)點是可以實現(xiàn)跨平臺交叉編譯,同時也可以進行本地編譯,從而簡化了開發(fā)人員的工作。
要使用 CMake 的 Kit 功能,需要先定義一個 Kit。在定義 Kit 時,需要指定以下幾個關(guān)鍵參數(shù):
- 工具鏈類型:例如 GNU、Clang 等
- 工具鏈版本:例如 GCC 5.3.0、Clang 9.0.0 等
- 構(gòu)建器類型:例如 Ninja、Visual Studio 等
- 構(gòu)建器版本:例如 Ninja 1.5.3、Visual Studio 2015 等
- 附加項:例如編譯選項、鏈接選項等
定義好 Kit 后,我們就可以在項目中使用這個 Kit 了。在 CMakeLists.txt 文件中,我們可以通過指定 Kit 來設(shè)置構(gòu)建選項和參數(shù)。例如,假設(shè)我們使用的 Kit 名稱為 “MyKit”,那么可以通過以下方式設(shè)置構(gòu)建選項:
cmake_minimum_required(VERSION 3.12)
project(MyProject)
# 指定 Kit
set(CMAKE_TOOLCHAIN_FILE /path/to/mykit.cmake)
# 其他構(gòu)建選項
...
在上述示例中,我們通過 set(CMAKE_TOOLCHAIN_FILE ...)
指定了使用的 Kit,然后可以設(shè)置其他構(gòu)建選項。在執(zhí)行 CMake 命令時,就可以使用 -DCMAKE_TOOLCHAIN_FILE=/path/to/mykit.cmake
選項來指定 Kit 所在的文件路徑。
總之,Kit 是 CMake 中非常有用的功能,可以幫助我們實現(xiàn)跨平臺交叉編譯和本地編譯,從而提高開發(fā)效率。
兩者是并行的嘛
在 CMake 中,Kit 和 Compiler 并不是類似于兩種并行的工具,而是在構(gòu)建和編譯過程中扮演不同的角色。
Kit 主要用于指定構(gòu)建、編譯和鏈接應(yīng)用程序的工具鏈,即在 CMake 構(gòu)建時使用哪個編譯器、鏈接器以及其他相關(guān)工具(如 make、ninja 等)。如果我們需要在不同平臺上進行編譯,或者需要使用不同版本的編譯器、不同的編譯器選項等,可以通過 Kit 來管理。
而 Compiler 則是 CMake 在查找和選擇編譯器時使用的過程。它會嘗試在系統(tǒng)環(huán)境變量 PATH
中查找可用的編譯器,并且根據(jù)編譯器的類型、版本、路徑等信息來選擇合適的編譯器。
可以說,Kit 和 Compiler 是在不同的層次上發(fā)揮作用的。Kit 主要用于指定編譯過程中使用的工具鏈,與編譯器本身并沒有直接關(guān)聯(lián)。而 Compiler 則是在工具鏈確定之后,用于確定最終使用哪個編譯器來進行編譯。
因此,在使用 CMake 進行構(gòu)建時,需要同時考慮 Kit 和 Compiler 的使用。對于復(fù)雜的項目,可能需要同時管理多個 Kit 和 Compiler,并根據(jù)實際需求進行配置和選擇。
kit默認配置好的嘛,我都沒配置就直接用了
在默認情況下,CMake 會使用系統(tǒng)安裝的工具鏈來構(gòu)建應(yīng)用程序,因此不需要手動配置 Kit。也就是說,如果您直接運行 cmake
命令進行構(gòu)建,則默認使用系統(tǒng)提供的編譯器、鏈接器以及其他相關(guān)工具,而不需要手動指定 Kit。
但是,在一些特定場景下,可能需要手動配置 Kit,例如:
- 進行交叉編譯,需要使用不同于系統(tǒng)默認的編譯器和工具鏈。
- 在不同操作系統(tǒng)上構(gòu)建不同版本的應(yīng)用程序,需要使用不同的工具鏈。
- 針對特定的硬件平臺進行開發(fā),需要使用特定的編譯器和工具鏈等。
在這些情況下,需要手動配置 Kit,并且將其與 CMakeLists.txt 文件中的構(gòu)建選項和參數(shù)結(jié)合使用,來確保應(yīng)用程序可以正確地編譯和構(gòu)建。
總之,CMake 中的 Kit 可以幫助我們管理工具鏈,減少構(gòu)建過程中的問題,并提高構(gòu)建的可移植性。雖然默認情況下不需要手動配置 Kit,但在某些特定場景下,手動配置 Kit 是非常有必要的。
gcc和mingw
是的,GCC 和 MinGW 都是編譯器,它們都可以將源代碼編譯成可執(zhí)行文件或庫文件。GCC 是 GNU Compiler Collection 的縮寫,是一個開源的編譯器集合,支持多種編程語言和多個平臺,包括 C、C++、Objective-C、Ada、Fortran 和 Java 等。MinGW 則是一個 Windows 下的 GCC 移植版本,提供了一組可移植的 GNU 工具鏈,可以在 Windows 平臺上編譯開源項目和應(yīng)用程序。
需要注意的是,GCC 和 MinGW 之間有一些區(qū)別。具體來說,MinGW 是針對 Windows 平臺而設(shè)計的,因此它提供了更好的 Windows API 支持和更好的兼容性,同時也包含了一些 Windows 下所需要的工具和庫。而 GCC 則是一款跨平臺的編譯器,在多個平臺上通用,但是在 Windows 下使用時需要特別注意一些問題,例如需要手動配置環(huán)境變量和路徑等。
總之,無論是使用 GCC 還是 MinGW,它們都是編譯器,可以將源代碼轉(zhuǎn)換為可執(zhí)行文件或庫文件。根據(jù)具體需求和平臺特點,我們可以選擇合適的編譯器和工具鏈來進行開發(fā)和編譯。
GCC 和 MinGW 的主要區(qū)別在于它們的目標(biāo)平臺和使用場景。GCC 是跨平臺的編譯器,可以在多個操作系統(tǒng)上都使用,并且支持多種編程語言和多種目標(biāo)平臺。MinGW 則是專門針對 Windows 平臺的 GCC 移植版本,提供了一套工具集,方便在 Windows 上構(gòu)建本地程序和移植的開源代碼。
關(guān)于生成 makefile 文件的問題,實際上不是由 GCC 和 MinGW 決定的。makefile 文件是一種用于自動化構(gòu)建的腳本文件,在 make 工具的幫助下,開發(fā)人員可以自動執(zhí)行編譯、鏈接等一系列操作,從而生成最終的可執(zhí)行文件。無論是使用 GCC 還是 MinGW,我們都可以使用 make 工具來完成自動化構(gòu)建的過程,并且生成 makefile 文件。
至于生成可執(zhí)行文件的問題,這實際上是由編譯器和鏈接器來決定的。編譯器會將源代碼編譯成目標(biāo)文件(如 .o 或 .obj),而鏈接器則會將目標(biāo)文件合并成最終的可執(zhí)行文件或庫文件。因此,無論是使用 GCC 還是 MinGW,它們都可以生成目標(biāo)文件和最終的可執(zhí)行文件,只是在使用上可能有一些細節(jié)上的差異。
Linux系統(tǒng)介紹
linux 多用戶多任務(wù)
windows 單用戶 多任務(wù)
linux 一切都是文件
創(chuàng)建文件 ,編輯文件,保存文件,關(guān)閉文件,重命名文件,刪除文件,恢復(fù)文件
root 管理員
命令
命令 空格 【選項】 空格 【操作對象】
ls -a -l -h 等效于 ls -alh文章來源:http://www.zghlxwxcb.cn/news/detail-495209.html
owner group other 三個對象的權(quán)限
chmod 777文章來源地址http://www.zghlxwxcb.cn/news/detail-495209.html
到了這里,關(guān)于catkin cmake官方教程解讀以及資料補充的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!