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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

Linux 交叉编译简介

發(fā)布時(shí)間:2023/11/28 生活经验 65 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux 交叉编译简介 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Linux 交叉編譯簡(jiǎn)介
主機(jī),目標(biāo),交叉編譯器
主機(jī)與目標(biāo)
編譯器是將源代碼轉(zhuǎn)換為可執(zhí)行代碼的程序。像所有程序一樣,編譯器運(yùn)行在特定類(lèi)型的計(jì)算機(jī)上,輸出的新程序也運(yùn)行在特定類(lèi)型的計(jì)算機(jī)上。
運(yùn)行編譯器的計(jì)算機(jī)稱(chēng)為主機(jī),運(yùn)行新程序的計(jì)算機(jī)稱(chēng)為目標(biāo)。當(dāng)主機(jī)和目標(biāo)是同一類(lèi)型的機(jī)器時(shí),編譯器是本機(jī)編譯器。當(dāng)宿主和目標(biāo)不同時(shí),編譯器是 交叉編譯器。

為什么要交叉編譯?
某些設(shè)備構(gòu)建程序的PC,用戶可以獲得適當(dāng)?shù)哪繕?biāo)硬件(或模擬器),啟動(dòng) Linux Release版,在該環(huán)境中進(jìn)行本地編譯。這是一種有效的方法(在處理 Mac Mini時(shí)甚至可能是一個(gè)好主意),但對(duì)于 linksys 路由器,或 iPod,有一些突出的缺點(diǎn):
? 速度- 目標(biāo)平臺(tái)通常比主機(jī)慢一個(gè)數(shù)量級(jí)或更多。大多數(shù)專(zhuān)用嵌入式硬件是為低成本和低功耗而設(shè)計(jì)的,而不是高性能。由于在高性能桌面硬件上運(yùn)行,現(xiàn)代模擬器(如 qemu)實(shí)際上比模擬的許多現(xiàn)實(shí)世界的硬件要快。
? 性能- 編譯非常耗費(fèi)資源。目標(biāo)平臺(tái)通常沒(méi)有臺(tái)式機(jī)GB 內(nèi)存和數(shù)百 GB 磁盤(pán)空間;甚至可能沒(méi)有資源來(lái)構(gòu)建“hello world”,更不用說(shuō)大而復(fù)雜的包了。
? 可用性-未運(yùn)行過(guò)的硬件平臺(tái)上運(yùn)行 Linux,需要交叉編譯器。即使在 Arm 或 Mips 等歷史悠久的平臺(tái)上,給定目標(biāo)找到最新的全功能預(yù)構(gòu)建本機(jī)環(huán)境很困難。如果平臺(tái)通常不用作開(kāi)發(fā)工作站,可能沒(méi)有現(xiàn)成的最新預(yù)構(gòu)建Release版,如果有,則可能已經(jīng)過(guò)時(shí)。如果必須先為目標(biāo)構(gòu)建Release版,才能在目標(biāo)上進(jìn)行構(gòu)建,無(wú)論如何都將返回交叉編譯。
? 靈活性- 功能齊全的 Linux Release版,由數(shù)百個(gè)軟件包組成,但交叉編譯環(huán)境可以從大多數(shù)方面依賴(lài)于主機(jī)的現(xiàn)有Release版。交叉編譯的重點(diǎn)是構(gòu)建要部署的目標(biāo)包,不是花時(shí)間獲取在目標(biāo)系統(tǒng)上運(yùn)行的僅構(gòu)建先決條件。
? 方便-用戶界面不友好,debug構(gòu)建中斷不方便。從 CD 安裝到?jīng)]有 CD-ROM 驅(qū)動(dòng)器的機(jī)器上,在測(cè)試環(huán)境和開(kāi)發(fā)環(huán)境之間來(lái)回重新啟動(dòng)。

