Linux中國

使用 CMake 和 VSCodium 設置一個構建系統

這篇文章是使用開源 DevOps 工具進行 C/C++ 開發系列文章的一部分。如果你從一開始就把你的項目建立在一個功能強大的工具鏈上,你的開發會更快和更安全。除此之外,這會使別人更容易地參與你的項目。在這篇文章中,我將搭建一個基於 CMakeVSCodium 的 C/C++ 構建系統。像往常一樣,相關的示例代碼可以在 GitHub 上找到。

我已經測試了在本文中描述的步驟。這是一種適用於所有平台的解決方案。

為什麼用 CMake

CMake 是一個構建系統生成器,可以為你的項目創建 Makefile。乍一看簡單的東西可能相當地複雜。在較高的層次上,你可以定義你的項目的各個部分(可執行文件、庫)、編譯選項(C/C++ 標準、優化、架構)、依賴關係項(頭文件、庫),和文件級的項目結構。CMake 使用的這些信息可以在文件 CMakeLists.txt 中獲取,它使用一種特殊的描述性語言編寫。當 CMake 處理這個文件時,它將自動地偵測在你的系統上已安裝的編譯器,並創建一個用於啟動它的 Makefile 文件。

此外,在 CMakeLists.txt 中描述的配置,能夠被很多編輯器讀取,像 QtCreator、VSCodium/VSCode 或 Visual Studio 。

示常式序

我們的示常式序是一個簡單的命令行工具:它接受一個整數來作為參數,輸出一個從 1 到所提供輸入值的範圍內的隨機排列的數字。

$ ./Producer 10
3 8 2 7 9 1 5 10 6 4 

在我們的可執行文件中的 main() 函數,我們只處理輸入的參數,如果沒有提供一個值(或者一個不能被處理的值)的話,就退出程序。

int main(int argc, char** argv){

    if (argc != 2) {
        std::cerr << "Enter the number of elements as argument" << std::endl;
        return -1;
    }

    int range = 0;

    try{
        range = std::stoi(argv[1]);
    }catch (const std::invalid_argument&){
        std::cerr << "Error: Cannot parse "" << argv[1] << "" ";
        return -1;
    }

    catch (const std::out_of_range&) {
        std::cerr << "Error: " << argv[1] << " is out of range";
        return -1;
    }

    if (range <= 0) {
        std::cerr << "Error: Zero or negative number provided: " << argv[1];
        return -1;
    }

    std::stringstream data;
    std::cout << Generator::generate(data, range).rdbuf();
}

producer.cpp

實際的工作是在 生成器 中完成的,它將被編譯,並將作為一個靜態庫來鏈接到我們的Producer 可執行文件。

std::stringstream &Generator::generate(std::stringstream &stream, const int range) {
    std::vector<int> data(range);
    std::iota(data.begin(), data.end(), 1);

    std::random_device rd;
    std::mt19937 g(rd());

    std::shuffle(data.begin(), data.end(), g);

    for (const auto n : data) {

        stream << std::to_string(n) << " ";
    }

    return stream;
}

Generator.cpp

函數 generate 引用一個 std::stringstream 和一個整數來作為一個參數。根據整數 range 的值 n,製作一個在 1n 的範圍之中的整數向量,並隨後打亂。接下來打亂的向量值轉換成一個字元串,並推送到 stringstream 之中。該函數返回與作為參數傳遞相同的 stringstream 引用。

頂層的 CMakeLists.txt

頂層的 CMakeLists.txt 的是我們項目的入口點。在子目錄中可能有多個 CMakeLists.txt 文件(例如,與項目所相關聯的庫或其它可執行文件)。我們先一步一步地瀏覽頂層的 CMakeLists.txt

第一行告訴我們處理文件所需要的 CMake 的版本、項目名稱及其版本,以及預定的 C++ 標準。

cmake_minimum_required(VERSION 3.14)

project(CPP_Testing_Sample VERSION 1.0)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

我們用下面一行告訴 CMake 去查看子目錄 Generator。這個子目錄包括構建 Generator 庫的所有信息,並包含它自身的一個 CMakeLists.txt 。我們很快就會談到這個問題。

add_subdirectory(Generator)

現在,我們將涉及一個絕對特別的功能: CMake 模塊 。載入模塊可以擴展 CMake 功能。在我們的項目中,我們載入了 FetchContent 模塊,這能使我們能夠在 CMake 運行時下載外部的資源,在我們的示例中是 GoogleTest

include(FetchContent)

FetchContent_Declare(
  googletest
  URL https://github.com/google/googletest/archive/bb9216085fbbf193408653ced9e73c61e7766e80.zip
)
FetchContent_MakeAvailable(googletest)

在接下來的部分中,我們會做一些我們通常在普通的 Makefile 中會做的事: 指定要構建的二進位文件、它們相關的源文件、應該鏈接的庫,以及編譯器可以找到頭文件的目錄。

add_executable(Producer Producer.cpp)

target_link_libraries(Producer PUBLIC Generator)

