1. 程式人生 > >Linux下使用cmake生成動態連結庫並使用

Linux下使用cmake生成動態連結庫並使用

使用cmake生成庫主要要注意三個資料夾

(1)原始檔資料夾
(2)中間資料夾(編譯生成的.o等檔案的資料夾)
(3)安裝資料夾(最終可用的庫所在的資料夾)

使用庫的步驟
(1)在工程檔案中包括庫函式的標頭檔案(可為絕對路徑,也可配置全域性環境變數用相對路徑)
(2)在CMakeLists.txt或整合開發環境中指定庫函式的動態連結庫或者靜態連結庫所在的資料夾路徑
(3)在CMakeLists.txt或整合開發環境中指定標頭檔案的資料夾路徑
(4)如果是動態連結庫,且庫函式不在linux預設查詢路徑下,執行時要修改環境變數才能使用

下文用最簡單的示例來表示這個過程,假設我的庫實現的是簡單的加法計算。庫函式的原始檔名字叫hello.c,庫函式的標頭檔案名字叫hello.h,生成的動態連結庫函式的名稱叫libhello.so,目標是在/hello/install資料夾下安裝這個庫,以便後來呼叫。設庫函式原始檔在/home/hello/libhello目錄,編譯生成的中間資料夾在/home/hello/build

#1.生成庫

資料夾結構如下

Linux下生成動態連結庫並使用(使用cmake)

##1.1編輯檔案

在libhello資料夾下編輯hello.c檔案

#include<stdio.h>
#include"hello.h"

void hello()
{
      printf("hello");
}

和hello.h標頭檔案。

#ifndef HELLO_H
#define HELLO_H
#include <stdio.h>
void hello();
#endif

##1.2使用cmake編譯和安裝

(1)在/home/hello/資料夾下新建CMakeLists.txt,新增以下內容

cmake_minimum_required (VERSION 2.6)

add_library(hello SHARED ${PROJECT_SOURCE_DIR}/libhello/hello.c)
install(TARGETS hello LIBRARY DESTINATION lib)

其中
add_library(hello SHARED ${PROJECT_SOURCE_DIR}/libhello/hello.c)

PROJECT_SOURCE_DIR 巨集的值是後文中cmake gui的where is source code 選項選擇的路徑值,也就是頂層CMakeList.txt所在檔案路徑的值。

才採用的是hello.c所在的絕對路徑。

控制檯輸入cmake-gui

如圖

Linux下生成動態連結庫並使用(使用cmake)

Linux下生成動態連結庫並使用(使用cmake)

##1.3將標頭檔案安裝到<prefix>/include/目錄下

Linux下生成動態連結庫並使用(使用cmake)

然後在cmake gui中點選configure配置,點選generate
然後在build資料夾make
make install

如圖

Linux下生成動態連結庫並使用(使用cmake)

#2.使用生成的動態連結庫

##2.1 方法1.直接用gcc指定標頭檔案路徑和動態連結庫路徑

步驟如下

如圖

Linux下生成動態連結庫並使用(使用cmake)

###2.1.2編譯主函式usehellolib.c 如下

#include <hello.h>
int main()
{
hello();
return 0;
}

Linux下生成動態連結庫並使用(使用cmake)

語法分析:
gcc 原始檔 -I標頭檔案目錄 -L動態連結庫目錄 動態連結庫檔名(去掉lib在前面加l) -o 生成的可執行檔名字
發現可以連結成功
但是輸入./usehellolib
會出現這個錯誤

Linux下生成動態連結庫並使用(使用cmake)

說明找不到庫,因為採用的是動態連結庫,所謂動態連結是在執行時連結,編譯連結的時候是直接告訴了GCC庫的位置,因此會成功,而執行是如果不告訴作業系統庫在哪個位置,當然找不到這個庫,程式也就不能執行。因此要告訴作業系統庫在哪個地方,linux使用LD_LIBRARY_PATH告訴系統庫在哪個地方。(LD_LIBRARY_PATH是Linux環境變數名,該環境變數主要用於指定查詢共享庫(動態連結庫)時除了預設路徑之外的其他路徑)。

設定環境變數可以有臨時,也可以永久設定。

再次執行 ./uselibhello
輸出hello

(2)永久設定解決方案

然後
source /root/.bashrc
就能夠運行了。

然後在控制檯執行

ldconfig

執行程式就能夠執行了。

解析:
INCLUDE_DIRECTORIES()告訴編譯器標頭檔案在哪個位置。
TARGET_LINK_LIBRARIES()告訴連結器動態連結庫在哪個位置
輸入
cmake.
make
會出現連結錯誤
/usr/bin/ld: cannot find -lhello
/usr/bin/ld: cannot find -l*解決方法
ld連結器告訴你找不到庫函式,那麼你就要把庫函式放到ld連結器能夠找到的地方。因此解決方法如下

ln -s 它的功能是為某一個檔案在另外一個位置建立一個同步的連結,這個命令最常用的引數是-s,具體用法是:ln -s 原始檔 目標檔案

方法3
類似於上文的動態連結庫的路徑設定方法
cd /etc/ld.so.conf.d/
cp libc.conf hello.conf
vi hello.conf

告訴連結器動態連結庫的路徑。
執行
ldconfig
輸入
ldconfig -p |grep libhello
輸出libhello動態連結庫資訊
設定好後
注意要重新刪除所有Cmake生成的檔案
再輸入
cmake.
make
就能夠正常使用了。

補充