日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
GNUC編譯器的程序員入門指南

C 語(yǔ)言廣為人知,深受新老程序員的好評(píng)。使用 C 語(yǔ)言編寫的源文件代碼,使用了標(biāo)準(zhǔn)的英語(yǔ)術(shù)語(yǔ),因而人們可以方便閱讀。然而,計(jì)算機(jī)只能理解二進(jìn)制代碼。為將代碼轉(zhuǎn)換為機(jī)器語(yǔ)言,你需要使用一種被稱為編譯器的工具。

從網(wǎng)站建設(shè)到定制行業(yè)解決方案,為提供做網(wǎng)站、成都網(wǎng)站建設(shè)服務(wù)體系,各種行業(yè)企業(yè)客戶提供網(wǎng)站建設(shè)解決方案,助力業(yè)務(wù)快速發(fā)展。成都創(chuàng)新互聯(lián)將不斷加快創(chuàng)新步伐,提供優(yōu)質(zhì)的建站服務(wù)。

最常見的編譯器是 GCC(GNU 編譯器集)。編譯過程涉及到一系列的中間步驟及相關(guān)工具。

安裝 GCC

為驗(yàn)證在你的系統(tǒng)上是否已經(jīng)安裝了 GCC,使用 gcc 命令:

$ gcc --version

如有必要,使用你的軟件包管理器來(lái)安裝 GCC。在基于 Fedora 的系統(tǒng)上,使用 dnf :

$ sudo dnf install gcc libgcc

在基于 Debian 的系統(tǒng)上,使用 apt :

$ sudo apt install build-essential

在安裝后,如果你想查看 GCC 的安裝位置,那么使用:

$ whereis gcc

演示使用 GCC 來(lái)編譯一個(gè)簡(jiǎn)單的 C 程序

這里有一個(gè)簡(jiǎn)單的 C 程序,用于演示如何使用 GCC 來(lái)編譯。打開你最喜歡的文本編輯器,并在其中粘貼這段代碼:

// hellogcc.c
#include
int main() {
printf("Hello, GCC!\n");
return 0;
}

保存文件為 hellogcc.c ,接下來(lái)編譯它:

$ ls
hellogcc.c
$ gcc hellogcc.c
$ ls -1
a.out
hellogcc.c

如你所見,a.out 是編譯后默認(rèn)生成的二進(jìn)制文件。為查看你所新編譯的應(yīng)用程序的輸出,只需要運(yùn)行它,就像你運(yùn)行任意本地二進(jìn)制文件一樣:

$ ./a.out
Hello, GCC!

命名輸出的文件

文件名稱 a.out 是非常莫名其妙的,所以,如果你想具體指定可執(zhí)行文件的名稱,你可以使用 -o 選項(xiàng):

(LCTT 譯注:注意這和最近 Linux 內(nèi)核廢棄的 a.out 格式無(wú)關(guān),只是名字相同,這里生成的 a.out 是 ELF 格式的 ——
也不知道誰(shuí)給起了個(gè) a.out 這破名字,在我看來(lái),默認(rèn)輸出文件名就應(yīng)該是去掉了 .c 擴(kuò)展名后的名字。by wxy)

$ gcc -o hellogcc hellogcc.c
$ ls
a.out hellogcc hellogcc.c
$ ./hellogcc
Hello, GCC!

當(dāng)開發(fā)一個(gè)需要編譯多個(gè) C 源文件文件的大型應(yīng)用程序時(shí),這種選項(xiàng)是很有用的。

在 GCC 編譯中的中間步驟

編譯實(shí)際上有四個(gè)步驟,即使在簡(jiǎn)單的用例中 GCC 自動(dòng)執(zhí)行了這些步驟。

  • 預(yù)處理:GNU 的 C 預(yù)處理器(cpp)解析頭文件(#include 語(yǔ)句),展開 宏macros 定義(#define 語(yǔ)句),并使用展開的源文件代碼來(lái)生成一個(gè)中間文件,如 hellogcc.i。
  • 編譯:在這個(gè)期間中,編譯器將預(yù)處理的源文件代碼轉(zhuǎn)換為指定 CPU 架構(gòu)的匯編代碼。由此生成是匯編文件使用一個(gè) .s
    擴(kuò)展名來(lái)命名,如在這個(gè)示例中的 hellogcc.s 。
  • 匯編:匯編程序(as)將匯編代碼轉(zhuǎn)換為目標(biāo)機(jī)器代碼,放在目標(biāo)文件中,例如 hellogcc.o 。
  • 鏈接:鏈接器(ld)將目標(biāo)代碼和庫(kù)代碼鏈接起來(lái)生成一個(gè)可執(zhí)行文件,例如 hellogcc 。

在運(yùn)行 GCC 時(shí),可以使用 -v 選項(xiàng)來(lái)查看每一步的細(xì)節(jié):

$ gcc -v -o hellogcc hellogcc.c

Compiler flowchart

手動(dòng)編譯代碼

體驗(yàn)編譯的每個(gè)步驟可能是很有用的,因此在一些情況下,你不需要 GCC 完成所有的步驟。

首先,除源文件文件以外,刪除在當(dāng)前文件夾下生成的文件。

$ rm a.out hellogcc.o
$ ls
hellogcc.c

預(yù)處理器

首先,啟動(dòng)預(yù)處理器,將其輸出重定向?yàn)?hellogcc.i :

$ cpp hellogcc.c > hellogcc.i
$ ls
hellogcc.c hellogcc.i

查看輸出文件,并注意一下預(yù)處理器是如何包含頭文件和擴(kuò)展宏中的源文件代碼的。

編譯器

現(xiàn)在,你可以編譯代碼為匯編代碼。使用 -S 選項(xiàng)來(lái)設(shè)置 GCC 只生成匯編代碼:

$ gcc -S hellogcc.i
$ ls
hellogcc.c hellogcc.i hellogcc.s
$ cat hellogcc.s

查看匯編代碼,來(lái)看看生成了什么。

匯編

使用你剛剛所生成的匯編代碼來(lái)創(chuàng)建一個(gè)目標(biāo)文件:

$ as -o hellogcc.o hellogcc.s
$ ls
hellogcc.c hellogcc.i hellogcc.o hellogcc.s

鏈接

要生成一個(gè)可執(zhí)行文件,你必須將對(duì)象文件鏈接到它所依賴的庫(kù)。這并不像前面的步驟那么簡(jiǎn)單,但它卻是有教育意義的:

$ ld -o hellogcc hellogcc.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000
ld: hellogcc.o: in function `main`:
hellogcc.c:(.text+0xa): undefined reference to `puts'

在鏈接器查找完 libc.so 庫(kù)后,出現(xiàn)一個(gè)引用 undefined puts 錯(cuò)誤。你必須找出適合的鏈接器選項(xiàng)來(lái)鏈接必要的庫(kù)以解決這個(gè)問題。這不是一個(gè)小技巧,它取決于你的系統(tǒng)的布局。

在鏈接時(shí),你必須鏈接代碼到核心運(yùn)行時(shí)(CRT)目標(biāo),這是一組幫助二進(jìn)制可執(zhí)行文件啟動(dòng)的子例程。鏈接器也需要知道在哪里可以找到重要的系統(tǒng)庫(kù),包括 libc 和 libgcc,尤其是其中的特殊的開始和結(jié)束指令。這些指令可以通過 --start-group 和 --end-group 選項(xiàng)來(lái)分隔,或者使用指向 crtbegin.o 和 crtend.o 的路徑。

這個(gè)示例使用了 RHEL 8 上的路徑,因此你可能需要依據(jù)你的系統(tǒng)調(diào)整路徑。

$ ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 \
-o hello \
/usr/lib64/crt1.o /usr/lib64/crti.o \
--start-group \
-L/usr/lib/gcc/x86_64-redhat-linux/8 \
-L/usr/lib64 -L/lib64 hello.o \
-lgcc \
--as-needed -lgcc_s \
--no-as-needed -lc -lgcc \
--end-group \
/usr/lib64/crtn.o

在 Slackware 上,同樣的鏈接過程會(huì)使用一組不同的路徑,但是,你可以看到這其中的相似之處:

$ ld -static -o hello \
-L/usr/lib64/gcc/x86_64-slackware-linux/11.2.0/ \
/usr/lib64/crt1.o /usr/lib64/crti.o hello.o /usr/lib64/crtn.o \
--start-group \
-lc -lgcc -lgcc_eh \
--end-group

現(xiàn)在,運(yùn)行由此生成的可執(zhí)行文件:

$ ./hello
Hello, GCC!

一些有用的實(shí)用程序

下面是一些幫助檢查文件類型、符號(hào)表symbol tables 和鏈接到可執(zhí)行文件的庫(kù)的實(shí)用程序。

使用 file 實(shí)用程序可以確定文件的類型:

$ file hellogcc.c
hellogcc.c: C source, ASCII text
$ file hellogcc.o
hellogcc.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
$ file hellogcc
hellogcc: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=bb76b241d7d00871806e9fa5e814fee276d5bd1a, for GNU/Linux 3.2.0, not stripped

對(duì)目標(biāo)文件使用 nm 實(shí)用程序可以列出 符號(hào)表 :

$ nm hellogcc.o
0000000000000000 T main
U puts

使用 ldd 實(shí)用程序來(lái)列出動(dòng)態(tài)鏈接庫(kù):

$ ldd hellogcc
linux-vdso.so.1 (0x00007ffe3bdd7000)
libc.so.6 => /lib64/libc.so.6 (0x00007f223395e000)
/lib64/ld-linux-x86-64.so.2 (0x00007f2233b7e000)

總結(jié)

在這篇文章中,你了解到了 GCC 編譯中的各種中間步驟,和檢查文件類型、符號(hào)表symbol tables 和鏈接到可執(zhí)行文件的庫(kù)的實(shí)用程序。在你下次使用
GCC 時(shí),你將會(huì)明白它為你生成一個(gè)二進(jìn)制文件所要做的步驟,并且當(dāng)出現(xiàn)一些錯(cuò)誤時(shí),你會(huì)知道如何逐步處理解決問題。


分享文章:GNUC編譯器的程序員入門指南
鏈接分享:http://www.5511xx.com/article/dhhddch.html