Linux学习笔记——例说makefile 增加自定义共享库

0.前言

从学习C语言开始就慢慢开始接触makefile,查阅了很多的makefile的资料但总感觉没有真正掌握makefile,如果自己动手写一个makefile总觉得非常吃力。所以特意借助博客总结makefile的相关知识,通过例子说明makefile的具体用法。

例说makefile分为以下几个部分,更多内容请参考【例说makefile索引博文】

1.只有单个C文件

2.含有多个C文件

3.需要包括头文件路径

4.增加宏定义

5.增加系统共享库

6.增加自定义共享库

7.一个实际的例子

【代码仓库】——makefile-example

代码仓库位于bitbucket,可借助TortoiseHg(GUI工具)克隆代码或者在网页中直接下载zip包。

【本例说明】

本例分为两个过程,先制作一个共享库,然后在使用这个共享库。共享库采用动态链接方式,后缀为.so。

1.gcc复习

【1】gcc指令中使用共享库使用前缀-l,共享库查找目录使用-L。

【2】一般情况下DLIBS中加入共享库,而LDFLAGS中加入共享库查找目录。

2.共享库源文件

和生成共享库有关的文件位于libtest目录中,在makefile最后把共享库复制到同级的lib目录中。具体内容请参考代码仓库并复制zip包。

【libtest.h】

指定接口,给出相应声明

#ifndef __LIBTEST_H

#define __LIBTEST_H

int sub(int a, int b);

int add(int a, int b);

#endif

【test-add.c】

int add(int a, int b)

{

return a+b;

}

【test-sub.c】

int sub(int a, int b)

{

return a-b;

}

3.共享库的makefile

请替换其中的[tab],并以代码仓库中的makefile文件为主。

# 指令编译器和选项

CC = gcc

CFLAGS = -Wall -std=gnu99

# 目标文件

TARGET = libtest.so

# C文件

SRCS = test-add.c test-sub.c

# 目标文件

OBJS = $(SRCS:.c=.o)

# 链接为可执行文件

$(TARGET):$(OBJS)

[tab]$(CC) -shared -o $@ $^

[tab]mv $(TARGET) ../lib

clean:

[tab]rm -rf $(TARGET) $(OBJS)

# 编译规则 $@代表目标文件 $< 代表第一个依赖文件

%.o:%.c

[tab]$(CC) $(CFLAGS) -o $@ -fPIC -c $<

【说明】

【1】目标为libtest.so,请务必以lib开头 .so结尾,在使用该共享库时系统会自动的去除lib和.so,使用时写成-ltest。

【2】多数内容和学习笔记中的多个文件相同。

【3】在链接过程中加入-shared参数,意为共享形式的目标文件。

【4】在编译过程中加入-fPIC参数,意为生成和地址无关的目标文件。

【5】在链接完成之后,通过mv指令把libtest.so移动到同级的lib目录中。

【6】如果有必要,可以把libtest.so复制到/usr/lib目录中,这样使用起来会更加方便。

【验证】

ldd test

linux-vdso.so.1 =>  (0x00007fffde960000)

libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ffe55b18000)

libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffe55750000)

/lib64/ld-linux-x86-64.so.2 (0x00007ffe55e38000)

【编译和执行】

make clean && make

【控制台输出】

rm -rf libtest.so test-add.o test-sub.o

gcc -Wall -std=gnu99 -o test-add.o -fPIC -c test-add.c

gcc -Wall -std=gnu99 -o test-sub.o -fPIC -c test-sub.c

gcc -shared -o libtest.so test-add.o test-sub.o

mv libtest.so ../lib

【1】编译过程中加入了-fPIC选项。

【2】链接过程中加入-shared选项。

【3】共享库为libtest.so。

【4】最后,共享库被移动到上一级的lib目录中。

4.源文件

调用共享库指定的接口,add和sub函数。

#include

#include

int main(void)

{

int a = 3;

int b = 2;

printf("a=%d\n", a);

printf("b=%d\n", b);

printf("a+b=%d\n", add(a, b));

printf("a-b=%d\n", sub(a, b));

return 0;

}

5.makefile

请替换其中的[tab],并以代码仓库中的makefile文件为主。

# 指令编译器和选项

CC = gcc

CFLAGS = -Wall -std=gnu99

# 目标文件

TARGET = test

# C文件

SRCS = test.c

# 头文件查找路径

INC = -I.

# 库文件和库查找路径

DLIBS = -ltest

LDFLAGS = -L./lib

# 指定运行时的库文件路径

RPATH = -Wl,-rpath=./lib

# 目标文件

OBJS = $(SRCS:.c=.o)

# 链接为可执行文件

$(TARGET):$(OBJS)

[tab]$(CC) -o $@ $^ $(LDFLAGS) $(DLIBS) $(RPATH)

clean:

[tab]rm -rf $(TARGET) $(OBJS)

# 连续动作,请清除再编译链接,最后执行

exec:clean $(TARGET)

[tab]@echo 开始执行

[tab]./$(TARGET)

[tab]@echo 执行结束

# 编译规则 $@代表目标文件 $< 代表第一个依赖文件

%.o:%.c

[tab]$(CC) $(CFLAGS) $(INC) -o $@ -c $<

6.具体说明

【1】DLIBS = -ltest 指定共享库,请注意共享库的名称为libtest.so,而-l参数只取test部分,去掉前缀lib和后缀.so。

