任務目標
- 建立一個靜態庫和動態庫,提供 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 指令安裝庫文件和頭文件