使用cmake構(gòu)建C/C++項目和動態(tài)庫

編譯C/C++文件時,很多時候都是直接使用像 gcc main.c 或者 g++ main.cpp 這樣的命令編譯的。但是代碼文件多了后,這樣編譯就很困難了。這時候 就出現(xiàn)了MakeFile 這個工具。

MakeFile 解決了多個文件編譯難的問題,有了MakeFile,只需要在MakeFile的目錄中 運行一下make 命令, 編譯就會自動完成。但是編寫MakeFile又很啰嗦,于是聰明的程序員們有開發(fā)了一個工具,自動生成MakeFile 文件,cmake 的作用就是自動生成MakeFile。畢竟寫cmake要比寫MakeFile要簡單很多

也許你會說,現(xiàn)在都是用IDE寫代碼,IDE都會自動自動編譯和運行,我還學(xué)這些干啥。但是有時候需要服務(wù)器上編譯項目,或者在沒有IDE的機器上編譯項目,這時候MakeFile就很有用了。其實很多IDE也是使用cmake完成編譯的,比如 clion

cmake 安裝

在linux上可以使用源碼安裝和包管理安裝,一般直接用包管理安裝就好了
Ubuntu和Debian
sudo apt-get install cmake

CentOS
sudo yum install cmake

因為cmake只是生成MakeFile,最終組織編譯的還是MakeFile,所以還有安裝make

make 一般都會預(yù)裝,為了保險,還是裝一下

Ubuntu和Debian
sudo apt-get install make

CentOS
sudo yum install make

cmake基本規(guī)則

cmake 也沒啥神秘的,本質(zhì)上也是根據(jù)一定的規(guī)則自動生成MakeFile的,也是有語法的

# 是注釋符號

預(yù)定義變量

PROJECT_NAME項目名稱
PROJECT_SOURCE_DIR工程的根目錄
PROJECT_BINARY_DIR 執(zhí)行cmake命令的目錄
PROJECT_BINARY_DIR 執(zhí)行cmake命令的目錄
CMAKE_CURRENT_SOURCE_DIR當(dāng)前CMakeLists.txt文件所在目錄
CMAKE_C_FLAGS設(shè)置C編譯選項
CMAKE_CXX_FLAGS設(shè)置C++編譯選項
CMAKE_C_COMPILER設(shè)置C編譯器
CMAKE_CXX_COMPILER設(shè)置C++編譯器
EXECUTABLE_OUTPUT_PATH設(shè)置編譯后可執(zhí)行文件目錄
LIBRARY_OUTPUT_PATH設(shè)置生成的庫文件目錄

常用規(guī)則

cmake_minimum_required(VERSION 3.16) 指令cmake 版本
project(hello_world) 設(shè)置工程名
include_directories(${PROJECT_SOURCE_DIR}/include) 添加頭文件路徑
link_directories(${PROJECT_SOURCE_DIR}/lib) 添加鏈接庫的路徑
add_subdirectory(module)添加 module 子目錄, 此目錄下也要有CMakeLists.txt文件
add_executable(project1 main.c)指定編譯的可執(zhí)行文件
add_library(lib1 SHARED library.c library.h)指定生成的庫文件,SHARED是生成動態(tài)庫,STATIC后生成靜態(tài)庫
add_compile_options() 添加編譯選項
target_link_libraries()指定動態(tài)鏈接庫
install()指定make install的目錄

set(XXXX YYYYYY)用于設(shè)置和修改變量
${XXXX} 使用變量

構(gòu)建一個簡單的項目

只有一個 main.c 文件

CMakeList.txt

cmake_minimum_required(VERSION 3.15)
project(project1 C)

set(CMAKE_C_STANDARD 99)

add_executable(project1 main.c)

main.c

#include <stdio.h>

int main() {
    printf("Hello, CMakeList!\n");
    return 0;
}
編譯一個debug版本
  1. mkdir debug 新建debug目錄
  2. cd debug 進入debug目錄
  3. cmake -DCMAKE_BUILD_TYPR=debug .. 指定編譯模式為debug
  4. make 生成可執(zhí)行文件

此時會生成project1文件

步驟 3 中 cmake -DCMAKE_BUILD_TYPE=release .. 指定編譯模式為release

構(gòu)建一個生成動態(tài)庫的項目

有兩個文件library.hlibrary.c
CMakeList.txt

cmake_minimum_required(VERSION 3.15)
project(shared C)

set(CMAKE_C_STANDARD 99)

add_library(shared SHARED library.c library.h)

library.h

int add(int a, int b);

library.c

int add(int a, int b) {
    return a + b;
}
生成動態(tài)庫
  1. mkdir lib 新建lib目錄
  2. cd lib 進入lib目錄
  3. cmake -DCMAKE_BUILD_TYPE=debug .. 指定編譯模式為debug
  4. make 生成可執(zhí)行文件
    此時會生成 libshared.so文件

在第一個項目中使用動態(tài)庫

首先把 libshared.so文件和library.h文件復(fù)制到第一個項目中

修改 CMakeList.txt

cmake_minimum_required(VERSION 3.15)
project(project1 C)

set(CMAKE_C_STANDARD 99)

add_executable(project1 main.c)

target_link_libraries(project1 ${PROJECT_SOURCE_DIR}/libshared.so)#指定動態(tài)庫文件
  1. mkdir debug 新建debug目錄
  2. cd debug 進入debug目錄
  3. cmake -DCMAKE_BUILD_TYPE=debug .. 指定編譯模式為debug
  4. make 生成可執(zhí)行文件

最終目錄如圖


把兩個項目合成一個

能不能在一個項目中生成動態(tài)庫并在這個項目中使用呢,當(dāng)然是可以的。

也就是在這個項目中部分文件編譯成動態(tài)庫 .so 文件, 部分文件編譯成 可執(zhí)行文件

修改 CMakeList.txt

cmake_minimum_required(VERSION 3.13.3)
project(project1 C)

set(CMAKE_C_STANDARD 99)

add_library(shared SHARED library.h library.c)

set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)#設(shè)置動態(tài)庫輸出目錄

add_executable(project1 main.c)

target_link_libraries(project1 shared)
  1. mkdir debug 新建debug目錄
  2. cd debug 進入debug目錄
  3. cmake -DCMAKE_BUILD_TYPE=debug .. 指定編譯模式為debug
  4. make 生成可執(zhí)行文件

最終目錄如圖

最后

通過幾個簡單的例子,介紹了一下cmake的基本使用,文中是使用cmake構(gòu)建的C項目,換成C++基本沒什么區(qū)別,就不展示了

cmake的功能遠不止這些,還需要在實戰(zhàn)中多學(xué)習(xí),多總結(jié)

2021-03-06 補充
通過上面的方式可以編譯運行,但是會有一個問題,就是 .so 文件不能更改目錄,一旦動態(tài)庫目錄變了,程序就沒法加載,程序也就沒法運行了。為此又找資料學(xué)習(xí)一番,另寫了一篇,傳送門

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容