5.静态库与动态库构建

本节的任务:
1.建立一个静态库和动态库,提供 HelloFunc 函数供其他程序编程使用,HelloFunc向终端输出 Hello World 字符串。
2.安装头文件与共享库

1.准备工作

创建t3目录

mkdir t3

2.建立共享库

cd t3
mkdir lib

在t3目录下建立CMakeLists.txt 内容如下:

project(hellolib)
add_subdirectory(lib)

在lib目录下建立两个文件hello.c与hello.h
hello.c内容如下:

#ifndef HELLO_H
#define HELLO_H

#include<stdio.h>

void HelloFunc();

#endif//HELLO_H 

hello.h内容如下:

#ifndef HELLO_H
#define HELLO_H

#include<stdio.h>

void HelloFunc();

#endif//HELLO_H 

在lib目录下建立CMakeLists.txt,内容如下:

set(LIBHELLO_SRC hello.c)
add_library(hello SHARED ${LIBHELLO_SRC})

3.编译共享库

按照习惯,我们建立一个build目录, 在build目录中

cmake ..
make

编译过程如下:

root@BIH-L-55661:/mnt/d/study/lwstudy/cmake/t3# mkdir build
root@BIH-L-55661:/mnt/d/study/lwstudy/cmake/t3# ls
CMakeLists.txt  build  lib
root@BIH-L-55661:/mnt/d/study/lwstudy/cmake/t3# cd build/
root@BIH-L-55661:/mnt/d/study/lwstudy/cmake/t3/build# ls
root@BIH-L-55661:/mnt/d/study/lwstudy/cmake/t3/build# cmake ..
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Warning (dev) in CMakeLists.txt:
  No cmake_minimum_required command is present.  A line of code such as

    cmake_minimum_required(VERSION 3.16)

  should be added at the top of the file.  The version specified may be lower
  if you wish to support older CMake versions for this project.  For more
  information run "cmake --help-policy CMP0000".
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Configuring done
-- Generating done
-- Build files have been written to: /mnt/d/study/lwstudy/cmake/t3/build

root@BIH-L-55661:/mnt/d/study/lwstudy/cmake/t3/build# make
Scanning dependencies of target hello
[ 50%] Building C object lib/CMakeFiles/hello.dir/hello.o
[100%] Linking C shared library libhello.so
[100%] Built target hello

这时,你就可以在lib目录得到一个 libhello.so

root@BIH-L-55661:/mnt/d/study/lwstudy/cmake/t3/build# cd lib/
root@BIH-L-55661:/mnt/d/study/lwstudy/cmake/t3/build/lib# ls
CMakeFiles  Makefile  cmake_install.cmake  libhello.so
root@BIH-L-55661:/mnt/d/study/lwstudy/cmake/t3/build/lib#

如果你要指定 libhello.so 生成的位置,可以通过在主工程文件 CMakeLists.txt 中修改 ADD_SUBDIRECTORY(lib) 指令来指定一个编译输出位置或者在 lib/CMakeLists.txt 中添加 SET(LIBRARY_OUTPUT_PATH <路径>) 来指定一个新的位置

这两者的区别我们上一节已经提到了,所以,这里不再赘述,下面,我们解释一下一个新的指令 ADD_LIBRARY
ADD_LIBRARY(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 … sourceN)
你不需要写全 libhello.so,只需要填写hello即可,cmake 系统会自动为你生成libhello.X
add_library(hello SHARED ${LIBHELLO_SRC})

类型有三种:

  • SHARED 动态库
  • STATIC 静态库
  • MODULE 在使用dyld的系统有效,如过不支持dyld,则被当作SHARED对待

4 添加静态库

同样使用上面的指令,我们在支持动态库的基础上再为工程添加一个静态库,按照一般的习惯,静态库名字跟动态库名字应该是一致的,只不过后缀是.a 罢了

