linux 编程技术

系统 1467 0

linux 编程技术No.1前期准备工作

GCC的编译过程分为预处理、生成汇编代码、生成目标代码和链接成可执行文件等4个步骤。

使用vim编写C 文件 : [lining@localhost program]$ vim hello.c 这样就会在program文件夹生成hello.c文件

编译C代码:使用如下命令“gcc 代码文件名”  如: [lining@localhost program]$ gcc hello.c 这样就会生成二进制可执行文件名称位a.out。

          如果需要指定输出的文件名称,使用 “gcc -o 代码文件名” 如:[lining@localhost program]$ gcc -o hello hello.c 这样就会生存名称为hello的可执行文件。

         [lining@localhost program]$ gcc -v -o hello hello.c 使用参数v可以显示GCC的工作整个过程。

编译C ++代码:与编译C 代码类似,只不过要把gcc换成g++。

使用GCC控制编译过程:

  1、预处理

            该步骤完成宏和include展开工作。在GCC 中使用参数E可控制GCC完成预处理。

           [lining@localhost program]$ gcc -E -o hello.pre.c hello.c 可通过查看hello.pre.c文件内容验证

       2、生成汇编代码

           编译器将预处理生成的代码进行处理,并根据编译参数进行优化,最后生成汇编代码。使用参数S。

          [lining@localhost program]$ gcc -S hello.c 将生成名为hello.s的汇编代码。

  3、生成目标代码

           目标代码生成阶段是把中间代码变换成特定机器上的绝对指令代码、可重定位的指令代码或汇编指令代码。GCC中使用参数c完成预编译、生成汇编代码和生成目标代码。

           [lining@localhost program]$ gcc -c hello.c 将生成名为hello.o的目标代码。

  4、链接生成最终可执行代码

            这一步相当与前面的程序编译。

GNU Make项目管理

        Make按照一定的规则对项目的源文件进行编译,并生成可执行的二进制文件。在使用gcc编译项目文件时,由于项目源文件代码很多,每次修改任何一个源代码文件都要重新编译和链接。

 Make通过读入配置好的文本文件,并根据文本文件中预先定义的规则和步骤,完成代码的编译和链接工作,最终生成所需要的项目文件。这个文本文件在缺省情况下文件名为makefile或Makefile。Make程序的命令形式是 “make[选项]、[目标]...”,可通过make -h 查看所支持选项。

        Make 在进行项目编译时会读makefile文件,比较该目标所依赖的源文件额日期和时间,以确定要编译的代码和相关的编译规则。当用户输入make命令后,Make将首先搜索该目录下是否存在makefile。如果没找到,则搜索名为makefile的文件,最后查找名为Makefile的文件。用户可通过 -f参数来指定makefile配置文件。

makefile的语法

  makefile文件由一组依赖关系和规则构成。每个依赖关系由一个目标(即将要创建的文件)和一组该目标所依赖的源文件组成。makefile的内容包含5个部分:显式规则,隐式规则,变量定义,指令和注释。

       这里主要介绍变量和指令这两个主要的部分。

       变量:区分大小写,与C/C++不同,定义变量不需要先声明。在定义变量后,如果要引用该变量,可以使用$(变量名)的形式访问该变量。

                  对上面的hello.c 编写带有变量定义的makefile    

      CC =
      
         gcc

hello : hello.c

          $(CC) 
      
      -o hello hello.c    //这儿需要注意,第二行的开头是tab字符,如果使用空格会在make命令下出现提示
    

                 完成编辑后,将其保存为makefile文件。在shell命令下输入make命令,编辑文件。

                 makefile中有一些预先设定的变量:

                     $@   表示当前规则中的目标文件名

                          $?     新修改过的依赖文件列表

                          $*      不包含扩展名的目标文件名

                          $<      当前规则中的第一个依赖文件名

                          $%     当目标文件为库文件时,该变量为库文件名;如果不是库文件,该变量为空值

                          $^      当前规则中的所有文件列表

                          AR     归档程序名称,默认为AR

                          ARFLAGS      归档程序选项

                         CC      C编译器命令名,默认为CC

                         CFLAGS     C编译器编译参数

   基于依赖关系的指定区:

               依赖关系定义了最终应用程序里的每个文件与源文件之间的关系。规则的写法如下

                       目标(可能存在多个目标)... :空格或tab键 依赖条件(可能存在多个依赖条件,以空格或tab隔开)...

  举例如下:

      myapp:    main.o 
      
        2
      
      .o 
      
        3
      
      
        .o

main.o:    main.c a.h


      
      
        2
      
      .o:    
      
        2
      
      
        .c a.h b.h


      
      
        3
      
      .o:    
      
        3
      
      .c b.h c.h
    

它表示目标myapp依赖于main.o,2.o和3.o, 而main.o依赖于 main.c和a.h,等等。如果你没有指定目标的名字作为make命令的一个参数,make命令将第一个目标定义为all。

      myapp:    main.o 
      
        2
      
      .o 
      
        3
      
      
        .o

      gcc 
      
      -o myapp main.o 
      
        2
      
      .o 
      
        3
      
      
        .o     

