3. CMake 系列 - 分模块编译安装项目
目錄
- 1. 項目目錄結構
- 2. 相關代碼
- 2.1 add 模塊
- 2.2 sub 模塊
- 2.3 測試模塊
- 2.4 頂層 CMakeLists.txt
- 3. 編譯 & 安裝
- 4. 項目安裝基本語法
- 4.1 安裝target
- 4.2 安裝普通文件
- 4.3 安裝目錄和腳本
1. 項目目錄結構
test2 ├── add │?? ├── add.c │?? ├── add.h │?? └── CMakeLists.txt ├── build ├── CMakeLists.txt ├── example │?? ├── CMakeLists.txt │?? ├── test_add.c │?? └── test_sub.c └── sub├── CMakeLists.txt├── sub.c└── sub.h說明:
add: 這個模塊是加法模塊,會生成動態庫和靜態庫。
sub:這個模塊是減法模塊,會生成動態庫和靜態庫。
example:這個模塊是測試add和sub模塊程序。
CMakeLists.txt:這里有4個CMakeLists.txt,頂層CMakeLists.txt文件管理其它模塊CMakeLists.txt文件,每個模塊CMakeLists.txt文件都只需管理自己編譯。
2. 相關代碼
2.1 add 模塊
add.h
#ifndef _ADD_H #define _ADD_Hint add(const int a, const int b);#endifadd.c
#include "add.h"int add(const int a, const int b) {return a+b; }CMakeLists.txt
# 遞歸獲取目錄下所有的C文件 file(GLOB_RECURSE c_files ./*.c)# 遞歸獲取目錄下所有的h文件 file(GLOB_RECURSE h_files ./*.h)#生成動態庫和靜態庫 add_library(add_lib_shared SHARED ${c_files}) add_library(add_lib_static STATIC ${c_files})#將動態庫和靜態庫的名字設置為 add set_target_properties(add_lib_shared PROPERTIES OUTPUT_NAME "add") set_target_properties(add_lib_static PROPERTIES OUTPUT_NAME "add")#設置動態庫版本 set_target_properties(add_lib_shared PROPERTIES VERSION 1.0 SOVERSION 1)#安裝動態庫和靜態庫 INSTALL(TARGETS add_lib_shared add_lib_staticLIBRARY DESTINATION libARCHIVE DESTINATION lib)#安裝頭文件 INSTALL(FILES ${h_files} DESTINATION include)2.2 sub 模塊
sub.h
#ifndef _SUB_H #define _SUB_Hint sub(const int a, const int b);#endifsub.c
#include "sub.h"int sub(const int a, const int b) {return a - b; }CMakeLists.txt
#遞歸獲取目錄下所有的C文件 file(GLOB_RECURSE c_files ./*.c)# 遞歸獲取目錄下所有的h文件 file(GLOB_RECURSE h_files ./*.h)#生成動態庫和靜態庫 add_library(sub_lib_shared SHARED ${c_files}) add_library(sub_lib_static STATIC ${c_files})#將動態庫和靜態庫的名字設置為 sub set_target_properties(sub_lib_shared PROPERTIES OUTPUT_NAME "sub") set_target_properties(sub_lib_static PROPERTIES OUTPUT_NAME "sub")#設置動態庫版本 set_target_properties(sub_lib_shared PROPERTIES VERSION 1.0 SOVERSION 1)#設置動態庫版本 set_target_properties(sub_lib_shared PROPERTIES VERSION 1.0 SOVERSION 1)#安裝動態庫和靜態庫 INSTALL(TARGETS sub_lib_shared sub_lib_staticLIBRARY DESTINATION libARCHIVE DESTINATION lib)#安裝頭文件 INSTALL(FILES ${h_files} DESTINATION include)2.3 測試模塊
test_add.c
#include "add.h"#include <stdio.h>int main(int argc, char **argv) {int a = 10;int b = 8;printf("%d + %d = %d\n", a, b, add(a, b));return 0; }test_sub.c
#include "sub.h"#include <stdio.h>int main(int argc, char **argv) {int a = 10;int b = 8;printf("%d - %d = %d\n", a, b, sub(a, b));return 0; }CMakeLists.txt
# 添加頭文件路徑 include_directories(${PROJECT_SOURCE_DIR}/add) include_directories(${PROJECT_SOURCE_DIR}/sub)# 添加第三方庫(add)頭文件路徑 link_directories(${PROJECT_SOURCE_DIR}/lib)# 生成執行文件 add_executable(test_add test_add.c) add_executable(test_sub test_sub.c)# 鏈接庫文件 target_link_libraries(test_add add) target_link_libraries(test_sub sub)# 安裝執行文件 INSTALL(TARGETS test_add test_subRUNTIME DESTINATION bin)2.4 頂層 CMakeLists.txt
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)#設置庫文件輸出目錄 set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)#設置執行文件輸出目錄 set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)# 添加子目錄 add_subdirectory(add) add_subdirectory(sub) add_subdirectory(example)說明:
頂層CMakeLists.txt管理子目錄的CMakeLists.txt, 從而實現模塊化編譯和管理。
3. 編譯 & 安裝
$ cd build $ cmake -DCMAKE_INSTALL_PREFIX=/home/mark/code/cmake/test2/_install .. $ make $ make install $ cd .. $ tree _install查看效果
_install/ ├── bin │?? ├── test_add │?? └── test_sub ├── include │?? ├── add.h │?? └── sub.h └── lib├── libadd.a├── libadd.so -> libadd.so.1├── libadd.so.1 -> libadd.so.1.0├── libadd.so.1.0├── libsub.a├── libsub.so -> libsub.so.1├── libsub.so.1 -> libsub.so.1.0└── libsub.so.1.0說明:
-DCMAKE_INSTALL_PREFIX:指定安裝目錄,需要是絕對路徑。
4. 項目安裝基本語法
4.1 安裝target
語法:
INSTALL(TARGETS targets... [[ARCHIVE|LIBRARY|RUNTIME] [DESTINATION <dir>] [PERMISSIONS permissions...] [CONFIGURATIONS [Debug|Release|...]] [COMPONENT <component>] [OPTIONAL] ] [...])targets: 一般填執行文件、動態庫、靜態庫。
ARCHIVE: 特指靜態庫。
LIBRARY: 特指動態庫。
RUNTIME: 特指執行文件。
dir: 安裝路徑,一般配合CMAKE_INSTALL_PREFIX使用,即表示為${CMAKE_INSTALL_PREFIX}/dir。若是dir以/開頭,表示絕對路徑,即不使用CMAKE_INSTALL_PREFIX變量。
一個例子:
#安裝動態庫和靜態庫 INSTALL(TARGETS sub_lib_shared sub_lib_staticLIBRARY DESTINATION libARCHIVE DESTINATION lib)# 安裝執行文件 INSTALL(TARGETS test_add test_subRUNTIME DESTINATION bin)4.2 安裝普通文件
語法
INSTALL(FILES files... DESTINATION <dir> [PERMISSIONS permissions...] [CONFIGURATIONS [Debug|Release|...]] [COMPONENT <component>] [RENAME <name>] [OPTIONAL])使用方法和上述方法類似,舉個簡單的例子,就大概知道怎么用了。
一個例子
#安裝頭文件 INSTALL(FILES ${h_files} DESTINATION include)4.3 安裝目錄和腳本
語法
INSTALL(DIRECTORY dirs... DESTINATION <dir> [FILE_PERMISSIONS permissions...] [DIRECTORY_PERMISSIONS permissions...] [USE_SOURCE_PERMISSIONS] [CONFIGURATIONS [Debug|Release|...]] [COMPONENT <component>] [[PATTERN <pattern> | REGEX <regex>] [EXCLUDE] [PERMISSIONS permissions...]] [...])說明
dirs:DIRECTORY 后面連接的路徑是所在Source目錄的相對路徑; 但務必注意: abc和 abc/有很大的區別: 如果目錄名不以/結尾,那么這個目錄將被安裝為目標路徑下的abc,如果目錄名以/結尾,代表將這個目錄中的內容安裝到目標路徑,但不包括這個目錄本身。
pattern: 使用正則表達式進行過濾.
permissions: 用于指定pattern過濾后的文件權限。
舉例說明
INSTALL(DIRECTORY icons scripts/ DESTINATION share/myproj PATTERN "CVS" EXCLUDE PATTERN "scripts/*" PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ)這條指令的執行結果是:將icons 目錄安裝到 <prefix>/share/myproj,
將scripts/中的內容安裝到<prefix>/share/myproj不包含目錄名為CVS
的目錄,對于scripts/*文件指定權限為OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ。
轉載于:https://www.cnblogs.com/standardzero/p/10793746.html
總結
以上是生活随笔為你收集整理的3. CMake 系列 - 分模块编译安装项目的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [转载]编译中的常见分析方法
- 下一篇: Python【每日一问】16