关闭

gcc学习笔记

197人阅读 评论(0) 收藏 举报
分类:

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

预处理 头进行展开,宏展开 生成.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
暂时了解有用了在细查参数吧。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:33201次
    • 积分:899
    • 等级:
    • 排名:千里之外
    • 原创:56篇
    • 转载:26篇
    • 译文:0篇
    • 评论:0条