【2】LDFLAGS = -L./lib 指定共享库路径,请注意上一步中已经把共享库复制到lib目录中。

【3】INC = -I./lib  指定libtest.h目录,也可把libtest.h复制到test.c所在的目录。

【4】$(CC) -o $@ $^ $(LDFLAGS) $(DLIBS) 链接过程指定共享库查找路径,指定共享库名称。

【5】第【1】和第【2】点只在链接过程有效,在执行过程中需要通过-Wl,-rpath=指定共享库路径。

【编译和链接】

make clean && make

【控制台输出】

rm -rf test test.o

gcc -Wall -std=gnu99 -I./lib -o test.o -c test.c

gcc -o test test.o -L./lib -ltest -Wl,-rpath=./lib

【执行】

在执行之前还可以通过ldd test查看libtest是否链接成功。

./test

a=3

b=2

a+b=5

a-b=1

从控制台的输出结果可以看出,共享库运行正常。

7.总结

【1】-l指定共享库名称,-L指定共享库路径。

8.参考资料

【1】gcc中的-Wl,rpath=选项

【2】makefile学习经验(三)----编译生成动态库文件(方式一)

linux添加自己的库,Linux学习笔记——例叙makefile 增加自定义共享库相关推荐

  1. Linux学习笔记——例说makefile 增加宏定义

    从学习C语言开始就慢慢开始接触makefile,查阅了很多的makefile的资料但总感觉没有真正掌握makefile,如果自己动手写一个makefile总觉得非常吃力.所以特意借助博客总结makef ...

  2. Linux学习笔记——例说makefile 综合案例

    0.前言 从学习C语言開始就慢慢開始接触makefile,查阅了非常多的makefile的资料但总感觉没有真正掌握makefile,假设自己动手写一个makefile总认为非常吃力.所以特意借助博客总 ...

  3. Linux与C++11多线程编程(学习笔记)

    多线程编程与资源同步 在Windows下,主线程退出后,子线程也会被关闭; 在Linux下,主线程退出后,系统不会关闭子线程,这样就产生了僵尸进程 3.2.1创建线程 Linux 线程的创建 #inc ...

  4. Linux内存从0到1学习笔记(4,TLB)

    一.TLB简介 Kernel初始化的时候,会在初始化内存中创建页表:而处理器读取指令和数据的时候需要首先通过MMU查表得到物理地址,然后在访问物理地址读取指令或数据.MMU查表过程汇中需要4次访问内存 ...

  5. Lib库使用学习笔记

    Lib库使用学习笔记 转自:http://blog.csdn.net/macky0668/article/details/6044867 技术前沿 2008-03-31 14:21:10 阅读177  ...

  6. 线性代数库 Armadillo 学习笔记

    线性代数库 Armadillo 学习笔记 项目环境 Xcode 项目配置 前置代码 矩阵基本操作 全零矩阵 全一矩阵 对角矩阵 打印一个矩阵 修改获取矩阵元素 获取某行某列 获取对角向量 转置矩阵 逆 ...

  7. STM32F407霸天虎HAL库CubeMX学习笔记——DS18B20

    STM32F407霸天虎HAL库CubeMX学习笔记--DS18B20 一.软件准备 二.硬件准备 三.CubeMX配置 四.Keil printf重写 tim.c DS18B20.h DS18B20 ...

  8. 【Python-pywt】 小波变化库—Pywavelets 学习笔记

    (转载) [Python ]小波变化库--Pywavelets 学习笔记_nanbei2463776506的博客-CSDN博客 https://blog.csdn.net/nanbei24637765 ...

  9. 《C++标准库》学习笔记 — STL —流

    <C++标准库>学习笔记 - STL -流 一.操控器 1.原理 2.自定义操控器 3.控制输入的宽度 二.自定义 I/O 操作符 1.重载输出操作符 2.输入操作符 三.自定义格式化标志 ...

最新文章

  1. 【Swift】变量/常量/类型总结
  2. gatewayproperties 是空_一个空手套白狼的商业模式
  3. java在所选路径中找到分号,classpath
  4. 清空缓存的命令_最实用的6个网络命令,网络故障不求人
  5. css中em与px的介绍及换算方法
  6. Linux中常用文件的含义
  7. python独立图形_在networkx中查找图形对象中的独立图形
  8. Pandas系列(一)数据读取、数据结构Dataframe和Series
  9. 领扣LintCode算法问题答案-983. 棒球游戏
  10. iPhone 5S对战Google Nexus5:有啥区别
  11. javascript设置网页快捷键
  12. STM32时钟系统与时钟启动顺序详解
  13. leet-code Z 字形变换详解
  14. python存储JSON
  15. 印象笔记android,印象笔记(Evernote) Android SDK 更新
  16. 水果姿态估计论文、数据集汇总
  17. elementUI表格表头内容自动生成
  18. 佛祖保佑 永无BUG ; 心外无法 法外无心
  19. 码农应该对自己好一点【挑选水杯全攻略】
  20. 关于4K超高清电视 你必须知道的十件事

热门文章

  1. redis学习笔记-持久化
  2. webstorm设置
  3. JavaScript最全的10种跨域共享的方法
  4. 运维自动化之ansible playbook安装apache
  5. linux修改网卡mac
  6. 有关大型数据中心项目建设的常见问题
  7. PHPCMS V9自定义分页函数
  8. JS创建对象学习笔记
  9. Anaconda 环境下 对Tushare进行测试
  10. 如果从Silverlight 读取本地GB2312格式的xml文件