除 add_executable 生成可執行文件外,還可以 add_library 生成鏈接庫。
一、Linux的鏈接庫
首先講一下 linux 的鏈接庫,就是一些函數代碼的二進制形式,有動態與靜態兩種,動態通常用.so爲後綴,靜態用.a爲後綴。
靜態鏈接庫 .a:
文件的命名方式:“libxxx.a”,庫名前加“lib”,後綴是“.a”,庫名是“xxx”。
靜態庫的代碼在編譯過程中已經被載入可執行程序,因此體積較大。
當要使用時,鏈接器會找出程序所需的函數,然後將它們拷貝到執行文件,由於這種拷貝是完整的,所以一旦連接成功,靜態程序庫也就不再需要了。
動態鏈接庫(共享庫):
文件命名方式:“libxxx.so”,庫名前加“lib”,後綴是“.so”,庫名是“xxx”。
動態庫的代碼是在可執行程序運行時才載入內存的,在編譯過程中僅簡單的引用,因此代碼體積較小。
某個程序在運行中要調用某個動態鏈接庫函數的時候,操作系統首先會查看所有正在運行的程序,看在內存裏是否已有此庫函數的拷貝了。如果有,則讓其共享那一個拷貝;只有沒有才鏈接載入。在程序運行的時候,被調用的動態鏈接庫函數被安置在內存的某個地方,所有調用它的程序將指向這個代碼段。因此,這些代碼必須使用相對地址,而不是絕對地址。在編譯的時候,我們需要告訴編譯器,這些對象文件是用來做動態鏈接庫的,所以要用地址無關代碼(Position Independent Code (PIC))。
動態鏈接庫的加載方式有兩種:隱式加載和顯示加載。
注意:linux下進行連接的缺省操作是首先連接動態庫,也就是說,如果同時存在靜態和動態庫,不特別指定的話,將與動態庫相連接。
二、創建鏈接庫
add_library(<name> [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
[source1] [source2 ...])
- name 創建的鏈接庫的名稱,在項目中必須是全局唯一的。
- STATIC、SHARED或MODULE可以指定要創建的庫的類型。 STATIC代表靜態鏈接庫。 SHARED代表動態鏈接庫。 MODULE庫是未鏈接到其他目標的插件,但可以使用類似dlopen的功能在運行時動態加載。
- EXCLUDE_FROM_ALL如果給出,將在創建的目標上設置相應的屬性。請參閱EXCLUDE_FROM_ALL
- source 創建鏈接庫所依賴的源文件。
三、一個例子:
hello.c
#include <stdio.h>
int hello()
{
printf("hello CMake!\n");
return 0;
}
CMakeLists.txt
# CMake最低版本要求
cmake_minimum_required(VERSION 3.5)
# 項目名稱
project(test_3)
# 指定生成目標
add_executable(test_3 main.c)
# 生成可執行文件
# 這裏直接寫庫名稱 test_2 就可以,CMake 會自動添加前綴 lib 和後綴 .a
add_library(test_2 STATIC hello.c)
編譯後的結果:(編譯方法同CMake學習(一)—— 最簡單的CMakeLists.txt)
libtest_2.a即生成的靜態鏈接庫。
參考:
https://www.cnblogs.com/inrgihc/articles/7909346.html
https://blog.csdn.net/sinat_34684122/article/details/81673605