LinuxDown

LinuxDown.com
Linux系统下载网——精选每一篇高品质的技术干货
  1. 首页
  2. 开源快讯
  3. 正文

基于指定编译器的确定编译参数过程流程图:编译

2023年7月18日 113点热度

序言

源码要运行,必须先转成二补码的机器码。这是编译器的任务。

例如,下边这段源码(假设文件名称作test.c)。

#includeintmain(void){fputs("Hello,world!n",stdout);return0;}

要先用编译器处理一下,能够运行。

$gcctest.c$./a.outHello,world!

对于复杂的项目,编译过程还必须分成三步。

$./configure$make$makeinstall

编译过程流程图:

3B9A0A70-879D-A2A6-D9BC-AE0362F4198D.png

一.编译的具体过程

1.配置(configure)

编译器在开始工作之前,须要晓得当前的系统环境,例如标准库在那里、软件的安装位置在那里、需要安装什么组件等等。这是由于不同计算机的系统环境不一样,通过指定编译参数,编译器就可以灵活适应环境,编译出各类环境都能运行的机器码。这个确定编译参数的步骤,就称作"配置"(configure)。

这种配置信息保存在一个配置文件之中,约定俗成是一个称作configure的脚本文件。一般它是由autoconf工具生成的。编译器通过运行这个脚本,得知编译参数。

configure脚本早已尽量考虑到不同系统的差别,但是对各类编译参数给出了默认值。假如用户的系统环境比较非常,或则有一些特定的需求,就须要自动向configure脚本提供编译参数。

$./configure--prefix=/www--with-mysql

里面代码是php源码的一种编译配置,用户指定安装后的文件保存在www目录,但是编译时加入mysql模块的支持。

2.确定标准库和头文件的位置

源码肯定会用到标准库函数(standardlibrary)和头文件(header)。它们可以储存在系统的任意目录中,编译器实际上没办法手动测量它们的位置,只有通过配置文件能够晓得。

编译的第二步,就是从配置文件中晓得标准库和头文件的位置。通常来说,配置文件会给出一个清单,列举几个具体的目录。等到编译时红帽子linux下载,编译器就按次序到这几个目录中,找寻目标。

3.确定依赖关系

对于小型项目来说,源码文件之间常常存在依赖关系,编译器须要确定编译的先后次序。假设A文件依赖于B文件,编译器应当保证做到下边两点。

(1)只有在B文件编译完成后,才开始编译A文件。(2)当B文件发生变化时,A文件会被重新编译。

编译次序保存在一个称作makefile的文件中,上面列举那个文件先编译,那个文件后编译。而makefile文件由configure脚本运行生成,这就是为何编译时configure必须首先运行的诱因。

在确定依赖关系的同时,编译器也确定了,编译时会用到什么头文件。

4.头文件的预编译(precompilation)

不同的源码文件,可能引用同一个头文件(例如stdio.h)。编译的时侯,头文件也必须一起编译。为了节约时间,编译器会在编译源码之前,先编译头文件。这保证了头文件只需编译一次,毋须每次用到的时侯,都重新编译了。

不过,并不是头文件的所有内容,就会被预编译。拿来申明宏的#define命令,就不会被预编译。

5.预处理(Preprocessing)

预编译完成后,编译器就开始替换掉源码中bash的头文件和宏。以本文开头的那段源码为例,它包含头文件stdio.h,替换后的样子如下。

externintfputs(constchar*,FILE*);externFILE*stdout;intmain(void){fputs("Hello,world!n",stdout);return0;}

为了易于阅读,里面代码只截取了头文件中与源码相关的那部份,即fputs和FILE的申明,省略了stdio.h的其他部份(由于它们特别长)。另外,里面代码的头文件没有经过预编译,而实际上,插入源码的是预编译后的结果。编译器在这一步都会移除注释。

这一步称为"预处理"(Preprocessing),由于完成以后,就要开始真正的处理了。

6.编译(Compilation)

预处理过后,编译器就开始生成机器码。对于个别编译器来说,还存在一个中间步骤,会先把源码转为汇编码(assembly),之后再把汇编码转为机器码。

下边是本文开头的那段源码转成的汇编码。

