gcc/g++ 链接库的编译与链接
GCC编译步骤
gcc -E t1.c -o t1.i 预处理
gcc -S t1.i -o t1.s 转成汇编语言
gcc -c t1.s -o t1.o 转成机器码
gcc t1.o -o t1.exe 链接
直接使用gcc t1.c将自动编译链接生成t1.out
或gcc t1.c -o t1.exe规定生成可执行文件的文件名
举例:
#include <stdio.h>
int main()
{
printf("hello world!");
return 0;
}
1.1预处理
预处理后生成1.i文件,打开如下:相当于把stdio.h文件包含进1.c文件了
//.....
# 1 "/usr/include/sys/cdefs.h" 1 3 4
# 43 "/usr/include/sys/cdefs.h" 3 4
# 1 "/usr/include/machine/_default_types.h" 1 3 4
# 41 "/usr/include/machine/_default_types.h" 3 4
# 41 "/usr/include/machine/_default_types.h" 3 4
typedef signed char __int8_t;
//......
# 741 "/usr/include/stdio.h" 3 4
static __inline int
_getchar_unlocked(void)
{
struct _reent *_ptr;
_ptr = (__getreent());
return (__sgetc_r(_ptr, ((_ptr)->_stdin)));
}
static __inline int
_putchar_unlocked(int _c)
{
struct _reent *_ptr;
_ptr = (__getreent());
return (__sputc_r(_ptr, _c, ((_ptr)->_stdout)));
}
# 797 "/usr/include/stdio.h" 3 4
# 2 "1.c" 2
# 3 "1.c"
int main()
{
printf("hello world!");
return 0;
}
1.2转汇编
转汇编 后生成1.s文件,打开如下:
.file "1.c"
.text
.def __main; .scl 2; .type 32; .endef
.section .rdata,"dr"
.LC0:
.ascii "hello world!\0"
.text
.globl main
.def main; .scl 2; .type 32; .endef
.seh_proc main
main:
pushq %rbp
.seh_pushreg %rbp
movq %rsp, %rbp
.seh_setframe %rbp, 0
subq $32, %rsp
.seh_stackalloc 32
.seh_endprologue
call __main
leaq .LC0(%rip), %rcx
call printf
movl $0, %eax
addq $32, %rsp
popq %rbp
ret
.seh_endproc
.ident "GCC: (GNU) 7.3.0"
.def printf; .scl 2; .type 32; .endef
1.3转为机器码
转机器码(二进制)后生成1.o文件,打开如下:
1.4连接成可执行文件(我在win7上演示的)
生成exe可执行文件
详情点击
gcc/g++的编译参数,这里只介绍 -L 、-l、-include、-I、-shared、-fPIC
-L :表示要链接的库所在的目录。-L. 表示要链接的库在当前目录, -L/usr/lib 表示要连接的库在/usr/lib下。目录在/usr/lib时,系统会自动搜索这个目录,可以不用指明。
-l (L的小写):表示需要链接库的名称,注意不是库文件名称,比如库文件为 libtest.so,那么库名称为test
-include :包含头文件,这个很少用,因为一般情况下在源码中,都有指定头文件。
-I (i 的大写):指定头文件的所在的目录,可以使用相对路径。
-shared :指定生成动态链接库
-fPIC: 表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时事通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码共享的目的。
生成链接库
第1步,生成目标文件:g++ -c xxx.cpp
第2步,创建静态链接库: ar cqs libxxxx.a xx1.o xx2.o xx3.o (参数选项请看【5】)
第3步,程序中使用静态链接库
第4步,创建动态链接库 g++ -fPIC -shared -o libxxx.so xx1.cpp xx2.cpp xx3.cpp
第5步,动态链接库使用
库的链接,上面简单演示了一遍库的生成过程,但是还有很多细节没有讲清楚。以下问题需要注意:
1. 链接过程中可能出现多种链接方式,需要使用一些参数来指定,下面只是一个演示,在测试时,自己填写具体的名称
[plain] view plain copy
- g++ testmain.o -o testmain -WI,-Bstatic -lstaticlib -WI,-Bdynamic -ldynamiclib
2. 链接过程中同一个库(名称相同)的静态和动态两种链接库,在链接过程中,系统优先选择动态链接库
3. 动态链接库路径,系统默认在/usr/lib 和/usr/local/lib两个库目录搜索,自己定义的库需要格外指定路径(设定变量LD_LIABRARY_PATH)或者将其拷贝到这两个目录下,在上面的例子的测试过程,已经有说明。当然也可以将当前路径添加到/etc/ld.so.conf文件中或者/etc/ld.so.conf.d目录下的一个文件中。
4. 查看动态链接库。有时候可能需要查看一个库中到底有哪些函数,nm命令可以打印出库中的涉及到的所有符号。库既可以是静态的也可以是动态的。nm列出的符号有很多,常见的有三种:
一种是在库中被调用,但并没有在库中定义(表明需要其他库支持),用U表示;
一种是在库中定义的函数,用T表示,这是最常见的;
另一种所谓的“弱态”符号,它们虽然在库中定义,但可能被其他库中的同名符号覆盖,用W表示。
使用ldd命令可以查看程序的库依赖:
gcc/g++ 链接库的编译与链接的更多相关文章
- gcc/g++实战之动态链接库与静态链接库编写
函数库一般分为静态库和动态库两种. 静态库: 是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了.其后缀名一般为”.a”. 动态库: 与之相反, ...
- GCC 预处理,汇编,编译,链接,连接静态库,动态库
gcc Record gcc -E file1.c > output gcc -E file1.c -o file1.i gcc -S file1.i -o file1.s gcc -S fil ...
- 静态库动态库的编译、链接, binutils工具集, 代码段\数据段\bss段解释
#1. 如何使用静态库 制作静态库 (1)gcc *.c -c -I../include得到o文件 (2) ar rcs libMyTest.a *.o 将所有.o文件打包为静态库,r将文件插入静态库 ...
- g++ 动态库的编译及使用
#ifndef __HELLO_H_ #define __HELLO_H_ void print(); #endif #include "hello.h" #include < ...
- gcc/g++以c++11编译
方法一: //在程序头加上预定义编译器命令 #pragma GCC diagnostic error "-std=c++11" //通过#pragma 指示 GCC编译器处理错误的 ...
- linux下C/C++编译时系统搜索 include 和 链接库 文件路径的指定
C/C++程序在linux下被编译和连接时,GCC/G++会查找系统默认的include和link的路径,以及自己在编译命令中指定的路径.自己指定的路径就不说了,这里说明一下系统自动搜索的路径. ...
- GCC 高版本7.4 编译链接 boost 报错 boost::thread::XXX’未定义的引用 解决方法
背景:开发中的项目之前一直用GCC4.8,boost库1.48版本的开发环境.现在因业务需求,需要更换GCC7.4,boost库1.70. 问题:可以正常编译BOOST的链接库文件,但是链接时候报错. ...
- C/C++ 静态链接库(.a) 与 动态链接库(.so)
平时我们写程序都必须 include 很多头文件,因为可以避免重复造轮子,软件大厦可不是单靠一个人就能完成的.但是你是否知道引用的那些头文件中的函数是怎么被执行的呢?这就要牵扯到链接库了! 库有两种, ...
- [转]Linux下用gcc/g++生成静态库和动态库(Z)
Linux下用gcc/g++生成静态库和动态库(Z) 2012-07-24 16:45:10| 分类: linux | 标签:链接库 linux g++ gcc |举报|字号 订阅 ...
随机推荐
- L2范数归一化概念和优势
1 归一化处理 归一化是一种数理统计中常用的数据预处理手段,在机器学习中归一化通常将数据向量每个维度的数据映射到(0,1)或(-1,1)之间的区间或者将数据向量的某个范数映射为1,归一化 ...
- Java8新特性 - 新时间和日期 API
本地时间和时间戳 主要方法: now:静态方法,根据当前时间创建对象 of:静态方法,根据指定日期/时间创建对象 plusDays,plusWeeks,plusMonths,plusYears:向当前 ...
- hdu 2616 暴力使用 dfs求最短路径(剪枝有点依稀)
Kill the monster Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- 【转载】Sqlserver中使用Round函数对计算结果四舍五入
在实际应用的计算中,很多时候我们需要对最后计算结果四舍五入,其实在Sqlserver中也有对应的四舍五入函数,就是Round函数,Round函数的格式为Round(column_name,decima ...
- 【转载】C#使用FirstOrDefault方法快速查找List集合中符合条件的第一个实体
在C#的List集合的操作中,有时候我们需要根据相关条件快速从List集合中获取到第一个符合条件的实体对象,例如有个全校班级的List集合,我们需要根据班级代码快速从List集合中查找出班级信息.可以 ...
- Topics in CS(difference between compile and interpret)
编译 Compile:把整个程序源代码翻译成另外一种代码,然后等待被执行,发生在运行之前,产物是「另一份代码」. 解释 Interpret:把程序源代码一行一行的读懂然后执行,发生在运行时,产物是「运 ...
- SVM-支持向量机总结
一.SVM简介 (一)Support Vector Machine 支持向量机(SVM:Support Vector Machine)是机器学习中常见的一种分类算法. 线性分类器,也可以叫做感知机,其 ...
- Nginx 安装 和 特性介绍
一:nginx 环境搭建 四项确认 确认系统网络可通行 确认yum可用 确认关闭iptables规则 确认停用selinux 查看iptables规则 iptables -L 关闭iptables规则 ...
- springboot 打包发布(war包)
版本关系: 软件名称 版本号 软件名称 版本号 spring boot 2.x jdk 1.8 tomcat 9.x springboot中的pom.xml文件 打包:右键点击项目,选择如下图: 填写 ...
- MySql 8.0服务端安装后,用navicat12连接时报2059错误_解决
先看连接错误 连接失败:2059 - Authentication plugin 'caching_sha2_password' cannot be loaded: .... 解决方法: 进入MySQ ...