文章目的對於跨平臺編譯,網上有很多教程和解釋,但零零碎碎總感覺不完整,所以想集中整理一下。但跨平臺編譯是一個很寬泛的問題,如果要全部說清楚,涉及到的問題會有很多,多番查證文獻也會拖慢進度,所以決定隱藏不必要的技術細節,從“不求甚解”的角度,解釋一下跨平臺遇到的各種問題。預計隱藏的部分1.舉例子。比如...
文章目的
對於跨平臺編譯,網上有很多教程和解釋,但零零碎碎總感覺不完整,所以想集中整理一下。但跨平臺編譯是一個很寬泛的問題,如果要全部說清楚,涉及到的問題會有很多,多番查證文獻也會拖慢進度,所以決定隱藏不必要的技術細節,從“不求甚解”的角度,解釋一下跨平臺遇到的各種問題。
預計隱藏的部分
1.舉例子。比如文章中提到,有一條(1101 0010)的機器碼指令,但其實並沒有這條指令,只是為了舉例子方便而構造出這麼一條指令。
2.簡化結構。文章中說"可執行程式 = 操作系統頭 + 完成任務的機器碼",事實上的可執行程式肯定不是這麼分塊,也不是這麼簡單,但從巨集觀來看,筆者認為這麼劃分可以反映一定的問題,也是合理的。
讀者定位
跨平臺編譯入門級玩家。
可以熟練使用shell腳本。
指導思想
簡化現實世界的電腦模型,從一種不同的角度描述遇到的問題。
和傳統不一樣的一些概念
程式源碼 = C/C++內置操作 + 各種庫調用
int main(int argc, char const *argv[]) { int prices[] = {7, 3, 8, 4, 5}; //c/c++內置操作 std::sort(prices, prices+5); //調用stl庫 return 0; }
可執行程式 = 操作系統頭 + 完成任務的機器碼
電腦 = 操作系統 + 處理器
為什麼做不到“一次編寫,到處運行”
具體描述:
為什麼在windows上編譯出來的.exe文件,不能放到linux上直接運行。
android是基於linux的系統,為什麼在linux上編譯出的可執行程式,在android上不能直接運行。
答:
可執行程式要想被成功執行,需要滿足兩個基本要求(操作系統頭+完成任務的機器碼)。
一是操作系統層面,你必須通知操作系統說:這個程式可不是一般的程式,它是可以被執行的!對於Windows來說,需要在[操作系統頭]裡面寫上"windows is great"的字樣;對於linux來說,需要寫上"linux is the best"的字樣,對於android來說,則要寫上“android i love you”等等。所以,一個用vs編譯出來的程式,只有windows會認為它是可執行的,但對於linux和android來說,“這是什麼?我不知道。”
二是處理器層面的,主要由兩大處理器廠商(Intel和AMD)所控制。CXX源碼編譯出的可執行程式,內部存儲的是機器碼,直接執行機器碼的,就是處理器。但不同的處理器對同一條機器碼的解釋是不一樣的。比如說(1101 0010)這條機器碼,在Intel看來,這是一條mov ax,ex指令;但在AMD看來,這是一條pop指令。所以,在Intel處理器上編譯出的程式,是不能直接跑在AMD處理器上的。
所以,一個程式要正確執行,必須保證:操作系統頭信息正確 + 對應處理器的機器碼正確。
交叉編譯cross platform compile
上面說到,在win上編譯的程式只能跑在win的機器上,在linux上編譯的程式只能跑在linux上,那想要編譯出一個能跑在手機端的程式該怎麼做?用跨平臺編譯器。
跨平臺編譯器是怎麼工作的
從源碼到可執行程式,可以分為2個步驟(下麵的說法與大多數教程不同)。
第一個步驟是把你自己寫的代碼,編譯成.obj文件;
第二個步驟是把你用到的庫文件(比如說stl),與你自己代碼生成的.obj文件進行鏈接,生成最終的可執行文件。
其中,你自己寫的代碼,本身就是跨平臺的,這個是由c++標準委員會規定給各個編譯器看的,無須你操心;
你用到的庫文件,相當一部分是用彙編實現,不具有跨平臺性,所以每個平臺都有自己的實現,這個也不用你操心。
你的工作是:寫自己的代碼,找到對應平臺的庫文件,把它們的位置都告訴編譯器,編譯器會生成一個跨平臺的可執行文件給你。
到哪裡找庫文件
Windows上,下載了vs,你只需要在vs里寫自己的代碼,尋找庫文件的任務vs會替你完成。
Linux上,下載了gcc/g++,你只需要寫自己的代碼,尋找庫文件的任務gcc/g++會替你完成。
Mac上,下載了xcode,你只需要寫自己的代碼,尋找庫文件的任務xcode會替你完成。
但由於你不可能在Android上跑一個vs/gcc/xcode,所以這個時候你要去google的官網上下載一個android專用的編譯器,也就是ndk。然後,你只需要寫自己的代碼,尋找庫文件的任務ndk會替你完成。
3.總結
基礎概念就這麼多,下麵是一些跨平臺編譯的例子。繼續看下去之前,請確保電腦上已經正確配置了ndk開發環境。