【Linux学习】实验11_Linux软件开发工具(1)

曾巧文 发布于:2012-5-11 0:32 分类:Linux学习 标签: Ubuntu linux 系统 实验

实验11 Linux软件开发工具(1)

一、            实验目的

1、  掌握编译工具gcc的使用。

2、  理解由源代码生成可执行文件的相关步骤。

3、  掌握静态库和动态库的创建与使用。

 

二、            实验要求

1、  硬件基本配置要求:双核CPU, 1G内存, 20G硬盘空间;软件需求:Windows XP以上系统,VMware 7.0Ubuntu10.04 DVD安装镜像。

2、  分组安排:11组;时间安排:2个课时;实验类型:验证型。

3、  实验的过程中完成实验报告,并于实验结束后上传到FTP服务器指定目录。

 

三、            实验内容

1、  gcc命令基本练习:

Ø  使用vi在用户主目录创建main.c文件,内容如下所示:

Ø  使用命令:gcc  main.c  -o  main,编译main.c并生成可执行文件main

Ø  sudo apt-get install vim

Ø  vim main.c

  #include

  #define STR "hell0 world"

   

  int main (int argc, const char *argv[])

  {

      int i;

      for (i = 0; i < argc; i++)

      {

          printf("%s\n",argv[i]);

      }

      printf("%s\n",STR);

  #ifdef DEBUG

     printf("Debug Info\n");

  #endif

      return 0;

 }

Ø  gcc main.c -o main

Ø  ./main

Ø  使用命令:./main,执行main程序,观察程序输出结果。

Ø 

Ø  使用命令:./main  a  b  c,执行main程序,观察程序输出结果。(main函数中的参数argcargv[]是什么? )

Ø 

Ø  参数argc 参数个数

Ø  参数argv[] 指针

2、  分步骤实现预处理、编译、汇编、链接过程:

Ø  使用选项-E,执行预处理工作。使用命令:gcc  -E  main.c  -o  main.i,查看main.i文件的内容,观察源代码中哪些部分被替换了?

Ø 

Ø  printf("%s\n",STR); 被替换成 printf("%s\n",”hello world”);

Ø  执行条件编译,使用命令:gcc  main.c  -E  -DDEBUG  -o  mainD.i,对比文件mainD.imain.iDEBUG宏部分的内容,看看有何区别。-DDEBUG选项的作用是什么?

Ø  Ps: vim下大写G可以跳到页尾

Ø 

Ø  文件mainD.imain.i中多了 printf("Debug Info\n");

Ø  -DDEBUG选项的作用是

Ø  使用选项-S,执行编译处理工作。使用命令gcc  main.i  -S  -o  main.smain.i进行编译,生成汇编文件main.s。查看main.s文件的内容,可以看到原来的c语言代码已被编译为汇编代码。

Ø 

Ø          .file   "main.c"

Ø          .section        .rodata

Ø  .LC0:

Ø          .string "hell0 world"

Ø          .text

Ø  .globl main

Ø          .type   main, @function

Ø  main:

Ø          pushl   %ebp

Ø          movl    %esp, %ebp

Ø          andl    $-16, %esp

Ø          subl    $32, %esp

Ø          movl    $0, 28(%esp)

Ø          jmp     .L2

Ø  .L3:

Ø          movl    28(%esp), %eax

Ø          sall    $2, %eax

Ø          addl    12(%ebp), %eax

Ø          movl    (%eax), %eax

Ø          movl    %eax, (%esp)

Ø          call    puts

Ø          addl    $1, 28(%esp)

Ø  .L2:

Ø          movl    28(%esp), %eax

Ø          cmpl    8(%ebp), %eax

Ø          jl      .L3

Ø          movl    $.LC0, (%esp)

Ø          call    puts

Ø          movl    $0, %eax

Ø          leave

Ø          ret

Ø          .size   main, .-main

Ø          .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"

Ø          .section        .note.GNU-stack,"",@progbits

Ø  使用选项-c,执行汇编工作。使用命令gcc  main.s  -c  -o  main.omain.s进行汇编,生成二进制的目标文件main.o

Ø  gcc  main.s  -c  -o  main.o

Ø  使用命令gcc  main.o  -o  main.dynamic,默认使用共享库进行链接,生成可执行文件main.dynamic,并运行该程序。

Ø  gcc  main.o  -o  main.dynamic

Ø  ./main.dynamic

Ø  使用命令gcc  main.o  -static  -o  main.static,不使用共享库进行链接,生成可执行文件main.static,并运行该程序。

Ø  gcc  main.o  -static  -o  main.static

Ø  ./main.static

Ø  比较main.dynamicmain.static两个文件的大小。(为什么这两个程序的执行效果一样,而文件大小却差别很大?)

Ø 

Ø  比较:main.dynamicmain.static小很多。

Ø  为什么这两个程序的执行效果一样,而文件大小却差别很大:

Ø  静态链接:由链接器在链接时将库的内容加入到可执行程序中,生成的程序较大。

Ø  动态链接:在可执行文件装载时或运行时,由操作系统的装载程序加载库

