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 |举报|字号 订阅 ...
随机推荐
- 解决webpack4.x使用autoprefixer 无效
安装 npm i webpck webpack-cli style-loader postcss-loader -D 配置 webpack.config.js module: { rules: [{ ...
- 在论坛中出现的比较难的sql问题:38(字符拆分 字符串检索问题)
原文:在论坛中出现的比较难的sql问题:38(字符拆分 字符串检索问题) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉得 ...
- 微信小程序通讯录字母排序
微信小程序通讯录 字母排序效果: demo地址:https://github.com/PeachCoder/wechat-contacts
- galera集群
一.环境准备 1.各主机配置静态域名解析: cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhos ...
- zabbix4.2的yum+mariadb方式部署安装
本文依据官方文档操作(英文4.2):https://www.zabbix.com/documentation/4.2/manual/installation/install_from_packages ...
- ext TreePanel树节点操作
1.全部展开 tree.expandAll();2.全部收缩 tree.collapseAll();3.得到父节点 node.parentNode4.判断是否有父节点 node.parentNode= ...
- stm32 触摸屏 XPT2046
引脚功能描述 控制字的控制位命令 控制字节各位描述 单端模式输入配置 差分模式输入配置 时序 前8个时钟用来通过DIN引脚输入控制字节,接着的12个时钟周期将完成真正的模数转换,剩下的3个多时钟周期将 ...
- Android NDK 学习之调用Java函数
本博客主要是在Ubuntu 下开发,且默认你已经安装了Eclipse,Android SDK, Android NDK, CDT插件. 在Eclipse中添加配置NDK,路径如下Eclipse-> ...
- shell 三剑客之 sed pattern 详解
sed 基础介绍 语法格式 sed 处理过程 sed 选项 cat sed.txt '-p' 打印输出 ,默认输出两次,流输出一次,源文件输出一次 sed 'p' sed.txt -n 只显示处理的 ...
- docker 部署oracle
Oracle数据库服务器Docker映像文档 Oracle Database Server 12c R2是行业领先的关系数据库服务器.Oracle数据库服务器Docker映像包含在Oracle Lin ...