Linux系统编程-2.ppt
7/23/2022Linux及编程2GNU CCvGCC的特性的特性面向多种语言面向多种语言 C,C+,Objective C,Pascal,Ada,Fortran能够对编译过程有更多的控制能够对编译过程有更多的控制可以控制嵌入在二进制执行文件中调试代码的数量和类型可以控制嵌入在二进制执行文件中调试代码的数量和类型可以优化执行代码可以优化执行代码有有30多个警告和多个警告和3个一般警告级个一般警告级可以进行交叉编译可以进行交叉编译对对C和和C+进行了大量扩展进行了大量扩展7/23/2022Linux及编程3GNU CCvC程序的编译过程程序的编译过程源代码源代码*.c预处理器(预处理器(cpp)编译器编译器(cc) 目标代码目标代码*.o链接器(链接器(ld)可执行文件可执行文件头文件头文件*.h库代码库代码引导代码引导代码7/23/2022Linux及编程4GNU CCv实例实例7/23/2022Linux及编程5GNU CCv实例实例在预处理后停止编译过程在预处理后停止编译过程7/23/2022Linux及编程6GNU CCv实例实例从指定的步骤开始编译从指定的步骤开始编译只编译不链接只编译不链接7/23/2022Linux及编程7GNU CCv对文件扩展名的解释对文件扩展名的解释For any given input file, the file name surfix determines what kind of compilation is done.file.cC source code which must be preprocessed.file.iC source code which should not be preprocessed.file.iiC+ source code which should not be preprocessed.file.hC or C+ header le to be turned into a precompiled header.file.cc, file.cp, file.cxx, file.cpp, file.CPP, file.c+, file.C C+ source code which must be preprocessed. Note that in .cxx, the last two letters must both be literally x. Likewise, .C refers to a literal capital C.file.hh, file.HC+ header file to be turned into a precompiled header.file.sAssembler code.file.SAssembler code which must be preprocessed.7/23/2022Linux及编程8GNU CCv常用的命令行选项常用的命令行选项-x languageSpecify explicitly the language for the following input files (rather than letting the compiler choose a default based on the file name suffix). This option applies to all following input files until the next -x option. Possible values for language are: vcc-headercpp-outputvc+c+-headerc+-cpp-outputvassemblerassembler-with-cpp-x noneTurn off any specification of a language, so that subsequent files are handled according to their file name suffixes (as they are if -x has not been used at all).7/23/2022Linux及编程9GNU CCv常用的命令行选项常用的命令行选项-x和下述几个选项结合实现分步编译和下述几个选项结合实现分步编译 -cCompile or assemble the source files, but do not link. -SStop after the stage of compilation proper; do not assemble. -EStop after the preprocessing stage; do not run the compiler proper. -o filePlace output in file file. vIf -o is not specified, the default is to put an executable le in a.out, the object file for source.suffix in source.o, its assembler file in source.s, and all preprocessed C source on standard output.-vPrint (on standard error output) the commands executed to run the stages of compilation. -#Like -v except the commands are not executed and all command arguments are quoted. This is useful for shell scripts to capture the driver-generated command lines.Note that some combinations (for example, -x cpp-output -E) instruct gcc to do nothing at all.7/23/2022Linux及编程10GNU CCv常用的命令行选项常用的命令行选项下述选项控制下述选项控制C(C+)的的“方言方言” -ansiIn C mode, support all ISO C89 programs. In C+ mode, remove GNU extensions that conflict with ISO C+.-std=Determine the language standard.vc89,iso9899:1990ISO C90 (same as -ansi).viso9899:199409ISO C90 as modied in amendment 1.vc99,c9x,iso9899:1999,iso9899:199xISO C99. vgnu89Default, ISO C90 plus GNU extensions (including some C99 features).vgnu99,gnu9xISO C99 plus GNU extensions. When ISO C99 is fully implemented in GCC, this will become the default. The name gnu9x is deprecated.vc+98The 1998 ISO C+ standard plus amendments.vgnu+98The same as -std=c+98 plus GNU extensions. This is the default for C+ code.7/23/2022Linux及编程11GNU CCv常用的命令行选项常用的命令行选项警告信息警告信息 Can request many specific warnings with options beginning W.-fsyntax-onlyCheck the code for syntax errors, but dont do anything beyond that.-pedanticIssue all the warnings demanded by strict ISO C and ISO C.-pedantic-errorsLike -pedantic, except that errors are produced rather than warnings.-wInhibit all warning messages.-Wchar-subscriptsWarn if an array subscript has type char.-WcommentWarn whenever 注释嵌套注释嵌套.-WformatCheck calls to printf and scanf, etc., to make sure that the arguments supplied have types appropriate to the format string specified, and that the conversions specified in the format string make sense.7/23/2022Linux及编程12GNU CCv常用的命令行选项常用的命令行选项警告信息警告信息-WnonnullEnable warning about passing a null pointer for arguments marked as requiring a non-null value by the nonnull function attribute.-Wimplicit-intWarn when a declaration does not specify a type.-Wimplicit-function-declaration-Werror-implicit-function-declarationGive a warning (or error) whenever a function is used before being declared.-WmainWarn if the type of main is suspicious.-Wmissing-bracesWarn if an aggregate or union initializer is not fully bracketed. For example, int a22 = 0, 1, 2, 3 .-WparenthesesWarn if parentheses are omitted in certain contexts, such as when there is an assignment in a context where a truth value is expected. E.g. if(a=2) .7/23/2022Linux及编程13GNU CCv常用的命令行选项常用的命令行选项警告信息警告信息-Wreturn-typeWarn whenever a function is defined with a return-type that defaults to int.-WswitchWarn whenever a switch statement has an index of enumeral type and lacks a case for one or more of the named codes of that enumeration.-Wswitch-defaultWarn whenever a switch statement does not have a default case.-Wunused-functionWarn whenever a static function is declared but not defined or a non-inline static function is unused.-Wunused-labelWarn whenever a label is declared but not used.-Wunused-parameterWarn whenever a function parameter is unused aside from its declaration.-Wunused-variableWarn whenever a local variable or non-constant static variable is unused aside from its declaration.-WunusedAll the above -Wunused options combined.7/23/2022Linux及编程14GNU CCv常用的命令行选项常用的命令行选项警告信息警告信息-WuninitializedWarn if an automatic variable is used without rist being initialized or if a variable may be clobbered by a set jmp call.-WallAll of the above -W options combined.-Wsystem-headersPrint warning messages for constructs found in system header files.-Wfloat-equalWarn if floating point values are used in equality comparisons.-Wundef Warn if an undefined identifier is evaluated in an #if directive.-Wunreachable-codeWarn if the compiler detects that code will never be executed.-Winline Warn if a function can not be inlined and it was declared as inline.-WerrorMake all warnings into errors.7/23/2022Linux及编程15GNU CCv常用的命令行选项常用的命令行选项警告信息的实例警告信息的实例有问题的源程序有问题的源程序7/23/2022Linux及编程16GNU CCv常用的命令行选项常用的命令行选项警告信息的实例警告信息的实例默认的编译过程默认的编译过程7/23/2022Linux及编程17GNU CCv常用的命令行选项常用的命令行选项警告信息的实例警告信息的实例找出找出printf格式的编译过程格式的编译过程7/23/2022Linux及编程18GNU CCv常用的命令行选项常用的命令行选项警告信息的实例警告信息的实例找出找出比较使用了附值和注释嵌套比较使用了附值和注释嵌套的编译过程的编译过程7/23/2022Linux及编程19GNU CCv常用的命令行选项常用的命令行选项警告信息的实例警告信息的实例找出找出变量为初始化变量为初始化的编译过程的编译过程7/23/2022Linux及编程20GNU CCv常用的命令行选项常用的命令行选项调试选项调试选项-gProduce debugging information in the operating systems native format (stabs, COFF, XCOFF, or DWARF). GDB can work with this debugging information.-ggdbProduce debugging information for use by GDB.-ftime-reportMakes the compiler print some statistics about the time consumed by each pass when it finishes.-fmem-reportMakes the compiler print some statistics about permanent memory allocation when it finishes.7/23/2022Linux及编程21GNU CCv常用的命令行选项常用的命令行选项调试选项调试选项-O-O1Optimizing compilation takes somewhat more time, and a lot more memory for a large function. With -O, the compiler tries to reduce code size and execution time, without performing any optimizations that take a great deal of compilation time.-O2Optimize even more.-O3Optimize yet more.-O0Do not optimize. This is the default.-OsOptimize for size.7/23/2022Linux及编程22GNU CCv常用的命令行选项常用的命令行选项控制预处理的选项控制预处理的选项-D name Predefine name as a macro, with definition 1.-D name=definitionPredefine name as a macro.-U name Cancel any previous definition of name, either built in or provided with a -D option.-undefDo not predefine any system-specific or GCC-specific macros. The standard predefined macros remain defined.7/23/2022Linux及编程23GNU CCv常用的命令行选项常用的命令行选项控制文件搜索路径控制文件搜索路径-I dirAdd the directory dir to the list of directories to be searched for header files. Directories named by -I are searched before the standard system include directories.-llibrary-L librarySearch the library named library (liblibrary.a) when linking.7/23/2022Linux及编程24GNU CCv常用的命令行选项常用的命令行选项体系结构相关体系结构相关-mtune=cpu-typeTune to cpu-type everything applicable about the generated code, except for the ABI and the set of available instructions. The choices for cpu-type are i386, i486, i586, i686, pentium, pentium-mmx, pentiumpro, pentium2, pentium3, pentium4, k6, k6-2, k6-3, athlon, athlon-tbird, athlon-4, athlon-xp, athlon-mp, winchip-c6, winchip2, k8, c3 and c3-2.-march=cpu-type Generate instructions for the machine type cpu-type.-mieee-fp-mno-ieee-fpControl whether or not the compiler uses IEEE floating point comparisons.-m32-m64Generate code for a 32-bit or 64-bit environment.7/23/2022Linux及编程25GNU make 管理项目管理项目 最主要也是最基本的功能:通过最主要也是最基本的功能:通过makefile文件来描述源程序之间的文件来描述源程序之间的相互关系并自动维护编译工作。相互关系并自动维护编译工作。 vGCC make 的特性的特性让用户将包含大量甚至特殊编译选项的长而复杂的编译命令只写一让用户将包含大量甚至特殊编译选项的长而复杂的编译命令只写一次,而多次使用次,而多次使用减少重复编译所需要的时间减少重复编译所需要的时间通过构建依赖信息数据库,可以让通过构建依赖信息数据库,可以让make在每次编译前检查是否可以在每次编译前检查是否可以找到所有需要的文件找到所有需要的文件可以让用户建立一个稳定的编译环境可以让用户建立一个稳定的编译环境可以让编译过程自动执行(通过可以让编译过程自动执行(通过shell script或或cron调用)调用)7/23/2022Linux及编程26GNU make 管理项目管理项目编译中,通过编译中,通过makefile文件来描述源程序之间的相互关系并自动维护编文件来描述源程序之间的相互关系并自动维护编译工作译工作vmakefile是一个文本形式的数据库文件是一个文本形式的数据库文件包含一些包含一些规则规则告诉告诉make做什么、怎么做和在什么条件做做什么、怎么做和在什么条件做GNU make被调用后顺序查找名为被调用后顺序查找名为GNUmakefile、makefile或或Makefile(习惯上用得最多)的文件(习惯上用得最多)的文件不仅可以用于编译,而且可以用于安装、删除等等不仅可以用于编译,而且可以用于安装、删除等等也可以指定其他文件起到也可以指定其他文件起到makefile的作用的作用7/23/2022Linux及编程27GNU make 管理项目管理项目makefile文件有一些文件有一些规则规则组成组成v规则规则 Rule规则的组成规则的组成vTarget:make最终需要创建的东西最终需要创建的东西vDependency list:编译目标需要的其他文件:编译目标需要的其他文件vCommand list:从依赖体创建出目标体所需执行的命令列表:从依赖体创建出目标体所需执行的命令列表Target通常都是程序,但也可是文本文件、手册页等通常都是程序,但也可是文本文件、手册页等Command可以是编译命令,也可以是可以是编译命令,也可以是shell命令命令语法:语法:target : dependency dependency commandTab7/23/2022Linux及编程28GNU make 管理项目管理项目v例子例子/* * helper.h - Header for helper.c */void msg(void);/* * helper.c - Helper code for howdy.c */#include #include helper.hvoid msg(void)printf(This message sent from Jupiter.n);7/23/2022Linux及编程29GNU make 管理项目管理项目v例子例子/* * hello.c - Canonical Hello, World! program */#include #include helper.hint main(void)printf(Hello, Linux programming world!n);msg();return 0;7/23/2022Linux及编程30GNU make 管理项目管理项目v例子例子# Sample Makefile for makehowdy: howdy.o helper.o helper.hgcc howdy.o helper.o -o howdyhelper.o: helper.c helper.hgcc -c helper.chowdy.o: howdy.cgcc -c howdy.chello: hello.cgcc hello.c -o helloall: howdy helloclean:rm howdy hello *.o默默认认目目标标体,体,make要要创创建建的的文文件件三个依赖体三个依赖体命令命令避免编译器调用未声明的函数产生出错信息避免编译器调用未声明的函数产生出错信息怎样生成单个目标怎样生成单个目标笼统规则笼统规则伪目标伪目标,没有依赖体,因此认为目标体是最新,没有依赖体,因此认为目标体是最新的,不会被自动执行的,不会被自动执行注释注释7/23/2022Linux及编程31GNU make 管理项目管理项目v例子例子笼统规则笼统规则判断无修改判断无修改无依赖体无依赖体7/23/2022Linux及编程32GNU make 管理项目管理项目v例子例子生成单个目标生成单个目标生成单个目标生成单个目标生成单个目标生成单个目标生成多个目标生成多个目标7/23/2022Linux及编程33GNU make 管理项目管理项目v例子例子# Sample2 Makefile for makehowdy: howdy.o helper.o helper.hgcc howdy.o helper.o -o howdyhelper.o: helper.c helper.hgcc -c helper.chowdy.o: howdy.cgcc -c howdy.chello: hello.cgcc hello.c -o helloall: howdy hello.PHONY: cleanclean:rm howdy hello *.o不检查是否存在有文件名和依赖体中的一个名字相匹配的不检查是否存在有文件名和依赖体中的一个名字相匹配的文件,而是直接执行与之相关的命令。文件,而是直接执行与之相关的命令。7/23/2022Linux及编程34GNU make 管理项目管理项目v例子例子检查到存在有文件名和目标体的名字相匹配的文件,又检查到存在有文件名和目标体的名字相匹配的文件,又无依赖体,故不执行与之相关的命令。无依赖体,故不执行与之相关的命令。修改修改Makefile如前如前slide。不检查是否存在有文件名和依赖体中的一个名字相匹配的不检查是否存在有文件名和依赖体中的一个名字相匹配的文件,而是直接执行与之相关的命令。文件,而是直接执行与之相关的命令。7/23/2022Linux及编程35GNU make 管理项目管理项目v例子例子7/23/2022Linux及编程36GNU make 管理项目管理项目为了简化编辑和维护,允许在为了简化编辑和维护,允许在makefile创建和使用变量创建和使用变量v变量变量一个名字(像是一个名字(像是C语言中的宏),代表一个文本字符串(变量的值)。语言中的宏),代表一个文本字符串(变量的值)。引用变量的地方,变量会被它的值所取代引用变量的地方,变量会被它的值所取代严格的文本替换严格的文本替换变量名是不包括变量名是不包括“:”、“#”、“=”、前置空白和尾空白的任何字符、前置空白和尾空白的任何字符串串变量名大小写敏感变量名大小写敏感定义定义vVARNAME=some_text 引用引用v$(VARNAME)7/23/2022Linux及编程37GNU make 管理项目管理项目v变量使用例子变量使用例子1objects = program.o foo.o utils.oprogram : $(objects)cc -o program $(objects)$(objects) : defs.hv变量使用例子变量使用例子2foo = c prog.o : prog.$(foo) $(foo) $(foo) -$(foo) prog.$(foo) 7/23/2022Linux及编程38GNU make 管理项目管理项目v两种变量定义两种变量定义递归展开变量递归展开变量#Makefile3foo = $(bar) bar = $(ugh) ugh = Huh? all:;echo $(foo) 简单展开变量简单展开变量x := fooy := $(x) barx := later就等价于:就等价于:y := foo barx := later7/23/2022Linux及编程39GNU make 管理项目管理项目v自动变量自动变量Make自动用特定的、熟知的值替换自动用特定的、熟知的值替换$表示规则的目标文件名。表示规则的目标文件名。$%当规则的目标文件是一个静态库文件时,代表静态库的一个成员名。当规则的目标文件是一个静态库文件时,代表静态库的一个成员名。如果目标不是静态库文件,其值为空。如果目标不是静态库文件,其值为空。$规则的第一个依赖文件名。规则的第一个依赖文件名。$?所有比目标文件更新的依赖文件列表,空格分割。如果目标是静态库所有比目标文件更新的依赖文件列表,空格分割。如果目标是静态库文件名,代表的是库成员(文件名,代表的是库成员(.o文件)。文件)。$规则的所有依赖文件列表,使用空格分隔。规则的所有依赖文件列表,使用空格分隔。$+类似类似“$”,但是它保留了依赖文件中重复出现的文件。,但是它保留了依赖文件中重复出现的文件。$(D)表示目标文件的目录部分(不包括斜杠)。表示目标文件的目录部分(不包括斜杠)。$(F)目标文件的完整文件名中除目录以外的部分(实际文件名)。目标文件的完整文件名中除目录以外的部分(实际文件名)。7/23/2022Linux及编程40GNU make 管理项目管理项目v隐含隐含(预定义预定义)变量变量用于定义程序名或给这些程序传递标志和参数用于定义程序名或给这些程序传递标志和参数AR函数库打包程序,可创建静态库函数库打包程序,可创建静态库.a文档。默认是文档。默认是“ar”。AS汇编程序。默认是汇编程序。默认是“as”。CCC编译程序。默认是编译程序。默认是“cc”。CXXC+编译程序。默认是编译程序。默认是“g+”。CPPC程序的预处理器(输出是标准输出设备)。默认是程序的预处理器(输出是标准输出设备)。默认是“$(CC) -E”。RM删除命令。默认是删除命令。默认是“rm -f”ARFLAGS执行执行“AR”命令的命令行参数。默认值是命令的命令行参数。默认值是“rv”。ASFLAGS执行汇编语器执行汇编语器“AS”的命令行参数的命令行参数(明确指定明确指定“.s”或或“.S”文件文件时时)CFLAGS执行执行“CC”编译器的命令行参数(编译编译器的命令行参数(编译.c源文件的选项)。源文件的选项)。CXXFLAGS执行执行“g+”编译器的命令行参数(编译编译器的命令行参数(编译.cc源文件的选项)。源文件的选项)。CPPFLAGS执行执行C预处理器预处理器“cc -E”的命令行参数(的命令行参数(C 和和 Fortran 编译器编译器会用到)。会用到)。LDFLAGS链接器(如:链接器(如:“ld”)参数。)参数。7/23/2022Linux及编程41GNU make 管理项目管理项目v隐式隐式(预定义预定义)规则规则为为make提供了重建一类目标文件通用方法,不需要在提供了重建一类目标文件通用方法,不需要在Makefile中明确地中明确地给出重建特定目标文件所需要的细节描述。给出重建特定目标文件所需要的细节描述。vmake对对C文件的编译过程是由文件的编译过程是由.c源文件编译生成源文件编译生成.o目标文件。当目标文件。当Makefile中出中出现一个现一个.o文件目标时,文件目标时,make会使用这个通用的方式将后缀为会使用这个通用的方式将后缀为.c的文件编译称的文件编译称为目标的为目标的.o文件。文件。vE.g.OBJS = editor.o screen.o keyboard.oeditor: $(OBJS)cc o editor $(OBJS).PHONY: cleanclean:rm editor $(OBJS)v只要目标文件名中除后缀以外其它部分相同,只要目标文件名中除后缀以外其它部分相同,make都能够使用若干个隐含规都能够使用若干个隐含规则来最终产生这个目标文件(当然最原始的那个文件必须存在)。则来最终产生这个目标文件(当然最原始的那个文件必须存在)。vE.g. 可以在可以在Makefile中这样来实现一个规则:中这样来实现一个规则:“foo : foo.h”,只要在当前目,只要在当前目录下存在录下存在“foo.c”这个文件,就可以生成这个文件,就可以生成“foo”可执行文件。可执行文件。7/23/2022Linux及编程42GNU make 管理项目管理项目v模式规则模式规则在模式规则中,目标文件是一个带有模式字符在模式规则中,目标文件是一个带有模式字符“%”的文件,使用模式来的文件,使用模式来匹配目标文件。匹配目标文件。文件名中的模式字符文件名中的模式字符“%”可以匹配任何非空字符串,除模式字符以外的可以匹配任何非空字符串,除模式字符以外的部分要求一致。部分要求一致。例如:例如:“%.c”匹配所有以匹配所有以“.c”结尾的文件(匹配的文件结尾的文件(匹配的文件名长度最少为名长度最少为3个字母。个字母。E.g.%.o : %.c$(CC) -c $(CFLAGS) $(CPPFLAGS) $ -o $v此规则描述了一个此规则描述了一个.o文件如何由对应的文件如何由对应的.c文件创建。文件创建。v规则的命令行中使用了自动化变量规则的命令行中使用了自动化变量“$”和和“$”,其中自动化变量,其中自动化变量“$”代代表规则的依赖体,表规则的依赖体,“$”代表规则的目标。代表规则的目标。v此规则在执行时,命令行中的自动化变量将根据实际的目标和依赖文件取对应此规则在执行时,命令行中的自动化变量将根据实际的目标和依赖文件取对应值。值。7/23/2022Linux及编程43GNU make 管理项目管理项目vmake出错信息出错信息FOO Error NNFOO signal descriptionv这类错误并不是这类错误并不是make的真正错误。它表示的真正错误。它表示make检测到检测到make所调用的作为执所调用的作为执行命令的程序返回一个非零状态行命令的程序返回一个非零状态missing separator. Stop.missing separator (did you mean TAB instead of 8 spaces?). Stop.v不可识别的命令行,不可识别的命令行,make在读取在读取Makefile过程中不能解析其中包含的内容。过程中不能解析其中包含的内容。commands commence before first target. Stop.missing rule before commands. Stop.vMakefile可能是以命令行开始:以可能是以命令行开始:以Tab字符开始,但不是一个合法的命令行字符开始,但不是一个合法的命令行(例如,一个变量的赋值)。命令行必须和规则一一对应。(例如,一个变量的赋值)。命令行必须和规则一一对应。No