欢迎来到CloudService文涵的博客

人生三从境界:昨夜西风凋碧树,独上高楼,望尽天涯路。 衣带渐宽终不悔,为伊消得人憔悴。 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。

【linux上机实验】实验六 Linux开发工具的使用(一)

【前 言】

愿,所有相遇,都恰逢其时!

愿,此刻心头,正满怀欣喜!

                 ---你好,朋友,欢迎你!

1. 用gcc带不同参数编译下列hello.c程序。

#include <stdio.h>
int main(){
	printf(”Hello World!\n”);
	return 0;
}

(1)只作预处理,不进行编译,相应命令为:gcc -E hello.c
(2)只进行编译,不做汇编,生成hello.s,命令为:gcc -S hello.c
(3)只生成目标文件,不做连接,生成hello.o,命令为:gcc -c hello.c
(4)以默认方式生成可执行程序a.out,命令为:gcc hello.c
(5)生成可执行程序hello.out,命令为:gcc hello.c -o hello.out
(6)生成可调试的可执行程序hello.out,命令为:gcc -g hello.c -o hello.out

gcc的常用选项:
 -c :只编译,不链接,生成目标文件“.o”。
 -S :只编译,不汇编,生成汇编代码“.S”。
 -E :只进行预编译/预处理,不做其他处理。
 -o file:输出文件名为file
 -g :在可执行程序中包含标准调试信息。
 -v :打印出编译器内部编译各过程的命令行信息和编译器的版本。
 -I dir :在头文件的搜索路径列表中添加dir目录
 -L dir :在库文件的搜索路径列表中添加dir目录
 -static :连接静态库(静态库也可以用动态库链接方式链接)
 -llibrary :连接名为library的库文件(显示指定需要链接的动态库文件)

2. Linux下用gcc的生成和使用动态库和静态库。

(1)要求学生按下述给出的步骤,在命令行上运行给出的命令。
(2)熟悉gcc编译运行c程序的三种思路,掌握静态库、动态库的创建和使用。

程序1: 创建hello.h文件

在命令行中输入以下命令,创建hello.h 文件:nano hello.h
image

在编辑器中,将以下内容粘贴到hello.h 文件中:
#ifndef HELLO_H
#define HELLO_H
void hello(const char *name);
#endif
按下 Ctrl + X,然后按 Y 保存并退出编辑器(如果需要你确定文件名按一下enter键)

程序2: 创建hello.c文件

在命令行中输入以下命令,创建hello.c文件:nano hello.c
image

在编辑器中,将以下内容粘贴到hello.c文件中:
#include <stdio.h>
void hello(const char *name) {
	printf("Hello %s!\n", name);
}
按下 Ctrl + X,然后按 Y 保存并退出编辑器(如果需要你确定文件名按一下enter键)

程序3: 创建main.c文件

在命令行中输入以下命令,创建main.c文件:nano main.c
image

在编辑器中,将以下内容粘贴到main.c文件中:
#include "hello.h" 
 int main(){ 
	 hello("everyone"); 
	 return 0; 
 }
按下 Ctrl + X,然后按 Y 保存并退出编辑器(如果需要你确定文件名按一下enter键)

注意:用gcc –o 编译hello.c,gcc将报错。这个道理非常简单,hello.c是一个没有main函数的.c程序,因此不够成一个完整的程序。无论静态库,还是动态库,都是由.o文件创建的。因此,我们必须将源程序hello.c通过gcc先编译成.o文件。

这个时候我们有三种思路:

  1. 通过编译多个源文件,直接将目标代码合成一个.o文件。
  2. 通过创建静态链接库libmyhello.a,使得main函数调用hello函数时可调用静态链接库。
  3. 通过创建动态链接库libmyhello.so,使得main函数调用hello函数时可调用动态链接库。

思路一:编译多个源文件

(1)只生成目标文件,不进行链接。即生成hello.o,main.o

命令:gcc –c hello.c main.c

用命令查看生成的文件(截屏给出查看结果):
image

