cmake使用教(三)构建动态库、静态库和安装共享库

6 篇文章 16 订阅

前两节简单的介绍了,cmake的简单使用和install的过程,本节将详细介绍构建动态库和静态库,以及共享动态库和静态库的过程

文件存放方式:

 创建test根目录,然后创建lib和build,在根目录下创建CMakeLists.txt,,在lib目录下创建CMakeLists.txt、hello.cpp、hello.h, 其中hello.cpp、hello.h内容如下:

hello.h
#ifndef HELLO_H
#define HELLO_H

#include<iostream>
void helloFunc();

#endif

//#######################################################
hello.cpp

#include "hello.h"
void helloFunc()
{
    std::cout<<"hello world"<<std::endl;
}

1.构建动态库和静态库

在根目录下面的CMakeLists.txt文件中添加如下代码:

因为根目录下的CMakeLists.txt无须构建文件,只需要启动子文件的CMakeLists.txt即可

# 版本判断
cmake_minimum_required(VERSION 3.0)
# 工程名
project(hellolib)
# 添加子目录,该目录为库目录,会调用子目录的cmake文件,进行构建库
add_subdirectory(lib)

主要的构建代码在lib/CMakeLists.txt里:

# 把所有源文件添加到列表
aux_source_directory(. DIR_LIB_SRCS)
# 如果文件很少,可以通过直接指定
# set(DIR_LIB_SRCS hello.cpp)

# 指定编译库输出的位置
set(LIBRARY_OUTPUT_PATH lib)
# 生成动态库
add_library(hello SHARED ${DIR_LIB_SRCS})

# 生成静态库
# 这样写会使得静态库没有构建,报错原因是动态库的名称也是hello即target不能重名
# add_library(hello STATIC ${DIR_LIB_SRCS}) 
# 修改名称后构建是可以成功的,会生成libhello_static.a和libhello.so两个文件,
# 但是同一种库我们希望名称一样
add_library(hello_static STATIC ${DIR_LIB_SRCS}) 

# 想要生成动态库和静态库相同名称的的库文件,则需要一个指令set_target_properties
# 这里只是通过重新命名的方法使其名字相同的,构建时还需不能相同
set_target_properties(hello_static PROPERTIES OUTPUT_NAME "hello")
# 获取相关属性也是通过set_target_properties
get_target_property(OUTPUT_VALUE hello_static OUTPUT_NAME)
message(STATUS "This is the hello_static OUTPUT_NAME:"${OUTPUT_VALUE})

# 动态库版本号设置 , VERSION指代动态库版本,SOVERSION 指代 API 版本。
set_target_properties(hello PROPERTIES VERSION 1.2 SOVERSION 1)
# 其中,libhello.so.1.2为动态库的文件名(realname),libhello.so.1为动态库的别名(soname),
# libhello.so为动态库的链接名(linkname)。

message(STATUS ${DIR_LIB_SRCS}"--构建库完成")

# 安装共享库和头文件
# 将动态库和静态库安装到<prefix>/lib
install(TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
# 安装头文件
install(FILES hello.h DESTINATION include/hello)

进入build执行以下命令: 

cmake -DCMAKE_INSTALL_PREFIX=/home/ubuntu/work/usr ..
make
make install

代码注释已经很相详细了,这里只需要强调几个指令和注意事项:

如果你要指定libhello.so生成的位置,可以通过在主工程文件CMakeLists.txt 中修改add_subdirectory(lib newdir)指令来指定一个编译输出位置或者在lib/CMakeLists.txt 中添加set(LIBRARY_OUTPUT_PATH newdir)来指定一个新的位置。newdir是相对路径,如下lib的lib里可以直接使用lib替换newdir

add_libraary指令

add_library(<name> [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            [<source>...])

name中你不需要写全libhello.so,只需要填写hello 即可,cmake系统会自动为你生成libhello.X

类型有三种:
SHARED,动态库
STATIC,静态库
MODULE,在使用 dyld 的系统有效,如果不支持dyld,则被当作SHARED对待。
EXCLUDE_FROM_ALL参数的意思是这个库不会被默认构建,除非有其他的组件依赖或者手
工构建。 

动态库和静态库构建

# 生成动态库
add_library(hello SHARED ${DIR_LIB_SRCS})
# 生成静态库
# 这样写会使得静态库没有构建,报错原因是动态库的名称也是hello即target不能重名
# add_library(hello STATIC ${DIR_LIB_SRCS}) 

如果动态库和静态库的名称相同,会导致后一个库无法构建,按照我们的例子因为hello 作为一个target是不能重名的,所以,静态库构建指令无效。

如果把静态库的名称hello 修改为hello_static,则可以顺利的构建,会生成libhello.so和libhello_static.a库文件。

这种结果显示不是我们想要的,我们需要的是名字相同的静态库和动态库,因为 target 名
称是唯一的,所以,我们肯定不能通过 add_library指令来实现了。这时候我们需要用到
另外一个指令:

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 两个库了。

与他对应的指令是:

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.

动态库版本号的设置

 按照规则,动态库是应该包含一个版本号的,我们可以看一下系统的动态库,一般情况是
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 版本。其中,libhello.so.1.2为动态库的文件名(realname),libhello.so.1为动态库的别名(soname), libhello.so为动态库的链接名(linkname)。

将上述指令加入lib/CMakeLists.txt 中,重新构建看看结果。
在build/lib 目录会生成:
libhello.so.1.2
libhello.so.1->libhello.so.1.2
libhello.so ->libhello.so.1

安装共享库和头文件

安装过程和上一节类似,这里不过得解释。

后面测试调用共享库执行程序

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值