導航:首頁 > 源碼編譯 > gcc能編譯elf嘛

gcc能編譯elf嘛

發布時間:2022-11-28 23:59:42

『壹』 arm-linux-gcc 和 arm-elf-gcc 的區別

在基於ARM的嵌入式系統開發中,常常用到交叉編譯的GCC工具鏈有兩種:
arm-linux-*和 arm-elf-*,兩者區別主要在於使用不同的C庫文件。arm-linux-*使用
GNU的Glibc,而arm-elf-*一般使用 uClibc/uC-libc或者使用REDHAT專門為嵌入式系統
的開發的C庫newlib.Glibc。uClibc/uC-libc以及 newlib都是C語言庫文件,只是所應
用的領域不同而已,Glibc是針對PC開發的,uClibc/uC-libc是與Glibc API兼容的小型
化C語言庫,實現了Glibc部分功能。

關於uClibc/uC-libc的說明,詳見如下:

There are two libc libraries commonly used with uClinux. uC-libc and
uClibc. They are quite different despite their similar names. Here is a
quick overview of how they are different.

uC-libc is the original library for uClinux. It was based on sources
from the Linux-8086 C library which was part of the ELKs project with m68000
support added by Jeff Dionne and Kenneth Albanowski. It is a fairly complete
libc implementation, however, some of the API's are a little non-standard
and quite a few common libc routines are not present. Currently it has
stable support for m68000, ColdFire and ARM (Non-MMU) architectures. It was
primary design goal is to be small and light weight. It does try to conform
to any standards, although its API tries to be compatible with most libcs,
it is not always exactly the same.

The uClinux distribution provides an environment that can compile using
either uC-libc or uClibc depending on your needs. For m68000 and Coldfire
platforms it is generally better to chose uC-libc as it supports shared
libraries and is the most commonly used libc for these CPUs. uClibc also
works quite well with almost all platforms supported by the distribution.
Which libc you choose to use will be decided by your requirements

uClinux有兩個經常使用的libc庫:uC-libc和uClibc。雖然兩者名字很相似,其實有差
別,下面就簡單的介紹一下二者的不同之處。uC -libc是最早為uClinux開發的庫,是
Jeff Dionne和Kenneth Albanowski為在EKLs項目中支持m68000在Linux-8086 C庫源碼
上移植的。uC-libc是一個完全的libc實現,但其中有一些api是非標準的,有些libc的
標准也沒有實現。uC-libc穩定地支持 m68000,ColdFire和沒有MMU的ARM。其主要設計
目標是「小」、"輕",並盡量與標准一致,雖然它的API和很多libc兼容,但是似乎並
不像它期望的那樣和所有標准一致。

uClibc就是為了解決這個問題從uC-libc中發展出來的。它的所有API都是標準的(正確
的返回類型,參數等等),它彌補了uC-libc中沒有實現的libc標准,現在已經被移植到
多種架構中。一般來講,它盡量兼容glibc以便使應用程序用uClibc改寫變的容易。
uClibc能夠在標準的 VM linux和uClinux上面使用。為了應用程序的簡潔,它甚至可以
在許多支持MMU的平台上被編譯成共享庫。Erik Anderson在uClibc背後做了很多的工
作。uClibc支持許多系列的處理器:m68000,Coldfire,ARM,MIPS,v850, x86,
i960,Sparc,SuperH,Alpha,PowerPC和Hitachi 8。不斷增加的平台支持顯示uClibc
能夠很容易的適應新的架構。uClinux發行版提供了環境能夠讓你選擇使用uC-libc或是
uClibc編譯。對於m68000和Coldfire平台來說,選擇uC-libc還是稍微好一點,因為它
支持共享庫,而共享庫是這些cpu經常使用的 libc.uClibc也幾乎和所有的平台都能很
好的工作。選擇哪種libc取決於你的需求。

newlib 是一個用於嵌入式系統的開放源代碼的C語言程序庫,由libc和libm兩個庫組
成,特點是輕量級,速度快,可移植到很多CPU結構上。newlib實現了許多復雜的功
能,包括字元串支持,浮點運算,內存分配(如malloc)和I/O流函數(printf,fprinf()
等等)。其中libc提供了c 語言庫的實現,而libm提供了浮點運算支持。

在為ARM交叉編譯gcc編譯器時,對gcc指定不同的配置選項時,使用的C語言庫就不同,
gcc編譯器默認使用Glibc,也可以使用 uClibc/uC-libc(基本兼容Glibc API),當使用
--with-newlib時,gcc編譯器不使用Glibc。當沒有交叉編譯Glibc時,可以使用
--with-newlib禁止連接Glibc而編譯bootstrap gcc編譯器。從gcc源目錄下的
config/arm中的t-linux和t-arm-elf中可以看出,不同的--target也影響gcc連接C語言
庫,t-linux(--target=arm-linux)默認使用Glibc,-arm-elf(--target=arm-elf)使用
- Dinhibit_libc禁止連接Glibc,這時我們就可以使用newlib等其他C語言庫編譯GCC工
具鏈。