(2)将目标文件链接生成可执行文件,即mymain。

命令:gcc hello.o main.o -o mymain

用命令查看生成的文件(截屏给出查看结果):
image

(3)运行生成的可执行文件mymain。

运行:./mymain

截屏给出查看结果:
image

思路二:创建静态链接库

静态库文件名的命名规范是以lib为前缀,紧接着跟静态库名,扩展名为.a。例如:我们要创建的静态库名为myhello,则静态库文件名就是libmyhello.a。创建静态库用ar命令。

ar格式:ar  rcs libxxx.a xx1.o xx2.o
ar中的三个参数:
r - 代表将文件插入归档文件中;
c - 代表建立归档文件;
s - 代表若归档文件中包含了对象模式,可利用此参数建立备存文件的符号表。

创建静态链接库步骤:

①将hello.c编译成.o文件
命令:gcc -c hello.c

②由.o文件创建静态库(使用ar工具将目标文件收集起来,放到一个归档文件中)
命令:ar cr libmyhello.a hello.o

③在程序中使用静态库
首先生成目标程序hello,然后运行hello程序看看结果如何。
命令:gcc -o hello main.c -L. -lmyhello

运行:./hello

结果显示(截屏):
image

删除静态库文件,试试公用函数hello是否真的连接到目标文件 hello中了。

命令:rm -rf libmyhello.a
运行:./hello

结果显示(截屏):
image

思路三:创建动态链接库(共享库)

静态链接库的一个缺点是,如果同时运行了许多程序,并且它们使用了同一个库函数,这样,在内存中会大量拷贝同一库函数,就会浪费很多珍贵的内存和存储空间。使用了共享链接库的Linux就可以避免这个问题。

创建动态链接库步骤:

①将hello.c编译成.o文件
命令:gcc -c hello.c

②由.o文件创建动态库文件
在系统提示符下键入以下命令得到动态库文件libmyhello.so。
命令:gcc -shared -fPIC -o libmyhello.so hello.o

注意:如果做到这一步报以下信息错误
image

解决办法:
问题出在 hello.o 文件上。需要使用 -fPIC 重新编译 hello.c 文件以生成位置无关的代码。

①删除现有的 .o 文件和动态库文件(如果存在):
命令:rm hello.o libmyhello.so

②使用 -fPIC 编译 hello.c 文件:
命令:gcc -c -fPIC hello.c

③创建动态库文件:
命令:gcc -shared -o libmyhello.so hello.o

现在,应该会成功创建名为 libmyhello.so 的动态库文件。

说明:“PIC”命令行标记告诉gcc产生的代码不要包含对函数和变量具体内存位置的引用,这是因为现在还无法知道使用该消息代码的应用程序会将它连接到哪一段内存地址空间。这样编译出的hello.o可以被用于建立共享链接库。建立共享链接库只需要用gcc的”-shared”标记即可。

③在程序中使用动态库
在程序中使用动态库和使用静态库完全一样,也是在使用到这些公用函数的源程序中包含这些公用函数的原型声明,然后在用gcc命令生成目标文件时指明动态库名进行编译。
命令:gcc -o hello main.c -L. -lmyhello
运行:./hello

结果显示:./hello: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory
错误提示,找不到动态库文件libmyhello.so。程序在运行时,会在/usr/lib和/lib等目录中查找需要的动态库文件。若找到,则载入动态库,否则将提示类似上述错误而终止程序运行。

有多种方法可以解决。

(1)我们将文件 libmyhello.so复制到目录/usr/lib中,再试试。
命令:sudo mv libmyhello.so /usr/lib 
运行:./hello
成功!

结果截屏:
image

(2)既然连接器会搜寻LD_LIBRARY_PATH所指定的目录,那么我们可以将这个环境变量设置成当前目录:
命令:export LD_LIBRARY_PATH=`pwd`
运行:./hello
成功!
LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。

结果截屏:
image

