CMake:03 靜態庫與動態庫構建

任務目標

  • 建立一個靜態庫和動態庫,提供 HelloFunc 函數供其他程序編程使用,HelloFunc 向終端輸出 Hello World 字符串
  • 安裝頭文件與共享庫

一、準備工作

① 進入 /home/lql/cmake 目錄

cd /home/lql/cmake

新建並進入 t3 工作目錄

mkdir t3 && cd t3

② 新建 CMakeLists.txt

vim CMakeLists.txt

輸入內容:

cmake_minimum_required(VERSION 3.10)

PROJECT(HELLOLIB)
ADD_SUBDIRECTORY(lib)

③ 新建並進入 lib 目錄(用於存放源文件 hello.c、hello.h 和 lib 目錄相應的 CMakeLists.txt)

mkdir build && cd build

新建 hello.c

vim hello.c

輸入內容:

#include "hello.h"

void HelloFunc()
{
    printf("Hello World \n");
}

新建 hello.h

vim hello.h

輸入內容:

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

新建 CMakeLists.txt

vim CMakeLists.txt

輸入內容:

SET(LIBHELLO_SRC hello.c)
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC}) // 生成動態庫 libhello.so

二、外部構建

① 新建並進入 build 目錄

mkdir build && cd build

② 構建

cmake ..
make

此時,就會在 build/lib 目錄下得到一個 libhello.so,這就是動態庫(共享庫)

也可以指定 libhello.so(目標二進制文件)生成的目錄,兩種方式

# 方式一
ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL]) // 指令通過 binary_dir 指定中間二進制文件和目標二進制文件存放目錄

# 方式二
SET(EXECUTABLE_OUTPUT_PATH <path>) // 通過 path 指定生成的可執行文件(目標二進制文件)的位置

三、添加靜態庫

修改 lib/CMakeLists.txt

SET(LIBHELLO_SRC hello.c)
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})

# 添加如下內容
ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC}) // 生成 libhello_static.a 靜態庫
# 使用 ADD_LIBRARY 指定同名動態庫和靜態庫,會提示重名錯誤
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello") // 修改生成的靜態庫名稱爲 hello,最終生成 libhello.a

四、安裝

使用 INSTALL 指定,安裝庫文件和頭文件

SET(LIBHELLO_SRC hello.c)
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})

ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")

# 添加如下內容
INSTALL(TARGETS hello hello_static
		LIBRARY DESTINATION lib
		ARCHIVE DESTINATION lib)
INSTALL(FILES hello.h DESTINATION include/hello)

安裝到 /home/lql/cmake/to

cmake -DCMAKE_INSTALL_PREFIX=/home/lql/cmake/to ..
make
make install

五、指令解釋

① ADD_LIBRARY

# SHARED:動態庫
# STATIC:靜態庫
# MODULE:使用 dyld 的系統有效,若不支持 dyld,則當做 SHARED 對待
ADD_LIBRARY(libname [SHARED|STATIC|MODULE] ${SRC_LIST}) // 生成庫文件,第二個參數不寫,默認爲 STATIC,即靜態庫

② ADD_SUBDIRECTORY

# source_dir:源文件所在目錄
# binary_dir:中間二進制文件和目標二進制文件存放目錄
# EXCLUDE_FROM_ALL:將所指定的目錄從編譯過程中排除
ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

小結

  • 通過 ADD_LIBRARY 指令構建動態庫和靜態塊
  • 通過 SET_TARGET_PROPERTIES 指令同時構建同名的動態庫和靜態庫(使用 ADD_LIBRARY 指定同名動態庫和靜態庫,會提示重名錯誤)
  • 使用 INSTALL 指令安裝庫文件和頭文件
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章