实验4:UNIX gcc编译器的使用与编程环境

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

gcc –o hello_rd hello.c -rdynamic #生成可执行程序 hello_rd (2)C++版 helloworld.C(可参照(1)进行编译,搞清楚参数的意义及作用) #include <iostream.h> main (void) { cout << "Hello, World!" << endl; } 用户可以像使用 gcc 一样,使用 c++或 g++来编译它: g++ hello.C #生成可执行程序 a.out c++ –o hello hell.C #生成可执行程序 hello g++ –s -o Hello hello.C #生成删除符号表的可执行程序 Hello 也可以使用 gcc 并指定库文件来编译 c++程序: gcc –c hello.C #生成目标文件 hello.o gcc –o h hello.C –lstdc++ #指定标准 c++库,生成可执行程序 h 也参照标准 c 的编译方法以不同形式编译 c++程序和 gelloworld.C。 2)多模块组合开发与编译、静态库的构造与使用 设有 C 语言文件 f1.c,内容为: #include <stdio.h> f1(int arg) { printf("F1: you passed %d\n",arg); } 设有 C 语言文件 f2.c,内容为: #include <stdio.h> f2(char *arg) { printf("F2: you passed %s\n",arg); } 主函数所的模块为 m.c,内容为: #include <stdio.h> main() { f1(16); f2("Hello World!"); } 编译和连接过程: gcc –c f1.c f2.c // 生成 f1.o 和 f2.o gcc –S f1.c f2.c // 生成 f1.s 和 f2.s gcc –o mp m.c f1.c f2.c //生成 mp 构造自己的静态库 gcc –o f1.c f2.c //生成目标文件 f1.o, f2.o ar crv libmyl.a f1.o f2.o //生成库 libmyl.a
if(err){ fprintf(stderr,err); exit(2); } f2=dlsym(sfp,"f2"); //获取函数 f2 入口地址(指针) err=dlerror(); //检查是否成功 if(err){ fprintf(stderr,err); exit(3); } fprintf(stderr,"-----------begine-------------\n"); f2("Test String"); //调用函数 f2 f1(tmpi); //调用函数 f1 fprintf(stderr,"++++++++++++end+++++++++++++++\n"); dlclose(sfp); exit(0); } 4)Makefile 的编写与使用 (1)针对 2)的 Makefile 文件 a.Makefile 文件的构造 f: f1.o f2.o f3.o gcc -o f f1.o f2.o f3.o f1.o: f1.c gcc –c f1.c f2.o: f2.c gcc –c f2.c f3.o: f3.c gcc –c f3.c b.Makefile 的使用 make #生成默认(第一个)目标 make f #生成目标 f make f1.o #生成目标 f1.o (2)针对 3)的 Makefile 文件 a.动态库生成 Makefile so.mk all : libmy.so SRC = f1.c f2.c TGT = $(SRC:.c=.o) %.o : %.c gcc -c $< libmy.so : $(TGT) gcc -shared -o $@ $(TGT) clean: rm -f $(TGT) 使用方法: make -f so.mk make -f so.mk all //关闭共享库
sfp=dlopen(SO_FILE,RTLD_LAZY); //打开共享库 if(sfp==NULL){ fprintf(stderr,dlerror()); exit(1); } f1=dlsym(sfp,"f1"); err=dlerror(); //获取函数 f1 入口地址(指针) //检查是否成功
ranlib libmyl.a 使用自己的库 gcc –o mp m.c libmyl.a gcc –o mp m.o libmyl.a gcc –o mp m.c -L. –lmyl
[注] 静态库和共享库的共同点:
//为子函数建立内容表 // 使用库 libmyl.a // 使用库 libmyl.a 和 m.o // 在当前目录以默认方法使用库 myl
#定义 all 目标 #定义源文件 #定义目标文件 #定义目标文件生成规则 #目标文件生成命令 #定义共享库生成规则 #共享库生成命令 #定义清理目标 #清理目标目标措施
make -f so.mk install make -f so.mk uninstall make -f so.mk clean b.共享库使用 Makefile e all : mydy SRC = f3.c TGT = $(SRC:.c=.o) %.o : %.c gcc -c $< mydy: $(TGT) gcc -o $@ $(TGT) -ldl clean: rm -f $(TGT) 使用方法: make -f e make -f so.mk all 5)实验报告的内容与书写 以书面形式记录下你的每一步过程,包括输入、输出信息(有截图) ,遇到的问题和解决的 办法。
Hale Waihona Puke 3、实验方法与注意事项实验室内的实验环境与系统是共用设施, 请不要在系统内做对系统或对其他用户不安全 的事情。 要求每个同学登录后系统后, 要在自己的家目录内容以自己名字和学号, 创建一个子目 录(已有者可以不再创建) 。以后所有工作都要在自己的目录内进行。建议以后的实验都在 同台计算机上做,这样可以保持连续性。 1)由于是以 root 用户工作的,权力很大,请不要在系统内做对系统或对其他用户不 安全的事情。 2)要求每个同学登录后系统后,要在自己的家目录内容以自己(汉语拼音)名字,使用 mkdir 命令创建一个子目录。以后所有工作都要在自己的目录内进行。 3)认真编写实验报告并上传服务器。 用户要按通常实验要认真书写实验报告。
实验 4:UNIX gcc 编译器的使用与编程环境 1、实验目的
(1)掌握 gcc 的用法; (2)了解目标代码、库函数的使用; (3)掌握静态库和共享库的构造与使用; (4)掌握多模块和多语言联合开发方法; (5)掌握 make 命令和 Makefile 文件的使用。
2、实现设备
一台装有 Windows 操作系统和 Linux 机系统的微机或服务器。
3)多模块组合开发与编译、共享库的构造与使用 参考 2)中的 f1.c 和 f2.c,构造和使用自己的共享库 (1)构造可共享库 gcc -c f1.c f2.c //生成目标文件 gcc -shared -o libmy.so f1.o f2.o //由目标文件生成共享库 或 gcc -shared –o libmy.so –c f1.c f2.c //由源文件生成共享库 (2)使用共享库 //设以下程序的文件名为 f3.c,f1.c 和 f2.c 如前 #include <stdio.h> #include <dlfcn.h> #define SO_FILE "./libmy.so" //共享库 libmy.so 被限定在当前目录,也可放在标准位置,但要使用 ldd 和 ldconfig 处理 main() { void *sfp; char *err; int tmpi=16; int (*f1)(int ),(*f2)(char *); //定义函数指针
.a, .so 都是.o 目标文件的集合,这些目标文件中含有一些函数的定义(机器码),而这些函数将在连 接时会被最终的可执行文件用到。 两者的区别: 静态库.a : 当程序与静态库连接时,库中目标文件所含的所有将被程序使用的函数的机器码被 copy 到最终的可执行文件中. 静态库有个缺点: 占用磁盘和内存空间. 静态库会被添加到和它连接的每个程序 中, 而且这些程序运行时, 都会被加载到内存中. 无形中又多消耗了更多的内存空间. 共享库.so : 与共享库连接的可执行文件只包含它需要的函数的引用表,而不是所有的函数代码,只有 在程序执行时, 那些需要的函数代码才被拷贝到内存中, 这样就使可执行文件比较小, 节省磁盘空间(更进 一步,操作系统使用虚拟内存,使得一份共享库驻留在内存中被多个程序使用).共享库还有个优点: 若库 本身被更新, 不需要重新编译与它连接的源程序。
4、实验过程
1)helloworld (1)C 语言版 helloworld.c #include <stdio.h> main() { printf(”Hello World!\n”); } 编译及运行方法: (注意观察各编译参数的意义及作用, 最后通过命令 ls –l a.out hello* 来观察所生成文件的不同,为什么会这样?) gcc –c hello.c #生成目标文件 hello.o gcc –S hello.c #生成汇编程序 hello.s gcc hello.c #生成可执行程序 a.out gcc –o hello hello.c #生成可执行程序 hello gcc –s –o hello_s hello.c #生成汇编程序 hello.s gcc –o hello_st hello.c -static #生成可执行程序 hello_st gcc –o hello_sh hello.c -shared #生成可执行程序 hello_sh
相关文档
最新文档