下面我们用这个指令再来添加静态库:
ADD_LIBRARY(hello STATIC ${LIBHELLO_SRC}) 就可以构建一个libhell.a的静态库了

如果我们需要的是名字相同的静态库和动态库,因为target名字是唯一的, 所以,我们肯定不能通过ADD_LIBRARY指令来实现了。这时候我们需要用到另外一个指令:
SET_TARGET_PROPERTIES, 其基本语法是:
SET_TARGET_PROPERTIES(target1 target2 … PROPERTIES prop1 value1 prop2 value2 …)
这条指令可以用来设置输出的名称,对于动态库,还可以用来指定动态库版本和 API 版本

在本例中,我们需要作的是向 lib/CMakeLists.txt 中添加一条
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME “hello”)
这样,我们就可以同时得到 libhello.so/libhello.a 两个库了
添加完如下:

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")

与他对应的指令是:
GET_TARGET_PROPERTY(VAR target property)
具体用法如下例,我们向 lib/CMakeListst.txt 中添加:
GET_TARGET_PROPERTY(OUTPUT_VALUE hello_static OUTPUT_NAME)
MESSAGE(STATUS “This is the hello_static OUTPUT_NAME:”${OUTPUT_VALUE})
如果没有这个属性定义,则返回 NOTFOUND

lib/CMakeListst.txt 内容如下:

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")
get_target_property(OUTPUT_VALUE hello_static OUTPUT_NAME)
message(STATUS "This is the hello_static OUTPUT_NAME:" ${OUTPUT_VALUE})

执行:

cmake .. 
make

编译过程如下: 打印出了 This is the hello_static OUTPUT_NAME:hello

root@BIH-L-55661:/mnt/d/study/lwstudy/cmake/t3/build# cmake ..
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- This is the hello_static OUTPUT_NAME:hello
CMake Warning (dev) in CMakeLists.txt:
  No cmake_minimum_required command is present.  A line of code such as

    cmake_minimum_required(VERSION 3.16)

  should be added at the top of the file.  The version specified may be lower
  if you wish to support older CMake versions for this project.  For more
  information run "cmake --help-policy CMP0000".
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Configuring done
-- Generating done
-- Build files have been written to: /mnt/d/study/lwstudy/cmake/t3/build
root@BIH-L-55661:/mnt/d/study/lwstudy/cmake/t3/build# make
Scanning dependencies of target hello_static
[ 25%] Building C object lib/CMakeFiles/hello_static.dir/hello.o
[ 50%] Linking C static library libhello.a
[ 50%] Built target hello_static
Scanning dependencies of target hello
[ 75%] Building C object lib/CMakeFiles/hello.dir/hello.o
[100%] Linking C shared library libhello.so
[100%] Built target hello

5.动态库版本号

按照规则,动态库是应该包含一个版本号的,我们可以看一下系统的动态库,一般情况是
libhello.so.1.2
libhello.so ->libhello.so.1
libhello.so.1->libhello.so.1.2
为了实现动态库版本号,我们仍然需要使用 SET_TARGET_PROPERTIES 指令
具体使用方法如下
SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)
VERSION 指代动态库版本,SOVERSION 指代 API 版本。
将上述指令加入 lib/CMakeLists.txt 中,重新构建看看结果。
在 build/lib 目录会生成:

root@BIH-L-55661:/mnt/d/study/lwstudy/cmake/t3/build/lib# ls -al
total 32
drwxrwxrwx 1 root root  4096 Oct 25 09:52 .
drwxrwxrwx 1 root root  4096 Oct 25 09:52 ..
drwxrwxrwx 1 root root  4096 Oct 25 09:52 CMakeFiles
-rwxrwxrwx 1 root root  6165 Oct 25 09:52 Makefile
-rwxrwxrwx 1 root root  1123 Oct 25 09:52 cmake_install.cmake
-rwxrwxrwx 1 root root  1826 Oct 25 09:52 libhello.a
lrwxrwxrwx 1 root root    13 Oct 25 09:52 libhello.so -> libhello.so.1
lrwxrwxrwx 1 root root    15 Oct 25 09:52 libhello.so.1 -> libhello.so.1.2
-rwxrwxrwx 1 root root 16200 Oct 25 09:52 libhello.so.1.2
root@BIH-L-55661:/mnt/d/study/lwstudy/cmake/t3/build/lib#