雖然GCC工具鏈配置了不同的的C語言庫,但由於這些C語言庫都可以用來支持GCC,它們
對核心數據的處理上不存在較大出入。因而arm-linux-* 和 arm-elf-*區別主要表現在
C語言庫的實現上,例如不同系統調用,不同的函數集實現,不同的ABI\啟動代碼以及
不同系統特性等微小的差別。

arm-linux-*和 arm-elf-*的使用沒有一個絕對的標准,排除不同庫實現的差異,gcc可
以編譯任何系統。arm-linux-*和 arm-elf-*都可以用來編譯裸機程序和操作系統,只
是在遵循下面的描述時系統程序顯得更加協調:

arm-linux-*針對運行linux的ARM機器,其依賴於指定的C語言庫Glibc,因為同樣使用
Glibc的linux而使得arm-linux-*在運行linux的ARM機器上編譯顯得更加和諧。

arm-elf-*則是一個獨立的編譯體系,不依賴於指定的C語言庫Glibc,可以使用newlib
等其他C語言庫,不要求操作系統支持,當其使用為嵌入式系統而設計的一些輕巧的C語
言庫時編譯裸機程序(沒有linux等大型操作系統的程序),如監控程序,bootloader等
能使得系統程序更加小巧快捷。

『貳』 如何使用GNU GCC編譯MQX應用

1. 安裝MQX4.0,在飛思卡爾官網把MQX的安裝文件下載下來。

2. 安裝好之後會在安裝目錄下生成如下圖所示的子目錄。

build目錄:包含了飛思卡爾不同平台不同編譯器的相關庫的Makefile文件。具體內容如下列表示意圖所示:
build
+---common
| +---make ... shared Makefiles with global settings, variables and paths
+--- ... board-specific folder
| +---make ... folder contains mass-build Makefile for all libraries
| +---tools ... tool-specific global settings, variables and paths
| +---bsp ... BSP Library Makefile
| +---psp ... PSP Library Makefile
| +---mfs ... MFS Library Makefile
| +---rtcs ... RTCS Library Makefile
| +---shell ... Shell Library Makefile
| +---usbd ... USB Device Library Makefile
| +---usbh ... USB Host Library Makefile
+---
+---make

3. 安裝CodeWarrior Development Studio V10.5編譯器。在飛思卡爾官網把CW10.5的安裝文件下載下來。安裝CW10.5時,請注意安裝目錄名稱不要帶空格。

CW10.5的Cross_Tools目錄已經自帶了GNU GCC for ARM Cortex-M4內核的交叉編譯工具鏈。

4. 安裝MinGW(Minimalist GNU on Windows) GNU工具集,在Windows下GNU GCC需要使用make.exe和sed.exe等工具。

5. 上述軟體安裝完畢後,按照實際安裝情況,修改編譯MQX所需的交叉工具鏈的目錄。
1).修改全局宏定義腳本$MQX_DIR\build\common\make\global.mak
指定GNU 交叉工具鏈的安裝路徑TOOLCHAIN_ROOTDIR宏定義,如:
TOOLCHAIN_ROOTDIR = C:/Freescale/CW10_5

2).指定編譯某一硬體平台需要GNU GCC編譯器的具體安裝路徑。如需要編譯twrk60d00m這款Demo板,修改腳本文件$MQX\build\twrk60d100m\make\tools\cw10gcc.mak,指定AS,CC,CX,AR,LD等工具的可執行文件。

#------------------------------------------------------------
# toolchain settings
#------------------------------------------------------------
AS = $(TOOLCHAIN_ROOTDIR)/Cross_Tools/arm-none-eabi-gcc-4_7_3/bin/arm-none-eabi-gcc.exe
CC = $(TOOLCHAIN_ROOTDIR)/Cross_Tools/arm-none-eabi-gcc-4_7_3/bin/arm-none-eabi-gcc.exe
CX = $(TOOLCHAIN_ROOTDIR)/Cross_Tools/arm-none-eabi-gcc-4_7_3/bin/arm-none-eabi-gcc.exe
AR = $(TOOLCHAIN_ROOTDIR)/Cross_Tools/arm-none-eabi-gcc-4_7_3/bin/arm-none-eabi-ar.exe
LD = $(TOOLCHAIN_ROOTDIR)/Cross_Tools/arm-none-eabi-gcc-4_7_3/bin/arm-none-eabi-gcc.exe

