gcc編譯C源文件


gcc編譯C程序的主要過程是:預處理---編譯---匯編---連接,其中:(以名為hello.c的源文件為例)

預處理:對各種預處理指令(#開頭,如#include,#define)進行處理,以及刪除注釋和多余空白字符。生成被修改的源程序hello.i

E是通知gcc對hello.c進行預編譯;o是對命令輸出結果進行導入操作

gcc -E hello.c -o hello.i

編譯:對代碼進行語法語義分析和錯誤判斷,生成匯編代碼文件hello.s

S是通知gcc對目標文件hello.i進行編譯

gcc -S hello.i -o hello.s

匯編:將匯編代碼轉化為計算機可識別的二進制文件,生成可重定位目標程序(二進制)hello.o

c是通知gcc對目標文件hello.s進行指令轉換操作

gcc -c hello.s -o hello.o

鏈接:將多個.o文件合並成一個可執行文件hello

gcc hello.o -o hello

hello文件即最后可以直接運行的可執行文件,通過./hello執行,通過objdump -d hello可以將可執行文件轉化為匯編語言

==========

或者可以直接通過執行gcc hello.c就可以直接生成二進制目標文件a.out,通過./a.out也可以執行結果

或者通過gcc hello.c -o hello,這樣可以給生成的文件取名為hello

==========

如果是鏈接兩個文件,可以參考:

https://blog.csdn.net/qq_31811537/article/details/79312908

https://www.linuxidc.com/Linux/2016-09/135473.htm

 

=================================

20190616補

今天在編譯gcc時遇到了問題,更新此帖記錄。

想了解elf,所以建立了一個簡單的hello.c源文件只做printf("hello")。根據別的ELF博客采用如下命令編譯:

gcc -c hello.c -o hello.o

想要./hello.o輸出的時候報錯Permission denied,這個問題可以通過在命令前加bash或chmod更改權限解決:

ly@ubuntu:~/Desktop$ ./hello.o
bash: ./hello.o: Permission denied
ly@ubuntu:~/Desktop$ bash ./hello.o
./hello.o: ./hello.o: cannot execute binary file
ly@ubuntu:~/Desktop$ chmod 777 hello.o
ly@ubuntu:~/Desktop$ ./hello.o
bash: ./hello.o: cannot execute binary file: Exec format error

然后重看這篇之前整理的博客發現直接用gcc命令編譯出來的是一個擴展名為out的二進制文件,並不是可以./執行的可執行文件。要直接生成可執行文件還是需要如下:

ly@ubuntu:~/Desktop$ gcc hello.c -o hello
ly@ubuntu:~/Desktop$ ./hello
hello
ly@ubuntu:~/Desktop$ gcc hello.c
ly@ubuntu:~/Desktop$ ./a.out
hello

之前整理的三種方式都可以生成可執行文件。

總結起來就是:帶了-c編譯時,-o生成的是.o文件。(畢竟-c只編譯生成目標文件,不鏈接)

ly@ubuntu:~/Desktop$ file ./a.out
./a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 2.6.32, BuildID[sha1]=2cf583ee1d914378202ee3968923649fcbb01514, not stripped
ly@ubuntu:~/Desktop$ file ./hello.o
./hello.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
ly@ubuntu:~/Desktop$ file ./hello
./hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 2.6.32, BuildID[sha1]=2cf583ee1d914378202ee3968923649fcbb01514, not stripped

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM