Linux 环境开发--gcc 编译以及动态连接

来源:互联网 发布:2016淘宝女装店铺名字 编辑:程序博客网 时间:2024/06/09 16:38

    • 简介
    • 一些基础概念
    • 常用编译选项
    • 静态库和共享库
    • 实例
    • 总结


简介

GNU编译器套装(英语:GNU Compiler Collection,缩写为GCC),一套编程语言编译器,以GPL及LGPL许可证所发布的自由软件,也是GNU项目的关键部分,也是GNU工具链的主要组成部份之一。GCC(特别是其中的C语言编译器)也常被认为是跨平台编译器的事实标准。1985年由理查德·马修·斯托曼开始发展,现在由自由软件基金会负责维护工作。

原名为GNU C语言编译器(GNU C Compiler),因为它原本只能处理C语言。GCC很快地扩展,变得可处理C++。之后也变得可处理Fortran、Pascal、Objective-C、Java、Ada,以及Go与其他语言。

许多操作系统,包括许多类Unix系统,如Linux及BSD家族都采用GCC作为标准编译器。苹果电脑Mac OS X 操作系统也采用这个编译器。

原本用C开发,后来因为LLVM、Clang的崛起,令GCC更快将开发语言转换为C++。许多C的爱好者在对C++一知半解的情况下主观认定C++的性能一定会输给C,但是Taylor给出了不同的意见,并表明C++不但性能不输给C,而且能设计出更好,更容易维护的程序(GCC’s move to C++)。
ps: 摘自 wiki http://zh.wikipedia.org/zh-cn/GCC

一些基础概念

一些文件:

后缀名 含义 后缀名 含义 .o c 代码文件 .s/.S 汇编语言原始程序 .c/.cc/.cxx C++ 代码文件 .h 预处理文件(头文件) .m Objective-C 代码文件 .o 可重定向文件 .i 经过预处理的 C 代码文件 .a/.so 编译后的库文件 .ii 经过预处理的 C++ 代码文件

gcc的编译流程分为了四个步骤:

预处理(Pre-Processing—->编译(Compiling)—–>汇编(Assembling)—–>链接(Linking)

常用编译选项

gcc有超过100个的可用选项,主要包括总体选项、告警和出错选项、优化选项和体系结构相关选项。这里列一些常用选项

选项 含义 -c 生成目标文件“.o” -S 生成汇编代码 -E 只进行预编译 -g 在可执行程序中包含标准调试信息 -o 输出文件 -v 打印出编译过程 -I 添加头文件搜索目录 -L 添加库搜索目录 -static 生成链接静态库 -llibrary 连接名为library的库文件(注意没有空格) -fPIC 地址无关代码 -shared 生成共享库

关于 -fPIC 选项是使共享库能使代码可以在多个进程间共享,需要一些汇编知识和代码运行堆栈机制知识,其实我还没怎么搞懂,给个博文地址研究研究吧
http://www.cnblogs.com/catch/p/3857964.html

静态库和共享库*

  • 静态库: 在linux中一般以 libxxx.a命名.静态库中包含了所有代码和数据,在编译时会把代码和数据拷贝合并到可执行文件当中.因此,静态库是编译时需要的,不是执行时需要的.
  • 共享库:在linux中一般以libxxx.M.N.so命名,MN为主副版本号,so文件当中有自己的代码和函数,当可执行文件运行并调用动态库中的文件时需要借助连接程序 ld 把控制全交给动态库中执行.

Linux系统中动态链接库的配置文件一般在/etc/ld.so.conf文件内,它里面存放的内容是可以被Linux共享的动态联库所在的目录的名字. /etc/ld.so.cache 是 /lib/ /usr/lib/ 目录下 /etc/ld.so.conf 中的记录 /etc/ld.so.conf.d/ 目录下所有文件的记录的缓存.动态加载时系ld 加载器会从这个缓存中找共享库的位值(这里要注意和windows不同,linux不会从可执行文件所在的目录搜索共享库,如果是临时使用可以使用命令ldconfig `pwd`)

实例

下面举个实例说明:
cat.c

#include <stdio.h>void cat_say(){    printf("I am cat\n");}

mouse.c

#include <stdio.h>void mouse_say(){    printf("I am cat\n");}

animal.h

#ifndef __ANIMAL_H__void cat_say();void mouse_say();#endif

main.c

#include <stdlib.h>#include "animal.h"int main(){    cat_say();    exit(0);}
[aquarius@localhost libtest]$ ll-rw-rw-r--: 1 aquarius aquarius 65 Mar  1 15:16 animal.h-rw-rw-r--: 1 aquarius aquarius 63 Mar  1 17:05 cat.c-rw-rw-r--: 1 aquarius aquarius 78 Mar  1 15:20 main.c-rw-rw-r--: 1 aquarius aquarius 67 Mar  1 15:21 mouse.c
  • 直接生成可执行文件
[aquarius@localhost libtest]$ gcc -o main main.c cat.c [aquarius@localhost libtest]$ ./main I am cat
  • 使用静态库
[aquarius@localhost libtest]$ gcc -c cat.c mouse.c[aquarius@localhost libtest]$ ll *.o-rw-rw-r--. 1 aquarius aquarius 1488 Mar  8 22:09 cat.o-rw-rw-r--. 1 aquarius aquarius 1488 Mar  8 22:09 mouse.o[aquarius@localhost libtest]$ ar -crv libanimal.a cat.o mouse.oa - cat.oa - mouse.o[aquarius@localhost libtest]$ gcc -o main main.c -L. -lanimal[aquarius@localhost libtest]$ ./mainI am cat

-L. 选项: 库搜索目录列表添加当前目录(注意后面有个点,没有空格)
-lanimal 选项: 连接名位libanimal.a后者libanimal.M.N.so的库文件,M为主版本号N为副版本号(注意 l 后面没有空格)

  • 使用共享库
[aquarius@localhost libtest]$ gcc -fPIC -shared -o libanimal.so cat.c mouse.c[aquarius@localhost libtest]$ gcc -o main main.c -L. -lanimal.1.0[aquarius@localhost libtest]$ ./main ./main: error while loading shared libraries: libanimal.1.0.so: cannot open shared object file: No such file or directory

出错了,为什么呢, 用 ldd 命令看一下依赖关系

[aquarius@localhost libtest]$ ldd ./main        linux-vdso.so.1 =>  (0x00007fff921f8000)        libanimal.1.0.so => not found        libc.so.6 => /lib64/libc.so.6 (0x00007fd5d0fd7000)        /lib64/ld-linux-x86-64.so.2 (0x00007fd5d13bc000)[aquarius@localhost libtest]$ sudo ldconfig `pwd`  

找不到动态库,为什么呢,上面说了,没有配置 ld 加载缓存

[aquarius@localhost libtest]$ ldd ./main        linux-vdso.so.1 =>  (0x00007fff477fb000)        libanimal.1.0.so => /home/aquarius/libtest/libanimal.1.0.so (0x00007f45cb476000)        libc.so.6 => /lib64/libc.so.6 (0x00007f45cb0b8000)        /lib64/ld-linux-x86-64.so.2 (0x00007f45cb69f000)[aquarius@localhost libtest]$ ./main I am cat

总结

好了,这就是linux下用gcc编译程序的过程和一些总结,但是在实际生成环境中真的是这样编译代码的吗?
当然不是的,这个过程只是为了学习一下gcc的编译过程以及静态库和共享库的一些知识,在实际生产环境中是使用 make 工具进行管理工程和编译的以及安装卸载的,make 工具需要 Makefile 文件,那么这个 Makefile 文件是手动编写的吗?
当然可以手动编写,但生产环境一般是用 automake 工具进行自动生成 Makefile 文件的(就是你编译安装软件是用的 ./configure)这个工具的使用篇幅也不小,有空在写吧…
小弟正在学习当中,有错误请大神指出,赐教^_^—-Aquarius_Coder

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 居住证到期了忘记续签了怎么办 贵州交警app忘记密码怎么办 科一第一次没过怎么办 社保转移时学历信息不符怎么办 天津摇号密码忘了怎么办 摇号账号密码忘了怎么办 京牌车去外地没有保险标怎么办 车子被扣12分怎么办 不在北京工作了社保怎么办 5年身份证到期了怎么办 c1驾照剩1分怎么办 c1驾校扣12分怎么办 我驾照扣了12分怎么办 小米手环绑定不了怎么办 小区总有小年青骑摩托车扰民怎么办 摩托车行驶证副本丢了怎么办 摩托车驾照副本丢了怎么办 公司行驶证掉了怎么办 身份证外迁了过户的话怎么办 驾照体检报告丢了怎么办 常州医保卡丢了怎么办 驾驶证违章罚单丢了怎么办 身份证被别人办了信用卡怎么办 被别人办了信用卡怎么办 考驾照体检忘带身份证怎么办 c证扣12分怎么办新规 c照12分不够扣怎么办 扣了18分怎么办一次性 c照累计扣12分怎么办 车辆超速扣12分怎么办 一次超速扣12分怎么办 分扣了罚款未交怎么办 c照一次扣12分怎么办 人在外地身份证到期了怎么办 手机进水了屏幕不亮怎么办 北京一证通过期怎么办 小米6音量键进水怎么办 考驾照怕过不了怎么办 学车对车没感觉怎么办 居住证到期2个月怎么办 生育险差一个月怎么办