linux下编译动态和静态链接库

简介:

静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。

动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。

查看当前工程目录的内容

[root@root config-file]# tree 

.

|-- Makefile

|-- Makefile.a

|-- Makefile.so

|-- configfile.c

|-- configfile.o

|-- include

|   |-- configfile.h

|   `-- our_syslog.h

|-- main.c

`-- main.o

1 directory, 9 files

[root@root config-file]# cat include/*.h

++++++++++++++++++++++++++++++++++++++++++++

int read_config_file(char *filename, char *keyword, char *value);

#define dmsg(log,format,args...) do{if(log) \

    fprintf(stderr, "WARING: " format , ##args);    \

    else    \

    fprintf(stderr, "INFO: " format , ##args);  \

    }while(0)

++++++++++++++++++++++++++++++++++++++++++++

Makefile.so生成动态链接库的makefile文件

[root@root config-file]# cat  Makefile.so 

CFLAGS += -I/root/config-file/include -fPIC

DFLAGS += $(CFLAGS) -shared


all : libfile.so


libfile.so: configfile.o

$(CC) $^ -o $@ $(DFLAGS)

%.o:%.c

$(CC) $(CFLAGS) -c $< -o $@


.PHONY : clean

clean :

-rm -f libfile.so *.o

Makefile.a生成静态链接库的makefile文件

[root@root config-file]# cat  Makefile.a

CFLAGS += -I/root/config-file/include


all : libfile.a


libfile.a: configfile.o

    $(AR) rcs $@ $^

%.o:%.c

    $(CC) $(CFLAGS) -c $< -o $@


.PHONY : clean

clean :

    -rm -f libfile.a *.o

主程序

[root@root config-file]# cat  main.c 

#include <stdio.h>

#include <stdlib.h>

#include "configfile.h"

#include "our_syslog.h"


int  main()

{

    char value[100]={0};

    read_config_file("/root/syslog.conf", "openwrt", value);

    dmsg(0,"%s\n", value);

    dmsg(1,"%s\n", value);

    return 0;

}

主程序的Makefile

[root@root config-file]# cat  Makefile

OBJS=configfile.o main.o


CFLAGS=-I/root/config-file/include

CFLIBS=-L/root/config-file -lfile -g -O -Wall


all:test


test: $(OBJS)

    $(CC) $^ -o $@ $(CFLAGS) $(CFLIBS)

%.o:%.c

    $(CC) -c $< -o $@ $(CFLAGS)


.PHONY : clean

clean :

    -rm -f test *.o

生产静态库

[root@root config-file]# make -f Makefile.a

gcc -I/root/config-file/include -c configfile.c -o configfile.o

ar rcs libfile.a configfile.o

[root@root config-file]# ar -t libfile.a #查看静态库中的文件

configfile.o

连接静态库,编译主程序

[root@root config-file]# make

gcc -c configfile.c -o configfile.o -I/root/config-file/include

gcc -c main.c -o main.o -I/root/config-file/include

gcc configfile.o main.o -o test -I/root/config-file/include -L/root/config-file -lfile -g -O -Wall

[root@root config-file]# ./test 

INFO: hello-openwrt

WARING: hello-openwrt

[root@root config-file]# rm libfile.a 

rm:是否删除 一般文件 “libfile.a”? y

生产动态库

[root@root config-file]# make -f Makefile.so 

gcc -I/root/config-file/include -fPIC -c configfile.c -o configfile.o

gcc configfile.o -o libfile.so -I/root/config-file/include -fPIC -shared

[root@root config-file]# ls

configfile.c  configfile.o  include  libfile.so  main.c  Makefile  Makefile.a  Makefile.so

连接动态库,编译主程序

[root@root config-file]# make

gcc -c configfile.c -o configfile.o -I/root/config-file/include

gcc -c main.c -o main.o -I/root/config-file/include

gcc configfile.o main.o -o test -I/root/config-file/include -L/root/config-file -lfile -g -O -Wall

[root@root config-file]# ./test 

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

这就是动态库和静态库的区别了

[root@root config-file]# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root/config-file

也可以放到/usr/lib下(64位系统/usr/lib64)

[root@root config-file]# ./test 

INFO: hello-openwrt

WARING: hello-openwrt

使用ldd命令查看可执行文件依赖于哪些库

[root@root config-file]# ldd test 

linux-gate.so.1 =>  (0x00782000)

libfile.so (0x007ae000)

libc.so.6 => /lib/libc.so.6 (0x007f4000)

/lib/ld-linux.so.2 (0x007d1000)



本文转自 Linux_woniu 51CTO博客,原文链接:http://blog.51cto.com/linuxcgi/1965301

相关文章
|
Linux 编译器 开发工具
【Linux快速入门(三)】Linux与ROS学习之编译基础(Cmake编译)
【Linux快速入门(三)】Linux与ROS学习之编译基础(Cmake编译)
843 2
|
存储 编译器 Linux
动态链接的魔法:Linux下动态链接库机制探讨
本文将深入探讨Linux系统中的动态链接库机制,这其中包括但不限于全局符号介入、延迟绑定以及地址无关代码等内容。
2337 141
|
10月前
|
Linux 编译器 vr&ar
Linux的动态库与静态库
静态库在编译时直接嵌入到最终的可执行文件中。
212 0
|
Ubuntu Linux Go
golang编译成Linux可运行文件
本文介绍了如何在 Linux 上编译和运行 Golang 程序,涵盖了本地编译和交叉编译的步骤。通过这些步骤,您可以轻松地将 Golang 程序编译成适合 Linux 平台的可执行文件,并在目标服务器上运行。掌握这些技巧,可以提高开发和部署 Golang 应用的效率。
2795 14
|
Linux 编译器 C语言
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
439 2
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
782 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
Linux
Linux - 如何编译源码安装软件
源码编译安装通常包括三个步骤:1) `./configure` 检测平台特征和依赖项,生成 Makefile;2) `make` 编译源码,生成可执行文件;3) `make install` 将可执行文件安装到指定目录并配置环境变量。
489 0
|
Linux 开发工具
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
449 0
|
7月前
|
Linux 应用服务中间件 Shell
二、Linux文本处理与文件操作核心命令
熟悉了Linux的基本“行走”后,就该拿起真正的“工具”干活了。用grep这个“放大镜”在文件里搜索内容,用find这个“探测器”在系统中寻找文件,再用tar把东西打包带走。最关键的是要学会使用管道符|,它像一条流水线,能把这些命令串联起来,让简单工具组合出强大的功能,比如 ps -ef | grep 'nginx' 就能快速找出nginx进程。
818 1
二、Linux文本处理与文件操作核心命令
|
7月前
|
Linux
linux命令—stat
`stat` 是 Linux 系统中用于查看文件或文件系统详细状态信息的命令。相比 `ls -l`,它提供更全面的信息,包括文件大小、权限、所有者、时间戳(最后访问、修改、状态变更时间)、inode 号、设备信息等。其常用选项包括 `-f` 查看文件系统状态、`-t` 以简洁格式输出、`-L` 跟踪符号链接,以及 `-c` 或 `--format` 自定义输出格式。通过这些选项,用户可以灵活获取所需信息,适用于系统调试、权限检查、磁盘管理等场景。
473 137
下一篇
开通oss服务