日韩性视频-久久久蜜桃-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编译链接及常用选项总结的全部內容,希望文章能夠幫你解決所遇到的問題。

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

    主站蜘蛛池模板: 超爽视频| av在线免 | caoporen超碰| 91n视频| aaa黄色| 欧美碰碰碰 | 国产精品麻豆一区二区三区 | 麻豆一区二区三区 | 日本韩国欧美 | 干美女视频 | 亚洲婷婷在线观看 | 国内激情 | 久草最新视频 | 国产有码视频 | 日韩精品久久久久久免费 | 日韩3p | 亚洲天堂影院在线观看 | av色先锋| 久久艹精品视频 | 国产精品国语自产拍在线观看 | 一区二区在线 | 欧美搞逼视频 | 丝袜脚交免费网站xx | 狠狠躁夜夜躁av无码中文幕 | 日日淫| 精品九九视频 | 日韩二区 | 京香julia在线观看 | 国产在线观看一区 | 久久男人的天堂 | 999精品在线视频 | 日韩精品一区二区三 | 老色鬼在线 | 精品日韩欧美 | 少妇爽| 国产色影院 | 蜜臀久久99精品久久久画质超高清 | 在线视频欧美日韩 | 伊人66 | 日韩欧美成人一区二区三区 | 涩涩爱影院 | 老司机一区二区三区 | 免费的毛片网站 | 日韩中文字幕免费视频 | 在线观看中文字幕一区二区 | 在线视频黄| 波多野结衣在线影院 | 夜夜高潮夜夜爽国产伦精品 | 天天插天天干 | 欧美影院在线观看 | 久久久久久久久久久久久久久久久 | 男女拍拍拍网站 | 亚洲国产婷婷 | 色很久 | 亚洲免费一二三区 | 成年网站免费在线观看 | 国产一二区在线观看 | 亚洲国产第一区 | 国产人与禽zoz0性伦 | 午夜视频| 色综合天天 | 久久九九视频 | 97色伦影院 | 在线综合网 | 免费观看污网站 | 好吊妞视频一区二区三区 | 成人区人妻精品一区二区不卡视频 | 国产黄色免费视频 | 日本精品免费在线观看 | 亚洲福利午夜 | 韩国伦理片在线观看 | 精品国产91久久久久久久妲己 | 成av人片在线观看www | 久久噜噜噜精品国产亚洲综合 | 国产久精品 | 日韩人妻精品中文字幕 | 久久免费视屏 | 黄页免费网站 | 欧美嫩交 | 天天干天天操天天爽 | 亚洲av第一成肉网 | 后进极品白嫩翘臀在线视频 | 亚洲色图21p | 免费看美女被靠到爽的视频 | 欧美精品一区二 | 日日网站 | 波多野结衣日韩 | 精品成人久久 | 欧美精品中文 | 手机版av | 日韩丰满少妇无码内射 | 91精品国产99久久久久久红楼 | 91精品人妻一区二区三区果冻 | 亚洲美女一区二区三区 | 欧美日韩午夜精品 | 99在线看 | 国产中文字幕网 | 亚洲乱码一区二区 | 中韩毛片|