gcc学习笔记

原创 2016年08月29日 00:09:03

由源代码到二进制可执行文件的步骤

预处理 头进行展开,宏展开 生成.i文件
编译 对应语言的编译器 生成。s
汇编 汇编器 生成 .o 偏移地址是从0开始
链接 重新定位地址,链接其他库

gcc 选项及演示

预处理
gcc -E hello.c -o hello.i //输出预处理后的文件
编译
gcc -S hello.i -o hello.s //输出汇编结果
汇编
gcc -c hello.s -o hello.o //输出二进制文件
链接
gcc hello.s -o hello //输出链接后的二进制,没有选项

-Wall 警告
-Idir 加入头文件搜索路径
-Ldir 加入索索库的目录
-llib 链接lib库
-g 在目标文件中加入调试信息,如果没有加盖选择是木能调试的

选项先后顺序可以调换

每次都尽量要加 -Wall选项

演示main调用hello_fn.c中的函数的编译过程

hello_fn.h
hello_fn.c
main.c

gcc -Wall hellow_fn.c main.c -o main
gcc -Wall -c hello_fn.c -o hello

gcc -Wall hello.o main.o -o main
单独编译的,如果更改其中一只更改了,只需要编译其中修改,重新链接一下

静态库和共享库之间的区别

静态库( .a文件),在链接阶段把二进制文件链接到可执行文件中。运行时不再需要静态库

动态库(共享库 .so .sa文件) 程序在运行的时候才会去链接动态库,多个程序共享动态库代码(节省了动态库的指令内存区)。

库的搜索路径

//-L 是在指定路径下搜索该库目录。
//-I 存放头文件的位置

  1. -L -I 从左到右搜
  2. C_INCLUDE_PATH lIBRARY_PATH 环境变量的值对应位置
    配置环境变量
    vi ~/bash_profile
    export LIBRARY_PATH = /home/hzz/code:/home/xiaoming/work
    export CPP_INCLUDE =/home/hzz/code/cppinclude
    export C_INCLUDE=/home/hzz/code/cinclude
    //注意与windows的不同,用: 分割
    3.系统默认路径
    /usr/include
    /usr/local/include
    /usr/lib
    /usr/local/lib
    (注意这里的 usr 为Unix System Resource 的意思)

修改完执行一遍该配置文件。

找共享库
//找共享库的位置修改方式
1.配置环境变量
vi ~/bash_profile
export LD_LIBRARY_PATH =/home/hzz/code/lib

2.配置 /etc/ld/ld.so.conf
然后用ldconfig 命令更新该文件

ldd main 可以看可执行程序包含哪些些库

演示生成静态库,并使用静态库

现有文件如下:
hello_fn.h
hello_fn.c
生成静态库
mian.c

gcc -c hello.c //输出hello.o文件
gcc -c main.c //输出main.o

可将多个.o文件,打包成.a文件
ar rcs libhello.a hello_fn.o //打包成.a 静态库
gcc -Wall main.o libhello.a -o main //链接进main二进制文件

另外一种使用库的方式(这种可能更常用)
gcc -Wall -L . main.o -o main -lhello

演示使用动态库

动态库库名规则libxxx.so

(fPIC 全拼为 position independent code)
gcc -shared -fPIC hello.o -o libhello.so

//使用
gcc -Wall -L . main.o -o main -lhello

动态库静态库混合使用

假设当前目录下有两个同名的hllo.a hello.so 库

gcc -L . main.o -o main -lhello //优先使用动态库
gcc -L . main.o -o main -static -lhello

当对动态库与静态库混合连接的时候,使用-static会导致所有的库都使用静态连接的方式。这时需要作用-Wl的方式:

gcc test.cpp -L. -Wl,-Bstatic -ltestlib -Wl,-Bdynamic -ltestdll
另外还要注意系统的运行库使用动态连接的方式,所以当动态库在静态库前面连接时,必须在命令行最后使用动态连接的命令才能正常连接 如:

gcc test.cpp -L. -Wl,-Bdynamic -ltestdll -Wl,-Bstatic -ltestlib -Wl,-Bdynamic

最后的-Wl,-Bdynamic表示将缺省库链接模式恢复成动态链接。

查看库的导出函数
nm *.so
readelf -a so
暂时了解有用了在细查参数吧。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

【Linux学习笔记】gcc编译单个文件

编译程序的基本知识 GCC编译器对程序的编译如图所示,分为四个阶段:预编译,编译和优化,汇编和链接。源文件:存放可编辑代码的文件,如存放C,C++和汇编语言的文件。 目标文件:经过编译器编译生成...

Linux学习笔记3--GCC动态库和静态库混合使用

今天,一个同事编译静态库,我也趁此机会在温习一下,先google一下,然后在自己实验。   首先,在网上抄个例子,内容如下:  1:建静态库 /*  hellos.h  */ ...

C/C++学习笔记第一天:MAC OS下搭建GCC和Sublime Text环境

本科的时候学了C C++ 这一路搞研究 也不太需要太多的编程,多半是算法仿真,所以编程感觉越来越差,趁这个暑假赶快拾起来。...

GCC-3.4.6源代码学习笔记(171)

5.13.5.2.2.1.1.3.3.            浮点数与形式多样的整形常量不同,在C++的前端中,具有REAL_TYPE类型的常量只能是REAL_CST。 output_constan...

GCC-3.4.6源代码学习笔记(168)

5.13.5.2.2.1.  初始值这里在我们的目标Linux/x86,输出文件将具有格式ELF。ELF是支持重定位及PIC(位置无关代码)的格式。【10】的第三章给出了关于ELF的一个很好的解释。...

GCC-3.4.6源代码学习笔记(149)

5.13.1.1.3.        引用类型的转换如果目标类型是引用类型(参见implicit_conversion的1106行),这是由【3】条文13.3.3.1.4“引用绑定”[over.ic...

GCC-3.4.6源代码学习笔记(169)

5.13.5.2.2.1.1.2.    确定输出节找到或准备好了常量描述符之后,接着在output_constant_def中调用下面的函数,尝试在内存中输出这个常量。 2509static voi...

GCC-3.4.6源代码学习笔记(140)

5.12.5.2.2.2.1.3.10.        完成派生类的RECORD_TYPE – 构建vtable记得在determine_primary_base中,如果我们找到一个主要基类,我们只...

GCC-3.4.6源代码学习笔记(157)

5.13.4.2.              迭代 – 发布tinfo现在所有需要代码发布的tinfo已经被串入unemitted_tinfo_decls中。接着在finish_file的26...

GCC-3.4.6源代码学习笔记(142)

5.12.5.2.2.2.1.3.12.        完成派生类RECORD_TYPE – 生成VTT虚表表(VTT)对于类来说不是必需的,因此下面的build_vtt可能生成VTT,有可...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:gcc学习笔记
举报原因:
原因补充:

(最多只允许输入30个字)