1. 实验记录

实验任务1

使用上述三种编译方法,对/notebooks/workspace目录下的bubbleSort.c, insertSort.c, selectSort.c, sort.c, sort.h进行编译(其中,sort.c是主程序,sort.h是头文件,其他的三个c程序分别实现了主程序需要用到的3个函数),写出步骤和结果。

第一种方法:直接使用如下命令行一次完成编译、链接过程

cd /notebooks/workspace

gcc bubbleSort.c insertSort.c selectSort.c sort.c -o sort 

bubbleSort.c、insertSort.c、selectSort.c和sort.c的后缀名(.c)指明了调用c编译器,gcc是GCC的众多编译器的统一入口,gcc靠后缀名决定调用什么编译器,-o 参数指定了可执行文件的文件名为sort。

linux实验4

用ls检查一下生成的可执行文件:

ls

linux实验4

运行可执行程序:./sort

linux实验4

为了避免跟下一种方法混淆,使用rm命令删除这种方法生成的可执行文件:rm sort。

第二种方法:编译bubbleSort.c、insertSort.c、selectSort.c为静态库,编译sort.c时指定静态库的位置。

步骤一:需要将bubbleSort.c、insertSort.c、selectSort.c编译成中间文件bubbleSort.o、insertSort.o、selectSort.o,使用如下命令行:

gcc -c bubbleSort.c insertSort.c selectSort.c

ls

linux实验4

可以看到已经生成了bubbleSort.o、insertSort.o、selectSort.o文件

步骤二:生成静态库文件,添加 bubbleSort.o、insertSort.o和selectSort.o到静态库中,使用如下命令行:

ar -r libsort.a bubbleSort.o insertSort.o selectSort.o

ls

linux实验4

可见,bubbleSort.o、insertSort.o和selectSort.o已生成。

命令行中,-r libsort.a参数表示建立静态库,名字为libsort.a。

步骤三:使用如下命令行生成可执行程序

gcc sort.c libcalc.a -o sort

ls

linux实验4

生成了可执行文件sort。使用rm命令删除静态库libsort.a和可执行文件sort。

第三种方法:建立共享库,编译时指定共享库。

步骤一:使用如下命令编译bubbleSort.c、insertSort.c和selectSort.c为bubbleSort.o、insertSort.o和selectSort.o:

gcc -c -fpic bubbleSort.c insertSort.c selectSort.c

ls

linux实验4

命令行中,-fpic指定bubbleSort.o、insertSort.o和selectSort.o为可重分配地址属性,pic是position independence code的缩写。

步骤二:使用bubbleSort.o、insertSort.o和selectSort.o生成共享库sort.so,命令如下:

gcc -shared bubbleSort.o insertSort.o selectSort.o -o sort.so

linux实验4

步骤三:编译sort.c,链接生成的共享库,使用命令如下:

gcc sort.c sort.so -o sort

linux实验4

在命令行窗口中运行新生成的该程序(sort)会发生错误,提示为:

.sort:error while loading shared libraries: sort.so: cannot open shared object file: No such file or directory。

原因是:共享库编译的sort程序执行时需要加载共享库sort.so,而步骤一和步骤二生成的共享库sort.so不在系统默认的共享库搜索路径中,所以错误提示为共享库sort.so不存在。

通过如下命令指明共享库的搜索路径为sort.so所在的当前目录:

export LD_LIBRARY_PATH=`pwd`

再次运行新生成的该程序sort,则可以正常运行。

linux实验4

实验任务3

请根据7.3讲述的Makefile的写法,为/notebooks/workspace目录下的bubbleSort.c, insertSort.c, selectSort.c, sort.c, sort.h编写Makefile文件,要求至少包括all和clean目标。

1、先编辑Makefile文件,命令如下:

all:sortapp #我们使用的是sort文件,不是main,所以用的是sortapp

sortapp:sort.o bubbleSort.o insertSort.o selectSort.o

             gcc -o [email protected] $^

sort.o:sort.c bubbleSort.h insertSort.h selectSort.h

            gcc -c $<

bubbleSort.o:bubbleSort.c bubbleSort.h

            gcc -c $<

insertSort.o:insertSort.c insertSort.h

 gcc -c $<

selectSort.o:selectSort.c selectSort.h

            gcc -c $<

