利用CMake搭建軟件編譯架構

利用CMake搭建軟件編譯架構

0 寫在前面的話

本博文主要介紹如何利用cmake組織軟件編譯,並且提供一個簡單的軟件編譯架構的模板。大家可以根據自己實際情況進行改動,本文主要的內容:

  • cmake 命令簡介
  • cmake 常用API詳解
  • 利用cmake搭建軟件編譯框架

主要的軟件環境如下:

  • cmake版本:3.15
  • os:Ubuntu 18.04 64bit
  • Language:c/c++
  • cmake 命令行模式
    大家可以從cmake官網下載cmake工具、查看相關的文檔
    Cmake官網

1 CMake 能做什麼

CMake是一種管理源代碼編譯的工具,最初被設計成Makefile的生成器,隨着應用越來越廣泛,利用CMake可以生成Visual Studio 等IDE的工程文件以便於其進行編譯。CMake主要在c/c++中使用,當然也可以利用它進行編譯其他語言。

2 CMake編譯模板 整體框架

目錄結構如下:

.
├── app  // 生成各種可執行文件 
│   ├── CMakeLists.txt  // 添加各種子目錄
│   └── cmake_test
│       ├── CMakeLists.txt  // 生成可執行文件 cmake_test
│       └── cmake_test.cpp
├── cmake_config  // cmake相關配置文件
│   ├── cm_commom.cmake  // 添加cmake一些公共的配置信息:比如說編譯選項等
│   ├── cm_device_type.cmake // 設備型號配置文件 
│   ├── cm_platform.cmake  // 平臺相關的配置文件 比如說:硬件平臺 軟件平臺等
│   └── cm_X86_64.cmake  // X86_64對應的配置文件
├── CMakeLists.txt  // 總體的cmake文件
├── components  // 組件類的配置文件 軟件系統的各個組件
│   ├── CMakeLists.txt  // 本級目錄的cmake文件
│   └── dpdk_fifo  // 無鎖隊列目錄
│       ├── CMakeLists.txt // 生成 靜態庫或者動態庫 
│       ├── rte_atomic.h
│       ├── rte_ring.cpp
│       └── rte_ring.h
├── include  // 公共的頭文件
├── lib  // Generate Dynamic Library or Static Library  in this directory ,all kinds of platform 
│   └── X86_64  // X86_64 platform 
│       ├── libdpdk_fifo.a
│       └── libdpdk_fifo.so
├── main_frame   // the main frame directory:include the main frame of the software system 
│   ├── CMakeLists.txt
│   └── Event  // the event modle  handles all kinds of event,such as: read write timer signal etc..
│       └── CMakeLists.txt
├── out  // the out directory : the exe file and the dynamic library
│   └── cmake_test
│       ├── cmake_test
│       └── libdpdk_fifo.so
└── third_party  // the third party header file in this directory

3 項目使用

建立一個臨時的編譯目錄 在該目錄中生成大量的中間文件

root@wan:/wan/fly_in_coding# mkdir build
root@wan:/wan/fly_in_coding# cd build/
root@wan:/wan/fly_in_coding/build# pwd
/wan/fly_in_coding/build
root@wan:/wan/fly_in_coding/build# pwd
/wan/fly_in_coding/build

生成Makefile

root@wan:/wan/fly_in_coding/build# cmake ../ -Dplatform=X86_64
-- The C compiler identification is GNU 7.4.0
-- The CXX compiler identification is GNU 7.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /wan/fly_in_coding/build

執行編譯

root@wan:/wan/fly_in_coding/build# make
Scanning dependencies of target dpdk_fifo
[ 25%] Building CXX object components/dpdk_fifo/CMakeFiles/dpdk_fifo.dir/rte_ring.cpp.o
[ 50%] Linking CXX shared library ../../../lib/X86_64/libdpdk_fifo.so
[ 50%] Built target dpdk_fifo
Scanning dependencies of target cmake_test
[ 75%] Building CXX object app/cmake_test/CMakeFiles/cmake_test.dir/cmake_test.cpp.o
[100%] Linking CXX executable cmake_test
[100%] Built target cmake_test
root@wan:/wan/fly_in_coding/build# ls
app  CMakeCache.txt  CMakeFiles  cmake_install.cmake  components  Makefile

進行安裝 將動態庫和可執行 文件複製到一個單獨的目錄下

root@wan:/wan/fly_in_coding/build# make install
[ 50%] Built target dpdk_fifo
[100%] Built target cmake_test
Install the project...
-- Install configuration: ""
-- Installing: /wan/fly_in_coding/out/cmake_test/cmake_test
-- Set runtime path of "/wan/fly_in_coding/out/cmake_test/cmake_test" to ""
-- Up-to-date: /wan/fly_in_coding/out/cmake_test
-- Installing: /wan/fly_in_coding/out/cmake_test/libdpdk_fifo.so

4 cmake文件清單及詳解

4.1 頂級CMakeLists.txt

cmake_minimum_required(VERSION 3.5)
add_subdirectory(components)
add_subdirectory(app)

4.2 app CMakeLists.txt

cmake_minimum_required(VERSION 3.5)
add_subdirectory(cmake_test)

4.2.1 cmake_test中文件清單

CMakeLists.txt