main.o:    main.c a.h

      gcc 
      
      -
      
        c main.c


      
      
        2
      
      .o:    
      
        2
      
      
        .c a.h b.h

      gcc 
      
      -c 
      
        2
      
      
        .c


      
      
        3
      
      .o:    
      
        3
      
      
        .c b.h c.h

      gcc 
      
      -c 
      
        3
      
      .c 
    

当我们执行make -f makefile1(我们把创建的第一个makefile自定义命名),首先会检查其他的依赖关系,最终确定需要有一个文件main.c。在这里我们令头文件都是空文件,我们可以用touch命令来创建它们:

[lining@localhost program]$ touch a.h
[lining@localhost program]$ touch b.h
[lining@localhost program]$ touch c.h

      
        1
      
       #include <stdlib.h>

  
      
        2
      
       #include <stdio.h>

  
      
        3
      
       #include 
      
        "
      
      
        a.h
      
      
        "
      
      
        4
      
      
        extern
      
      
        void
      
      
         function_two();

  
      
      
        5
      
      
        extern
      
      
        void
      
      
         function_three();

  
      
      
        6
      
      
        void
      
      
         main()

  
      
      
        7
      
      
         {

  
      
      
        8
      
      
                 function_two();

  
      
      
        9
      
      
                 function_three();

 
      
      
        10
      
               printf(
      
        "
      
      
        %s\n
      
      
        "
      
      ,
      
        "
      
      
        This is a test
      
      
        "
      
      
        );

 
      
      
        11
      
       }
    

2.c 和3.c

      
        /*
      
      
         2.c 
      
      
        */
      
      
        1
      
       #include 
      
        "
      
      
        a.h
      
      
        "
      
      
        2
      
       #include 
      
        "
      
      
        b.h
      
      
        "
      
      
        3
      
      
        void
      
      
         function_two(){

  
      
      
        4
      
      
         }


      
      
        /*
      
      
         3.c 
      
      
        */
      
      
        1
      
       #include 
      
        "
      
      
        b.h
      
      
        "
      
      
        2
      
       #include 
      
        "
      
      
        c.h
      
      
        "
      
      
        3
      
      
        void
      
      
         function_three(){

  
      
      
        4
      
       }
    

然后执行make命令:make -f makefile1生成目标文件myapp,再执行如下命令:

[lining@localhost program]$ ./myapp 
This is a test
如果我们使用变量将使得我们在以后的维护过程中更加方面,我们把上面的makefile文件改造

      CC=
      
        gcc

CFLAGS1
      
      =-
      
        o

CFLAGS2
      
      =-
      
        c

myapp:    main.o 
      
      
        2
      
      .o 
      
        3
      
      
        .o

      $(CC) $(CFLAGS1) $@ main.o 
      
      
        2
      
      .o 
      
        3
      
      
        .o     

main.o:    main.c a.h

      $(CC) $(CFLAGS2) main.c


      
      
        2
      
      .o:    
      
        2
      
      
        .c a.h b.h

      $(CC) $(CFLAGS2) 
      
      
        2
      
      
        .c


      
      
        3
      
      .o:    
      
        3
      
      
        .c b.h c.h

      $(CC) $(CFLAGS2) 
      
      
        3
      
      
        .c 

clean:

      rm main.o

      rm 
      
      
        2
      
      
        .o

      rm 
      
      
        3
      
      .o
    

使用 clean 可将中间生成的文件做必要的清理,这样目标就没有依赖关系了。在正常情况下,如果没有告诉Make执行clean命令(make -f makefile1 clean),clean将永远不被执行。

Make在makefile中没有指明具体处理规则时会采用惯例来处理。例如,将后缀.c的文件编译为.o文件,也就说说我们不必写出将后缀.c的文件编译为.o文件的规则,Make命令就自动识别并执行。常见的隐含规则如下:

       C 程序编译: .o文件自动由同名的.c文件生成,编译命令为: $(CC) -c $(CPPFLAGS) $(CFLAGS)

       C++程序编译: .o文件自动由同名的.c文件或.cc文件生成,编译命令为:$(CXX) -c $(CPPFLAGS) $(CFLAGS)

  Pascal程序编译: .o文件自动由同名的.p生成,编译命令为:$(PC) -c $(PFLAGS)

makefile的模式规则:

       Make支持编写模式规则来定义用户自己的隐含规则。相比于一般的规则,模式规则在形式上只是含有“%”的通配符(其功能类似于shell中的“*”)。如果确定了依赖关系中的“%”模式,Make就会按要求去匹配当前目录下的所有文件名,一旦找到符合规则的文件,Make就会执行该规则下的命令。如

      %.o : %
      
        .c

               $(CC) 
      
      -c $(CFLAGS) $(CPPFLAGS) $< -o $@
    

该模式规则表示当前目录下的所有以.c结尾的文件编译成以.o结尾的目标文件。宏$<将被扩展为起始文件的名字。而$@将被替换成生成的目标文件。

 关于调试的知识将在以后的章节中介绍。

 



 
 

linux 编程技术


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论