首页 > 其他 > 详细

gcc 和 库

时间:2019-11-14 23:54:24      阅读:148      评论:0      收藏:0      [点我收藏+]

一、gcc编译器编译的四个流程
简:  
  预处理 、编译 、汇编 、链接
详:
  c和c++ 编译器是集成的,编译一般分为4个步骤:
  预处理(preprocessing)     
    gcc -E  XX.c -o XX.i        --->宏替换,展开头文件
  编译(compilation)      
    gcc -S XX.i -o XX.s      --->检查语法,生成汇编文件
  汇编 (assembly)       
    gcc -c  XX.s -o XX.o        --->生成目标文件(二进制文件)
  链接(linking)        
    gcc XX.o -o  XXX       --->链接库,检查环境变量,生成可执行文件
  执行
    ./XXX    
支持后缀:
    .c c原始程序
    .C/.cc/.cxx c++原始程序
    .m Objective-C原始程序
    .i 已 经过预处理的c原始程序
    .ii 已 经过预处理的c++原始程序
    .s/.S 汇编语言原始程序
    .h 预处理文件(头文件)
    .o 目标文件
    .a/.so 编译后的库文件(动态库,静态库)
 
常见错误:
    1.头文件错误   预处理阶段(Can not find include file head.h)
                            -I 头文件路径
    2.C语法错误    编译阶段 (syntex error)
    3.未定义符号   编译阶段 (Undefined symbol)
    4.库链接错误   链接阶段 (undefined reference ‘sqrt‘)
                            ld:-lm:No such file or directory
                            多线程的时候:
                            -lpthread
                            -lsqlite3
                            -L
    5.段错误       运行阶段 Segmentation fault(core dumped)
 
 
二、静态库和动态库区别
 
区别:
 a.命名上: 静态库文件名的命名方式是“libxxx.a”,库名前加”lib”,后缀用”.a”,“xxx”为静态库名;动态库的命名方式与静态库类似,前缀相同,为“lib”,后缀变为“.so”。所以为“libmytime.so”
 b.链接上: 静态库的代码是在编译过程中被载入程序中;动态库在编译的时候并没有被编译进目标代码,而是当程序执行到相关函数时才调用该函数库里的对应函数
 c.更新上: 如果所使用的静态库发生更新,程序必须重新编译;动态库的改变并不影响程序,动态函数库升级比较方便
 d.当同一个程序分别使用静态库,动态库两种方式生成两个可执行文件时,静态链接生成的文件所占用的内存要远远大于动态链接所生成的文件
 e.内存上: 静态库每一次编译都需要载入静态库代码,内存开销大;系统只需载入一次动态库,不同的程序可以得到内存中相同的动态库的副本?,内存开销小
 f.静态库和程序链接有关和程序运行无关;动态库和程序链接无关和程序运行有关
 g.动态库效率比静态库较低,动态库有自己的目录,调用库切换目录,可执行代码移植方面,需要移植库。但优点大于缺点。
 
扩:
 “ldd 可执行文件”命令可以查看动态库。而“printf函数在libc库中”
 Linux下绝大多数的库是动态库,以软连接的形式,链接到不同的版本号,方便库升级,应用程序不需要更改库的信息。
 Linux常见存放库目录 /usr/lib   /usr/local/lib  /lib
 
静态库创建和使用:
 [1].gcc -c math.c                  
  --->生成了math.o
 [2].ar crs libmymath.a math.o      
  --->打包静态库 mymath
 [3].gcc -o test test.c [-static] -L. -lmymath  
  --->编译时指定用的库
 [4].  ./test                          
  --->运行
注:
 若动态库、静态库都有,且路径、名字相同,优先链接动态库。
 此时若要指定为静态库,需要加-static
 
动态库创建和使用:
 [1].gcc -c -fPIC math.c -Wall    
  --->生成了math.o fPIC地址无关代码。位置独立。不加会出错。
 [2].gcc -shared -o libmymath.so.1 math.o 
  --->打包动态库mymath
 [3].ln -s libmymath.so.1 libmymath.so
  --->“ln –s 源文件 目标文件” 用libcommon.so给程序用
 [4].gcc -o test test.c -L. -lmymath    
  --->编译时指定用的库
 执行之前:
 1.把动态库添加到系统的库文件目录中
   --->系统用,不建议
 2.export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:我的动态库路径
 3.临时环境变量,在新窗口不能用了,可以添加到~/.vimrc或 ~/.bashrc   
   --->普通用户下推荐
 4.添加 /etc/ld.so.conf.d/自定义名称.conf文件,执行ldconfig刷新        
   --->移植时推荐
 [5].  ./test                      
  --->运行  
 [6].ldd ./test  
  -->查看库
 
资料:
 库
   https://blog.csdn.net/eastonwoo/article/details/8241693 
   https://blog.csdn.net/zqixiao_09/article/details/50464434
 ln -s:
   https://blog.csdn.net/xiaminli/article/details/73381562
 Linux 环境配置文件
   https://zhidao.baidu.com/question/431422600553069324.html
   https://blog.51cto.com/13451715/2299854

gcc 和 库

原文:https://www.cnblogs.com/LiaoLuLian/p/11863137.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!