3、  静态库和共享库的创建与使用:

Ø  使用vi在用户主目录创建libtest1.c文件,内容如下所示:

Ø  #include

Ø  void sayHello()

Ø  {

Ø        printf("hello\n");

Ø  }

 

Ø  使用vi在用户主目录创建libtest2.c文件,内容如下所示:

Ø  使用vi在用户主目录创建libtest.h文件,内容如下所示:

  #ifndef LTBTEST_H

  #define LTBTEST_H

  extern void sayHello(void);

  extern void sayWorld(void);

  #endif

Ø  使用vi在用户主目录创建helloworld.c文件,内容如下所示:

Ø  #include "libtest.h"

Ø  int main(void)

Ø  {

Ø      sayHello();

Ø      sayWorld();

Ø      return 0;

Ø  }

Ø  使用gcclibtest1.c libtest2.c编译生成目标代码文件libtest1.olibtest2.o

Ø  gcc libtest1.c -c -o libtest1.o

Ø  gcc libtest2.c -c -o libtest2.o

Ø  使用命令:ar  rs  libtest.a  libtest1.o  libtest2.o,将目标文件打包生成静态库libtest.a

Ø  ar  rs  libtest.a  libtest1.o  libtest2.o

Ø  使用命令:gcc  helloworld.c  -o  helloworld进行编译,命令的输出结果说明什么问题。

Ø 

Ø  没有定义sayhellosayworld

Ø  使用命令:gcc  helloworld.c  -L.  -ltest  -o  helloworld-a进行编译, “-L.”是指在当前目录下查找库文件, “-ltest” 是指要使用的库文件名为:libtest

Ø 

Ø  使用命令:ldd  helloworld-a 查看可执行文件helloworld-a需要哪些共享库文件。输出的信息中有libtest.a这个库文件吗?为什么?

Ø       linux-gate.so.1 =>  (0x00190000)

Ø         libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x0085c000)

Ø         /lib/ld-linux.so.2 (0x00e02000)

Ø      没有,因为默认目录还没有这个文件

Ø  使用mv命令将当前目录下的静态库文件libtest.a移动到系统用户库文件默认目录/usr/lib,此时重新编译helloworld.c文件可以使用什么命令?

Ø  gcc  helloworld.c  -ltest  -o  helloworld-a

Ø  使用命令:gcc  libtest1.c  libtest2.c  -fPIC  -shared  -o  libtest.so,生成共享库

Ø  libtest.sol

Ø  gcc  libtest1.c  libtest2.c  -fPIC  -shared  -o  libtest.so

Ø  使用命令:gcc  helloworld.c  -L.  -ltest  -o  helloworld-so进行编译。

Ø  此时执行helloworld-so这个文件,出现的错误提示是什么?使用命令:ldd  helloworld-so查看可执行文件helloworld-so需要哪些共享库文件,从输出的结果说明libtest.so无法找到。

Ø  ./helloworld-so: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory

Ø         linux-gate.so.1 =>  (0x003bf000)

Ø         libtest.so => not found

Ø         libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x004e7000)

Ø         /lib/ld-linux.so.2 (0x00168000)

Ø  使用mv命令将当前目录下的共享库文件libtest.so移动到系统用户库文件默认目录/usr/lib。此时执行helloworld-so这个文件看看有无问题。

Ø  再次使用命令:ldd  helloworld-so查看可执行文件helloworld-so需要哪些共享库文件。输出的信息和刚才有什么区别?

Ø         linux-gate.so.1 =>  (0x009db000)

Ø         libtest.so => /usr/lib/libtest.so (0x0071e000)

Ø         libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00110000)

Ø         /lib/ld-linux.so.2 (0x002c4000)

Ø  输出信息中找到了libtest.so

Ø  使用命令:ls  -l  helloworld-* 查看比较下链接静态库和链接共享库的这两个可执行文件的大小。哪个文件更大?为什么?

helloworld-a更大,因为 helloworld-a链接静态库helloworld-so链接共享库

Ø   

版权所有:《曾巧文博客-关注互联网IT技术,记录生活点滴》 => 《【Linux学习】实验11_Linux软件开发工具(1)
本文地址://qiaowen.net/post-1217.html
除非注明,文章均为 《曾巧文博客-关注互联网IT技术,记录生活点滴》 原创,欢迎转载!转载请注明本文地址,谢谢。

有 5460 人浏览,获得评论 4 条

评论:

龙岩无痛人流
2012-05-11 15:05
嘿嘿 挺不错的博客支持下
曾巧文
2012-05-11 22:12
@龙岩无痛人流:有空可以常来,呵呵
爱范儿
2012-05-11 08:13
嘿嘿,LINUX我们才学点皮毛呢
曾巧文
2012-05-11 22:11
@爱范儿:呵呵,一起学习

发表评论:

Powered by emlog 粤ICP备12040901号

>>本作品采用-知识共享署名-非商业-禁止演绎-协议-进行许可 |站点地图 | | | | 开放分类目录 |