6. 修改完畢上述腳本後,就可以開始使用GNU GCC編譯MQX。在windows命令窗口下進入需要編譯的目錄,如Tower K60的編譯目錄:$MQX\build\twrk60d100m\make。在命令行下輸入make指令:
C:\Freescale\Freescale_MQX_4_0\build\twrk60d100m\make>mingw32-make build TOOL=cw10gcc CONFIG=debug

這條make指令能夠將整個MQX進行編譯,並生成bsp.a,psp.a,shell.a,rtcs.a,usbd.a,usbh.a等庫文件。

7. MQX系統庫編譯完畢後,可以進行應用程序的編譯。在命令窗口進入需要編譯的應用程序目錄。如需要編譯hello常式代碼,進入$MQX\mqx\examples\hello\make目錄,在命令下輸入make命令:
C:\Freescale\Freescale_MQX_4_0\mqx\examples\hello\make>mingw32-make BOARD=twrk60d100m TOOL=cw10gcc CONFIG=debug LOAD=intflash build

GNU GCC將會編譯應用程序代碼,並與MQX的bsp.a,psp.a的庫文件鏈接,生成.elf格式的可以執行文件。

8. 下載調試.elf可執行文件。在CW10.5中New創建一個Bareboard Project工程,選擇需要使用的下載調試器,並且選定使用GNU GCC作為編譯器。在菜單Properties --> Run/Debug Setting中選擇需要下載的目標文件。然後通過菜單Run-->Debug下載調試程序。

『叄』 用同一種語言(如c語言)編出來的軟體格式為什麼會有不同

我感覺你是在問,為什麼各種軟體要求的擴展名不同(也就是格式不同),比如word的doc,txt等等,是這樣的么?

回答:
可能是無意中造成的,比如某人編了個軟體,要求按照某種他自己定義的格式去讀文件,而市面上沒有這種格式,因此他就自己定義了一種,並用了一個特殊的擴展名。
也可能是有意這樣做的,比如某公司編寫了一軟體a,這個軟體很好,大家都用,其它公司看著眼紅,也想編個軟體b並且要能打開a軟體的文件(也就是兼容a),a公司為了競爭需要,在下一版本的軟體中特意改寫了文件讀取形式,讓b軟體打不開a文件。
因此,這跟編程語言不同沒關系

回答第二個問題,安裝完後產生的許多文件夾大部分是程序文件夾,也就是說這個軟體的程序是放在那個文件夾下面的,整個文件夾就是那個軟體,因此你看不懂,也不用看懂。這種文件夾不能刪,刪了的話軟體就運行不了了。

『肆』 高版本gcc編譯出的程序在低版本glibc機器上運行

比如我們用gcc 9.3.0編譯程序,但需要發布的機器gcc版本是4.8.5,怎麼辦?

你可能想到如下方法

將libc和libstdc++靜態編譯,編譯時帶上如下參數。

glibc並不推薦靜態鏈接,你依賴的其他庫可能依賴的了glibc,並且往往是動態鏈接的,可以通過 nm <bin> | grep GLIBC_ 確定你的程序是否依賴了glibc。

使用攜帶gcc9.3.0環境的容器發布程序,是可以的。但是在一些沒有容器且沒有sudo許可權的場合,依然不太友好。

這個方法雖然聽起來不是很優雅,但其實如果你對elf文件有一些了解,是不錯的方式。下面說下具體的方法。

當你有條件獲得程序源碼,並能夠重新編譯時,可以直接在編譯時指定相關參數來解決。
先說編譯時要增加的參數:

gcc參數

ld參數

這兩個參數分別設置的elf文件中的rpath和interpreter欄位。

rpath
全名 run-time search path ,是elf文件中一個欄位,它指定了可執行文件執行時搜索so文件的第一優先位置,一般編譯器默認將該欄位設為空。elf文件中還有一個類似的欄位runpath,其作用與rpath類似,但搜索優先順序稍低。搜索優先順序:

如果你需要使用相對路徑指定lib文件夾,可以使用 ORIGIN 變數,ld會將ORIGIN理解成可執行文件所在的路徑。

interpreter
動態庫載入器,程序啟動時,操作系統會先把控制權轉交給ld-linux-x86-64.so.2,該so負責載入所有程序依賴的so。。這個欄位在鏈接時會幫你自動設置,64bit程序一般為 /lib64/ld-linux-x86-64.so.2 。修改rpath或者LD_LIBRARY_PATH指向本地lib目錄,但通過ldd程序,發現/lib64/ld-linux-x86-64.so.2這個so仍然指向系統so。原因就是這個欄位是寫死在elf文件中的,並不受LD_LIBRARY_PATH影響。

