Linux下Makefile,静态库,动态库的实现

首先,创建一个文件夹,并在改文件夹下存进如下文件:

cal.h:头文件

#ifndef cal_h
#define cal_h

int add(int,int);
int sub(int,int);
int mul(int,int);
int div(int,int);
int mod(int,int);
int sqtr(int,int);
#endif

add.c:加法模块

#include"cal.h"
int add(int var1, int var2){
    return var1 + var2;

}

div.c:除法模块

#include"cal.h"
int div(int var1,int var2){

    return var1 / var2;
}

mod.c:取余模块

#include"cal.h"

int mul(int var1,int var2){
    return var1 * var2;
}

sqrt:勾股定理模块

#include"cal.h"

int sqrt(int var1,int var2){
    return sqrt(var1^2+var2^2);
}

mul.c加法模块

#include"cal.h"

int mul(int var1,int var2){
    return var1 * var2;
}

sub.c:减法模块

#include"cal.h"

int sub(int var1,int var2){
    return var1 - var2;
}

testcal.c

#include <stdio.h>
#include "cal.h"

int main(int argc, char **argv)
{
    int var1;
    int var2;
    printf("please input var1:");
    scanf("%d",&var1);
    printf("please input var2:");
    scanf("%d",&var2);

    printf("%d add %d is %d\n",var1, var2, add(var1,var2));
    printf("%d sub %d is %d\n",var1, var2, sub(var1,var2));
    printf("%d mul %d is %d\n",var1, var2, mul(var1,var2));
    printf("%d div %d is %d\n",var1, var2, div(var1,var2));
    printf("%d mod %d is %d\n",var1, var2, mod(var1,var2));
    printf("%d sqrt %d is %d\n",var1,var2,sqrt(var1,var2));
    return 0;

}

一:没有库的实现,首先编写makeflie文件:

OBJ=testcal.o add.o sub.o mul.o div.o mod.o sqtr.o
testcal:$(OBJ) cal.h
    gcc $(OBJ) -o testcal
testcal.o:testcal.c
add.o:add.c
sub.o:sub.c
mul.o:mul.c
div.o:div.c
mod.o:mod.c
sqrt.o:sqrt.c

.PHONY:cleanA clean
cleanA:
    rm testcal $(OBJ)
clean:
    rm $(OBJ)

首先解释一下makeflie文件最重要的第二和第三行代码:testcal表示要生成的目标文件,冒号右边的表示要生成这个文件所要依赖的文件,$(OBJ)表示讲OBJ里的变量取出来。

然后输入make运行,得到以下显示:

[[email protected]QNJ4U2U codeStudy]$ make
cc    -c -o testcal.o testcal.c
cc    -c -o add.o add.c
cc    -c -o sub.o sub.c
cc    -c -o mul.o mul.c
cc    -c -o div.o div.c
cc    -c -o mod.o mod.c
gcc testcal.o add.o sub.o mul.o div.o mod.o -o testcal

同时输入ls -l可以查看文件大小

total 44
-rw-rw-rw- 1 ouyangxi ouyangxi  247 Mar 22 14:37 Makefile
-rw-rw-rw- 1 ouyangxi ouyangxi   59 Mar 15 22:14 add.c
-rw-rw-rw- 1 ouyangxi ouyangxi 1232 Mar 22 14:38 add.o
-rw-rw-rw- 1 ouyangxi ouyangxi  198 Mar 15 22:42 cal.h
-rw-rw-rw- 1 ouyangxi ouyangxi   52 Mar 15 22:06 div.c
-rw-rw-rw- 1 ouyangxi ouyangxi 1232 Mar 22 14:38 div.o
drwxrwxrwx 1 ouyangxi ouyangxi  512 Mar 21 09:42 libou.a
drwxrwxrwx 1 ouyangxi ouyangxi  512 Mar 21 09:46 libou.so
drwxrwxrwx 1 ouyangxi ouyangxi  512 Mar 21 09:37 liboyx.a
drwxrwxrwx 1 ouyangxi ouyangxi  512 Mar 20 19:40 liboyx.so
-rw-rw-rw- 1 ouyangxi ouyangxi   52 Mar 15 22:07 mod.c
-rw-rw-rw- 1 ouyangxi ouyangxi 1240 Mar 22 14:38 mod.o
-rw-rw-rw- 1 ouyangxi ouyangxi   52 Mar 15 22:32 mul.c
-rw-rw-rw- 1 ouyangxi ouyangxi 1232 Mar 22 14:38 mul.o
-rw-rw-rw- 1 ouyangxi ouyangxi   63 Mar 15 22:04 sub.c
-rw-rw-rw- 1 ouyangxi ouyangxi 1232 Mar 22 14:38 sub.o
-rwxrwxrwx 1 ouyangxi ouyangxi 8696 Mar 22 14:38 testcal
-rw-rw-rw- 1 ouyangxi ouyangxi  568 Mar 18 23:34 testcal.c
-rw-rw-rw- 1 ouyangxi ouyangxi 2832 Mar 22 14:38 testcal.o