為什么交叉編譯很難?
便攜式本機(jī)編譯很困難。
大多數(shù)程序是在 x86 硬件上開(kāi)發(fā)的,在本地編譯的。交叉編譯會(huì)遇到兩種類(lèi)型的問(wèn)題:程序本身的問(wèn)題和構(gòu)建系統(tǒng)的問(wèn)題。
第一類(lèi)問(wèn)題會(huì)影響所有非 x86 目標(biāo),包括本機(jī)和交叉構(gòu)建。大多數(shù)程序?qū)\(yùn)行的機(jī)器類(lèi)型做出假設(shè),必須與相關(guān)平臺(tái)匹配,否則程序?qū)o(wú)法運(yùn)行。常見(jiàn)的假設(shè)包括:
? Word size - 將指針復(fù)制到 int 可能會(huì)在 64 位平臺(tái)上丟失數(shù)據(jù),通過(guò)乘以 4 而不是 sizeof(long) ,確定 malloc 的大小不好。整數(shù)溢出導(dǎo)致細(xì)微安全漏洞,ala“if (x+y < size) memset(src+x,0,y);”,當(dāng) x=1000 時(shí),在 32 位硬件上產(chǎn)生 4 GB 的 memset y=0xFFFFFFF0…
? Endianness - 不同的系統(tǒng)用不同的方式在內(nèi)部存儲(chǔ)二進(jìn)制數(shù)據(jù),從磁盤(pán)或網(wǎng)絡(luò)中,讀取 int 或 float 數(shù)據(jù)可能需要轉(zhuǎn)換。
? Alignment - 某些平臺(tái)(例如 arm)只能從 4 字節(jié)的偶數(shù)倍的地址,讀取或?qū)懭胝麛?shù),否則出現(xiàn)段錯(cuò)誤。處理任意alignment的處理,未alignment的數(shù)據(jù)都較慢,編譯器通常會(huì)填充結(jié)構(gòu)alignment變量。將結(jié)構(gòu)視為可以發(fā)送到磁盤(pán)或通過(guò)網(wǎng)絡(luò)發(fā)送的數(shù)據(jù)塊,需要額外的工作確保一致的表示。
? 默認(rèn)簽名- “char”數(shù)據(jù)類(lèi)型,默認(rèn)為有符號(hào)或無(wú)符號(hào),因平臺(tái)而異(從編譯器到編譯器),導(dǎo)致一些非常令人驚訝的錯(cuò)誤。簡(jiǎn)單解決方法是提供一個(gè)編譯器參數(shù),如“-funsigned-char”,強(qiáng)制默認(rèn)值為已知值。
? NOMMU - 如果目標(biāo)平臺(tái)沒(méi)有內(nèi)存管理單元,需要更改幾項(xiàng)內(nèi)容。需要 vfork(),不是 fork(),只有某些類(lèi)型的 mmap() 工作(共享或只讀,但不能在寫(xiě)入時(shí)復(fù)制),堆棧不會(huì)動(dòng)態(tài)增長(zhǎng)。
大多數(shù)包的目標(biāo)是在本地編譯時(shí)可移植,至少會(huì)接受補(bǔ)丁,修復(fù)提交到適當(dāng)?shù)拈_(kāi)發(fā)郵件列表的任何上述問(wèn)題(NOMMU 問(wèn)題除外)。
然后是交叉編譯。

