资源预览内容
第1页 / 共88页
第2页 / 共88页
第3页 / 共88页
第4页 / 共88页
第5页 / 共88页
第6页 / 共88页
第7页 / 共88页
第8页 / 共88页
第9页 / 共88页
第10页 / 共88页
亲,该文档总共88页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
嵌入式Linux GCC培训主讲老师: 欧阳坚GCC是什么? GCC: GNU Compiler Collection; GCC支持多种硬件平台和操作系统,能编译多种语言 (C, C+, Java, Ada95, Objective C, .etc); GCC与G+的关系: GCC用于编译多种语言编写的程序,主要是C; G+用于编译C+程序,以GCC为基础,编译过程 中加入了C+的支持库,参数与GCC基本一致; 可以利用GCC编译C+程序,但是需要在参数中加 入引用的C+库,比如libstdc+ (如gcc -o out lstdc+ main.cc)。可执行程序的生成过程 预处理(Preprocessing):分析各种预处理命令 ,如#define, #include, #if等; 编译(Compilation): 根据输入文件产生汇编语言 的程序; 汇编(Assembly): 将汇编语言输入,产生扩展 名为.o的目标文件; 链接(Linking):以.o目标文件,库文件作为输入 ,生成可执行文件;源程序文件 (.h, .c, .cc, .etc)经预处理的文件 (.i, .ii)汇编语言文件 (.s)目标文件 (.o)可执行程序 (.out)GCC支持的文件类型 C文件. cC源代码 .hC头文件 C+文件 file.hh, file.hC+头文件 file.C, file.cc, file.cxx等C+源文件 预处理后的文件 file.i预处理后的C源文件 file.ii预处理后的C+源文件 编译后的文件 .o目标代码 (obj) .s汇编代码文件 file.a目标文件库GCC编译选项 命令行:gcc options infile -E不生成文件,只输出预处理结果(输出终端) -S只预处理和编译,把文件编译成为汇编代码 greet.s -c预处理,编译和汇编,生成.o的obj文件 ( greet.o ) -o file输出名为file的可执行文件名 (缺省为a.out) -O -O2优化编译 -g: 产生可用于调试的输出 -Wall提示更多警告信息 -Wstrict-prototypes如果函数的声明或定义没有指出 参 数类型,编译器就发出警告. -Wl,option 将option作为选项传递给linker, option 逗号分 割, 如:-Wl,-soname,libmymath.so.1与库和路径相关选项 -I dir 在dir这个目录寻找被include的文件 -L dir 在dir这个目录寻找被-l的库 -l name 链接库文件名为libname.a或libname.so的库 -fpic或-fPIC 产生位置无关的目标代码,以构造共 享库(shared library) -static 禁止与共享库链接,若没有,则优先 选择共享库链接 -shared 产生共享库,在创建共享函数库时使用示例与宏相关的选项 -Dmacro: 相当于在源程序中使用 #define macro 1 -Dmacro=value -Umacro: 取消宏的定义3. GCC编译过程3.1 GCC编译过程典型的编译过程test.c 预处理 test.i 编译 test.s 汇编test.o 连接 test $ cat test.c (查看程序源代码)#include int main(int argc, char *argv) printf(“hello worldn“);return 0; $ gcc o test test.c (编译连接程序) $ ./test (执行test程序)3.2 预处理预编译命令: $ gcc -o test.i -E test.c 或者 $ cpp -o test.i test.c 这里cpp不是值c plus plus,而是the C Preprocessor) 执行结果: 生成预处理后的文件test.i, 该文件包含 了test.c需要的所有的类型和函数申明。 原理:读取c源程序,对伪指令和特殊符号进行处理 。包括宏,条件编译,包含的头文件,以及一些 特殊符号。基本上是一个替换的过程。Hello.c#include int main(void) printf(“hellon”); 预处理命令 gcc E hello.c gcc E hello.c o hello.i注释这一行看看预处理的结果 注意#include的作用和用途-E表示做预处理 -o 表示预处理的输出存于 hello.i文件中,而不是屏幕上#define用法#include #define AA 100 int main(void) AABBprintf(“hellon”); 预处理命令 gcc E hello.c DBB=hello gcc E hello.c DBB=“printf(”hello”);” gcc E hello.c DBB (等效于-DBB=1)注释这一行看看预处理的结果-D表示在命令行中传入宏定义 -DBB=后面是一个宏的定义, 可以加双引号。#define带参数#include #define AA(a,b) a = b int main(void) AA(int a, 1);BB;printf(“hellon”); 预处理命令 gcc E hello.c DBB=hello gcc E hello.c DBB=“printf(”hello”);”注释这一行看看预处理的结果-D表示在命令行中传入宏定义 -DBB=后面是一个宏的定义, 可以加双引号。展开就成了:int a = 1; AA宏带两个参数 #ifdef #if defined #if !defined #ifndef #elif defined #elif !defined #else #if #elif #endif -E D”AA=100”#define带参数#include #ifdef AA aa #elif defined BB bb #elif defined CC cc #else other #endif int main(void) printf(“hellon”); #ifdef AA 等效于 #if defined AA 表示当定义了宏AA表示除此之外的情况表示否则定义了宏CC的情况gcc E hello.c DAA=1aa int main(void) printf(“hellon”); gcc E hello.c DBB=1bb int main(void) printf(“hellon”); gcc E hello.c DCC=1cc int main(void) printf(“hellon”); gcc E hello.cother int main(void) printf(“hellon”); #if使用#define带参数#include #if AA aa #elif BB bb #elif CC cc #else other #endif int main(void) printf(“hellon”); #if AA 表示AA非零的情况 也就是AA除了0其它数字都为真表示除此之外的情况#elif BB 表示BB非零的情况 #elif表示否则如果gcc E hello.c DAA=1aa int main(void) printf(“hellon”); gcc E hello.c DAA=0 other int main(void) printf(“hellon”); gcc E hello.c DBB=1bb int main(void) printf(“hellon”); gcc E hello.c DBB=0 other int main(void) printf(“hellon”); gcc E hello.c DCC=1cc int main(void) printf(“hellon”); gcc E hello.c DCC=0 other int main(void) printf(“hellon”); gcc E hello.cother int main(void) printf(“hellon”); #的用法 在函数式宏定义中, #运算符用于创建字符串,#运算符后面应 该跟一个形参(中间可以有空格或Tab), 例如: #define STR(s) # s char *p = STR(helloworld) 结果变成: char *p = “helloworld”#的用法 在宏定义中可以用#运算符把前后两个预处理 Token连接成一个预处理Token,和#运算符不同 ,#运算符不仅限于函数式宏定义,变量式宏定 义也可以用。例如: #define FOO(a) foo#a int a = FOO(bar); int b = FOO(); 预处理之后变成: int a = foobar; int b = foo;预处理头文件xxx.h #ifndef HEADER_FILENAME #define HEADER_FILENAME /* body of header */ #endif 当xxx.h被多次包含的时候。有三个头文件和一个C文件 common.h file2.h file3.h main.ccommon.h#ifndef _COMMON_H_ #define _COMMON_H_ static int test(void) printf(“hellon”); #endif如果没有写上红色部分的 ,是什么情况。file1.h file1.h文件内容如下 #include “common.h” file2.h文件内容如下 #include “common.h”main.c main.c内容如下 #include #include “file1.h” #include “file2.h” int main(void) test(); gcc o main main.c#include 和” ”区别 #include #include “common.h”常用的#debug宏定义 int main() printf(“here 1n”); printf(“here 2n”); printf(“here 3n”); 开发阶段太多printf 如何在开发阶段 加入printf,在程序 发布的时候去掉 printf呢常用的#debug宏定义 int main() debug(“here 1n”); debug(“here 2n”); d
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号