.file"test.c".section.rodata.LC0:.string"Hello,world!n".text.globlmain.typemain,@functionmain:.LFB0:.cfi_startprocpushq%rbp.cfi_def_cfa_offset16.cfi_offset6,-16movq%rsp,%rbp.cfi_def_cfa_register6movqstdout(%rip),%raxmovq%rax,%rcxmovl$14,%edxmovl$1,%esimovl$.LC0,%edicallfwritemovl$0,%eaxpopq%rbp.cfi_def_cfa7,8ret.cfi_endproc.LFE0:.sizemain,.-main.ident"GCC:(Debian4.9.1-19)4.9.1".section.note.GNU-stack,"",@progbits

这些转码后的文件称为对象文件(objectfile)。

注:make(gcc),其调用gcc执行编译的过程依赖于配置文件makefile

7.联接(Linking)

对象文件还不能运行linux源码结构,必须进一步转成��执行文件。假如你仔细看上一步的转码结果,会发觉其中引用了stdout函数和fwrite函数。也就是说,程序要正常运行,不仅里面的代码以外,还必须有stdout和fwrite这两个函数的代码,它们是由C语言的标准库提供的。

编译器的下一步工作,就是把外部函数的代码(一般是后缀名为.lib和.a的文件),添加到可执行文件中。这就称作联接(linking)。这些通过拷贝,将外部函数库添加到可执行文件的形式,称作静态联接(staticlinking),后文会提及还有动态联接(dynamiclinking)。

make命令的作用,就是从第四步头文件预编译开始,仍然到做完这一步。

8.安装(Installation)

上一步的联接是在显存中进行的,即编译器在显存中生成了可执行文件。下一步,必须将可执行文件保存到用户事先指定的安装目录。

表面上,这一步很简单,就是将可执行文件(连带相关的数据文件)拷贝过去就行了。并且实际上,这一步还必须完成创建目录、保存文件、设置权限等步骤。这整个的保存过程就称为"安装"(Installation)。

9.操作系统联接

可执行文件安装后,必须以某种形式通知操作系统,让其晓得可以使用这个程序了。例如,我们安装了一个文本阅读程序,常常希望双击txt文件,该程序都会手动运行。

这就要求在操作系统中,登记这个程序的元数据:文件名、文件描述、关联后缀名等等。Linux系统中,这种信息一般保存在/usr/share/applications目录下的.desktop文件中。另外,在Windows操作系统中,还须要在Start启动菜单中,构建一个快捷方法。

这种事情就称作"操作系统联接"。makeinstall命令,就拿来完成"安装"和"操作系统联接"这两步。

10.生成安装包

讲到这儿,源码编译的整个过程就基本完成了。并且只有极少一部份用户,乐意耐着脾气,从头到尾做一遍这个过程。事实上,假如你只有源码可以交给用户,她们会认定你是一个不友好的家伙。大部份用户要的是一个二补码的可执行程序,立即才能运行。这就要求开发者,将上一步生成的可执行文件,弄成可以分发的安装包。

所以,编译器还必须有生成安装包的功能。一般是将可执行文件(连带相关的数据文件),以某种目录结构,保存成压缩文件包,交给用户。

11.动态联接(Dynamiclinking)

正常情况下,到这一步,程序早已可以运行了。至于运行期间(runtime)发生的事情,与编译器一概无关。并且,开发者可以在编译阶段选择可执行文件联接外部函数库的形式,究竟是静态联接(编译时联接),还是动态联接(运行时联接)。所以,最后还要提一下,哪些称作动态联接。

后面早已说过,静态联接就是把外部函数库linux源码结构,拷贝到可执行文件中。这样做的用处是,适用范围比较广,不用担忧用户机器缺乏某个库文件;缺点是安装包会比较大,但是多个应用程序之间,难以共享库文件。动态联接的做法恰好相反,外部函数库不步入安装包,只在运行时动态引用。好处是安装包会比较小,多个应用程序可以共享库文件;缺点是用户必须事先安装好库文件,并且版本和安装位置都必须符合要求,否则就不能正常运行。

现实中,大部份软件采用动态联接,共享库文件。这些动态共享的库文件,Linux平台是后缀名为.so的文件,Windows平台是.dll文件,Mac平台是.dylib文件。

二、Linux编译安装的具体实现

1.编译安装源程序的前提:

1).提供开发环境:开发工具和开发库

2).编译安装须要的包组:

DevelopmentTools、ServerPlatformDevelopment、DesktopPlatformDevelopment、DebugTools

2.configure脚本常用的选项:

--help获取./configure脚本帮助--prefix=:指定安装路径;多数程序都有默认安装路径;--sysconfidr=:指定配置文件安装路径;--with-PACKAGE[=ARG]:在自由软件社区里,有使用已有软件包和库的优秀传统.当用'configure'来配置一个源码树时,可以提供其他早已安装的软件包的信息--without-PACKAGE:有时侯你可能不想让你的软件包与系统已有的软件包交互。比如,你可能不想让你的新编译器使用GNUld--enable-FEATURE:一些软件包可能提供了一些默认被严禁的特点,可以使用'--enable-FEATURE'来起用它--disable-EEATURE:关掉指定的默认特点

3.编译安装源程序技巧:

1)、展开源代码,找INSTALL、README;不存在这种文件时,找项目官方文档;

2)、根据安装说明执行安装操作;

3.程序安装于专用目录时,安装后的配置:

1)、导出二补码程序所在路径至PATH环境中

#exportPATH=/usr/local/nginx/sbin:$PATH实现永久有效的办法:/etc/profile.d/*.sh

2)、导出库文件给OS

OS查找库文件方式:按照/etc/ld.so.conf配置文件指定的路径搜索,或搜索/lib,/lib64,/usr/lib,/usr/lib64,把查找到的所有的库文件路径和其名称映射关系保存为一个缓存文件/etc/ld.so.cache;

/etc/ld.so.conf配置文件有其它组成部份:/etc/ld.so.conf.d/*.conf

假定nginx安装于/usr/local/nginxlinux移植,此目录中有其库文件子目录lib,导入此目录中库文件:

(1)新建文件/etc/ld.so.conf.d/nginx.conf,在文件添加如下行:

/usr/local/nginx/lib

(2)运行命令:ldconfig

ldconfig的主要用途:

默认搜救/lilb和/usr/lib,以及配置文件/etc/ld.so.conf内所列的目录下的库文件。

搜索出可共享的动态链接库,库文件的格式为:lib***.so.**,从而创建出动态放入程序(ld.so)所需的联接和缓存文件。

缓存文件默认为/etc/ld.so.cache,该文件保存已排好序的动态链接库名子列表。

ldconfig一般在系统启动时运行,而当用户安装了一个新的动态链接库时,就须要手工运行这个命令。

常用选项:

-v:用此选项时,ldconfig将显示正在扫描的目录及搜索到的动态链接库,还有它所创建的联接的名子.-p:显示当前OS早已加载到的所有库文件名称及其文件所在路径的映射关系;

ldconfig须要注意的地方:

(a)、往/lib和/usr/lib上面加东西,是不用更改/etc/ld.so.conf文件的,并且添加完后须要调用下ldconfig,不然添加的library会找不到。

(b)、如果添加的library不在/lib和/usr/lib上面的话,就一定要更改/etc/ld.so.conf文件,往该文件追加library所在的路径,之后也须要重新调用下ldconfig命令。诸如在安装mysql的时侯,其库文件/usr/local/mysql/lib,就须要追加到/etc/ld.so.conf文件中。命令如下:

#echo"/usr/local/mysql/lib">>/etc/ld.so.conf#ldconfig-v|grepmysql

(c)、如果添加的library不在/lib或/usr/lib下,然而却没有权限操作写/etc/ld.so.conf文件的话,这时就须要往export里写一个全局变量LD_LIBRARY_PATH,就可以了。

(3)、帮助文件导入

man命令搜索特定路径查找指南页文件,这种路径是定义在/etc/man.config中的MANPATH参数所指定的路径下的;

新增办法:编辑/etc/man.config文件,新增一个MANPATH参数,其值为新安装程序的man指南所在的目录;

/usr/local/nginx/share/man/{man1,man8}man-M/path/to/manKEYWORD

(4)、头文件导入

有些程序安装后会生成对自己拥有库文件调用插口相关头文件系统查找头文件的路径为/usr/include

导入独立安装应用程序的头文件方式:创建链接至/usr/include下即可;

比如:

/usr/local/nginx/include#ln-sv/usr/local/nginx/include/*/usr/include/#ln-sv/usr/local/nginx/include/usr/include/nginx

perl源程序的编译安装方式:

(1)perlMakefile.in(2)make(3)makeinstall

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: lib文件 linux编译 文件目录 源码 编译程序
最后更新:2023年7月18日

Linux系统下载网

每日更新,欢迎收藏♥ 不积跬步无以至千里,加油,共勉。