6.安装共享库和头文件

以上面的例子,我们需要将 libhello.a, libhello.so.x 以及 hello.h 安装到系统目
录,才能真正让其他人开发使用,在本例中我们将 hello 的共享库安装到<prefix>/lib
目录,将 hello.h 安装到<prefix>/include/hello 目录。

利用上一节了解到的 INSTALL 指令,我们向 lib/CMakeLists.txt 中添加如下指令:

INSTALL(TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
INSTALL(FILES hello.h DESTINATION include/hello)

注意,静态库要使用 ARCHIVE 关键字
通过:

cmake -DCMAKE_INSTALL_PREFIX=/tmp/usr ..
make
make install

我们就可以将头文件和共享库安装到系统目录/tmp/usr/lib 和/tmp/usr/include/hello 中了。

root@BIH-L-55661:/mnt/d/study/lwstudy/cmake/t3/build# cmake -DCMAKE_INSTALL_PREFIX=/tmp/usr ..
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- This is the hello_static OUTPUT_NAME:hello
CMake Warning (dev) in CMakeLists.txt:
  No cmake_minimum_required command is present.  A line of code such as

    cmake_minimum_required(VERSION 3.16)

  should be added at the top of the file.  The version specified may be lower
  if you wish to support older CMake versions for this project.  For more
  information run "cmake --help-policy CMP0000".
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Configuring done
-- Generating done
-- Build files have been written to: /mnt/d/study/lwstudy/cmake/t3/build
root@BIH-L-55661:/mnt/d/study/lwstudy/cmake/t3/build# make
Scanning dependencies of target hello_static
[ 25%] Building C object lib/CMakeFiles/hello_static.dir/hello.o
[ 50%] Linking C static library libhello.a
[ 50%] Built target hello_static
Scanning dependencies of target hello
[ 75%] Building C object lib/CMakeFiles/hello.dir/hello.o
[100%] Linking C shared library libhello.so
[100%] Built target hello
root@BIH-L-55661:/mnt/d/study/lwstudy/cmake/t3/build# make install
[ 50%] Built target hello_static
[100%] Built target hello
Install the project...
-- Install configuration: ""
-- Installing: /tmp/usr/lib/libhello.so.1.2
-- Up-to-date: /tmp/usr/lib/libhello.so.1
-- Up-to-date: /tmp/usr/lib/libhello.so
-- Installing: /tmp/usr/lib/libhello.a
-- Up-to-date: /tmp/usr/include/hello/hello.h
root@BIH-L-55661:/mnt/d/study/lwstudy/cmake/t3/build# tree /tmp/usr/
/tmp/usr/
├── include
│   └── hello
│       └── hello.h
└── lib
    ├── libhello.a
    ├── libhello.so -> libhello.so.1
    ├── libhello.so.1 -> libhello.so.1.2
    └── libhello.so.1.2

3 directories, 5 files

7.小节

本小节,我们谈到了:
如何通过 ADD_LIBRARY 指令构建动态库和静态库。
如何通过 SET_TARGET_PROPERTIES 同时构建同名的动态库和静态库。
如何通过 SET_TARGET_PROPERTIES 控制动态库版本
最终使用上一节谈到的 INSTALL 指令来安装头文件和动态、静态库。

在下一节,我们需要编写另一个高级一点的 Hello World 来演示怎么使用我们已经构建的
构建的共享库 libhello 和外部头文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘大望

谢谢你请的咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值