編譯時帶上這兩個參數,下面只需要將你程序依賴的so打包一份,隨程序進行發布即可。

當你無法編譯程序時,也可以通過其他方式修改rpath和interpreter。這種情況需要使用到一個工具 patchelf ,通過 dnf install patchelf 即可安裝。你可以通過它修改elf文件的rpath和interpreter:

除了絕對路徑,一種比較常見的方式是在部署前,使用 pwd 獲取當前路徑,使用相對路徑指向本地lib。

『伍』 LINUX 的gcc等編程的工具如何啟動我剛剛接觸linux!!!

不需要專門的啟動
偶也是初入門著
先在一個TXT文檔裡面編輯命令
保存為.c文件
點任務欄的。。啟動命令行編輯器
進入你存放程序的地址
然後再編輯即可 gcc *.c -o

『陸』 Linux下的gcc編譯後生成Linux下的可執行文件,window下gcc編譯後是exe文件,為什麼不一樣啊是怎麼做到的

首先,這win和Linux下的gcc功能是一樣的,實際的gcc.exe和linux下的gcc這兩個文件不是一樣的,他們畢竟需要在工作在不同的平台上,而且他們做的一些工作是有區別的。
編譯過程是把源文件翻譯成機器碼,然後鏈接成一個整體,拼接成一個文件。不管是win下的exe還是Linux下的ELF,都是按照一定規范來的,比如頭部放什麼,尾部放什麼,中間又存哪些信息等。但是,如果要編譯出正確的可執行的文件,不同的操作系統里就必須按照不同的規范來組織這個文件。
這些文件的執行過程,並不是說它們可以直接執行,執行的時候,系統把它們從磁碟上,讀到內存中,經過一系列的前期工作,才可以最終執行起來,這個前期過程都是操作系統來搞定的。
你不應該問gcc是怎麼做到的,而應該問gcc為什麼需要這樣。如果你需要知道細節,去看《程序員的自我修養》

『柒』 Uboot編譯為什麼沒有生成elf格式的文件

1、通過gcc編譯出來的是elf文件
2、通過objcpy可以把elf文件轉換為bin文件

CC=ppc-gcc
LD=ppc-ld
OBJCOPY=ppc-obj
$(CC)-g$(CFLAG)-cboot.S
#先將boot.S文件生成boot.o
$(LD)-g-Bstatic-T$(LDFILE)
-Ttext0x12345600boot.o
--start-group-Mapboot.map-oboot.elf
#再將boot.o生成boot.elf
$(OBJCOPY)-Obinary-R.note-R.comment-Sboot.elfboot.bin
#接著將boot.elf轉換為boot.bin
#使用-Obinary(或--out-target=binary)輸出為原始的二進制文件
#使用-R.note(或--remove-section)輸出文件中不要.note這個section,縮小了文件尺寸
#使用-S(或--strip-all)輸出文件中不要重定位信息和符號信息,縮小了文件尺寸

『捌』 如何把.elf格式的文件編譯成uimage格式

在終端中輸入 gcc 文件名 -o 目標文件名 然後 ./目標文件名 就行了,沒有目標文件名,自動存為 a 執行 ./a 就行了。 在使用Gcc編譯器的時候,我們必須給出一系列必要的調用參數和文件名稱。GCC編譯器的調用參數大約有100多個,其中多數參數我們

『玖』 elf是什麼格式,怎麼運行

Executable Linkable Format
就是可執行文件。
gcc 編出來的。
http://crquan.blogbus.com/logs/1651240.html

閱讀全文

與gcc能編譯elf嘛相關的資料

熱點內容
國產系統怎麼解壓 瀏覽:540
戰雙程序員 瀏覽:483
him觸摸編程軟體 瀏覽:931
植物大戰僵屍存檔怎麼轉移安卓 瀏覽:852
java棧的元素 瀏覽:737
程序員與籃球事件 瀏覽:675
app反編譯不完整 瀏覽:788
電腦上的文件夾怎麼調整 瀏覽:7
伺服器無響應是什麼原因呀 瀏覽:984
wd文檔里的app怎麼製作 瀏覽:513
電腦里的文件夾沒有了一般能恢復嗎 瀏覽:418
哪裡有配加密鑰匙的 瀏覽:210
伺服器開不了機怎麼把數據弄出來 瀏覽:958
gif動態圖片怎麼壓縮 瀏覽:521
黑猴子棒球壓縮文件解壓密碼 瀏覽:631
如何讓app適應不同的手機屏幕大小 瀏覽:10
蘋果手機如何給安卓手機分享軟體 瀏覽:761
蘋果電腦怎麼運行騰訊雲伺服器 瀏覽:59
明日之後沙石堡命令助手 瀏覽:261
蛋糕店用什麼樣的app 瀏覽:877