除了本機(jī)編譯的問(wèn)題外,交叉編譯還有其自身的一系列問(wèn)題:
? 配置問(wèn)題- 具有單獨(dú)配置步驟的包(標(biāo)準(zhǔn) configure/make/make install 的“./configure”部分),通常會(huì)測(cè)試字節(jié)順序或頁(yè)面大小等內(nèi)容,在本機(jī)編譯時(shí)可移植。交叉編譯時(shí),這些值在主機(jī)系統(tǒng)和目標(biāo)系統(tǒng)之間不同,在主機(jī)系統(tǒng)上運(yùn)行測(cè)試,給出錯(cuò)誤的答案。當(dāng)目標(biāo)沒(méi)有該軟件包或版本不兼容時(shí),配置檢測(cè)主機(jī)上,是否存在軟件包支持。
? HOSTCC vs TARGETCC -構(gòu)建過(guò)程需要編譯在主機(jī)系統(tǒng)上運(yùn)行,如上述配置測(cè)試,或生成代碼的程序(如創(chuàng)建 .h 文件的 C 程序,在main構(gòu)建期間 #included )。用目標(biāo)編譯器替換主機(jī)編譯器,破壞在構(gòu)建過(guò)程中運(yùn)行庫(kù)。這樣的庫(kù)需要訪問(wèn)主機(jī)和目標(biāo)編譯器,需要說(shuō)明何時(shí)使用。
? 工具鏈泄漏- 配置不當(dāng)?shù)慕徊婢幾g工具鏈,將主機(jī)系統(tǒng)的一些內(nèi)容泄漏到已編譯的程序中,導(dǎo)致通常易于檢測(cè),但難以診斷和糾正的故障。工具鏈可能 #include 錯(cuò)誤的頭文件,或在鏈接時(shí)搜索錯(cuò)誤的庫(kù)路徑。共享庫(kù)通常依賴(lài)于其它共享庫(kù),可能會(huì)潛入對(duì)主機(jī)系統(tǒng)的意外鏈接時(shí)引用。
? 庫(kù)- 動(dòng)態(tài)鏈接的程序必須在編譯時(shí),訪問(wèn)適當(dāng)?shù)墓蚕韼?kù)。目標(biāo)系統(tǒng)的共享庫(kù),需要添加到交叉編譯工具鏈中,以便程序可以鏈接到。
? 測(cè)試- 在本機(jī)構(gòu)建上,開(kāi)發(fā)系統(tǒng)提供了方便的測(cè)試環(huán)境。交叉編譯時(shí),確認(rèn)“hello world”構(gòu)建成功,可能需要(至少)配置引導(dǎo)加載程序,內(nèi)核,根文件系統(tǒng)和共享庫(kù)。

腳注 1:計(jì)算機(jī)類(lèi)型之間最顯著的區(qū)別是執(zhí)行程序的處理器,其它差異包括庫(kù) ABI(例如 glibc 與 uClibc),具有可配置字節(jié)序的機(jī)器(arm 與 armeb),或不同模式的機(jī)器,可以運(yùn)行 32 位和 64 位代碼(例如 x86 上的 x86-64)。
腳注 2:在構(gòu)建編譯器時(shí),第三種類(lèi)型稱(chēng)為“加拿大交叉”,一種不在主機(jī)系統(tǒng)上運(yùn)行的交叉編譯器。加拿大交叉構(gòu)建了一個(gè)編譯器,該編譯器在一個(gè)目標(biāo)平臺(tái)上運(yùn)行,另一臺(tái)目標(biāo)機(jī)器生成代碼。首先創(chuàng)建從主機(jī)到第一個(gè)目標(biāo)的臨時(shí)交叉編譯器,作為第二個(gè)目標(biāo)構(gòu)建另一個(gè)交叉編譯器構(gòu)建這樣的外部編譯器。第一個(gè)交叉編譯器的目標(biāo)成為運(yùn)行新編譯器的主機(jī),第二個(gè)目標(biāo)是新編譯器生成輸出的平臺(tái)。這種技術(shù)通常用于為目標(biāo)平臺(tái)交叉編譯新的本機(jī)編譯器。
腳注 3:現(xiàn)代桌面系統(tǒng)足夠快,模擬目標(biāo)在模擬器下進(jìn)行本地編譯,實(shí)際上是一種可行的策略。比交叉編譯慢得多,需要為目標(biāo)查找或生成本機(jī)構(gòu)建環(huán)境(無(wú)論如何都必須設(shè)置交叉編譯器),可能會(huì)因模擬器和要部署的真實(shí)硬件之間的差異崩潰。
腳注 4:交叉編譯工具鏈傾向于為其實(shí)用程序的名稱(chēng)加上前綴,ala “armv5l-linux-gcc”。如果簡(jiǎn)單地稱(chēng)為“gcc”,主機(jī)和本機(jī)編譯器就不能同時(shí)在 $PATH 中。

參考鏈接:
http://landley.net/writing/docs/cross-compiling.html

總結(jié)

以上是生活随笔為你收集整理的Linux 交叉编译简介的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。