原创
从源代码编译和安装程序(转)
2011-9-9 17:25
1452
11
11
分类:
工程师职场
从源代码编译和安装程序。
A:如何得到源代码
什么是源代码?就是你用C语言编辑的XXX.c文件。
从网络上下载的开源软件一般的格式是.tar.gz.
.gz表示一种压缩方式,.tar表示一种归档方式,下面你可以看到源代码是被如何归档和压缩的,我们用rarlinux-3.6.0.tar.gz来做例子
那么如何从这样的归档文件中找到源代码呢
gzip -d rarlinux-3.6.0.tar.gz -d选项表示解压缩
我们可以看到rarlinux-3.6.0.tar.gz变成了rarlinux-3.6.0.tar.
tar -xf rarlinux-3.6.0.tar -xf表示把所有的文件从归档文件中释放出来
当然,这个例子解压缩出来的并不是C的源代码,我没有找到合适的例子。
B:关于make运作方式
我们在刚才的基础上,进入rar文件,并且运行
make > info.txt
看看我们的make都干了些什么?
&nb; -p表示需要时创建上级目录,目录存在的时候不做错误处理。
mkdir -p /usr/local/lib
cp rar unrar /usr/local/bin
cp rarfiles.lst /etc
cp default.sfx /usr/local/lib
再看看,rar文件夹中makfile中都有些什么?
cat Makefile
PREFIX=/usr/local 这是shell变量,你可以用echo $PREFIX看看。
install:
mkdir -p $(PREFIX)/bin
mkdir -p $(PREFIX)/lib
cp rar unrar $(PREFIX)/bin
cp rarfiles.lst /etc
cp default.sfx $(PREFIX)/lib
很像吧,没错,因为make是按照一定的规则去完成配置文件中的内容。这个配置文件默认的名字是makefile,当然也可以变。这个配置文件对于我来说不需要会写,但是总要读的懂。
了解下make命令的基本参数:偶不是编程的,捡有用的说。
-c dir 这个是make工作的路径,默认是当然路径。
-f filename 这个用指定的文件作为配置文件,默认是makefile。
-d 打印debug信息
在这个例子中我们可以知道make的工作方式,这对于从源代码运行程序是很有用的。
A:介绍一下可以用来搞定安装的全部工具。
gcc-这个是编译器
make-包含从makefiles产生二进制文件的make命令,当然还有其他的一些功能。
glibc-重要的共享库,c库和基本的数学库。没有这个连系统都没有办法运行。
glibc-devel-包含了创建可执行文件所需要的标准头文件。
binutils-包含编译程序需要的使用工具,主要是汇编和链接程序。
kernel-source-包含内核源代码
libc-包含libc5,而上面我们提到的glibc是linc6.
对于只想安装别人做好的软件的人,关键是gcc和make ,而其他的看看rpm中有没有就可以了。
B:关于软件包。
linux下你可以发现的软件包,会有不同的格式,这很讨厌,但是他可以让你知道,这些开源项目是在什么环境开发和编译出来的,支持什么。
搜集一下
filename-4.2.3.i386.rpm 这个表示可以用rpm来安装,我们最喜欢的方式。
filename-4.2.3.tar.gz 这个表示用gz压缩,用tar归档,至于是什么,那就不知道了
filename-4.2.3.src.tar.gz 这个表示用gz压缩,用tar归档,内容是源代码
filename-4.2.3.bin.SPARC.tar.gz 这个是表示用gz压缩,用tar归档,可以在SPARC工作站上运行,的2进制代码。
filename-4.2.3.bin.ELF.static.tar.gz 这个表示用gz压缩,用tar归档,由静态连接的FLF的可执行文件组成的2进制文件。
4.2.3 表示第4版,第2个补丁,第3次修改。
全面的说一下。
rpm.有这个后缀表示是fedora使用的2进制文件,这个不是说里面的内容2进制的,而是说他可以被fedora的软件管理器使用。可以用归档文件管理器把他打开。
tar.这个是用tar归档,使用tar 命令打开
gz.和z.这个是说用gzip压缩的,用gzip命令打开
tgz.这个扩展名和以上的结合,容易搞定
bz2.用bzip2压缩的,可以用bip2命令打开
taz.和tz.这个表示用tar压缩,也用tar命令打开
lsm.这个通常是介绍归档内容的文本,可以和软件包一起下载。
deb.这个同rpm但是用于Debian
如果你不能肯定格式的话,可以用file命令来确定.
好了,现在你可以把源文件从任何软包中掏出来,下面我们要编译他。
C:现在我们看一下C 的编译过程..
预编译,编译生成汇编,汇编生成目标文件,目标文件连接库文件生成可执行文件,这个过程人人都知道,但是究竟如何呢?
牢骚一下:太多的编译器都是一步到位,其实这对学习不是什么好事情,至少我觉得,在学习过程中把简单的东西弄的麻烦,在工作的过程中把麻烦的东西弄的简单。
这里的例子选自 lorne
预编译 gcc -E
编译 gcc -S 这两个有gcc rpm包就可以。
汇编as
连接ld 这两个需要安装binutils rpm包
1,预编译
编写c源程序game.c
#include
int main()
{
printf("Hello World!\n");
} 传说中的helloworld
gcc -E -o pregame game.c
这是会出现一个pregame文件
看看他是什么格式
file pregame
pregame: ASCII C program text
也就说预编译之后的文件仍然是c源代码。那么预编译作了些什么呢?
可以看看都有些什么玩意.
cat pregame
你会发现 pregame和game 差不多,区别是pregame中没有了#include也灭有类似的格式。
这就是预编译的作用他把game.c中包含的头文件加在main函数的上面.
gcc -o game game.c 生成 可执行程序 game
gcc -o pregame pregame.c 生成可执行程序pregame
注意:这两个命令,我们忽略了as和ld的步骤。
pregame最好用.c做为文件名
发现 game和pregame的运行结果一样,这也说明了预编译的作用.
总结一下预编译的作用这些是lorne大人总结的,与我无关)
把"include"的文件拷贝到要编译的源文件中。
用实际值替代"define"的文本。在调用宏的地方进行宏替换。
2.编译。
这个过程是用于生成汇编语言。这是编译过程的一步,是一步,是一步啊,同志们~~~~~~~~~~~~~~!!
gcc -S -o aspregame pregame.c
会声称一个aspregame文件,看看是什么东西?
file aspregame
aspregame: ASCII assembler program text
嘿嘿出现了,汇编程序文本.
有兴趣你可以看一下
cat aspregame
.file "pregame.c"
.section .rodata
.LC0:
.string "Hello World!"
.text
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $4, %esp
movl $.LC0, (%esp)
call puts
addl $4, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (GNU) 4.1.0 20060304 (Red Hat 4.1.0-3)"
.section .note.GNU-stack,"",@progbits
传说中的汇编。
最好用.asm作为文件名。
3.生成目标文件.
这一步我们可以用gcc来完成,但是还是用as吧,总觉得一步到位的东西,不是很适合学习。
as -o ldaspregame aspregame
会生成ldaspregame文件
看看他是什么?
file ldaspregame
ldaspregame: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
ELF格式的文件,浮动的,意思是这个程序的地址是可以被修改来适应初始地址,其实就是未连接的目标文件。
注意:我们可以把任何的一个.c文件通过gcc -S变成汇编,在把他变成目标文件。
最要用.o做为文件名
4.连接成为可执行文件
那么现在我们来生成可执行文件吧
这里要说明什么是动态链接库,相当于winxxx中的dll文件,在这里是so文件,ELF格式就是支持动态链接库的。
gcc -o exldaspregame ldaspregame
好了声称了可执行文件ldaspregame
任何一个.c文件都可以生成目标文件,他们需要被连接来执行。
这里我有一个问题,希望高手可以解答:
本来我想用ld来连接文件,ld ldaspregame
但是提示错误为:
ld: warning: cannot find entry symbol _start; defaulting to 08048094 对‘puts’未定义的引用
以为是没有设置要连接的库文件。
ld /bin/libc.so.6 ldaspregame
仍然错误
提示错误为
ld: warning: cannot find entry symbol _start; defaulting to 08048094
entry symbol_start究竟是什么东西?gcc又是怎样完成这一步骤的?
D:编译器稍微高级的使用方法。
首先,介绍模块化编程方法。
其实就是把程序的源代码分成多个文件。大多数的自由软件也都是这样组成的。c语言中带有main函数的文件被成为主模块,其他的是辅助模块.
来个例子,这个例子取自 Bradley L.Jones PeterAitken
建立list2101.c,calc.c,calc.h文件.内容分别是。
list2101.c
#include
#include "calc.h"
int main(void)
{
int x;
printf("enter an integer value:");
scanf("%d",&x);
printf("\nthe square of %d is %ld.\n",x,sqr(x));
return 0;
}
calc.c
#include "calc.h"
long sqr(int x)
{
return ((long)x*x);
}
calc.h
long sqr(int x);
未完 ......................................
关闭
站长推荐
/3
文章评论(0条评论)
登录后参与讨论