3.使用下面的程序(或自己的程序),用gcc生成和使用动态库和静态库,写出具体步骤,给出结果截屏。

程序1:addsub.h文件
#ifndef ADDSUB_H
#define ADDSUB_H
	int add(int m,int n);
	int sub(int m,int n);
#endif

程序2:add.c文件
int add(int m,int n)
{
	return m+n;
}

程序3:sub.c文件
int sub(int m,int n)
{
	return m-n;
}

程序4:main.c文件
#include <stdio.h>
#include "addsub.h"
int main()
{
	int x,y;
	printf("Please enter two integers separated by a space:");
	scanf("%d%d",&x,&y);
	printf("%d+%d=%d\n",x,y,add(x,y));
	printf("%d-%d=%d\n",x,y,sub(x,y));
	return 0;
}

思路一:创建动态库:

程序1: 创建addsub.h

在命令行中输入以下命令,创建addsub.h文件:nano addsub.h

在编辑器中,将以下内容粘贴到addsub.h文件中:
#ifndef ADDSUB_H
#define ADDSUB_H
	int add(int m,int n);
	int sub(int m,int n);
#endif
按下 Ctrl + X,然后按 Y 保存并退出编辑器(如果需要你确定文件名按一下enter键)

程序2: 创建add.c

在命令行中输入以下命令,创建add.c文件:nano add.c

在编辑器中,将以下内容粘贴到add.c文件中:
int add(int m,int n)
{
	return m+n;
}
按下 Ctrl + X,然后按 Y 保存并退出编辑器(如果需要你确定文件名按一下enter键)

程序3: 创建sub.c

在命令行中输入以下命令,创建sub.c文件:nano sub.c

在编辑器中,将以下内容粘贴到sub.c文件中:
int sub(int m,int n)
{
	return m-n;
}
按下 Ctrl + X,然后按 Y 保存并退出编辑器(如果需要你确定文件名按一下enter键)

程序4: 创建main.c

在命令行中输入以下命令,创建main.c文件:nano main.c

在编辑器中,将以下内容粘贴到main.c文件中:
#include <stdio.h>
#include "addsub.h"
int main()
{
	int x,y;
	printf("Please enter two integers separated by a space:");
	scanf("%d%d",&x,&y);
	printf("%d+%d=%d\n",x,y,add(x,y));
	printf("%d-%d=%d\n",x,y,sub(x,y));
	return 0;
}
按下 Ctrl + X,然后按 Y 保存并退出编辑器(如果需要你确定文件名按一下enter键)

1.将给定的程序进行编译并创建目标文件:

命令:gcc -c add.c sub.c main.c

这将生成 add.o、sub.o 和 main.o 三个目标文件。
image

2.创建动态库文件 .so:

命令: gcc -shared -o libaddsub.so add.o sub.o

这将生成一个名为 libaddsub.so 的动态链接库文件。
image

3.编译程序并链接动态库:

命令: gcc -o main main.o -L. -laddsub

这将编译并链接 main.o,并指定 -L. 选项以告知编译器在当前目录中查找库文件,-laddsub 表示链接名为 libaddsub.so 的动态库。
image

4.运行程序:

命令: ./main

这将执行可执行文件 main,打印出加法和减法的结果。
image

思路二:创建静态库

1.将给定的程序进行编译并创建目标文件:

命令:gcc -c add.c sub.c main.c

2.创建静态库文件 .a:

命令: ar rcs libaddsub.a add.o sub.o

这将生成名为 libaddsub.a 的静态库文件。
image

3.编译程序并链接静态库:

命令: gcc -o main main.o -L. -laddsub

这将编译并链接 main.o,并指定 -L. 选项以告知编译器在当前目录中查找库文件,-laddsub 表示链接名为 libaddsub.a 的静态库。
image

4.运行程序:

命令: ./main

这将执行可执行文件 main,打印出加法和减法的结果。
image

完结,撒花!

posted on 2023-11-22 11:08  Cloudservice  阅读(1347)  评论(0编辑  收藏  举报