日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Gcc编译链接及常用选项总结

發布時間:2025/3/15 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Gcc编译链接及常用选项总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


轉載文章:http://www.franktly.com

前言


GNU CC(簡稱Gcc)是GNU項目中符合ANSI C標準的編譯系統,能夠編譯用C、C++和Object- C等語言編寫的程序。Gcc不僅功能強大,而且可以編譯如C、C++、Object C、Java等多種語言,而且Gcc又是一個交叉平臺編譯器,它能夠在當前CPU平臺上為多種不同體系結構的硬件平臺開發軟件。本章中的示例均采用Gcc版本為4.8.2。

Gcc編譯鏈接流程


Gcc編譯鏈接流程分為四個步驟:

  • 預處理(Pre-Processsing)
  • 編譯(Compiling)
  • 匯編(Assembling)
  • 鏈接(Linking)
  • Gcc指令的一般格式為:

    gcc [option1] compile-files [option2] object-files

    其中目標文件可缺省,Gcc默認生成的可執行文件命名為:編譯文件名.out

    下面以簡單的hello world程序為例說明Gcc編譯的四個過程:

    123456 #include <stdio.h>void main(int argc, char* argv[]){ printf("hello world"); return;}

    預處理過程

    option1?為-E,生成的目標文件為.i(c)或.ii(c++)后綴的經過預處理的編譯輸入文件,Gcc指令為:

    tly@ubuntu ~> gcc -E test.c -o test.i

    生成的預編譯文件內容為:

    1234567891011121314151617181920212223242526 # 1 "test.c"# 1 "<command-line>"# 1 "/usr/include/stdc-predef.h" 1 3 4# 1 "<command-line>" 2# 1 "test.c"# 1 "/usr/include/stdio.h" 1 3 4# 27 "/usr/include/stdio.h" 3 4# 1 "/usr/include/features.h" 1 3 4# 374 "/usr/include/features.h" 3 4# 1 "/usr/include/i386-linux-gnu/sys/cdefs.h" 1 3 4... 省略...extern char *ctermid (char *__s) __attribute__ ((__nothrow__ , __leaf__));# 913 "/usr/include/stdio.h" 3 4extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));# 943 "/usr/include/stdio.h" 3 4# 2 "test.c" 2void main(int argc, char* argv[]){printf("hello world");return;}

    Gcc預處理過程把<stdio.h>的內容插入到hello.i文件中了

    編譯

    option1?為-S,生成的目標文件為.s或.S后綴的經過編譯但是沒有匯編過的匯編文件,Gcc編譯過程首先要檢查代碼的規范性、是否有語法錯誤等,以確定代碼的實際要做的工作,在檢查無誤后,Gcc把代碼翻譯成匯編語言Gcc指令為:

    tly@ubuntu ~> gcc -S test.i -o test.s

    生成的編譯之后的匯編文件內容為:

    123456789101112131415161718192021222324252627282930 .file "test.c" .section .rodata.LC0: .string "hello world" .text .globl main .type main, @functionmain:.LFB0: .cfi_startprocpushl %ebp .cfi_def_cfa_offset 8 .cfi_offset 5, -8movl %esp, %ebp .cfi_def_cfa_register 5andl $-16, %espsubl $16, %espmovl $.LC0, (%esp) call printf nop leave .cfi_restore 5 .cfi_def_cfa 4, 4 ret .cfi_endproc.LFE0: .size main, .-main .ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2" .section .note.GNU-stack,"",@progbits~

    Gcc編譯過程已經將其轉化為匯編語言了

    匯編

    option1?為-c,生成的目標文件為以.o為后綴的二進制目標代碼文件,Gcc指令為:

    tly@ubuntu ~> gcc -c test.s -o test.o

    生成的匯編之后的目標文件內容為:

    123 ^?ELF^A^A^A^@^@^@^@^@^@^@^@^@^A^@^C^@^A^@^@^@^@^@^@^@^@^@^@^@^X^A^@^@^@^@^@^@4^@^@^@^@^@(^@^M^@^@U<89>?<83>?e<83>ì^P?^D$^@^@^@^@èü???<90>é?hello world^@^@GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2^@^@^@^@^T^@^@^@^@^@^@^@^AzR^@^A|^H^A^[^L^D^D<88>^A^@^@^\^@^@^@^\^@^@^@^@^@^@^@^X^@^@^@^@A^N^H<85>^BB^M^ET?^L^D^D^@^@^@.symtab^@.strtab^@.shstrtab^@.rel.text^@.data^@.bss^@.rodata^@.comment^@.note.GNU-stack^@.rel.eh_frame^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^_^@^@^@^A^@^@^@^F^@^@^@^@^@^@^@4^@^@^@^X^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@^[^@^@^@ ^@^@^@^@^@^@^@^@^@^@^@?^C^@^@^P^@^@^@^K^@^@^@^A^@^@^@^D^@^@^@^H^@^@^@%^@^@^@^A^@^@^@^C^@^@^@^@^@^@^@L^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@+^@^@^@^H^@^@^@^C^@^@^@^@^@^@^@L^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@0^@^@^@^A^@^@^@^B^@^@^@^@^@^@^@L^@^@^@^L^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@8^@^@^@^A^@^@^@0^@^@^@^@^@^@^@X^@^@^@%^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^A^@^@^@A^@^@^@^A^@^@^@^@^@^@^@^@^@^@^@}^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@U^@^@^@^A^@^@^@^B^@^@^@^@^@^@^@<80>^@^@^@8^@^@^@^@^@^@^@^@^@^@^@^D^@^@^@^@^@^@^@Q^@^@^@ ^@^@^@^@^@^@^@^@^@^@^@?^C^@^@^H^@^@^@^K^@^@^@^H^@^@^@^D^@^@^@^H^@^@^@^Q^@^@^@^C^@^@^@^@^@^@^@^@^@^@^@?^@^@^@_^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@^A^@^@^@^B^@^@^@^@^@^@^@^@^@^@^@ ^C^@^@°^@^@^@^L^@^@^@ ^@^@^@^D^@^@^@^P^@^@^@ ^@^@^@^C^@^@^@^@^@^@^@^@^@^@^@D^C^@^@^T^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^A^@^@^@^@^@^@^@^@^@^@^@^D^@??^@^@^@^@^@^@^@^@^@^@^@^@^C^@^A^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^C^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^D^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^E^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^G^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^H^@^@^@^@^@^@^@^@^@^@^@^@^@^C^@^F^@^H^@^@^@^@^@^@^@^X^@^@^@^R^@^A^@^M^@^@^@^@^@^@^@^@^@^@^@^P^@^@^@^@test.c^@main^@printf^@^L^@^@^@^A^E^@^@^Q^@^@^@^B^@^@ ^@^@^@^B^B^@^@

    Gcc匯編成的.o目標文件是亂碼,不過可以通過nm命令查看其符號表:

    tly@ubuntu ~> nm test.o 00000000 T mainU printf

    鏈接

    在成功編譯之后,就進入了鏈接階段,這個hello world小程序的鏈接過程主要是查找包含的stdio.h頭文件的printf()函數的實現(因為stdio.h頭文件只包含函數聲明),這個函數實現是在libc.so.6的庫文件中。在沒有特別指定時,Gcc會到系統默認的搜索路徑/usr/lib下進行查找,也就是鏈接到libc.so.6庫函數中去,這樣就能實現函數printf()了,而這也就是鏈接的作用。

    函數庫一般分為靜態庫動態庫兩種。
    靜態庫:是指編譯鏈接時,把庫文件的代碼全部加入到可執行文件中,因此生成的文件比較大,但在運行時也就不再需要庫文件了。其后綴名一般為.a(linux)或.lib(windows)。
    動態庫: 與之相反,在編譯鏈接時并沒有把庫文件的代碼加入到可執行文件中,而是在程序執行時由運行時鏈接文件加載庫,這樣可以節省系統的開銷。動態庫一般為.so(linux)或.dll(windows),如前面所述的libc.so.6就是動態庫。
    Gcc在編譯時默認使用動態庫

    當然,也可以一次性使用-c選項,直接生成目標文件test.o,Gcc指令為:

    tly@ubuntu ~> gcc -c test.c -o test.o

    完成了鏈接之后,Gcc就可以生成可執行文件test,Gcc指令為:

    tly@ubuntu ~> gcc test.o -o test

    運行該可執行文件test:

    tly@ubuntu ~> ./test hello world?

    Gcc編譯選項分析

    Gcc有超過100個的可用選項,一般主要包括以下五種類型選項:

  • 總體選項
  • 告警和出錯選項
  • 優化選項
  • 體系結構相關選項
  • 總體選項


    選項名 選項意義
    -E 只是編譯不匯編,生成匯編代碼.s
    -S 只進行預編譯生成.i,不做其他處理
    -c 只是編譯不鏈接,生成目標文件.o
    -g 在可執行程序中包含標準調試信息
    -o file 把輸出文件輸出到file里
    -v 打印出編譯器內部編譯各過程的命令行信息和編譯器的版本
    -I dir 在頭文件的搜索路徑列表中添加dir目錄
    -L dir 在庫文件的搜索路徑列表中添加dir目錄
    -static 鏈接靜態庫
    -llibrary 鏈接名為library的庫文件庫

    對于-I dir選項可在頭文件的搜索路徑列表中添加dir目錄。由于Linux中頭文件都默認放到了/usr/include/目錄下,因此,當用戶希望添加放置在其他位置的頭文件時,就可以通過-I dir選項來指定(-L dir類似),這樣,Gcc就會到相應的位置查找對應的目錄
    <>表示在標準路徑中搜索頭文件,“ ”表示在本目錄中搜索,如果把自定義的頭文件#include<my.h>改為#include “my.h”,就不需要加上“-I”選項了
    -I dir和-L dir都只是指定了路徑,而沒有指定文件,因此不能在路徑中包含文件名

    對于-llibrary選項,省去了前綴lib,它實際上是指示Gcc去連接庫文件liblibrary.so。由于在Linux下的庫文件命名時有一個規定:必須以lib三個字母開頭。因此在用-l選項指定鏈接的庫文件名時可以省去lib三個字母。也就是說Gcc在對-llibrary進行處理時,會自動去鏈接名為liblibrary.so的文件

    告警和出錯選項


    選項名 選項意義
    -ansi 支持符合ANSI標準的C程序
    -pedantic 允許發出ANSI C標準所列的全部警告信息
    -pedantic-error 允許發出ANSI C標準所列的全部錯誤信息
    -w 關閉所有告警
    -Wall 允許發出Gcc提供的所有有用的報警信息

    修改上述的helloworld測試程序為:

    1234567 #include <stdio.h>void main(int argc, char* argv[]){ long long tmp; // 增加非ANSI-C類型long long 未使用的臨時變量tmp printf("hello world"); return 0; // 返回錯誤類型int}

    1.默認無告警和出錯選項情況:

    tly@ubuntu ~> gcc -c test.c -o test.o test.c: In function ‘main’: test.c:6:3: warning: ‘return’ with a value, in function returning void [enabled by default]return 0;^

    只識別了main的錯誤返回類型int

    2.增加-ansi選項情況:

    tly@ubuntu ~> gcc -c test.c -o test.o -ansi test.c: In function ‘main’: test.c:6:3: warning: ‘return’ with a value, in function returning void [enabled by default]return 0;^

    只識別了main的錯誤返回類型int

    3.增加-pedantic選項情況:

    tly@ubuntu ~> gcc -c test.c -o test.o -pedantic test.c:2:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]void main(int argc, char* argv[])^ test.c: In function ‘main’: test.c:4:8: warning: ISO C90 does not support ‘long long’ [-Wlong-long]long long tmp;^ test.c:6:3: warning: ‘return’ with a value, in function returning void [enabled by default]return 0;^

    識別了main的錯誤返回類型int 和 long long 非 ISO C90 支持類型

    4.增加-pedantic-errors選項情況:

    tly@ubuntu ~> gcc -c test.c -o test.o -pedantic-errors test.c:2:6: error: return type of ‘main’ is not ‘int’ [-Wmain]void main(int argc, char* argv[])^ test.c: In function ‘main’: test.c:4:8: error: ISO C90 does not support ‘long long’ [-Wlong-long]long long tmp;^ test.c:6:3: error: ‘return’ with a value, in function returning voidreturn 0;^

    識別了main的錯誤返回類型int 和 long long 非 ISO C90 支持類型

    5.增加-w選項情況:

    tly@ubuntu ~> gcc -c test.c -o test.o -w

    屏蔽了告警和出錯信息

    6.增加-Wall選項情況:

    tly@ubuntu ~> gcc -c test.c -o test.o -Wall test.c:2:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]void main(int argc, char* argv[])^ test.c: In function ‘main’: test.c:6:3: warning: ‘return’ with a value, in function returning void [enabled by default]return 0;^ test.c:4:13: warning: unused variable ‘tmp’ [-Wunused-variable]long long tmp;^

    識別了main的錯誤返回類型int 和臨時變量tmp未使用的告警信息

    優化選項


    選項名 選項意義
    -On n是一個代表優化級別的整數,典型的范圍是從0變化到2或3

    不同的優化級別對應不同的優化處理工作。
    -O 提供基礎級別的優化
    -O2 提供更加高級的代碼優化,會占用更長的編譯時間
    -O3 提供最高級的代碼優化
    進行調試的時候,最好關閉編譯優化,否則程序自動優化,執行的步驟可能有變化

    體系結構相關選項


    選項名 選項意義
    -mcpu=type 對不同的CPU使用相應的CPU指令。可選擇的有i386、i486、pentium等
    -mieee-fp 使用IEEE標準進行浮點數的比較
    -mno-ieee-fp 不使用IEEE標準進行浮點數的比較
    -msoft-float 輸出包含浮點庫調用的目標代碼
    -mshort 把int類型作為16位處理,相當于short int
    -mrtd 將函數參數個數固定的函數用ret NUM返回,節省調用函數的一條指令

    福利答謝大家! 感謝您閱讀本篇文章,對此特別發放一個無門檻的現金紅包,打開支付寶掃碼領取,可以領到錢的哦!



    總結

    以上是生活随笔為你收集整理的Gcc编译链接及常用选项总结的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 91网站观看| 天天操好逼 | 双性娇喘浑圆奶水h男男漫画 | 三级黄毛片| 美女野外找人搭讪啪啪 | 美女av网址| 色婷婷av国产精品 | 欧美综合另类 | 久草中文在线视频 | 91小宝寻花一区二区三区 | 摸一摸操一操 | 国产欧美大片 | 天天干狠狠干 | 日韩有码中文字幕在线观看 | 91亚洲在线| 亚洲精品国产成人无码 | 98久久久 | 欧美三级午夜理伦三级老人 | 快色视频在线观看 | 91美女片黄在线观看游戏 | 97狠狠操 | 五月天婷婷在线播放 | 国产精品久久久久久久免费大片 | 天天看片天天爽 | 黄色片xxx| 亚洲国产99 | 男女啪啪网站 | 深夜福利1000| 青草福利在线 | www.夜夜爽 | 亚洲精品美女网站 | 性史性dvd影片农村毛片 | 日本综合色 | 久久综合伊人77777麻豆最新章节 | 美女露胸露尿口 | 一区二区三区视频在线 | 日韩精品在线观看一区 | www.天堂av.com | 黄色录像一级大片 | jizz视频在线观看 | 波多野吉衣在线观看视频 | 日本在线视频免费观看 | 天天干天天操 | 国产精品一区在线观看你懂的 | 69视频网站| 激情网站在线观看 | 欧美99久久精品乱码影视 | 天天碰天天碰 | 亚洲风情亚aⅴ在线发布 | www.国产区 | 三级a做爰全过程 | 人妻少妇一区二区 | 视频在线观看一区二区三区 | 国产一区二区三区影视 | 久久久久久av无码免费网站 | 蘑菇av | 亲嘴扒胸摸屁股免费视频日本网站 | 国产成人无码网站 | 深夜福利免费在线观看 | 无码人妻aⅴ一区二区三区 国产高清一区二区三区四区 | 18在线观看免费入口 | 91在线观看免费高清完整版在线观看 | 国产高清精品在线 | 一本色道久久综合亚洲精品图片 | 国产日韩第一页 | 青草视频污| 亚洲欧美日韩一区二区三区在线观看 | 五月丁香啪啪 | 久久高清一区 | 中文字幕人妻一区二区在线视频 | 国产女人18毛片水真多 | 欧美人性生活视频 | 欧美日韩18 | 精品人妻一区二区三区四区五区 | 在线观看中文字幕一区二区 | 久久中文字幕电影 | 三上悠亚中文字幕在线播放 | 在线观看自拍 | 久久蜜桃av | 最新在线中文字幕 | 亚洲精品乱码久久久久久日本蜜臀 | 狐狸视频污 | 日日日日日日bbbbbb | 国内少妇精品 | 成人网在线播放 | 短视频在线观看 | 好看的中文字幕 | 国产第四页 | 佐山爱av在线| 大奶毛片 | 日韩三级不卡 | 玉女心经 在线 | 久久精品女人毛片国产 | 色综合99 | 色校园| 2025中文字幕 | 免费看91| 看看毛片| 99国产精品99久久久久久 |