1.什麼是gcc
- gcc(GUN C Compile)編譯器的作者是Richard Stallman,也是GNU項目的奠基者
- 什麼是gcc?
gcc是GNU Compiler Collection的縮寫。最初是作爲C語言的編譯器(GNU C Compile),現在已經支持多種語言了,如C,C++,Java,Pascal,Ada,COBOL語言等 - gcc支持多種硬件平臺,甚至對Don Knuth設計的MMIX這類不常見的計算機都提供了完善的支持
2.gcc特點
- gcc是一個可移植的編譯器,支持多種硬件平臺
- gcc不僅僅是個本地編譯器,它還能跨平臺交叉編譯
- gcc有多種語言前端,用於解析不同的語言
- gcc是按模塊話設計的,可以加入新語言和新CPU架構的支持
- gcc是自由軟件
3.gcc編譯過程
- 預處理(Pre-Processing),編譯(Compiling),彙編(Assembing),鏈接(Linking)
(1)預處理:將頭文件,宏進行展開
(2)gcc其實是一個工具鏈,在編譯時,會調用其它的工具
(3)彙編:可重定位目標程序.o文件中程序的地址是從0開始的,正在要運行的程序其地址肯定不是從0開始的,要重新定位爲可以在內存中可以加載運行的程序,通過鏈接器將可重定位目標程序的代碼重新定位到內存中的某個地址
(4)鏈接器不僅有定位的功能,還會鏈接其它程序庫,也會被鏈接到可執行文件中
(5)可執行文件加載或者拷貝到內存,即可運行
4.gcc常用選項
選項名 | 作用 |
-o | 產生目標(.i,.s,.o,可執行文件等) |
-E | 只運行C預編譯器 |
-S | 告訴編譯器產生彙編語言文件後停止編譯,產生的彙編語言文件擴展名爲.s |
-c | 通知gcc取消鏈接步驟,即編譯源碼並在最後生成目標文件 |
-Wall | 使gcc對源文件的代碼有問題的地方發出警告 |
-Idir | 將dir目錄加入搜索頭文件的目錄路徑 |
-Ldir | 將dir目錄加入搜索庫的目錄路徑 |
-llib | 鏈接lib庫 |
-g | 在目標文件中嵌入調試信息,以便gdb之類的調試程序調試 |
- eg:01\hello.c
#include <stdio.h>
#define HELLOWORLD "hello world\n"
int main(void)
{
printf(HELLOWORLD);
return 0;
}
- 編譯過程解釋如下:
(1)預處理
預處理就是頭文件展開,宏展開的步驟
gcc -E hello.c -o hello.i
vi hello.c
(2)編譯
.s是一個彙編程序
gcc -S hello.i -o hello.s
vi hello.s
(3)彙編
hello.o文件是一個二進制文件
gcc -c hello.s -o hello.o
vi hello.o
gcc -c hello.c 可以顯示生成同名的.o文件,等價於下面的
gcc -c hello.c -o hello.o 編譯生成可重定位目標文件
(4)鏈接:不需要任何選項
gcc hello.s -o hello
./hello
- -Wall的使用
下面的eg如果不加-Wall選項,編譯器是不報任何錯誤的,但是得到的結果卻不是預期的
01\print.c
#include <stdio.h>
int main(void)
{
printf("Two plus two is %f", 4);
return 0;
}
下面的bad.c就是print.c
加上-Wall選項
5.gcc編譯多文件
- eg代碼如下:
===============01\hello_fn.h================
#ifndef _HELLO_FN_H
#define _HELLO_FN_H
void hello(const char* name);
#endif
===============01\hello_fn.c================
#include <stdio.h>
#include "hello_fn.h"
void hello(const char* name)
{
printf("hello %s!!!\n", name);
}
=====================01\main.c==================
#include "hello_fn.h"
int main(void)
{
hello("world");
return 0;
}
- 用法1:一次性編譯
hello_fn.h
hello_fn.c
main.c
一次性編譯
gcc hello_fn.c main.c -o newhello
- 用法2:獨立編譯
大型項目用的多,比如更新的main.c文件,則只需要編譯main.c生成重定位目標文件,最後執行鏈接,生成可執行文件
gcc -Wall -c main.c -o main.o
gcc -Wall -c hello_fn.c -o hello_fn.o
gcc -Wall main.o hello_fn.o -o newhello 鏈接生成可執行文件