C/C++ 如何進行持續交付?使用 Jenkins+Conan!

C 和 C ++ 目前被應用在操做系統、嵌入式系統、財務、科研、汽車、機器人、遊戲等很是重要的行業。主要緣由是 C 和 C++ 相比於其餘技術來講擁有很高的性能。但一樣,C/C ++ 生態系統也面臨一些巨大的挑戰:web

  • 巨石應用 -- 擁有數百萬甚至更多行代碼,在不使用現代工具的狀況下很難管理項目。架構

  • 應用程序二進制接口(ABI)不兼容 -- 爲了保證庫與其餘庫和應用程序的兼容性,須要控制不一樣的配置(如操做系統,體系架構和編譯)。運維

  • 編譯時間慢 -- 因爲包含頭文件和預處理器擴大,再加上上述挑戰,須要特別注意優化過程並僅重建須要重建的庫。分佈式

  • 代碼連接和內聯 -- 靜態 C/C++ 庫能夠嵌入來自相關庫的頭文件。另外,共享庫能夠嵌入一個靜態庫。在這兩種狀況下,當它們的依賴關係發生變化時,都須要管理庫的重建。ide

  • 不一樣的生態系統 -- 針對不一樣的平臺、目標和用途,有許多不一樣的編譯器和生成系統。工具

    本文將展現如何使用 Jenkins CI,Conan C/C++ 包管理器和 JFrog Artifactory 通用工件存儲庫實現 DevOps C/C++ 開發的最佳實踐。性能

    Conan,C/C++ 包管理器

    Conan 的誕生就是爲解決這些痛點。測試

    Conan 使用了 Python,描述瞭如何經過顯式調用任何構建系統來構建庫,還描述了用戶所需的信息(包括目錄,庫名等)。Conan 使用「Settings」(操做系統,架構,編譯器等)管理不一樣的配置和 ABI 的兼容性。當一個設置被改變時,Conan 爲同一個庫生成一個不一樣的二進制版本。優化

    C/C++ 如何進行持續交付?使用 Jenkins+Conan!


    構建後的二進制文件能夠上傳到 JFrog Artifactory 或 Bintray,與團隊或整個社區共享。 團隊中的開發人員不須要從新編譯庫,Conan 將從配置好的遠程庫(分佈式模型)中僅提取匹配用戶配置所需的二進制包。 可是還有更多的挑戰須要解決:ui

    • 如何管理 C/C++ 項目的開發和發佈過程?

    • 如何分發你的 C/C++ 庫?

    • 如何測試你的 C/C ++ 項目?

    • 如何爲不一樣的配置生成多個包?當其中一個更改時,如何管理庫的重建?

    Conan 生態系統

    Conan 生態系統正在快速發展,使用 C/C++ 的 DevOps 如今已經成爲現實:

    • JFrog Artifactory 管理完整的開發和發佈週期。

    • JFrog Bintray 是通用的分發中心。

    • Jenkins 自動執行項目測試,生成 Conan 軟件包的不一樣二進制配置,並自動重建庫。

    C/C++ 如何進行持續交付?使用 Jenkins+Conan!


    Jenkins Artifactory 插件

    • 提供 Conan DSL,是比較通用但有效的從 Jenkins 流水線腳本調用 Conan 的方法。

    • 使用 Artifactory 實例管理遠程配置,隱藏認證詳細信息。

    • 收集從 Conan 操做(安裝/上傳包)的工件來生成 Buildinfo 而且發佈到 Artifactory。 BuildInfo 對象是很是有用的,例如,將建立的 Conan 包推廣到不一樣的存儲庫並對 Jenkins 構建具備完整的可追溯性:

    C/C++ 如何進行持續交付?使用 Jenkins+Conan!


    下面是帶有 Artifactory 插件的 Conan DSL 的一個例子。首先咱們配置 Artifactory 存儲庫,而後檢索依賴關係並最終構建它:

    C/C++ 如何進行持續交付?使用 Jenkins+Conan!


    在上面的例子中你能夠看到 Conan DSL 是很是明確的。它對經常使用操做有很大的幫助,並且也容許強大的自定義集成。這對於 C/C++ 項目很是重要,由於每一個公司都有一個很是具體的項目結構,自定義集成等。

    複雜的 Jenkins 流水線操做:管理和並行包的構建

    正如咱們在本文開始時看到的那樣,在構建 C/C++ 項目時節省時間相當重要。 如下是幾種優化流程的方法:

    • 只從新構建須要重建的庫。 有些庫已經被一個依賴庫的改變而影響了。

    • 若是可能,並行構建。 當項目關係圖中兩個或多個庫之間沒有關係時,能夠並行構建它們。

    • 並行構建不一樣的配置(操做系統,編譯器等)。

      咱們來看一個使用 Jenkins 流水線功能的例子

      C/C++ 如何進行持續交付?使用 Jenkins+Conan!


      上圖顯示了咱們的項目 P 及其依賴關係(A-G)。咱們但願分發兩個不一樣的體系結構,x86 和 x86_64。

      若是咱們改變庫 A 會發生什麼?

      若是咱們碰到 A(v1)的版本沒有問題,咱們能夠更新 B 的要求,也能夠將版本升級到 B(v1)等等。完整的流程以下:

      • 將A(v1)版本推送到 Git,Jenkins 將構建 x86 和 x86_64 二進制文件。Jenkins 會把全部的包上傳到 Artifactory。

      • 手動將 B 更改成 v1,如今取決於 A1,推送到 Git,Jenkins 將使用從 Artifactory 檢索到的新 A1 來爲 x86 和 x86_64 構建 B(v1)。

      • 對 C,D,F,G 和咱們的項目重複相同的過程。

        可是,若是咱們在開發庫中開發咱們的庫,咱們可能依賴於最新的 A 版本,或者將在每次 Git 推送時重寫 A(v0)軟件包,而且咱們但願在這種狀況下自動重建受影響的庫 B,D,F ,G 和 P。

        Jenkins 流水線會怎麼作

        首先咱們須要知道哪些庫須要從新構建。「conan info --build_order」命令會標識在咱們的項目中被更改的庫,而且還告訴咱們哪些能夠並行從新構建。

        因而,咱們建立了兩個 Jenkins 管道任務:

        • 創建每一個單一庫的 SimpleBuild 任務。相似於使用 Jenkins Artifactory 插件使用 Conan DSL 的第一個示例。這是一個參數化的任務,接收須要構建的庫。

        • MultiBuild 任務,在可能的狀況下並行的協調、啓動「 SimpleBuild」任務。

        咱們也有一個 Yml 配置的倉庫。 Jenkins 任務將使用它來了解每一個庫的配置,以及要使用的不一樣配置文件。在這種狀況下,它們是 x86 和 x86_64。

        C/C++ 如何進行持續交付?使用 Jenkins+Conan!


        這意味着咱們須要開始構建 B,而後咱們能夠並行構建 D 和 F,最後構建 G。請注意,庫 C 不須要重建,由於它不受 A 庫變化的影響。

        「MultiBuild」任務的 Jenkins 流水線腳本將對「SimpleBuild」任務的並行調用,最後並行啓動組。

        C/C++ 如何進行持續交付?使用 Jenkins+Conan!


        最終,這將會發生什麼:

        • 兩個 SimpleBuild 任務將被觸發,都是用於構建庫 B,一個用於 x86 仍是另外一個用於 x86_64 體系結構

        C/C++ 如何進行持續交付?使用 Jenkins+Conan!


        • 一旦「A」和「B」被構建,將觸發「F」和「D」,4個工做將同時運行「SimpleBuild」任務(x86,x86_64)

        C/C++ 如何進行持續交付?使用 Jenkins+Conan!


        • 最後將構建「G」。因此2個工做將平行運行。

        Jenkins Stage 視圖:

        MultiBuild

        C/C++ 如何進行持續交付?使用 Jenkins+Conan!


        SimpleBuild

        C/C++ 如何進行持續交付?使用 Jenkins+Conan!


        咱們能夠在不一樣節點(Windows,OSX,Linux ...)中配置「 SimpleBuild 」任務,並控制 Jenkins 配置中可用的執行程序的數量。

        總結

        對於 C/C++ 來講,落地 DevOps 仍然是許多公司須要作的事情。 這須要大量的時間投入,但從長遠來看能夠節省不少的時間在開發階段而且釋放生命週期。 並且它提升了 C/C++ 產品的質量和可靠性。

        上面的 Jenkins 示例演示瞭如何並行控制庫構建,只是經過 Groovy 代碼和一個自定義的方便的 Yml 文件。 關於它的偉大的事情不是例子或代碼自己。 最重要的是能夠定義本身的流水線腳本以適應特定的工做流程,這要歸功於 Jenkins Pipeline,Conan 和 JFrog Artifactory。

        原文連接:https://jenkins.io/blog/2017/07/07/jenkins-conan/

        做者: 王志宇

        JFrog 中國研發工程師,曾在惟品會擔任研發工程師,擅長Java,參與過多個互聯網平臺的研發和運維工做,現專一於Devops 落地,持續集成、持續交付領域。

        歡迎轉載,但轉載請註明做者與出處。謝謝!

        相關文章
        相關標籤/搜索