可以看testcal可执行文件非常小,只有8K大

最后执行可执行文件,使用命令:./testcal

[[email protected] codeStudy]$ ./testcal
please input var1:6
please input var2:8
begin run:6 add 8 is 14
6 sub 8 is -2
6 mul 8 is 48
6 div 8 is 0
6 mod 8 is 6

二、使用静态库文件,生成静态库。库文件一般以lib为前缀,紧接着是库的名称oyx,扩展名为.a,例如我们这里要创建库名liboyx.a的库,使用命令ar,具体如下:

ar rcs libcal.a add.o sub.o mul.o div.o mod.o

使用静态库,创建库文件的接口文件头文件,本文中是cal.h文件,使用库文件的文件testCal.c包含头文件cal.h文件即可,使用如下命令编译:

gcc -o testCal testCal.c -static -L. -lcal

其中,testcal为最终的可执行文件,testcal.c表示要生成testcal所要依靠的文件,这里还要注意以下-L后面是有.的,千万不要漏掉。

[[email protected] liboyx.a]$ ./testcal
please input var1:1
please input var2:4
begin run:1 add 4 is 5
1 sub 4 is -3
1 mul 4 is 4
1 div 4 is 0
1 mod 4 is 1

可见,testcal可以编译运行,在来看看这时的testcal的大小:

[[email protected] liboyx.a]$ ls -l
total 969
-rw-rw-rw- 1 ouyangxi ouyangxi   1232 Mar 20 19:28 add.o
-rw-rw-rw- 1 ouyangxi ouyangxi    198 Mar 20 19:28 cal.h
-rw-rw-rw- 1 ouyangxi ouyangxi   1232 Mar 20 19:28 div.o
-rw-rw-rw- 1 ouyangxi ouyangxi   6580 Mar 20 19:30 liboyx.a
-rw-rw-rw- 1 ouyangxi ouyangxi   1240 Mar 20 19:28 mod.o
-rw-rw-rw- 1 ouyangxi ouyangxi   1232 Mar 20 19:28 mul.o
-rw-rw-rw- 1 ouyangxi ouyangxi   1232 Mar 20 19:28 sub.o
-rwxrwxrwx 1 ouyangxi ouyangxi 958552 Mar 20 19:31 testcal
-rw-rw-rw- 1 ouyangxi ouyangxi    568 Mar 20 19:28 testcal.c

虽然静态库使用起来比较方便,其具有良好的远程地址链接性,但是其缺点就是占有的地址空间很大。

三:动态库的实现

先创建一个文件夹方便我们操作,再将所有的.o,testcal.c和cal.h放进这个文件夹

首先运行如下命令:

gcc -shared -fPIC -o liboyx.so add.o sub.o mul.o div.o mod.o

库文件一般以lib为前缀,紧接着是库的名称oyx,扩展名为.so,这样就生成了一个名称为liboyx.so的动态库

然后输入以下命令:

gcc -o testcal testcal.c -L. -loyx

即可生成一个名为testcal的可执行文件,但当我输入./testcal后却发现无法编译,这时再输入以下指令:

export LD_LIBRARY_PATH=$(pwd)
或者
sudo ldconfig /home/munication/WORKM/libDemo/

就可以解决问题了,这是再输入./testcal:

[[email protected] liboyx.so]$ export  LD_LIBRARY_PATH=$(pwd)
[[email protected]-QNJ4U2U liboyx.so]$ ./testcal
please input var1:1
please input var2:5
begin run:1 add 5 is 6
1 sub 5 is -4
1 mul 5 is 5
1 div 5 is 0
1 mod 5 is 1

可见,可以成功运行,再看看文件大小

[[email protected] liboyx.so]$ ls -l
total 45
-rw-rw-rw- 1 ouyangxi ouyangxi 1232 Mar 20 19:36 add.o
-rw-rw-rw- 1 ouyangxi ouyangxi  198 Mar 20 19:40 cal.h
-rw-rw-rw- 1 ouyangxi ouyangxi 1232 Mar 20 19:36 div.o
-rwxrwxrwx 1 ouyangxi ouyangxi 7664 Mar 20 19:38 liboyx.so
-rw-rw-rw- 1 ouyangxi ouyangxi 1240 Mar 20 19:36 mod.o
-rw-rw-rw- 1 ouyangxi ouyangxi 1232 Mar 20 19:36 mul.o
-rw-rw-rw- 1 ouyangxi ouyangxi 1232 Mar 20 19:36 sub.o
-rwxrwxrwx 1 ouyangxi ouyangxi 8544 Mar 20 19:40 testcal
-rw-rw-rw- 1 ouyangxi ouyangxi  568 Mar 20 19:39 testcal.c
-rw-rw-rw- 1 ouyangxi ouyangxi 2832 Mar 20 19:36 testcal.o

