利用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官網進行查看。