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 |举报|字号 订阅 ...
随机推荐
- POJ1573(Robot Motion)--简单模拟+简单dfs
题目在这里 题意 : 问你按照图中所给的提示走,多少步能走出来??? 其实只要根据这个提示走下去就行了.模拟每一步就OK,因为下一步的操作和上一步一样,所以简单dfs.如果出现loop状态,只要记忆每 ...
- iOS Touch Id 开发
Touch Id Touch Id是iPhone5S后加入的一项新的功能,也就是大家熟知的指纹识别技术.大家用得最多的可能是手机的解屏操作,不用在和以前一样输入手机的四位数密码进行验证.一方面不用担心 ...
- nginx日志文件的配置
文章来源 运维公会: nginx日志文件的配置 1.日志介绍 nginx有两种日志,一种是访问日志,一种是错误日志. 访问日志中记录的是客户端对服务器的所有请求. 错误日志中记录的是在访问过程中,因为 ...
- Interval 用法总结
语法:INTERVAL 'integer [- integer]' {YEAR | MONTH} [(precision)][TO {YEAR | MONTH}] 该数据类型常用来表示一段时间差, 注 ...
- python高并发的详解
一.什么是高并发 高并发(High Concurrency)是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时并行处理很多请求. 高并发相关常用的一些指标有响应时间( ...
- Python标准库3.4.3-webbrowser-21.1
21.1. webbrowser — Convenient Web-browser controller Source code: Lib/webbrowser.py 翻译:Z.F. The web ...
- Linux系统用终端打开图片
一.现在开发多数使用的系统都是linux系统,但有的时候会遇到一些比较麻烦的小问题,比如:在某个文件夹中存入大量的图片时,想要查看某张图片的时候,当你使用图形化显示的时候,就会很卡,所以在这里我针对于 ...
- JS函数篇【2】
什么是函数 函数的作用,可以写一次代码,然后反复地重用这个代码. <h3 onload="add2(1,2,3);add3(4,5,6)"></h3> &l ...
- 2019-ACM-ICPC-南京区网络赛-E. K Sum-杜教筛+欧拉定理
2019-ACM-ICPC-南京区网络赛-E. K Sum-杜教筛+欧拉定理 [Problem Description] 令\(f_n(k)=\sum_{l_1=1}^n\sum_{l_2=1}^n\ ...
- CH6201 走廊泼水节[最小生成树]
描述 [简化版题意]给定一棵N个节点的树,要求增加若干条边,把这棵树扩充为完全图,并满足图的唯一最小生成树仍然是这棵树.求增加的边的权值总和最小是多少. 我们一共有N个OIER打算参加这个泼水节,同时 ...