target_include_directories(Producer PUBLIC "${PROJECT_BINARY_DIR}")

通過下面的語句,我們使 CMake 來在構建文件夾中創建一個名稱為 compile_commands.json 的文件。這個文件會展示項目的每個文件的編譯器選項。在 VSCodium 中載入該文件,會告知 IntelliSense 功能在哪裡查找頭文件(查看 文檔)。

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

最後的部分為我們的項目定義一些測試。項目使用先前載入的 GoogleTest 框架。單元測試的整個話題將會劃歸到另外一篇文章。

enable_testing()

add_executable(unit_test unit_test.cpp)

target_link_libraries(unit_test gtest_main)

include(GoogleTest)

gtest_discover_tests(unit_test)

庫層次的 CMakeLists.txt

現在,我們來看看包含同名庫的子目錄 Generator 中的 CMakeLists.txt 文件。這個 CMakeLists.txt 文件的內容更簡短一些,除了單元測試相關的命令外,它僅包含 2 條語句。

add_library(Generator STATIC Generator.cpp Generator.h)
target_include_directories(Generator INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

我們使用 add_library(...) 來定義一個新的構建目標:靜態的 Generator 庫。我們使用語句 target_include_directories(...) 來把當前子目錄添加到其它構建目標的頭文件的搜索路徑之中。我們也具體指定這個屬性的範圍為類型 INTERFACE:這意味著該屬性僅影響鏈接到這個庫的構建目標,而不是庫本身。

開始使用 VSCodium

通過使用 CMakeLists.txt 文件中的信息,像 VSCodium 一樣的 IDE 可以相應地配置構建系統。如果你還沒有使用 VSCodium 或 VS Code 的經驗,這個示例項目會是一個很好的起點。首先,轉到它們的 網站 ,然後針對你的系統下載最新的安裝軟體包。打開 VSCodium 並導航到 「 擴展 Extensions 」 標籤頁。

為了正確地構建、調試和測試項目,搜索下面的擴展並安裝它們:

![Searching extensions](/data/attachment/album/202202/07/111041ibqjo1dibv3n7i6n.png "Searching extensions")

如果尚未完成,通過單擊起始頁的 「 克隆 Git 存儲庫 Clone Git Repository 」 來克隆存儲庫。

![Clone Git repository](/data/attachment/album/202202/07/111041d72a7vj6d7uz7xel.png "Clone Git repository")

或者手動輸入:

git clone https://github.com/hANSIc99/cpp_testing_sample.git

之後,通過輸入如下內容來簽出標籤 devops_1

git checkout tags/devops_1

或者,通過單擊 「main」 分支按鈕(紅色框),並從下拉菜單(黃色框)中選擇標籤。

![Select devops_1 tag](/data/attachment/album/202202/07/111042u77bed5l4axy6lty.png "Select devops_1 tag")

在你打開 VSCodium 內部中的存儲庫的根文件夾後,CMake Tools 擴展會偵測 CMakeLists.txt 文件並立即掃描你的系統尋找合適的編譯器。你現在可以單擊屏幕的底部的 「 構建 Build 」 按鈕(紅色框)來開始構建過程。你也可以通過單擊底部區域的按鈕(黃色框)標記來更改編譯器,它顯示當前活動的編譯器。

![Build compiler](/data/attachment/album/202202/07/111042svrzzha9wigwpehv.png "Build compiler")

要開始調試 Producer 可執行文件,單擊調試器符號(黃色框)並從下拉菜單中選擇 「 調試 Debug Producer」(綠色框)。

![Starting the debugger](/data/attachment/album/202202/07/111042u9cqmszcc0ijnjmg.png "Starting the debugger")

如上所述,Producer 可執行文件要求將元素的數量作為一個命令行的參數。命令行參數可以在 .vscode/launch.json 中具體指定。

![Command-line arguments](/data/attachment/album/202202/07/111043pv4ehvv2eq4ehe86.png "Command-line arguments")

好了,你現在能夠構建和調試項目了。

結束語

歸功於 CMake ,不管你正在運行哪種操作系統,上述步驟應該都能工作。特別是使用與 CMake 相關的擴展,VSCodium 變成了一個強大的 IDE 。我沒有提及 VSCodium 的 Git 集成,是因為你已經能夠在網路上查找很多的資源。我希望你可以看到:提供一個適當的 CMake 配置文件可以使其他人更容易地構建、使用和貢獻於你的項目。在未來的文章中,我將介紹單元測試和 CMake 的測試實用程序 ctest

via: https://opensource.com/article/22/1/devops-cmake

作者:Stephan Avenwedde 選題:lujun9972 譯者:robsean 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的電子郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國

    Linux中國

    DevOps 將去向何方?

    微軟、谷歌、亞馬遜、IBM 和甲骨文如今都在關注云上的 DevOps。這些大公司正在給企業提供 IT 自動化的服務。然而,DevOps 仍然在持續的演進中。DevSecOps、AIOps 和 NoOps 正在成為下一個流行詞。