点赞
< 上一篇
下一篇 >

Linux系统下载网

每日更新,欢迎收藏♥
不积跬步无以至千里,加油,共勉。

最新 热点 随机
最新 热点 随机
Linux运维视频教程 一般配置,即默认以后台程序方式运行是一个意思 linux web proxy 超越期待!Linux下的高效Web代理服务器及技巧详解 公众号获取账号所属类目的公共库模板标题列表 开源社区评测:Linux游戏开发对比 Linux chown命令:更改文件和目录所有权 高速无线网络畅享,tplink300M Linux驱动带你飞 Linux系统的秘密技巧:轻松修改文件创建日期 Windows远程连接Linux,轻松跨平台操作 关于linux下获取文件的创建时间与实战的相关资料 树莓派Linux系统:极简体验大比拼 Linux系统如何修改文件的时间touch命令的描述指令? Linux上运行exe文件的软件,你绝对不能错过这些 蓝牙耳机怎么连接电脑?笔记本蓝牙适配器的开启方法 全新Linux局域网聊天软件 系统启动时自动运行程序的三种功能方法介绍 Linux系统下载攻略:掌握这些技巧,轻松get Linux查看端口占用情况linux命令:ps、grep、kill 剖析ARM Linux内核:奥秘与精髓解读 康华:Linux内核空间和用户空间的区别及用法
快速定位目标文件,Linux文档管理软件!Linux运维视频教程简洁高效:Linux创建用户,配置sudo权限指南ls-alrtAFR-a显建站服务器的参考价值-显Linux查看GTK版本的实用技巧14种嵌入式操作系统的特点及特点解决RedHat浏览器中文乱码问题的七种方法Linux命令行不会删除的文件,很抱歉这个技巧unix系统和linux系统 Unix和Linux系统的经验技巧,你了解吗?lastb列出登入系统失败的用户相关信息补充说明命令嵌入式操作系统的特点及发展前景分析嵌入式Linux文件系统的结构是基于树状的根在顶部Linux操作系统下载:选择适合你的发行版获取UbuntuLinux操作系统的PDF文件文件的基础知识介绍Linux下Python开发经验与技巧分享Linux,下的日志文件系统的载体介绍-苏州安嘉Linux编程:系统IO速度稳定性评测IMAP和POP有什么区别?如何配置邮件客户端使用IMAPLinux轻松下载文件,简单操作!Linux远程主机的指定目录内容的使用命令
redhat启动故障排查与修复对比评测 1.常见Linux发行版的Linux内核内部功能介绍及解决办法 Linux搜索文件夹,快速找到你需要的! (Linux基础知识)远程主机忘记root密码的操作思路 Linux命令安装JDK,轻松提升Java开发效率 Linux内核下载地址,Linux之旅加速! Linux操作系统进程内核文件的设置文件是什么 怎么分配磁盘空间?哪种分配方法适用我? Linux系统管理 阿里云官方公共Linux系统镜像不会安装图形化桌面组件 如何快速地下载并学习Linux的经验和技巧? 解密Linux系统下的/dev目录:作用与意义 unix系统和linux系统 Unix和Linux系统的经验技巧,你了解吗? 微软Build大会宣布了哪些重大产品和更新?回来了 关于Linux操作系统LSB命令的十个方面详细分析! linux源码结构 Linux下TIME-WAIT状态的Socket持续状态是60s左右? Linux,下的日志文件系统的载体介绍-苏州安嘉 Linux基础知识:LINUX软件配置文件常见格式及应用程序 如何参与Linux内核之旅开源社区比较感兴趣? 通俗来讲就是字符设备与块设备的区别字符驱动程序讲解
标签聚合
命令 软件 文件 应用 电脑 内核 操作 linux系统 文件目录 linux服务器
书籍
课程
技术群
技术干货大合集↓
  • 2023年9月 / 98篇
  • 2023年8月 / 122篇
  • 2023年7月 / 122篇
  • 2023年6月 / 119篇
  • 2023年5月 / 123篇
  • 2023年4月 / 113篇
  • 2023年3月 / 265篇
友情链接:

Linux书籍 | Linux命令 | Linux系统 | RHCE红帽认证 | Linux软件 | Linux教程 | CentOS系统 | Linux内核 | Linux服务器 | Linux大神 | IT资源

COPYRIGHT © 2023 LinuxDown.com ALL RIGHTS RESERVED.

京ICP备14023444号-2