操作系统上机指导——计算机与信息科学系软件工程教研室Gedit编辑器操作系统上机指导——计算机与信息科学系软件工程教研室GCC=GNUCompilerCollection目前,GCC可以支持多种高级语言,如C、C++ADAObjectCJAVAFortranPASCAL编译器—gcc操作系统上机指导——计算机与信息科学系软件工程教研室GCC下的工具cpp—预处理器GNUC编译器在编译前自动使用cpp对用户程序进行预处理gcc—符合ISO等标准的C编译器g++—基本符合ISO标准的C++编译器gcj—GCC的java前端gnat—GCC的GNUADA95前端编译器—gcc操作系统上机指导——计算机与信息科学系软件工程教研室例://Hello.c#includestdio.hintmain(intargc,char**argv){printf(“Hello,linux!\n”);}编译:gcchello.c–ohello或gcc–ohellohello.c【理解】格式:gcc–o输出文件名源文件名o表示out(输出)运行:./hello【理解】./hello表示在当前目录下的hello编译器—gcc操作系统上机指导——计算机与信息科学系软件工程教研室GCC是GNU项目的编译组件之一gcc,cc,c++,g++,gcc和cc是一样的,c++和g++是一样的,一般c程序就用gcc编译,c++程序就用g++编译;gcc编译器能将C,C++源程序,汇编程序和目标程序编译链接成为可执行文件。编译器—gcc操作系统上机指导——计算机与信息科学系软件工程教研室GCC的版本$gcc–v查看gcc的版本,内核不同,可能gcc的版本不同GCC是一组编译工具的总称C编译器cc,ccl,ccplus,gccC++编译器c++,ccplus,g++源码预处理器cpp,cpp0库文件libgcc.a,libgcc_eh.a,libgcc_s.so编译器—gcc操作系统上机指导——计算机与信息科学系软件工程教研室GCC编译过程中的文件类型*.cC语言源代码文件*.a由目标文件构成的档案库文件*.C,*.cc,*.cxxC++源代码文件*.h程序所包含的头文件*.i已经预处理过的C源代码文件*.ii已经预处理过的C++源代码文件*.mObjective-C源代码文件*.o编译后的目标文件*.s汇编语言源代码文件*.S经过预编译的汇编语言源代码文件编译器—gcc操作系统上机指导——计算机与信息科学系软件工程教研室四个编译步骤1.预处理,生成.i的文件[预处理器cpp]2.将预处理后的文件不转换成汇编语言,生成文件.s[编译器egcs]3.有汇编变为目标代码(机器代码)生成.o的文件[汇编器as]4.连接目标代码,生成可执行程序[链接器ld]库依赖gcchello.c–I/home/include–ohello编译器—gcc操作系统上机指导——计算机与信息科学系软件工程教研室例:假设有两个源文件main.c和factorial.c,现在要编译生成一个计算阶乘的程序。/*程序清单main.c*/#includestdio.h#includestdlib.hintfactorial(intn);intmain(intargc,char**argv){intn;if(argc2){printf(Usage:%sn\n,argv[0]);return-1;}else{n=atoi(argv[1]);printf(Factorialof%dis%d.\n,n,factorial(n));}return0;}操作系统上机指导——计算机与信息科学系软件工程教研室/*程序清单factorial.c*/#includestdio.h#includestdlib.hintfactorial(intn){if(n=1)return1;elsereturnfactorial(n-1)*n;}操作系统上机指导——计算机与信息科学系软件工程教研室编译gccmain.cfactorial.c-ofac运行./fac5结果Factorialof5is120操作系统上机指导——计算机与信息科学系软件工程教研室关于头文件头文件的位置/usr/include:系统头文件/usr/local/include:本地头文件操作系统上机指导——计算机与信息科学系软件工程教研室关于头文件在Linux下,一个完整的C语言开发环境到少包括以下三个组成部分:函数库glibc(在/usr/lib和/lib目录中)编译器gcc系统头文件glibc_header(*.h)glibc是构成一个完整的C语言开发环境所必不可少的组成部分,也是Linux下C语言的主要函数库。glibc_header中包含了系统编译源代码所需要的声明文件,如果缺少系统头文件,很多用到系统功能的C程序将无法编译。(包含在/usr/include/及其子目录中)操作系统上机指导——计算机与信息科学系软件工程教研室关于头文件在标准C中有两种形式的头文件使用方式:#includeheadfile.h#include“headfile.h”区别:#includeheadfile.h型头文件搜索范围为默认位置/usr/include,#include“headfile.h”型头文件的搜索位置为当前目录,在Linux的GNUC中,若当前目标不存在headerfile.h,则也会到默认位置去搜索。操作系统上机指导——计算机与信息科学系软件工程教研室关于函数库函数库中的函数可以通过连接程序与应用程序进行连接,而不必在每次开发程序时都对这些通用的函数进行编译。不同类型的应用程序将会使用不同的函数库。如数学应用将使用数学库libm(/usr/lib/libm.a,/usr/lib/libm.so),标准的C库libc(/usr/lib/libc.a,/usr/lib/libc.so)。【注意】*.h只是对函数的声明(declaration),函数的定义是在具体的函数库中操作系统上机指导——计算机与信息科学系软件工程教研室所有的程序都将使用标准的C函数库libc,该库中包含了内存管理或输入输出操作的基本函数,这些库都存放在/usr/lib或/lib这些系统公用的目录中,系统中的任何用户都可以利用这些库。注:用户可以自己定义自己的函数库!关于函数库操作系统上机指导——计算机与信息科学系软件工程教研室静态库(*.a):代码在编译时就已连接到开发人员开发的应用程序中。静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库共享库(sharedobject,以*.so作为后缀):只是在程序开始运行时才载入,在编译时,只是简单地指定需要使用的库函数。动态库:是共享库的另一种变化形式,也是在程序运行时载入,使用的库函数不是在程序运行开始,而是在程序中的语句需要使用该函数时才载入。类似于windowsOS中的DLL文件。库的三种使用形式操作系统上机指导——计算机与信息科学系软件工程教研室共享库的生成方法动态库可以在程序运行期间释放动态库所占用的内存,腾出空间供其他程序使用。由于共享库和动态库并没有在程序中包括库函数的内容,只是包含了对库函数的引用,因此代码的规模比较小。生成用户共享库的方法:gcctest1.ctest2.ctest3.c-fPIC-shared-olibtest.so使用自定义的库进行编译、连接gcctest.c-L.libtest.so-otest操作系统上机指导——计算机与信息科学系软件工程教研室静态库的生成方法静态库的生成方法:Step1:编译而不连接gcctest1.c-c-otest1.ogcctest2.c-c-otest2.ogcctest3.c-c-otest3.oStep2:生成ar命令生成静态库arrcslibtest.atest1.otest2.otest3.oStep3:使用静态库编译和连接,生成可执行文件gcctest.c-L.libtest.a-otest操作系统上机指导——计算机与信息科学系软件工程教研室库文件名由前缀lib和库名以及后缀组成。根据库的类型不同,后缀名也不一样。共享库名的格式:库的名称.so.主版本号.次版本号静态库名的格式:库的名称.a【例如】libm.so.5数学共享库的标识字符为m,版本号为5libm.a静态数字库libc.a为标准C库库文件名操作系统上机指导——计算机与信息科学系软件工程教研室/lib系统必备共享库/usr/lib标准共享库和静态库/usr/share兼容性函数库/usr/X11R6/libX11R6的函数库/usr/local/lib本地函数库函数库存放的标准目录操作系统上机指导——计算机与信息科学系软件工程教研室gcc[options][filenames]-c:只激活预处理,编译,和汇编,也就是他只把程序做成obj文件。eg:gcc-chello.c//生成.o的obj文件-S:只激活预处理和编译,就是指把文件编译成为汇编代码。eg:gcc-Shello.c//生成.s的汇编代码-E:只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面。eg:gcc-Ehello.cpianoapan.txt编译器—gcc操作系统上机指导——计算机与信息科学系软件工程教研室-o:制定目标名称,缺省的时候,gcc编译出来的文件是a.out。eg:gcc-ohello.exehello.cgcc-ohello.asm-Shello.c-g:表示我们要求编译器在编译的时候提供我们以后对程序进行调试的信息。-ggdb:将尽可能的生成gdb的可以使用的调试信息。编译器—gcc操作系统上机指导——计算机与信息科学系软件工程教研室-includefile:包含某个代码,简单来说,就是便以某个文件,需要另一个文件的时候,就可以用它设定,功能就相当于在代码中使用includefilenameeg:gcchello.c-include/root/pianopan.h-Idir:在你使用#include“file”的时候,gcc/g++会先在当前目录查找你所制定的头文件,如果没有找到,他回到缺省的头文件目录找,如果使用-I制定了目录,他会先在你所制定的目录查找,然后再按常规的顺序去找,对于#includefile,gcc/g++会到-I制定的目录查找,查找不到,然后将到系统的缺省的头文件目录查找。编译器—gcc操作系统上机指导——计算机与信息科学系软件工程教研室-Ldir:制定编译的时候,搜索库的路径。比如你自己的库,可以用它制定目录,不然编译器将只在标准库的目录找。这个dir就是目录的名称。-O0/O1/O2/O3:编译器的优化选项的4个级别,O0表示没有优化,O1为缺省值,O3优化级别最高-static:禁止使用动态库,所以,编译出来的东西,一般都很大,也不需要什么动态连接库,就可以运行.-share:尽量使用动态库,所以生成文件比较小,但是需要系统由动态库.编译器—gcc操作系统上机指导——计算机与信息科学系软件工程教研室-l参数和-L参数-l参数就是用来指定程序要链接的库,-l参数紧接着就是库名,那么库名跟真正的库文件名有什么关系呢?就拿数学库来说,它的库名是m,它的库文件名是libm.so,很容易看出,把库文件名的头lib和尾.so去掉就是库名了。编译器—gcc操作系统上机指导——计算机与信息科学系软件工程教研室-include和-I参数-include用来包含头文件,但一般情况下包含头文件都在源码里用#includexxxxxx实现,-include参数很少用。-I参数是用来指定头文件目录,/usr/include目录一般是不用指定的,gcc知道去那里找,但