gcc是什么,干嘛的
gcc是Linux下最常用的C语言编译器,它是GNU项目中符合ANSI C标准编译器,能够编译C语言,C++语言编写的程序。它不仅功能强大,而且使用简单灵活。他可以支持不同的硬件平台,常见的有Inter x86/ ARM 等几十种体系结构。它可以运行中不同的操作系统,Linux、Solaris、Windows等。它既支持宿主开发,也支持交叉编译。
gcc怎么用
编译过程
预处理(-E)–.i[中间文件]–>编译(-S)–.s[汇编文件]–>汇编(-c)–.o[二进制机器码]–>链接(二进制可执行文件)
gcc 常用选项
-c 只编译,不链接 .生成.o文件 【通常用于编译不包含主程序的子程序文件】
-o 指定文件名
-g 产生调试器gdb所必需的符号信息 【要对源代码调试,就要加入这个选项】
-O 对程序进行优化编译、链接
-O2 更好地优化编译、链接
-Wall 输出警告信息
-w 关闭警告信息
-D 宏定义
gcc头文件或库的搜索路径的设定
对所有用户有效修改/etc/profile文件
对个人有效则修改~/.bashrc文件
在PATH中找到可执行文件程序的路径。
export PATH =$PATH:$HOME/bin
(可一次指定多个搜索路径,”:”用于分隔它们)
gcc找到头文件的路径
C_INCLUDE_PATH=/usr/include/libxml2:/MyLib
export C_INCLUDE_PATH
g++找到头文件的路径
CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/usr/include/libxml2:/MyLib
export CPLUS_INCLUDE_PATH
找到动态链接库的路径
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/MyLib
export LD_LIBRARY_PATH
找到静态库的路径
LIBRARY_PATH=$LIBRARY_PATH:/MyLib
export LIBRARY_PATH
添加头文件搜索路径
gcc foo.c -I /home/xiaowp/include -o foo
添加动态库搜索路径
gcc foo.c -L /home/xiaowp/lib -lfoo -o foo
添加静态库搜索路径
gcc foo.c -L /home/xiaowp/lib -static -lfoo -o foo
库文件安装
sudo apt-cache search 库文件名
sudo apt-get install 下载搜索到的,后缀是-dev的那个包就可以了。
或者
①进入/usr/local/cppunit/lib,把找不到的动态链接库【libcppunit.so.1.12…】copy到根目录的/lib下。
②编辑自己个人目录下的配置文件.bashrc。通过修改LD_LIBRARY_PATH解决。
LD_LIBRARY_PATH=/usr/local/cppunit/lib:LD_LIBRARY_PATH
gcc中C语言包含头文件和查找库文件的方法
- #include <> gcc在系统预设文件中查找 /usr/include
- #include”” gcc 在当前目录下查找头文件【对于小项目头文件可以直接放在该文件夹内】
- -I dirname 将名为dirname的目录加入程序头文件目录列表中 (在预处理阶段使用的选项)【对于大项目,头文件往往放在指定的文件夹内】
那么arm-linux-gcc与gcc 有什么不同呢
通过对比通过gcc工具链 和 arm-linux-gcc工具链产生出来的可执行文件
file executable-file 可以看出前者是在x86 PC机的Linux系统下可运行的程序,后者是在ARM 平台的嵌入式Linux运行的程序。
所谓的arm-linux-gcc交叉工具链,指的是我们在PC的Linux系统下来开发ARM嵌入式开发板上嵌入式Linux的程序的一个工具集。
所谓的交叉开发
用功能强大的宿主机(PC)来进行开发
然后再把程序传输到目标板运行
怎么使用arm-linux-gcc交叉工具链
- 交叉编译器 arm-linux-gcc
使用方法跟gcc相同,只是寻找同文件的路径与gcc不同 - 交叉链接器 arm-linux-ld
arm-linux-ld -T led.lds -o led.elf led.o //(多个.o文件要都链接就都放在这)
- 交叉ELF文件工具 arm-linux-readelf
arm-linux-readelf -a led.elf //查看elf文件 大小端
arm-linux-readelf -d led //查看所必须的库文件
- 交叉反汇编器 arm-linux-objdump
arm-linux-objdump -D -S hello > dump //查看汇编代码
//在编译的时候可以加上调试信息 arm-linux-gcc -g hello.c -o hello 这样查看汇编代码更方便
- 交叉 文件格式转换 arm-linux-objcopy
//无论是直接arm-linux-gcc直接产生,还是arm-linux-ld产生可可执行文件,其实都是elf格式的可执行文件,还不能直接在ARM处理器上运行(你看到的可运行,是在嵌入式Linux上,其实是嵌入式Linux系统的elf解析成二进制后运行的)
arm-linux-objcopy -O binary led.elf led.bin //-O指明二进制binary, 输入 输出文件
- -
- -L dirname 将名为dirname的目录加到程序的库文件的搜索列表【在连接过程中使用的参数】
- -lname 指示编译器,在链接时,装载名为libanme.a的函数库,该函数库位于系统预设的目录(/usr/lib)或者-L选项指定的目录下。
如gcc server.c -o server -L pthread (线程函数的库){库是事先编写好的代码,经过编译后可以直接调用的文件。库充分体现了软件重用的思想,对于一些常用的功能,可以编写一系列的函数,并按功能放在库文件中。系统默认提供了很多库,如数学函数库,我们也可以编写自己的吗库文件}
gcc的报错类型
- syntex error C语言语法错误
- 头文件/库文件错误
头文件名错误、头文件所在目录名错误、错误的使用<> “” - 未定义的符号 undefine symbol
变量/函数未定义、未定义的符号是一个库函数里的
make的使用和Makefile的编写
大型项目中,整个系统被分为若干单元,每个模块完成一个相对独立的功能,各模块相互作用,构成一个完整的系统。对于这样的软件系统,是不可能使用一条或几条gcc命令就可以编译生成可执行文件的,而且模块通常都要进过反复的修改,如果每次修改都由人工输入命令来完成工作,这样既效率低下,又容易出错。
Makefile基本构成
目标文件列表 分隔符 依赖文件列表 [; 命令]
main :main.o module1.o module2.o
gcc main.o module1.o module2.o -o main
main.o : main.c head1.h head2.h
gcc -c main.c
module1.o :module1.c head1.h
gcc -c module1.c
module2.o :module2.c head2.h
gcc -c module1.c
#This is a makefile
make //执行make
make 首先寻找当前目录下的Makefile文件,找到之后,
在当前目录下寻找第1行中的目标文件main,发现没有,去寻找main的依赖文件,发现也没有,然后就跳过第2行的编译命令。
定位到第3行,寻找目标文件main.o,发现没有,于是寻找依赖文件main.c head1.h head2.h,都被找到,于是执行第4行的gcc 命令。
定位到第5行,没有module1.o ,但是有module1.c head1.h,执行第6行
定位到第7行,没有module2.o ,但是有module2.c head2.h,执行第8行
定位到第9行,发现是注释,不予理睬,之后make回溯到第一行,此时依赖都有了,执行第二条编译命令,最后生成目标文件main.
一个完整的Makefile由5部分构成:显式规则、隐含规则、使用变量、文件指示和注释。