#要求cmake版本最低3.5
cmake_minimum_required(VERSION 3.5)
include (../../cmake_config/cm_commom.cmake)
#根據設備類型選擇不同的cmake配置文件
include (${PROJECT_ROOT_PATH}/cmake_config/cm_X86_64.cmake)
#設置當前工程名字
set(project_name cmake_test)
set (CMAKE_INSTALL_PREFIX ${PROJECT_ROOT_PATH}/out/${project_name})
#添加源文件目錄
aux_source_directory(. DIR_SRCS)

#當前模塊生成可以行文件
add_executable(${project_name} ${DIR_SRCS})

#添加當前模塊需要的庫
target_link_libraries(${project_name}  libdpdk_fifo.so ) 
install(TARGETS ${project_name} DESTINATION ${CMAKE_INSTALL_PREFIX})
install(DIRECTORY ${LIBRARY_OUTPUT_PATH}/ DESTINATION ${CMAKE_INSTALL_PREFIX} FILES_MATCHING PATTERN "*.so")

cmake_test.cpp

#include <stdio.h>
#include "rte_ring.h"
int main(void)
{
        struct rte_ring * r = NULL;
        r = rte_ring_create("test_ring",32,0);
        if(r != NULL)
        {
                rte_ring_destory(r);
        }
        else
        {

        }
        printf("cmake_test \n");
        return 0;
}

4.3 cmake_config 文件詳解

├── cmake_config // cmake相關配置文件
│ ├── cm_commom.cmake // 添加cmake一些公共的配置信息:比如說編譯選項等
│ ├── cm_device_type.cmake // 設備型號配置文件
│ ├── cm_platform.cmake // 平臺相關的配置文件 比如說:硬件平臺 軟件平臺等
│ └── cm_X86_64.cmake // X86_64對應的配置文件

cm_commom.cmake

#添加 c++11 編譯選項
add_compile_options(-std=c++11)

#添加 debug -g 編譯選項
add_compile_options(-g)

add_compile_options(-fPIC)

#把編譯警告當做錯誤處理 
#add_compile_options(-Werror) 

SET(PROJECT_ROOT_PATH "/wan/fly_in_coding")

#添加公共的頭文件
include_directories(
                                        #當前
                                        ./ 
                                        # 第三庫文件   
                                        ${PROJECT_ROOT_PATH}/third_party/

                                        ${PROJECT_ROOT_PATH}/app/cmake_test

                                        # 主框架頭文件
                                        ${PROJECT_ROOT_PATH}/main_frame/

                                        # 組件頭文件
                                        ${PROJECT_ROOT_PATH}/components/
                                        ${PROJECT_ROOT_PATH}/components/dpdk_fifo/

                                        )
#SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_ROOT_PATH}/out) 

cm_device_type.cmake

#根據設備類型選擇不同的cmake配置文件
if(${DEVICE} STREQUAL "MODLE1")
        add_definitions(-DMODLE1)
elseif(${DEVICE} STREQUAL "MODLE2")
        add_definitions(-DMODLE2)
elseif(${DEVICE} STREQUAL "MODLE3")
        add_definitions(-DMODLE3)
elseif(${DEVICE} STREQUAL "MODLE4")
        add_definitions(-DMODLE4)
else()    
endif()

cm_platform.cmake

#根據設備類型選擇不同的cmake配置文件
if(${platform} STREQUAL "X86_64")
    include (${PROJECT_ROOT_PATH}/cmake_config/cm_X86_64.cmake)
elseif(${platform} STREQUAL "NPNC2")
    include (${PROJECT_ROOT_PATH}/cmake_config/cm_X86_64.cmake)
else()
    include (${PROJECT_ROOT_PATH}/cmake_config/cm_X86_64.cmake)
endif()

cm_X86_64.cmake

add_definitions(-DX86_64)
SET(LIBRARY_OUTPUT_PATH  ${PROJECT_ROOT_PATH}/lib/X86_64)
link_directories(${PROJECT_ROOT_PATH}/lib/X86_64)

4.4 components 文件詳解

├── components // 組件類的配置文件 軟件系統的各個組件
│ ├── CMakeLists.txt // 本級目錄的cmake文件
CMakeLists.txt

#要求cmake版本最低3.5
cmake_minimum_required(VERSION 3.5)
# 添加子設備
add_subdirectory(dpdk_fifo)

│ └── dpdk_fifo // 無鎖隊列目錄
│ ├── CMakeLists.txt // 生成 靜態庫或者動態庫
│ ├── rte_atomic.h
│ ├── rte_ring.cpp
│ └── rte_ring.h

4.4.1 dpdk_fifo中文件清單

CMakeLists.txt

#要求cmake版本最低3.5
cmake_minimum_required(VERSION 3.5)

include (../../cmake_config/cm_commom.cmake)
include (${PROJECT_ROOT_PATH}/cmake_config/cm_platform.cmake)


#添加源文件目錄
aux_source_directory(. DIR_SRCS)

#當前模塊生成靜態庫 
#add_library(dpdk_fifo STATIC ${DIR_SRCS})
# 當前模塊生成動態庫 
add_library(dpdk_fifo SHARED ${DIR_SRCS})

5 結束語

上述模板可以應用一般的項目,可以根據自己的實際情況進行改動,文件清單中對每個函數的使用也進行了比較詳細地解釋,如果對於文中API 還有不清楚的可以去cmake官網進行查看。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章