Linux下使用cmake生成动态链接库并使用

栏目: C · 发布时间: 5年前

内容简介:使用cmake生成库主要要注意三个文件夹(1)源文件文件夹(2)中间文件夹(编译生成的.o等文件的文件夹)

使用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

#include"hello.h"

void hello()

{

printf("hello");

}

和hello.h头文件。

#ifndef HELLO_H

#define HELLO_H

#include

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所在的绝对路径。

(2)打开Cmake图形化 工具 并配置参数最后生成Makefile

注意(我的顶层CMakeLists.txt在/home/linuxidc/workspace/hello路径下)

控制台输入cmake-gui

如图

Linux下使用cmake生成动态链接库并使用

a)在where is source code选项选择/home/linuxidc/workspace/hello

b)在where to build the binaries选项选择/home/linuxidc/workspace/hello/build

c)在CMAKE_INSTALL_PREFIX选择可执行文件安装的路径/home/linuxidc/workspace/hello/install

d)选择编译类型CMAKE_BUILD_TYPE 设置为Debug,release

e )点击configure配置,弹出编译器类型选择界面,选择编译器类型

f )点击generate就能在where to build the binaries目录下看到Makefile文件了

在/home/linuxidc/workspace/hello/build文件夹下输入make在当前文件夹下生成libhello.so

输入make install

Linux下使用cmake生成动态链接库并使用

在/home/linuxidc/workspace/hello/install即CMAKE_INSTALL_PREFIX路径的看到文件

libhello.so

库的编译和安装已经实现了,为了方便使用,还需要将头文件安装到安装目录下。

##1.3将头文件安装到/include/目录下

在顶层文件夹下的CMakeLists.txt加入以下语句安装头文件到

/home/linuxidc/workspace/hello/install/include文件夹

INSTALL(FILES ${PROJECT_SOURCE_DIR}/libhello/hello.h

DESTINATION include)

Linux下使用cmake生成动态链接库并使用

然后在cmake gui中点击configure配置,点击generate

然后在build文件夹make

make install

如图

Linux下使用cmake生成动态链接库并使用

#2.使用生成的动态链接库

##2.1 方法1.直接用gcc指定头文件路径和动态链接库路径

步骤如下

###2.1.1在目录/home/linuxidc/workspace/下新建工程usehellolib

如图

Linux下使用cmake生成动态链接库并使用

###2.1.2编译主函数usehellolib.c 如下

#include

int main()

{

hello();

return 0;

}

###2.1.3使用gcc命令链接并执行生成的可执行文件

在/home/linuxidc/workspace/usehellolib 目录下输入命令

linuxidc@linuxidc:~/workspace/usehellolib$

gcc usehellolib.c -I/home/linuxidc/workspace/hello/install/include -L/home/linuxidc/workspace/hello/install/lib -lhello -o usehellolib

Linux下使用cmake生成动态链接库并使用

语法分析:

gcc 源文件 -I头文件目录 -L动态链接库目录 动态链接库文件名(去掉lib在前面加l) -o 生成的可执行文件名字

发现可以链接成功

但是输入./usehellolib

会出现这个错误

linuxidc@linuxidc:~/workspace/usehellolib$ ./usehellolib

./usehellolib: error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory

Linux下使用cmake生成动态链接库并使用

说明找不到库,因为采用的是动态链接库,所谓动态链接是在运行时链接,编译链接的时候是直接告诉了GCC库的位置,因此会成功,而运行是如果不告诉操作系统库在哪个位置,当然找不到这个库,程序也就不能运行。因此要告诉操作系统库在哪个地方,linux使用LD_LIBRARY_PATH告诉系统库在哪个地方。(LD_LIBRARY_PATH是Linux环境变量名,该环境变量主要用于指定查找共享库(动态链接库)时除了默认路径之外的其他路径)。

设置环境变量可以有临时,也可以永久设置。

(1)临时设置解决方案:

输入命令

linuxidc@linuxidc:~/workspace/usehellolib$

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/linuxidc/workspace/hello/install/lib

再次运行 ./uselibhello

输出hello

(2)永久设置解决方案

永久设置解决方案一:

su用户下

编辑.bashrc文件

vi /root/.bashrc

在最后加入

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/linuxidc/workspace/hello/install/lib

然后

source /root/.bashrc

就能够运行了。

永久设置解决方案二:

本文使用的是Ubuntu 18.04.2系统

编辑该文件

vi /etc/ld.so.conf.d/libc.conf

在文件的末尾加入要调用的动态链接库的路径

本文加入

/home/linuxidc/workspace/hello/install/lib

然后在控制台执行

ldconfig

运行程序就能够执行了。

##2.2 方法2.Cmake链接动态链接库

那么在大型工程中怎么链接外部共享库呢?本节介绍编辑CMakeLists.txt来使用生成的动态链接库。

在工程目录/home/linuxidc/workspace/usehellolib下新建CMakeLists.txt如下:

PROJECT(usehellolib)

ADD_EXECUTABLE(usehellolib usehellolib.c)

INCLUDE_DIRECTORIES(/home/linuxidc/workspace/hello/install/include)

TARGET_LINK_LIBRARIES(usehellolib /home/linuxidc/workspace/hello/install/lib/libhello.so)

解析:

INCLUDE_DIRECTORIES()告诉编译器头文件在哪个位置。

TARGET_LINK_LIBRARIES()告诉链接器动态链接库在哪个位置

输入

cmake.

make

会出现链接错误

/usr/bin/ld: cannot find -lhello

/usr/bin/ld: cannot find -l*解决方法

ld链接器告诉你找不到库函数,那么你就要把库函数放到ld链接器能够找到的地方。因此解决方法如下

方法1

将要调用的库函数复制到linux默认搜索库函数的目录下

即/usr/lib 目录。

sudo cp /home/linuxidc/workspace/hello/install/lib/libhello.so /usr/lib

方法2

使用软链接(个人理解类似于创建快捷方式)

sudo ln -s /home/linuxidc/workspace/hello/install/lib/libhello.so /usr/lib/libhello.so

ln -s 它的功能是为某一个文件在另外一个位置建立一个同步的链接,这个命令最常用的参数是-s,具体用法是:ln -s 源文件 目标文件

方法3

类似于上文的动态链接库的路径设置方法

cd /etc/ld.so.conf.d/

cp libc.conf hello.conf

vi hello.conf

编辑hello.conf的内容如下

/home/linuxidc/workspace/hello/install/lib

告诉链接器动态链接库的路径。

执行

ldconfig

输入

ldconfig -p |grep libhello

输出libhello动态链接库信息

设置好后

注意要重新删除所有Cmake生成的文件

再输入

cmake.

make

就能够正常使用了。

补充

方法4

如果加上link_directories这一句就不会出现 cannot find -l* 的问题,最终的CMakeLists.txt如下

project(usehellolib)

cmake_minimum_required (VERSION 2.6)

INCLUDE_DIRECTORIES(/home/linuxidc/workspace/hello/install/include)

link_directories(/home/linuxidc/workspace/hello/install/lib)

add_executable(${PROJECT_NAME} usehellolib.c)

target_link_libraries(${PROJECT_NAME} hello.so)

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

本文永久更新链接地址: https://www.linuxidc.com/Linux/2019-01/156197.htm


以上所述就是小编给大家介绍的《Linux下使用cmake生成动态链接库并使用》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

第四次革命

第四次革命

[意]卢西亚诺•弗洛里迪(Luciano Floridi)著 / 王文革 / 浙江人民出版社 / 2016-5 / 64.90元

 随着线上线下大融合以及人工智能的极大发展,人类已经进入超历史时代。在这一时代中,人类终于迎来了继哥白尼革命、达尔文革命、神经科学革命之后自我认知的第四次革命——图灵革命,整个世界正化身为一个信息圈,每个人都生活在云端,人类已不再是信息圈毋庸置疑的主宰。毫无疑问,图灵革命引爆了人工智能重塑整个人类社会的序曲!  那么在人工智能时代,人类如何保证自己最钟爱的财富——“隐私”不被窃取?如何应......一起来看看 《第四次革命》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

URL 编码/解码
URL 编码/解码

URL 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具