可以看见,testcal文件只有8k左右,相比于静态库,动态库生成的可执行文件要小的多,但是动态库其缺点就是要保持远程地址与.o变量地址一致。

附加:在建立动态库的时候要使用gcc -fPIC-c add.c sub.c mul.c div.c mod.c sqrt.c命令确保所以的.o文件都链接到内存上。

原文地址:https://www.cnblogs.com/ouyangmail/p/12546209.html

时间: 2024-08-29 11:58:23

Linux下Makefile,静态库,动态库的实现的相关文章

Linux下gcc编译控制动态库导出函数小结

Linux下gcc编译控制动态库导出函数小结 来源 https://www.cnblogs.com/lidabo/p/5703890.html 根据说明文档“How To Write Shared Libraries"介绍, 有四种方法: 1. 在方法声明定义时,加修饰:__attribute__((visibility("hidden"))) 就是说将不公开的函数都加上这个属性,没加的就是可见的 2. gcc 在链接时设置 -fvisibility=hidden,则不加 v

indy openssl lazarus 编程linux下出现不能装载动态库的问题原因!

版本不对的原因. 具体在10.5.9下修改此参数即可解决问题. LoadFunction() has an ACritical parameter. It is set to True by default, but can be set to False for individual functions (and currently is False for TLS 1.1+ and DTLS functions). You can patch IdSSLOpenSSLHeaders.pas

在linux下制作libxxx.so 动态库

在linux下面动态库的使用是非常常用的,也是非常实用的. 步骤一: 创建一个.h头文件 ,头文件中声明动态库中的函数 #ifndef _TEST_H_ #define _TEST_H_ #ifdef __cplusplus /*c c++ 混合编程*/ extern "C" { #endif <span style="font-family: Arial, Helvetica, sans-serif;">/*c c++ 混合编程*/</span&

linux下,一些关于动态库的问题:

程序运行是加载动态库的几种方法: 第一种,通过ldconfig命令    ldconfig是一个动态链接库管理命令,为了让动态链接库为系统所共享,还需运行动态链接库的管理命令它,ldconfig命令通常在系统启动时运行,而当一个用户安装我新的动态库时,就需要手工运行这个命令.ldconfig命令的用途, 主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下, 搜索出可共享的动态链接库(格式如lib*.so*), 进而创建出动态装入程序(

linux下C语言编程动态库so的编写及调用

//test_so.h #include <stdio.h> void test_a(); void test_b(); //test_a.c #include "so_test.h" void test_a() { printf("this is in test_a...\n"); } //test_b.c #include "so_test.h" void test_b() { printf("this is in te

linux下的静态库创建与查看,及如何查看某个可执行依赖于哪些动态库

linux下的静态库创建与查看,及如何查看某个可执行依赖于哪些动态库 创建静态库:ar -rcs test.a *.o查看静态库:ar -tv test.a解压静态库:ar -x test.a 查看程序依赖的动态库:readelf -a xxx|grep library如:可以看到,下面的交叉程序hello执行依赖于如下两个动态库.[email protected]:~/test$ arm-none-linux-gnueabi-readelf -a hello|grep "library&quo

linux下的静态库和动态库

一.linux下的静态库 静态库中的被调用的函数的代码会在编译时一起被复制到可执行文件中去的!!可执行文件在运行不需要静态库的存在! 二.linux下动态库的构建和使用 1.动态库的构建 gcc  -fPIC  -shared    -o  lib库名.so   源文件列表 例: gcc   -fPIC  -shared  -o  libmylib.so  max.c  min.c 2.动态库使用 gcc    -o  最终的可执行文件  源文件列表  -L 动态库的目录  -l库名 例子: 已

linux下的静态连接库和动态链接库

对linux的静态连接库和动态链接库分不清楚,在看了一篇博文后,现在想做个自己的总结,以加深印象: 1.库的基本概念: 库是可执行代码的二进制形式,其可以被调入操作系统调入内存进行执行. 在window和linux系统,都存在各自的库,但是两种系统的库并不能兼容,因为它们的编译器,连接器,汇编器都是不相同的. 在windows下,静态连接库的后缀是.lib;动态链接库的后缀是.dll 在linux系统下,静态链接库的后缀是.a;动态链接库的后缀是.so 2.静态连接库和动态链接库的命名: 静态连

Linux 静态库&amp;动态库调用

1.什么是库在windows平台和linux平台下都大量存在着库.本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行.由于windows和linux的本质不同,因此二者库的二进制是不兼容的.本文仅限于介绍linux下的库.2.库的种类linux下的库有两种:静态库和共享库(动态库).二者的不同点在于代码被载入的时刻不同.静态库的代码在编译过程中已经被载入可执行程序,因此体积较大.共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小.3.库存在