GCC创建库文件

GCC将源程序转换为可执行程序过程

例如源文件为test.cpp
  • 预处理。转换源代码中宏定义和预处理指令语句,删除注释与空行,生成test.i文件。
  • 编译。错误检查,无错误则翻译成汇编代码,生成test.s文件。
  • 汇编。将汇编代码汇编成机器指令,生成test.o文件。
  • 链接。将文件中引用符号与其他文件中该符号定义链接起来,生成test可执行文件。
    gcc编译流程

GCC创建静态库文件示例

创建库头文件

vi calc.h

头文件声明的函数

extern float aver(float&,float&);//关键字extern不能少,因为定义和声明在不同文件。
extern float sum(float&,float&);

创建aver.cpp文件

vi aver.cpp

实现函数功能

#include "calc.h"
using namespace std;
float aver(float &num1,float &num2){
	return (num1+num2)/2;
}

创建sum.cpp文件

vi sum.cpp

实现sum.cpp功能

#include "calc.h"
using namespace std;
float sum(float &num1,float &num2){
	return num1+num2;
}

静态库文件由一系列目标文件组成的单一文件。使用-c选项将文件编译为目标文件而不进行汇编和链接

g++ -c -o aver.o aver.cpp
g++ -c -o sum.o sum.cpp

使用ar命令生成静态库文件

ar rc libmycalc.a aver.o sum.o //ar生成静态库命令。r将目标文件加入静态库,有同名文件则删除,c表示创建新的静态库文件

静态库文件名称必须已lib开头,后缀为.a。

测试一下

创建一个static_lib.cpp文件,文件内容如下。

#include <stdio.h>
#include <iostream>
#include "calc.h"
using namespace std;
int main(){
	float num1= 3.4 ;
	float num2 = 5.4;
	cout<< aver(num1,num2)<<endl;
	cout<<sum(num1,num2)<<endl;
	return 0;
}

编译一下

g++ static_lib.cpp -Bstatic -L. -lmycalc -o static_lib

其中-Bstatic 表示强制gcc将静态库中函数定义代码复制到应用程序。-L参数表示指定库文件路径,因为在同一文件目录所以为“.",-lmycalc表示寻找名为libmycalc.a的库文件,-o指定输出可执行程序名称。
输出结果

[tr@localhost calc]$ ./static_lib
4.4
8.8

查看一下相关文件

-rw-rw-r--. 1 toor toor   101   aver.cpp
-rw-rw-r--. 1 toor toor  1472   aver.o
-rw-rw-r--. 1 toor toor    67   calc.h
-rw-rw-r--. 1 toor toor  2952   libmycalc.a
-rwxrwxr-x. 1 toor toor 22728   static_lib
-rw-rw-r--. 1 toor toor   201   static_lib.cpp
-rw-rw-r--. 1 toor toor    96   sum.cpp
-rw-rw-r--. 1 toor toor  1256   sum.o

GCC创建动态库

同样以上述代码为例,首先生成目标文件不进行汇编和链接,方式和创建静态库文件差不多,只是需要添加一个参数 -fPIC 表示生成位置无关代码。

g++ -c -fPIC aver.cpp -o aver.o
g++ -c -fPIC sum.cpp -o sum.o

用上述生成的aver.o 与sum.o 目标文件生成动态库

g++ -shared -o libmycalc.so aver.o sum.o//-shared参数表示告诉编译器生成动态
库,共享库名称与静态库名称命名规则相似,后缀以.so结尾
g++ static_lib.cpp -L. -lmycalc -o static_lib //生成可执行目标文件,语法与静态库相似

在执行可执行文件static_lib前首先要设置环境变量LD_LIBRARY_PATH。

LD_LIBRARY_PATH=.  //将库文件路径设置为当前路径
export LD_LIBRARY_PATH //使设置的环境变量立即生效

编译器查找动态库的文件路径顺序:
1.环境变量LD_LIBRARY_PATH指定的路径
2.缓存文件/etc/ld.so.cache指定的路径
3.默认的共享库目录,先是/lib,然后是/usr/lib
上述设置的环境变量名称是特定的,如果环境变量名称错误会导致可执行程序找不到动态库文件。删除不想要的环境变量名称可以使用 unset delete_pathname 删除要不需要的环境变量。使用env命令查看系统中设置的环境变量。

ok, 测试一下
[tr@localhost calc]$ ./static_lib
4.4
8.8

查看一下生成的文件

-rw-rw-r--. 1 tr tr   101   aver.cpp
-rw-rw-r--. 1 tr tr  1472   aver.o
-rw-rw-r--. 1 tr tr    67   calc.h
-rwxrwxr-x. 1 tr tr 16328   libmycalc.so
-rwxrwxr-x. 1 tr tr 22680   static_lib
-rw-rw-r--. 1 tr tr   201   static_lib.cpp
-rw-rw-r--. 1 tr tr    96   sum.cpp
-rw-rw-r--. 1 tr tr  1256   sum.o

发布了3 篇原创文章 · 获赞 0 · 访问量 83

猜你喜欢

转载自blog.csdn.net/m0_46327721/article/details/105017547