原创 从源代码编译和安装程序(转)

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);
                未完 ......................................
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
11
关闭 站长推荐上一条 /3 下一条