位元詩人 [C 語言] 程式設計教學:基於 CMake 的 C 函式庫專案

C 語言專案
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

前言

承接上一篇文章的概念,本文使用 CMake 來建立一個 C 函式庫專案,用來展示 CMake 的使用方式。

使用此專案

我們將這個微型專案放在 GitLab 上,使用 Git 即可複製此專案:

$ git clone https://gitlab.com/cwchen/cmake-mylib-test.git

使用前同樣要先將工作目錄移到專案的根目錄上:

$ cd cmake-mylib-test

使用 CMake generator 的方式同上一篇文章,我們就不重覆展示。但編譯函式庫的重點在於要使用靜態函式庫還是動態函式庫。在 CMake 中,使用 BUILD_SHARED_LIBS 變數來控制編譯的行為。

若不想使用動態函式庫,則使用以下指令來編譯:

$ cmake -DBUILD_SHARED_LIBS=OFF -G "Unix Makefiles"

這時候編譯出來的函式庫就會是靜態函式庫。

反之,若想使用動態函式庫,則將指令修改如下:

$ cmake -DBUILD_SHARED_LIBS=ON -G "Unix Makefiles"

使用 CMake 生成自動編譯設定檔後,按照各個自動編譯軟體的指令去編譯專案即可,此處不重覆展示指令。

撰寫 CMake 設定檔

為了突顯 CMake 的部分,本範例專案刻意把 C 程式碼的部分寫得相當簡單,這裡就不展示出來。直接來看 CMakeLists.txt 部分的寫法:

cmake_minimum_required(VERSION 2.8.11)            #[[  1 ]]
project(Mylib)                                    #[[  2 ]]

set(LIBRARY_OUTPUT_PATH dist)                     #[[  3 ]]

include_directories(${Mylib_SOURCE_DIR}/include)  #[[  4 ]]
include_directories(${Mylib_SOURCE_DIR}/src)      #[[  5 ]]
include_directories(${Mylib_SOURCE_DIR}/tests)    #[[  6 ]]

option(BUILD_SHARED_LIBS OFF)                     #[[  7 ]]

if (BUILD_SHARED_LIBS)                            #[[  8 ]]
    add_library(mylib SHARED                      #[[  9 ]]
        ${Mylib_SOURCE_DIR}/src/mylib.c           #[[ 10 ]]
        ${Mylib_SOURCE_DIR}/src/mylib.def         #[[ 11 ]]
        )                                         #[[ 12 ]]
else()                                            #[[ 13 ]]
    add_library(mylib                             #[[ 14 ]]
        ${Mylib_SOURCE_DIR}/src/mylib.c           #[[ 15 ]]
        ${Mylib_SOURCE_DIR}/src/mylib.def         #[[ 16 ]]
        )                                         #[[ 17 ]]
endif()                                           #[[ 18 ]]

set_source_files_properties(mylib.def             #[[ 19 ]]
    PROPERTIES HEADER_FILE_ONLY TRUE)             #[[ 20 ]]

add_executable(mylib_test                         #[[ 21 ]]
    ${Mylib_SOURCE_DIR}/include/mylib.h           #[[ 22 ]]
    ${Mylib_SOURCE_DIR}/test/mylib_test.c         #[[ 23 ]]
    )                                             #[[ 24 ]]
target_link_libraries(mylib_test mylib)           #[[ 25 ]]

enable_testing()                                  #[[ 26 ]]

if (WIN32)                                        #[[ 27 ]]
    add_test(NAME mylib COMMAND mylib_test        #[[ 28 ]]
        WORKING_DIRECTORY dist)                   #[[ 29 ]]
else()                                            #[[ 30 ]]
    add_test(NAME mylib COMMAND mylib_test)       #[[ 31 ]]
endif()                                           #[[ 32 ]]

第 1 行要指定 CMake 的最低可用版本。由於我們有用到一些新的語法特性,所以 CMake 的版本比前一個範例高一些。

第 2 行設置專案名稱。這項設置對於一部分的自動編譯設定檔會有影響,像是 Visual Studio Solution。

第 3 行設置專案產出的位置。由於本專案是巢狀專案,我們將產出放置在子目錄 dist

第 7 行至第 18 行設置使用動態函式庫或靜態函式庫來編譯此專案,並加入相關的 C 原始檔。預設是使用靜態函式庫,但專案使用者可透過參數改動預設設置。

第 19 行及第 20 行將 mylib.def 視為標頭檔。 .def 檔案僅用於 MSVC (Visual C++) 編譯系統,用來指定輸出的函式。

第 21 行至第 24 行設置測試程式會用到的檔案。

第 25 行指定測試程式連結到本專案生成的函式庫。

第 26 行開啟專案的測試功能。

第 27 至第 32 行將專案加上測試。在 Windows 上,得將函式庫和測試程式擺在同一個工作目錄,所以,我們在 Windows 上時,將工作目錄移到 dist 子目錄中。在 Unix 或類 Unix 系統上,則用一般的配置即可。

結語

在本文中,我們展示了一個以 CMake 為基礎的 C 函式庫專案,並為此專案加上簡易的測試程式。讀者可參考本文的設置,用來建立自己的 C 函式庫專案。

關於作者

身為資訊領域碩士,位元詩人 (ByteBard) 認為開發應用程式的目的是為社會帶來價值。如果在這個過程中該軟體能成為永續經營的項目,那就是開發者和使用者雙贏的局面。

位元詩人喜歡用開源技術來解決各式各樣的問題,但必要時對專有技術也不排斥。閒暇之餘,位元詩人將所學寫成文章,放在這個網站上和大家分享。