Unix -- 动静库

Unix 系列



一、编译过程

GCC :

/*步骤一:编写 .C文件 */
 vi hello.c   
 
/*步骤二:预编译头文件扩展*/
 gcc -E hello.c -o hello.i  
 
/*步骤三:编译生成汇编代码 */
 gcc -S hello.i -o hello.s 
 
/*步骤四:编译获得目标代码 */
 gcc -c hello.s -o hello.o
 
/*步骤五:生成可执行代码*/
 gcc hello.o -o hello 
文件后缀文件描述
.h头文件
.c预处理的C语言源代码
.s汇编语言
.o目标文件
.a静态库文件
.so共享(动态)库文件
.out可执行文件

编译另外可使用:

  1. gcc -Wall Wall.c // 产生全部警告
  2. gcc -Werror werror.c -o werror // 将所有警告变成error
  3. gcc -x c++ cpp.c -lstdc++ -o cpp // 使用c++编译,-lstdc表示链接C++库

二、预编译

#progma

//此文件依赖于相同路径下的 dep.c ,且需要dep.c的修改时间在此文件之前
#progma GCC dependency "dep.c"   

//只要出现goto,就视为语法毒药,禁忌
#pragma GCC poison  goto    

//按字节对齐,可回头看,常用于结构体
#pragma pack()    

#if

#if (VER <3)
    #error "版本太低"
#elif (VER>3)
    #warning "版本太高"
#endif

三、常见宏

void print(void)
{
	//当前被编译文件
    printf("_BASE_FILE_ : %s\n",_BASE_FILE_); 
    
    //输出宏所在文件
    printf("_FILE_ : %s\n",_FILE_);  
    
    //输出行号
    printf("_LINE_ : %s\n",_LINE_);  
    
    //输出 此函数位置
    printf("_FUNCTION_ : %s\n",_FUNCTION_);  
    
    //输出 此函数层数包含关系
    printf("_INCLUDE_LEVEL_ : %s\n",_INCLUDE_LEVEL_); 
}

四、库文件

1. 静态库

一、说明

概念:将多个目标文件打包成一个文件,链接静态库:将库中被调用的代码复制到调用模块;
在这里插入图片描述

特点
1. 占用较大的空间 ;
2. 若改变库中的.o文件,需要重新链接,否则使用的还是旧的 ;
3. 在运行时无需依赖库,执行效率高;
4. 只是在链接时用到,编译时不使;

二、构建

构建静态库: .c -> .o -> .a

//此命令将x.o y.o z.o 打包 libxxx.a静态库

ar -r libxxx.a x.o y.o z.o     

使用方法:

gcc -lxxx   // "l"后面跟库名   

gcc -L<库路径>   //使用库路径

三、制作静态链接文件:

写 cal.c + show.c 文件

//-----------------------------------制作静态库
//calc.h
#ifndef _CALC_H
#define _CALC_H
int add(int,int);
int sub(int,int);
#endif

//calc.c
#include "calc.h"
int add(int a,int b){
    return a+b;
}
int sub(int a,int b){
    return a-b;
}
———————————————————————————————————————————————————————————
//vi show.h
#ifndef _SHOW_H
#define _SHOW_H
void print(int,char,int,int);
#endif

//vi show.c
#include <stdio.h>
#include "show.h"
void print(int a,char op,int b,int c){
    printf("%d%c%d=%d\n",a,op,b,c);
}

由两个O文件生成 .a静态库文件

ar -r libmath.a calc.o show.o

// vi math.h //只需要包括这个头文件,就可以包含所有声明
#ifndef _MATH_H
#define _MATH_H
#include "calc.h"
#include "show.h"
#endif
//  vi math.c
#include "math.h"
int main(void)
{
    int a=30, b=20;
    show(a,'+',b,add(a,b));
    show(a,'-',b,sub(a,b));
    return 0;
}

方法一:
gcc main.c -o main -lmath -L. //表明静态库的名称为math,路径为当前文件夹

方法二:
export LIBRARY_PATH =. //链接使用的环境变量,找库相对地址
gcc main.c -o main -lmath //在已定义的环境变量找库


2.动态库

一、说明

  1. 动态库调用时 不拷贝,真正的内存空间只需要一份即可。(shared object,so,DLL);
  2. 只要保证接口保持不变,无需重新链接编译;
  3. 代码运行时主要依赖库,执行效率低;
    在这里插入图片描述

二、构建

库内部的函数调用也用相对地址表示:

//fpic-位置无关码:程序中运行时,库映射的的各进程地址不同,调用时库绝对地址也不同
gcc -c -fpic xxx.c -> xxx.o   

//【类似于分配指针】-但相对地址一定一样
gcc -shared -o libxxx.so x.o y.o z.o

动态库使用方法:

方法一:
gcc ... -lxxx -L<库路径>   //表明动态库的名称为math,路径为当前文件夹
方法二:
export LIBRARY_PATH =<库路径>
gcc ... -lmath     //运行时所调用的动态库必须位于LD_LIBRARY_PATH环境变量所表示的路径中

三、制作动态库文件

制作库文件 xxxx.so

gcc -c -fpic calc.c   //生成calc.o
gcc -c -fpic show.c   //生成show.o
gcc -shared -o libmath.so calc.o show.o //生成动态库

分别定义链接地址和运行时的库地址,两个都需要声明

export LIBRARY_PATH =.    //链接使用的环境变量,找库相对地址
export LD_LIBRARY_PATH =.    //运行时拿着相对地址找函数

使用动态库编译:

gcc main.c -o main -lmath   //使用环境变量方法

总结

本章节主要回顾静态库、动态库的制作方法与使用;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值