clean:

            rm sortapp sort.o bubbleSort.o insertSort.o selectSort.o 3>/dev/null

为了简化Makefile,可以使用特定的变量[email protected],$^,$<,它们的含义为:

[email protected] 目标文件

$^ 所有的依赖文件

$< 第一个依赖文件

2、再编辑头文件bubbleSort.h、insertSort.h和selectSort.h,命令如下:(下面的分号是写在文件中的,不是分行)

void BubbleSort(int A[],int N);

void InsertionSort(int A[],int N);

void SelectSort(int A[],int N);  #使用cat bubbleSort.c来查看函数

linux实验4

编辑文件如下:

linux实验4

3、直接使用make -f Makefile

linux实验4

4、使用make -f Makefile clean删除所有目标文件。因为all目标依赖对象是sortapp,所以执行该目标可以完成编译.

linux实验4

2. 思考题回答

    源代码级别的调试和二进制级别的调试有什么区别?

    (写错了)

3. 实验体会

      通过实验任务1,知道有三种使用gcc编译的方法:(以实验为例)

      一:直接使用如下命令行一次完成编译、链接过程:

      cd /notebooks/workspace   #先切换到文件所在目录

      gcc bubbleSort.c insertSort.c selectSort.c sort.c -o sort #直接将.c文件改成.o文件,并放入sort中

 二:编译bubbleSort.c、insertSort.c、selectSort.c为静态库,编译sort.c时指定静态库的位置。

           (1)使用如下命令行:

                 gcc -c bubbleSort.c insertSort.c selectSort.c

     将bubbleSort.c、insertSort.c、selectSort.c编译成中间文件           bubbleSort.o、insertSort.o、selectSort.o。

          (2)使用如下命令行:

ar -r libsort.a bubbleSort.o insertSort.o selectSort.o

生成静态库文件libsort.a,同时添加 bubbleSort.o、insertSort.o和selectSort.o到静态库中。

          (3)使用命令行gcc sort.c libcalc.a -o sort生成可执行程序。

       三、建立共享库,编译时指定共享库。

(1)使用如下命令:

gcc -c -fpic bubbleSort.c insertSort.c selectSort.c。

编译bubbleSort.c、insertSort.c和selectSort.c为bubbleSort.o、insertSort.o和selectSort.o。

         (2)使用如下命令:

gcc -shared bubbleSort.o insertSort.o selectSort.o -o sort.so

生成共享库sort.so。

         (3)使用命令如下:gcc sort.c sort.so -o sort,编译sort.c,链接生成的共享库。

 共享库编译的sort程序执行时需要加载共享库sort.so,而(1)和(2)生成的共享库sort.so不在系统默认的共享库搜索路径中,所以错误提示为共享库sort.so不存在。

通过如下命令指明共享库的搜索路径为sort.so所在的当前目录即可:

export LD_LIBRARY_PATH=`pwd`

通过实验任务3,知道怎么编写Makefile文件使其自动编译。先查看目录下所要编写的文件有哪些,没有头文件还需要根据.c文件中函数的函数名编辑头文件。

Makefile文件由“依赖关系+规则”部分组成(即首字母靠行起始对齐的部分,“规则”部分根据情况可不写)。如下:

sortapp:sort.o bubbleSort.o insertSort.o selectSort.o

 gcc -o sortapp sort.o bubbleSort.o insertSort.o selectSort.o

该部分中,“依赖关系”为“sortapp:sort.o bubbleSort.o insertSort.o selectSort.o”,即目标为“sortapp”,依赖对象为sort.o bubbleSort.o insertSort.o和selectSort.o,目标对象和依赖对象均为文件,表明当依赖对象sort.o bubbleSort.o insertSort.o和selectSort.o比目标文件sortapp新的时候(即依赖对象发生改变),执行紧接着的“规则”的命令,也就是“gcc -c [email protected] $^”,注意:“规则”前面有一个TAB间隔。

为了简化Makefile,可以使用特定的变量[email protected],$^,$<,它们的含义为:新的时候

[email protected] 目标文件

$^ 所有的依赖文件

$< 第一个依赖文件

也知道了使用make -f Makefile clean会删除所有目标文件,但因为all目标依赖对象是sortapp,所以执行该目标仍可以完成编译。

相关文章: