標題: C項目的文件組織和GCC編譯步驟分解 [打印本頁]
作者: michaelchain 時間: 2021-8-26 11:41
標題: C項目的文件組織和GCC編譯步驟分解
本帖最后由 michaelchain 于 2021-8-26 11:45 編輯
C項目的文件組織和編譯C項目的代碼, 由頭文件(.h后綴)和C文件(.c后綴)組成
- C語言的函數和變量, 分聲明和定義兩個階段
- 頭文件和C文件是等價的, 相當于C文件的一部分, 其功能由人為劃分, 用于變量和函數的聲明, 頭文件也可以用于變量和函數的定義, 但是這屬于非標準用法, 一般不這么用
- 同一個編譯中, 函數在一處定義, 處處可用(除非使用static關鍵字)
- 在A.c中定義后, 在B.c中用extern聲明這個函數, 就可以調用
- 將A.c中的函數聲明提取到A.h, 在B.c中include A.h, 或者通過B.c include B.h, B.h include A.h, 都可以實現函數引用
- C的編譯, 是按文件編譯的, 每個C文件會編譯為一個目標文件
- 頭文件不單獨編譯, 與include這個頭文件的C文件, 在預編譯階段展開, 之后在C文件中編譯
- 編譯需要知道C文件的列表和頭文件的目錄列表
- 編譯會依次編譯C文件列表中的每個文件, 不管最終是否用到
C項目結構示例定義一個頭文件 inc.h,聲明兩個函數func1和func2, 將定義寫在func1.c和func2.c. 在main.c中通過main.h引用inc.h, 調用這些函數, 程序目錄結構如下
- ├── inc
- │ ├── func1.c
- │ ├── func2.c
- │ └── inc.h
- ├── main.c
- ├── main.h
- └── obj
復制代碼
main.c
- #include <stdio.h>
- #include "main.h"
- int main()
- {
- uint8_t a = 0x08;
- uint8_t b = func1(a);
- printf("%X", b);
- return 0;
- }
復制代碼
main.h- #ifndef MAIN_H
- #define MAIN_H
- #include "inc.h"
- #endif
復制代碼
inc.h
- #ifndef INC_H
- #define INC_H
- typedef unsigned char uint8_t;
- uint8_t func1(uint8_t a);
- uint8_t func2(uint8_t a);
- #endif
復制代碼
func1.c
- #include "inc.h"
- uint8_t func1(uint8_t a)
- {
- a = a << 1;
- return a;
- }
復制代碼
func2.c
- #include "inc.h"
- uint8_t func2(uint8_t a)
- {
- a = a >> 1;
- return a;
- }
復制代碼
gcc的編譯過程
gcc命令其實依次執行了四步操作
- 預處理(Preprocessing),
- 編譯(Compilation),
- 匯編(Assemble),
- 鏈接(Linking)
1.預處理(Preprocessing)預處理用于將所有的#include頭文件以及宏定義替換成其真正的內容,預處理之后得到的仍然是文本文件,但文件體積會大很多。gcc的預處理是預處理器cpp來完成的,你可以通過如下命令對 main.c進行預處理:
gcc -E -I./inc main.c -o obj/main.i# or$ cpp main.c -I./inc -o obj/main.i-E是讓編譯器在預處理之后就退出,不進行后續編譯過程; -I指定頭文件目錄, -o指定輸出文件名.
經過預處理之后代碼體積會大很多, main.c只有10行, 但是main.i有749行, 預處理之后的文件可以用文本編輯器查看
2.編譯(Compilation)這一步的編譯將經過預處理之后的程序轉換成特定匯編代碼的過程, 編譯的命令如下:
$ gcc -S -I./inc main.c -o obj/main.s-S讓編譯器在編譯之后停止. 這一步會生成程序的匯編代碼, 內容如下:
.file "main.c"
.text
.section .rodata
.LC0:
.string "%X"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
endbr64
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movb $8, -2(%rbp)
movzbl -2(%rbp), %eax
movl %eax, %edi
call func1@PLT
movb %al, -1(%rbp)
movzbl -1(%rbp), %eax
movl %eax, %esi
leaq .LC0(%rip), %rdi
movl $0, %eax
call printf@PLT
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0"
.section .note.GNU-stack,"",@progbits
.section .note.gnu.property,"a"
.align 8
.long 1f - 0f
.long 4f - 1f
.long 5
0:
.string "GNU"
1:
.align 8
.long 0xc0000002
.long 3f - 2f
2:
.long 0x3
3:
.align 8
4:
3.匯編(Assemble)
匯編過程將上一步的匯編代碼轉換成機器碼(machine code),這一步產生了二進制的目標文件, gcc匯編過程通過as命令完成
as obj/main.s -o obj/main.o# porgcc -c obj/main.s -o obj/main.o這一步需要給每一個源文件產生一個目標文件, 以便后面link
gcc -c -I./inc inc/func1.c -o obj/func1.ogcc -c -I./inc inc/func2.c -o obj/func2.o
4.鏈接(Linking)通過上面的步驟, 在obj目錄下已經有main.o, func1.o和func2.o這三個目標文件, 現在需要通過linker將這些目標文以及所需的庫文件(.so等)鏈接成最終的可執行文件(executable file)
命令如下
gcc -o obj/main obj/main.o obj/func1.o obj/func2.o這時候在obj目錄下就會生成可執行文件main
鏈接并不會忽略未使用的目標文件
上面的編譯產生的main文件大小為16824字節, 不管在main中是否調用了func1或者func2.
如果在link中去掉func2.o (因為main中未調用func2, 所以不會產生錯誤), 這樣產生的main文件為16760字節
gcc -o obj/main obj/main.o obj/func1.o如果需要減小尺寸, 可以使用 -fdata-sections -ffunction-sections -Wl --gc-sections -Os等參數優化. 例如
gcc -Os -fdata-sections -ffunction-sections test.cpp -o test -Wl,--gc-sections
頭文件, 靜態庫(.lib, .a) 和動態庫(.dll, .so)靜態庫 vs 動態庫庫文件就是已經預編譯好的目標文件, 只需要link到你的程序里就可以用了, 例如常見的方法 printf() and sqrt(). 庫文件有兩種類型: 靜態庫和動態庫(也叫共享庫).
靜態庫 在Linux下使用擴展名.a, 在Windows下使用擴展名.lib, 當link靜態庫時, 這些對象文件的機器碼會被復制到你的可執行文件中.
動態庫 在Linux下使用擴展每.so, 在Windows下使用擴展名.dll, 當你的程序link靜態庫時, 只會在你的程序可執行文件中添加一個表, 在運行你的程序之前, 操作系統會將這些外部方法的機器碼載入進來. 這種方式可以節約磁盤資源, 讓程序更小, 另外大多數操作系統也運行內存中的一份動態庫在多個運行的程序中共享. 動態庫升級時無需重新編譯執行程序.
GCC默認情況下以動態庫方式link. 要查看庫內容, 可以用命令nm filename
編譯中定位包含頭文件和庫文件 (-I, -L and -l)當編譯項目時, 編譯器需要頭文件的信息, linker需要庫文件解決外部依賴.
對于項目中include的頭文件, 編譯器會去搜索相應的路徑, 這些路徑通過 -Idir 參數 ( 或者環境變量 CPATH) 指定, 因為頭文件的文件名是已知的, 所以編譯器只需要知道路徑.
對于linker, 會去搜索庫路徑, 這個通過 -Ldir 參數 (大寫 'L' 后面是路徑) (或者環境變量 LIBRARY_PATH). 另外你需要指定庫名稱. 在Unix系統中, 庫文件 libxxx.a 通過參數 -lxxx 指定 (小寫字符 'l' 不帶lib前綴, 不帶.a擴展名). 在Windows下, 需要提供文件全名, 例如 -lxxx.lib. 路徑和文件名都需要指定.
默認的 Include-paths, Library-paths 和 Libraries可以通過cpp -v命令列出:
> cpp -v......#include "..." search starts here:#include <...> search starts here: /usr/lib/gcc/x86_64-pc-cygwin/6.4.0/include /usr/include /usr/lib/gcc/x86_64-pc-cygwin/6.4.0/../../../../lib/../include/w32api在編譯時, 加入-v參數開啟verbose mode, 可以了解系統中使用到的庫路徑(-L)以及庫明細(-l)
> gcc -v -o hello.exe hello.c......-L/usr/lib/gcc/x86_64-pc-cygwin/6.4.0-L/usr/x86_64-pc-cygwin/lib-L/usr/lib-L/lib-lgcc_s // libgcc_s.a-lgcc // libgcc.a-lcygwin // libcygwin.a-ladvapi32 // libadvapi32.a-lshell32 // libshell32.a-luser32 // libuser32.a-lkernel32 // libkernel32.aEclipse CDT 在 Eclipse CDT 中, 可以在項目上右鍵, 點擊project ⇒ Properties ⇒ C/C++ General ⇒ Paths and Symbols, 在標簽頁"Includes", "Library Paths" and "Libraries"下, 設置 include path, library paths 和 libraries.
GCC環境變量GCC 使用下列環境變量:
- PATH: 用于搜索可執行文件和運行時的動態鏈接庫(.dll, .so).
- CPATH: 用于搜索頭文件包含路徑. 優先級低于直接用-I<dir>指定的路徑. C_INCLUDE_PATH and CPLUS_INCLUDE_PATH可分別用于指定C和C++的頭文件路徑.
- LIBRARY_PATH: 用于搜索庫文件的路徑, 優先級低于用-L<dir>指定的路徑.
參考
| 歡迎光臨 (http://m.izizhuan.cn/bbs/) |
Powered by Discuz! X3.1 |
水蜜桃在线视频|
色婷婷在线视频|
亚洲精品国产精品自产a区红杏吧
亚洲精品国产精品乱码不99按摩
亚洲精品国产精品久久清纯直播
亚洲精品国产精品国自产在线
|
又黄又爽的网站|
国产成人福利网站|
亚洲国产视频一区二区|
中文av一区|
日本电影在线观看网站|
av在线免费播放网址|
久久国产精品99国产精|
伊人久久久久久久久久久|
亚洲免费观看在线视频|
最近中文视频在线|
91精品一区国产高清在线gif|
欧美三级黄网|
波多野结衣av在线|
免费激情小视频|
亚洲视频网站在线|
国产精品成人无码|
538任你躁在线精品视频网站|
成片免费观看|
久草视频免费在线|
无码人妻h动漫|
日本精品久久久久影院|
欧美日韩大陆在线|
国产mv日韩mv欧美|
国产真实有声精品录音|
黄色片免费在线|
偷窥自拍欧美色图|
成人免费毛片东京热|
gogo亚洲国模私拍人体|
精品久久蜜桃|
中文字幕亚洲二区|
亚洲狼人国产精品|
国产.欧美.日韩|
亚洲在线日韩|
国产精品一区二区三区www|
免费黄视频网站|
a级片在线播放|
欧美黄色一级生活片|
最新av网址在线观看|
日本欧美爱爱爱|
精品国产麻豆免费人成网站|
欧洲美女亚洲激情|
久久无码高潮喷水|
国产精品无码电影在线观看|
日韩最新中文字幕|
精品国产无码在线|
日本丰满少妇黄大片在线观看|
久草免费福利在线|
久久亚洲精品无码va白人极品|
激情六月丁香婷婷|
中文字幕乱码在线|
久久出品必属精品|
东方伊人免费在线观看|
国产不卡在线观看视频|
亚洲精品国产精品国自产网站|
在线观看成人毛片|
国产婷婷在线视频|
国产xxxx孕妇|
国产精品爱久久久久久久小说|
欧美人与动性xxxxx杂性|
综合欧美视频一区二区三区|
亚洲欧美综合图片|
五月天亚洲激情|
美日韩在线观看|
欧美三级理伦电影|
亚洲日本va午夜在线电影|
综合激情网...|
欧美成人明星100排名|
成人亚洲在线观看|
91社区在线观看播放|
91cn在线观看|
国产成人精品一区二三区在线观看
|
亚洲aa在线观看|
国产精品美女黄网|
四虎一区二区|
狠狠干视频网站|
亚洲一级片免费观看|
一区二区三区免费在线观看视频
|
欧美性xxxxxx少妇|
日韩精品一区二区三区视频在线观看
|
www.97av.com|
中文字幕第8页|
国产91色蝌蚪视频|
亚洲an天堂an在线观看|
免费在线观看黄色|
精品91福利视频|
无码日韩精品一区二区免费|
国产在视频线精品视频www666|
国产精品夜夜夜|
蜜桃久久av一区|
成人福利在线看|
国产欧美一区二区精品婷婷
|
一区二区三区在线视频免费观看|
色综合久久综合中文综合网|
91精品国产色综合久久久蜜香臀|
日韩av最新在线观看|
久久91亚洲精品中文字幕|
国产91色在线播放|
亚洲一区免费看|
日本三区在线观看|
无码人妻aⅴ一区二区三区|
黄色片中文字幕|
亚洲av成人无码久久精品老人|
国产精品不卡一区二区三区在线观看|
国产在线视频福利|
www国产精品|
国产精品99免费看|
粉嫩在线一区二区三区视频|
欧美日韩一区二区不卡|
深夜福利亚洲导航|
国产精品美女免费看|
久久av免费一区|
www.xxx麻豆|
免费网站在线高清观看|
中文字幕人成高视频|
国产福利在线看|
精品久久久网|
日韩欧美1区|
www.在线视频|
国产精品字幕|
日韩av网站免费在线|
成人丝袜高跟foot|
亚洲嫩草精品久久|
久久久国产精品视频|
亚洲字幕在线观看|
亚洲一二三不卡|
国产欧美一级片|
一级在线观看|
欧美少妇网站|
国产一区二区三区成人欧美日韩在线观看|
亚洲精品国产一区二区精华液|
色偷偷av亚洲男人的天堂|
日本免费高清一区二区|
国产日韩欧美久久|
天天色影综合网|
亚洲AV无码乱码国产精品牛牛
|
露出调教综合另类|
老妇喷水一区二区三区|
国产精品传媒在线|
日韩一区二区免费在线电影
|
国产亚洲欧美日韩美女|
国产精品久久久久久久久久久不卡
|
精品无码在线观看|
欧美人善zozσ性伦交|
婷婷av在线|
少妇精品久久久一区二区三区|
久久香蕉精品|
欧美色偷偷大香|
国产精品推荐精品|
91精品国自产在线|
老太做爰xxxx|
清纯唯美激情亚洲|
日本aⅴ免费视频一区二区三区|
亚洲18女电影在线观看|
中文字幕精品网|
欧美交换配乱吟粗大25p|
亚洲午夜18毛片在线看|
岛国爱情动作片在线|
欧美美女被草|
久久久精品人体av艺术|
亚洲国产精品电影在线观看|
91国产在线播放|
无限资源日本好片|
欧美一级淫片免费视频黄|
拍拍拍在线观看视频免费|
四虎影院成人在线观看|
午夜激情视频在线观看|
国产精品久久久免费|
精品免费国产二区三区|
999国产视频|
中文国语毛片高清视频|
狠狠干夜夜操|
国产三级精品三级在线观看国产|
国产成人av网站|
深夜福利国产精品|
久久九九国产视频|
国产第一页在线观看|
啊啊啊好爽视频|
99久久这里有精品|
国产成人精品免费看|
精品国产免费视频|
99热一区二区三区|
国产理论片在线观看|
免费a在线观看|
久久五月天小说|
一区二区三区欧美亚洲|
91丨九色丨国产在线|
在线黄色免费网站|
狠狠色噜噜狠狠|
亚洲激情播播|
亚洲欧美日韩国产手机在线|
欧美激情精品久久久久久变态
|
懂色一区二区三区av片|
色婷婷精品久久二区二区密|
青草视频.com|
97精品国产一区二区三区|
欧美日韩成人综合在线一区二区|
亚洲一区二区不卡视频|
国产高清不卡视频|
成人网ww555视频免费看|
成人欧美一区二区三区|
91超碰caoporn97人人|
免费在线观看的av网站|
在线视频在线视频7m国产|
亚洲国产aⅴ精品一区二区|
丰满岳妇乱一区二区三区|
5g影院天天爽成人免费下载|
久久久全国免费视频|
日本中文视频|
国产精品久久久亚洲一区|
在线观看久久久久久|
日本美女视频一区|
一本久久精品|
久久综合五月婷婷|
欧美日韩一级片网站|
国产精品成人久久电影|
91亚洲国产成人精品一区|
91网址在线观看|
久久亚洲影视婷婷|
日本午夜人人精品|
91在线播放观看|
裸体网站视频|
在线看的av网站|
成人免费视频播放|
91精品久久久久久久久久久久久久|
中文字幕第3页|
97色伦图片97色伦在线电影|
日本v片在线高清不卡在线观看|
久久久人成影片一区二区三区观看|
免费精品99久久国产综合精品应用|
免费h视频网站|
国产精品综合|
久久久久五月天|
日韩黄色一区二区|
乱子伦在线视频|
在线成人亚洲|
亚洲视频专区在线|
国产精品欧美激情在线观看|
桃乃木香奈和黑人aⅴ在线播放|
青青草这里只有精品|
午夜av电影一区|
国产精品自拍合集|
亚洲成年人电影网站|
www.久久|
日韩理论片网站|
亚洲成人第一|
国产精品久久久亚洲第一牛牛|
欧美国产专区|
亚洲图片在区色|
免费在线观看你懂的|
久播影院第一理论片|
久久国产精品区|
久久性爱视频网站|
国产人成免费视频|
99精品国自产在线|
一区二区中文字幕在线|
999日本视频|
久久精品无码人妻|
在线影院av|
琪琪一区二区三区|
久久成人综合视频|
永久免费看mv网站入口78|
国产卡一卡2卡三卡免费视频|
国产精品乱战久久久|
欧美日韩中文字幕在线视频|
成人在线看片|
久久久久亚洲视频|
亚洲美女炮图|
av一本久道久久综合久久鬼色|
亚洲一区av在线播放|
中文字幕国产免费|
h版电影在线播放视频网站
|
亚洲国产成人在线|
国语自产在线不卡|
亚洲高潮女人毛茸茸|
大陆一级毛片|
日韩精品电影在线观看|
久久久久久高潮国产精品视|
538精品视频|
天堂中文а√在线|
成人午夜视频免费看|
亚洲一区中文字幕|
97成人免费视频|
亚洲高清在线一区|
日韩欧美在线观看一区二区三区|
久章草在线视频|
成年人免费av|
久久视频国产|
国产一区二区黑人欧美xxxx|
给我免费观看片在线电影的|
毛片在线播放网址|
久久这里只有精品6|
你懂的视频在线一区二区|
亚洲熟妇av乱码在线观看|
免费在线国产视频|
91在线视频播放|
欧洲成人免费视频|
日本特黄特色aaa大片免费|
av在线中文|
国产麻豆成人精品|
91av在线播放|
亚洲自拍一区在线观看|
99综合久久|
日韩一区二区视频|
欧美成人精品一区二区综合免费|
色综合888|
捆绑紧缚一区二区三区视频|
国产精品一区二区久久国产|
北条麻妃一区二区三区在线观看|
欧美一区二区三区人|
国产日产精品一区二区三区的介绍|
а天堂中文最新一区二区三区|
中文字幕av日韩|
亚洲中文字幕一区二区|
激情综合自拍|
久久免费视频1|
国产剧情演绎av|
伊人色综合久久天天人手人婷|
中文字幕乱码在线人视频|
亚洲色图官网|
最近2019中文字幕mv免费看|
97精品人妻一区二区三区在线|
在线国产日韩|
欧美日韩无遮挡|
www.国产在线|
www国产成人免费观看视频 深夜成人网|
美日韩免费视频|
国产精品粉嫩av|
亚洲二区在线观看|
国产精欧美一区二区三区白种人|
性xxxx丰满孕妇xxxx另类|
国产日本欧洲亚洲|
免费高清一区二区三区|
黄上黄在线观看|
91精品婷婷国产综合久久性色
|
狠狠综合久久av一区二区蜜桃
|
美女三级福利视频|
国产精品人成在线观看免费|
亚洲精品美女在线观看|
免费在线观看黄色av|
成人精品影视|
日韩av片免费在线观看|
麻豆精品国产自产在线|
免费在线观看成人|
japanese在线播放|
麻豆tv入口在线看|
日韩精品视频在线播放|
97超碰资源站|
国产一区二区视频在线|
欧美中文娱乐网|
亚洲精华国产精华|
777xxx欧美|
波多野结衣电影在线播放|
首页国产欧美久久|
大伊香蕉精品视频在线|
暖暖在线中文免费日本|
自拍亚洲一区欧美另类|
www久久com|
久久噜噜亚洲综合|
扒开伸进免费视频|
日韩av网站在线免费观看|
国产精品国产三级国产专区53|
亚洲精华国产|
精品欧美aⅴ在线网站|
你懂的在线观看网站|
日韩中文av|
国产女人水真多18毛片18精品|
中文在线最新版天堂8|
欧美一级理论性理论a|
在线免费观看高清视频|
韩国视频一区二区|
久久久久免费看黄a片app|
a天堂在线资源|
日韩国产高清污视频在线观看|
国内毛片毛片毛片毛片|
99视频在线精品|
国产肉体xxxx裸体784大胆|
波多野结衣在线观看一区二区三区
|
狠狠操天天操夜夜操|
中文天堂在线一区|
中文字幕在线1|
欧美超碰在线|
日本高清视频免费在线观看|
综合另类专区|
久久精品电影网站|
国内精品麻豆|
精品日韩美女的视频高清|
国产熟妇一区二区三区四区|
国产精品18久久久久久久久久久久|
韩国视频一区二区三区|
在线女人免费视频|
国产精品久久久久久中文字
|
国产乱国产乱300精品|
又黄又色的网站|
中文字幕日韩一区二区不卡
|
自拍视频在线网|
久久视频中文字幕|
黄色毛片免费|