g++ linux 编译开栈_方舟编译器编译hello world踩坑全记录
閑來無事,看到方舟編譯器完整開源,于是打算拿來試著編譯一個東西來,接下來把踩過的一些坑記錄一下。
參考文檔
方舟編譯器的官網(wǎng)是
OpenArkCompiler?www.openarkcompiler.cn但是這個網(wǎng)站上的文檔其實是過時的,沒有更新過的,應該去查閱的文檔是開源代碼里的文檔部分,也就是下面鏈接里的doc部分
方舟編譯器/OpenArkCompiler?gitee.com編譯環(huán)境如下:
CPU:R9-3900X 其中虛擬機給了16核
內(nèi)存:64G 其中虛擬機給了32G 后面會講為什么給了這么多。
磁盤:虛擬機250G機械硬盤,實際編譯過程中操作系統(tǒng)比較吃硬盤,建議用固態(tài)。
操作系統(tǒng):ubuntu 20.10
jdk:openjdk-8
首先是文檔部分,需要用到兩個文檔,分別是開發(fā)者指南和環(huán)境配置,也就是
doc/cn/DeveloperGuide.md · 方舟編譯器/OpenArkCompiler - Gitee.com?gitee.comdoc/cn/DevelopmentPreparation.md · 方舟編譯器/OpenArkCompiler - Gitee.com?gitee.com根據(jù)開發(fā)者指南頭部,下載源碼到本地。這里需要注意的是,不要使用開發(fā)者指南中的地址,要用gitee的地址,也就是本文的第二個鏈接,真正的“官網(wǎng)”
懶人復制版:
git clone https://gitee.com/openarkcompiler/OpenArkCompiler.git下載完以后是環(huán)境搭建。官方的推薦是
硬件推薦配置2 GHz 雙核處理器或者更高等級CPU
2 GB 系統(tǒng)內(nèi)存及以上
200GB 可用磁盤空間
CPU不必多說,人有多大膽,機有多大產(chǎn),錢包多大,電腦就多6
內(nèi)存的需求其實只能滿足方舟編譯器這個本體的編譯,而實際的編譯過程其實還需要編譯安卓的AOSP,這個需要耗費大量的磁盤和內(nèi)存,只是為了編譯出一個8.6M的java基礎庫
這個文件可以從網(wǎng)上下載到:
Gitee 極速下載/java-core?gitee.com但是為了照著文檔來,而且這是兩年前的文件,不知道靠不靠譜,這次手動去編譯。
如果你不打算編譯這個文件,則不需要200G磁盤,100G就綽綽有余。如果你打算像我一樣自己編譯,那么恭喜你,噩夢開始。首先2G內(nèi)存遠遠不夠,可以通過改腳本的編譯線程數(shù)來降低內(nèi)存占用,腳本默認是32線程編譯,我一路增加到了32G才堪堪完成編譯。
實際上在32G的情況下依舊出現(xiàn)了一次out of memory然后進程被kill掉的情況。這種情況下其實再make一次接著之前的編譯就好。要是每次都超內(nèi)存再給虛擬機加內(nèi)存。
適當降低編譯線程數(shù)量應該可以降低內(nèi)存占用,不過我沒試過。降低方法后面會提到。
文檔中推薦安裝的gcc5和g++5在本系統(tǒng)源里已經(jīng)不能使用,因此忽略該部分,改為使用gcc10和g++10,嗯,跨步很大,不過問題不大。
按照文檔cd 到tools目錄,準備執(zhí)行setup.sh。這里建議打開setup.sh腳本,有一些內(nèi)容我們可以提前修改,加快編譯速度,還可以定制一些東西。以下修改是我個人修改,請酌情參考,單純編譯的話,僅建議加速相關的修改。
ANDROID_VERSION=android-10.0.0_r35 ANDROID_SRCDIR=$MAPLE_ROOT/../android/$ANDROID_VERSION這里我把ANDROID_VERSION替換為了android-10.0.0_r47。不換安卓11的原因是官方說暫不支持安卓11。
ninja跟gn
相關內(nèi)容沒有修改,體積不大,不會下載很長時間。
clang編譯器
if [ ! -f $TOOLS/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04/bin/clang ]; thencd $TOOLSwget https://releases.llvm.org/8.0.0/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xzecho unpacking clang+llvm ...tar xf clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xzecho Downloaded clang+llvm. fi這里我修改了下載的llvm clang為clang+llvm-11.0.0-x86_64-linux-gnu-ubuntu-20.04
https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/clang+llvm-11.0.0-x86_64-linux-gnu-ubuntu-20.04.tar.xz?github.com同樣的,根據(jù)文檔里做對應修改
解壓并放置到openarkcompiler/tools目錄修改openarkcompiler/build/config.gni文件,將CLANG_PATH變量配置為clang編譯器所在路徑,例如:CLANG_PATH = "${MAPLE_ROOT}/tools/clang+llvm-11.0.0-x86_64-linux-gnu-ubuntu-20.04"修改openarkcompiler/build/core/maple_variables.mk文件,將CLANG_PATH配置為clang編譯器所在路徑,例如:CLANG_PATH := ${MAPLE_ROOT}/tools/clang+llvm-11.0.0-x86_64-linux-gnu-ubuntu-20.04其中${MAPLE_ROOT}為openarkcompiler源碼根目錄。
修改之后setup.sh會重新下載8.0的文件,可以通過touch一個tools/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04/bin/clang文件來跳過,也可以直接修改setup.sh中的文件名。
加速:該文件體積較大,建議提前下載,然后放到tools目錄里,原版下載地址在setup.sh中,如果你下載原版的話就不需要修改這些參數(shù),只需要tar xf解壓即可。
linaro gcc編譯器
if [ ! -f $TOOLS/gcc-linaro-7.5.0/bin/aarch64-linux-gnu-gcc ]; thencd $TOOLSwget https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/gcc-linaro-7.5.0-2019.12-i686_aarch64-linux-gnu.tar.xzecho unpacking gcc ...tar xf gcc-linaro-7.5.0-2019.12-i686_aarch64-linux-gnu.tar.xzmv gcc-linaro-7.5.0-2019.12-i686_aarch64-linux-gnu gcc-linaro-7.5.0echo Downloaded gcc aarch64 compiler. fi這次我沒改版本,直接用的7.5.0,日后有興趣再用10.2編譯一次。但是架構需要變更,我的電腦是64位,對應的下載文件應該變成gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar
https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz?releases.linaro.org加速:該文件體積較大,建議提前下載,然后放到tools目錄里,原版下載地址在setup.sh中,tar xf解壓,然后按照官方文檔重命名
解壓并放置到openarkcompiler/tools目錄,并將文件夾更名為gcc-linaro-7.5.0。NDK
if [ ! -f $TOOLS/android-ndk-r21/ndk-build ]; thencd $TOOLSwget https://dl.google.com/android/repository/android-ndk-r21d-linux-x86_64.zipecho unpacking android ndk ...unzip android-ndk-r21d-linux-x86_64.zip > /dev/nullmv android-ndk-r21d android-ndk-r21echo Downloaded android ndk. fi加速:該文件體積較大,建議提前下載,然后放到tools目錄里,原版下載地址在setup.sh中,unzip解壓,然后按照官方文檔重命名
解壓并放置到openarkcompiler/tools目錄,并將文件夾更名為android-ndk-r21。d8
相關內(nèi)容沒有修改,體積不大,不會下載很長時間。
下載編譯AOSP
這步可選,編譯安卓源碼,重頭戲。
# download and build andriod source if [ ! -d $ANDROID_DIR/out/target/product/generic_arm64/obj ]; thenmkdir -p $ANDROID_SRCDIRcd $ANDROID_SRCDIRrepo init -u https://android.googlesource.com/platform/manifest -b $ANDROID_VERSIONrepo sync. ./build/envsetup.shlunch 2make -j32ln -s $ANDROID_SRCDIR $ANDROID_DIRecho Downloaded and built AOSP. fi首先提前安裝好repo,根據(jù)谷歌官方的開源環(huán)境安裝所需組件:
sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip這里建議根據(jù)實際環(huán)境可選擇性的安裝,需要卸載gcc 10,g++10的組件可以不安。這里需要使用openjdk-8,如果用11會大概率報錯。
附安卓官方編譯環(huán)境搭建指南地址
https://source.android.com/source/initializing?source.android.com這一步強烈建議手動操作,按照腳本里的自己一步一步執(zhí)行,容易排錯。ANDROID_DIR變量和ANDROID_VERSION變量可以在腳本頭部找到。
然后按照腳本,創(chuàng)建$ANDROID_SRCDIR的目錄,然后進到這個目錄。
repo在同步的時候會檢查repo是否有更新,這里在repo init之前添加一個環(huán)境變量
export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo'修改代碼同步地址,這里選擇了清華大學的鏡像,對應的repo命令行改為,后面安卓版本號根據(jù)你自己的設計修改:
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-10.0.0_r35make -j32這一行就是編譯線程的修改,根據(jù)你電腦的配置進行修改,我頭鐵32線程死扛,所以耗了32G內(nèi)存,一般這個數(shù)量選擇為虛擬機里CPU核心數(shù)的2倍即可。
ok,開始漫長的編譯吧。
在編譯過程中可能會遇到一個報const指針轉換的錯誤,打開對應的代碼去掉const標志即可。
找不到某.so缺lib庫就安裝對應的lib庫。
遇到killed就
sudo dmesg看看是不是內(nèi)存溢出了,重新開始編譯,或者加內(nèi)存。
在make完之后,使用ln命令創(chuàng)建軟鏈接,這里要注意目錄層級不要搞錯。
重點:在創(chuàng)建完軟鏈接之后務必執(zhí)行來生成libjava-core文件
make core-all創(chuàng)建java-core.jar
# create java-core.jar if [ ! -f $MAPLE_ROOT/libjava-core/libart.jar ]; thenmkdir -p $MAPLE_ROOT/libjava-coreJLIBDIR=$ANDROID_DIR/out/target/product/generic_arm64/obj/JAVA_LIBRARIEScp -f $JLIBDIR/core-libart_intermediates/javalib.jar $MAPLE_ROOT/libjava-core/libart.jarcp -f $JLIBDIR/core-oj_intermediates/javalib.jar $MAPLE_ROOT/libjava-core/oj.jarcd $MAPLE_ROOT/libjava-core$MAPLE_ROOT/build/d8 --min-api 39 --output . libart.jar oj.jarmv classes.dex libcore-all.dexecho Copied jar files. fi這一步是有坑的,代碼應該是還沒同步完整,少了一步,在兩個cp后面還需要執(zhí)行:
DevelopmentPreparation.md documentation:116 * 將`openarkcompiler/android/out/target/product/generic_arm64/obj/JAVA_LIBRARIES/core-all_intermediates/javalib.jar`拷貝到`openarkcompiler/libjava-core`目錄,
并命名為`java-core.jar`, 同時碼云> 上也提供了編譯好的libcore的jar文件,你可以下載直接使用,下載鏈接`https://http://gitee.com/mirrors/java-core/`;
即:
cp -f $JLIBDIR/core-all_intermediates/javalib.jar $MAPLE_ROOT/libjava-core/java-core.jar參考issue:
Problem making OpenArkCompiler libcore and running sample programs. · Issue #I29K2F · 方舟編譯器/OpenArkCompiler - Gitee.com?gitee.comgcc、clang-r353983c
相關內(nèi)容沒有修改,正常跑腳本即可。
libicuuc.so
if [ ! -f $MAPLE_ROOT/third_party/icu/lib/aarch64-linux-gnu/libicuuc.so ]; thencd $TOOLSwget https://github.com/unicode-org/icu/archive/release-56-1.tar.gztar zxf release-56-1.tar.gzDIR=$TOOLS/icu-release-56-1/icu4cexport CROSS_BUILD_DIR=$DIR/linuxexport ANDROID_NDK=$MAPLE_ROOT/tools/android-ndk-r21export ANDROID_TOOLCHAIN=$DIR/toolchainexport PATH=$ANDROID_TOOLCHAIN/bin:$PATHmkdir -p $DIR/linux $DIR/aarch64(cd $DIR/linux; ../source/runConfigureICU Linux --prefix=$DIR/prebuilts; make -j16)(cd $DIR; $ANDROID_NDK/build/tools/make-standalone-toolchain.sh --platform=android-21 --install-dir=$ANDROID_TOOLCHAIN --toolchain=aarch64-linux-android-clang3.6)(cd $DIR/aarch64; ../source/configure --prefix=$DIR/prebuilt --host=aarch64-linux-android CFLAGS='-Os' CXXFLAGS='--std=c++11' --enable-shared=yes -with-cross-build=$CROSS_BUILD_DIR CC=aarch64-linux-android-clang CXX=aarch64-linux-android-clang++ AR=aarch64-linux-android-ar RINLIB=aarch64-linux-android-ranlib --with-data-packaging=archive; make -j16)AARCH64DIR=$MAPLE_ROOT/third_party/icu/lib/aarch64-linux-gnumkdir -p $AARCH64DIRcd $AARCH64DIRcp -f $DIR/aarch64/lib/libicuuc.so libicuuc.so.56cp -f $DIR/aarch64/stubdata/libicudata.so libicudata.so.56ln -s libicuuc.so.56 libicuuc.soln -s libicudata.so.56 libicudata.soecho Downloaded icu. fi加速:這一步里release-56-1.tar.gz文件體積較大,建議提前下載,注釋掉wget一行
#wget https://github.com/unicode-org/icu/archive/release-56-1.tar.gz然后手動下載這個文件,放到tools目錄,注意文件名字得是release-56-1.tar.gz,不然后面的tar zxf會找不到文件。
libz.so.1.2.8
相關內(nèi)容沒有修改,體積不大,不會下載很長時間。
到此為止,環(huán)境搭建部分結束,環(huán)境配置文檔DevelopmentPreparation.md后面的內(nèi)容就不需要看了,都包含在setup.sh了。setup.sh這個文件本身可以重復執(zhí)行,前面執(zhí)行好的部分也不會重復執(zhí)行,如果你發(fā)現(xiàn)重復執(zhí)行了,說明你手動執(zhí)行的過程還有紕漏,需要手動修正。
編譯方舟編譯器
參考開發(fā)者指南DeveloperGuide.md,開始編譯。
首先編譯生成OpenArkCompiler及maple runtime部分的Release版本:
在OpenArkCompiler目錄下執(zhí)行
source build/build.sh生成libjava-core.mplt文件
cd libjava-core jbc2mpl -injar java-core.jar -out libjava-core編譯Sample
cd samples/helloworld/ make這里我吧helloworld.java中末尾的感嘆號改成了問號,來確認確實是執(zhí)行了自己編譯的代碼。編譯完成后執(zhí)行:
java HelloWorld執(zhí)行結果:
完事。
結語
編譯的最重要的工作都在編譯AOSP上和找官方文檔上,官方文檔得互相湊,還得參考社區(qū)issue才能湊齊完整的編譯方法。然后真正的方舟編譯器編譯只有幾分鐘,真的是何苦來哉。
編譯出來的jar文件是直接在x86平臺上跑的,應該是跨平臺支持的,不知道前面搭建armv8的交叉編譯環(huán)境目的是什么,只是為了編譯AOSP么。方舟編譯器真的只是一個編譯器,想要編譯完整的安卓app需要一套ide,暫時沒空搞了,就先這樣吧,給大家一些踩過的坑的經(jīng)驗,文中有錯誤的地方希望大家可以及時指出。
關于方舟編譯器的深入學習可以移步中科院軟件所 智能軟件研究中心大佬 @小乖他爹 的文章,比我的水文干貨質量高多了。
參考資料:上面都有。
總結
以上是生活随笔為你收集整理的g++ linux 编译开栈_方舟编译器编译hello world踩坑全记录的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 7-10外连接查询
 - 下一篇: dexpler的使用方法