lzhiyong / termux-ndk

android-ndk for termux
Other
519 stars 54 forks source link

考虑绕过llvm_android直接交叉编译 #143

Closed xiaoxi-ij478 closed 8 months ago

xiaoxi-ij478 commented 11 months ago

我准备在手机上直接运行ndk(不用termux),就先试了一下llvm_android在电脑上交叉编译,然后发现不好使,直接进源码目录用ndk编译,最后成功了,但最后安装到手机上还是得调整一下目录结构才能正常使用,不知道这种方法可不可以做成脚本

这是我的配置命令,我编译的是r450784版:(xz等外置库我预先编译好了)

cmake \
-DCMAKE_TOOLCHAIN_FILE=/opt/android-sdk/ndk/25.2.9519653/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=arm64-v8a \
-DANDROID_PLATFORM=android-28 \
-DANDROID_CCACHE=/usr/bin/ccache \
-DCMAKE_INSTALL_PREFIX="$PWD/out" \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_ASSERTIONS=OFF \
-DLLVM_ENABLE_TERMINFO=OFF \
-DLLVM_ENABLE_THREADS=ON \
-DLLVM_USE_NEWPM=ON \
-DLLVM_LIBDIR_SUFFIX=64 \
-DCLANG_REPOSITORY_STRING=https://android.googlesource.com/toolchain/llvm-project \
-DBUG_REPORT_URL=https://github.com/android-ndk/ndk/issues \
-DLIBCXX_HAS_ATOMIC_LIB=NO \
-DLLVM_ENABLE_LIBCXX=ON \
-DPython3_EXECUTABLE=/usr/bin/python3 \
-DLLDB_ENABLE_LUA=OFF \
-DLLDB_ENABLE_PYTHON=OFF \
-DLLDB_ENABLE_LZMA=ON \
-DLIBLZMA_INCLUDE_DIR=/home/careful/Desktop/Android/llvm/toolchain/xz/build/out/include/ \
-DLIBLZMA_LIBRARY=/home/careful/Desktop/Android/llvm/toolchain/xz/build/out/lib/liblzma.a \
-DLLDB_ENABLE_LIBEDIT=ON \
-DLibEdit_INCLUDE_DIRS=/home/careful/Desktop/Android/llvm/external/libedit/build/out/include/ \
-DLibEdit_LIBRARIES=/home/careful/Desktop/Android/llvm/external/libedit/build/out/lib/libedit.a \
-DLLDB_ENABLE_LIBXML2=ON \
-DLLDB_ENABLE_CURSES=ON \
-DCURSES_INCLUDE_DIRS='/home/careful/Desktop/Android/llvm/external/libncurses/build/out/include/;/home/careful/Desktop/Android/llvm/external/libncurses/build/out/include/ncurses/' \
-DCURSES_LIBRARIES='/home/careful/Desktop/Android/llvm/external/libncurses/build/out/lib/libncurses.a;/home/careful/Desktop/Android/llvm/external/libncurses/build/out/lib/libform.a;/home/careful/Desktop/Android/llvm/external/libncurses/build/out/lib/libpanel.a' \
-DPANEL_LIBRARIES='/home/careful/Desktop/Android/llvm/external/libncurses/build/out/lib/libncurses.a;/home/careful/Desktop/Android/llvm/external/libncurses/build/out/lib/libform.a;/home/careful/Desktop/Android/llvm/external/libncurses/build/out/lib/libpanel.a' \
-DLLVM_ENABLE_PROJECTS='clang;lld;clang-tools-extra;polly;bolt;lldb' \
-DLLVM_ENABLE_RUNTIMES='libcxx;libunwind;openmp;compiler-rt;libcxxabi' \
-DLIBUNWIND_ENABLE_SHARED=FALSE \
-DLIBUNWIND_TARGET_TRIPLE=aarch64-linux-android28 \
-DLIBUNWIND_ENABLE_ASSERTIONS=FALSE \
-DOPENMP_ENABLE_LIBOMPTARGET=FALSE \
-DOPENMP_ENABLE_OMPT_TOOLS=FALSE \
-DLIBOMP_ENABLE_SHARED=FALSE \
-DCOMPILER_RT_INCLUDE_TESTS=OFF \
-DCOMPILER_RT_DEFAULT_TARGET_TRIPLE=aarch64-linux-android28 \
-DLLVM_TARGETS_TO_BUILD=AArch64 \
-DLLVM_BUILD_LLVM_DYLIB=ON \
-DCLANG_VENDOR='Android (9352603, based on r450784d1)' \
-DLLVM_BUILD_RUNTIME=ON \
-DLLVM_INCLUDE_GO_TESTS=OFF \
-DLIBXML2_INCLUDE_DIR=/home/careful/Desktop/Android/llvm/external/libxml2/build/out/include/libxml2/ \
-DLIBXML2_LIBRARY=/home/careful/Desktop/Android/llvm/external/libxml2/build/out/lib/libxml2.so \
-DLLVM_HOST_TRIPLE=aarch64-linux-android28 \
-DLLVM_DEFAULT_TARGET_TRIPLE=aarch64-linux-android28 \
-DLLVM_TARGET_ARCH=AArch64 \
-DSANITIZER_ALLOW_CXXABI=OFF \
-DCLANG_PYTHON_BINDINGS_VERSIONS=3 \
-DCOMPILER_RT_BUILD_LIBFUZZER=ON \
-DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=ON \
-DLIBCXX_ENABLE_ABI_LINKER_SCRIPT=OFF \
-DLLVM_INCLUDE_TESTS=FALSE \
-DRUNTIMES_CMAKE_ARGS="-DCMAKE_ASM_FLAGS=/opt/android-sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/14.0.7/lib/linux/aarch64/libatomic.a /dev/shm/llvm-build/lib64/clang/14.0.0/lib/aarch64-linux-android28/libclang_rt.builtins.a /opt/android-sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/14.0.7/lib/linux/aarch64/libunwind.a -L/opt/android-sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/14.0.7/lib/linux/aarch64/;-DCMAKE_MODULE_LINKER_FLAGS=/opt/android-sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/14.0.7/lib/linux/aarch64/libatomic.a /dev/shm/llvm-build/lib64/clang/14.0.0/lib/aarch64-linux-android28/libclang_rt.builtins.a /opt/android-sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/14.0.7/lib/linux/aarch64/libunwind.a -L/opt/android-sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/14.0.7/lib/linux/aarch64/;-DCMAKE_SHARED_LINKER_FLAGS=/opt/android-sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/14.0.7/lib/linux/aarch64/libatomic.a /dev/shm/llvm-build/lib64/clang/14.0.0/lib/aarch64-linux-android28/libclang_rt.builtins.a /opt/android-sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/14.0.7/lib/linux/aarch64/libunwind.a -L/opt/android-sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/14.0.7/lib/linux/aarch64/;-DCMAKE_EXE_LINKER_FLAGS=/opt/android-sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/14.0.7/lib/linux/aarch64/libatomic.a /dev/shm/llvm-build/lib64/clang/14.0.0/lib/aarch64-linux-android28/libclang_rt.builtins.a /opt/android-sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/14.0.7/lib/linux/aarch64/libunwind.a -L/opt/android-sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/14.0.7/lib/linux/aarch64/;-DCMAKE_TOOLCHAIN_FILE=/opt/android-sdk/ndk/25.2.9519653/build/cmake/android.toolchain.cmake;-DANDROID_ABI=arm64-v8a;-DANDROID_PLATFORM=android-28;-DANDROID_CCACHE=/usr/bin/ccache" \
../llvm-project/llvm
lzhiyong commented 11 months ago

build.py本质上也是生成一个这样的编译配置文件,只要你的这个配置命令没什么问题,编译出来的clang也是正确的,完全可以不使用build.py进行编译

我觉得最好就是参考build.py默认生成的,然后再自己修改,但是每个Ndk版本这些编译脚本可能会有所改动

build.py编译时会进行打补丁,同时配置profdata文件进行优化

xiaoxi-ij478 commented 11 months ago

其实我这个想法是因为按照您给的patch修改以后我还是没法编译过(可能确实是因为版本不同的问题)才想出的 如果ndk版本之间编译脚本没有太大变化,或许可以直接用以前版本的脚本,省一些时间

xiaoxi-ij478 commented 11 months ago

我觉得分析配置参数都是简单工作,重点还是在于后面的打包工作,因为我编译出来的clang一堆文件都不在标准位置(可能是我的配置参数有误),还需要后期调整才能运行

zongou commented 11 months ago

我发现一个项目 https://github.com/shengyun-zhou/llvm-cross-toolchains 我试了一下编译gnumake没有问题。

看了看代码只是整理了一下文件,所以我试着proot的Debian里,下载预编译的llvm工具链放到linux-64的ndk里,试了一下编译gnumake,没有问题。

所以有可能我们不需要下载30G的源码再解决一大堆bug去编译,直接替换整理一下文件就行了。 zig工具链是可以直接在安卓裸机上跑的,所以有可能,我们操作一下就能搞出直接在手机上直接跑的工具链,而且不会很麻烦。

xiaoxi-ij478 commented 11 months ago

我发现一个项目 https://github.com/shengyun-zhou/llvm-cross-toolchains 我试了一下编译gnumake没有问题。

看了看代码只是整理了一下文件,所以我试着proot的Debian里,下载预编译的llvm工具链放到linux-64的ndk里,试了一下编译gnumake,没有问题。

所以有可能我们不需要下载30G的源码再解决一大堆bug去编译,直接替换整理一下文件就行了。 zig工具链是可以直接在安卓裸机上跑的,所以有可能,我们操作一下就能搞出直接在手机上直接跑的工具链,而且不会很麻烦。

我就是这么做的,已经做出来了,而且可以直接用,只不过很多文件的位置还得调整一下,不知道这一步可不可以写一个脚本

xiaoxi-ij478 commented 11 months ago

Screenshot_2023-10-21-22-40-52-055_jackpal androidterm

zongou commented 11 months ago

你想实现啥效果?


From: xiaoxi-ij478 @.> Sent: Saturday, October 21, 2023 22:44 To: lzhiyong/termux-ndk @.> Cc: zongou @.>; Comment @.> Subject: Re: [lzhiyong/termux-ndk] 考虑绕过llvm_android直接交叉编译 (Issue #143)

[Screenshot_2023-10-21-22-40-52-055_jackpal androidterm]https://user-images.githubusercontent.com/32544095/277114574-08abcc29-54a1-4225-b18d-32a6e8393e27.jpg

― Reply to this email directly, view it on GitHubhttps://github.com/lzhiyong/termux-ndk/issues/143#issuecomment-1773814611, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AFRAYUBKHCSD7QVNJRJBWO3YAPNUJAVCNFSM6AAAAAA5V3HCKWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONZTHAYTINRRGE. You are receiving this because you commented.Message ID: @.***>

xiaoxi-ij478 commented 11 months ago

就是直接在安卓裸机上跑工具链啊

zongou commented 11 months ago

我看你应该是直接编译的安卓llvm工具链,上面那个项目用到了--sysroot这样的变量,文件是直接从ndk里面提取的,所以我们也可以这么搞,提取一下文件,然后通过变量或参数传递给clang应该就行,我们不需要一整个ndk,这样可以大幅度缩小体积


From: ZongOu Huang @.> Sent: Saturday, October 21, 2023 22:54 To: xiaoxi-ij478 @.>; lzhiyong/termux-ndk @.>; lzhiyong/termux-ndk @.> Cc: Comment @.***> Subject: Re: [lzhiyong/termux-ndk] 考虑绕过llvm_android直接交叉编译 (Issue #143)

你想实现啥效果?


From: xiaoxi-ij478 @.> Sent: Saturday, October 21, 2023 22:44 To: lzhiyong/termux-ndk @.> Cc: zongou @.>; Comment @.> Subject: Re: [lzhiyong/termux-ndk] 考虑绕过llvm_android直接交叉编译 (Issue #143)

[Screenshot_2023-10-21-22-40-52-055_jackpal androidterm]https://user-images.githubusercontent.com/32544095/277114574-08abcc29-54a1-4225-b18d-32a6e8393e27.jpg

― Reply to this email directly, view it on GitHubhttps://github.com/lzhiyong/termux-ndk/issues/143#issuecomment-1773814611, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AFRAYUBKHCSD7QVNJRJBWO3YAPNUJAVCNFSM6AAAAAA5V3HCKWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONZTHAYTINRRGE. You are receiving this because you commented.Message ID: @.***>

zongou commented 11 months ago

我试试操作一下zig,和你是同一个目标,裸机上跑工具链


From: ZongOu Huang @.> Sent: Saturday, October 21, 2023 23:03 To: xiaoxi-ij478 @.>; lzhiyong/termux-ndk @.>; lzhiyong/termux-ndk @.> Cc: Comment @.***> Subject: Re: [lzhiyong/termux-ndk] 考虑绕过llvm_android直接交叉编译 (Issue #143)

我看你应该是直接编译的安卓llvm工具链,上面那个项目用到了--sysroot这样的变量,文件是直接从ndk里面提取的,所以我们也可以这么搞,提取一下文件,然后通过变量或参数传递给clang应该就行,我们不需要一整个ndk,这样可以大幅度缩小体积


From: ZongOu Huang @.> Sent: Saturday, October 21, 2023 22:54 To: xiaoxi-ij478 @.>; lzhiyong/termux-ndk @.>; lzhiyong/termux-ndk @.> Cc: Comment @.***> Subject: Re: [lzhiyong/termux-ndk] 考虑绕过llvm_android直接交叉编译 (Issue #143)

你想实现啥效果?


From: xiaoxi-ij478 @.> Sent: Saturday, October 21, 2023 22:44 To: lzhiyong/termux-ndk @.> Cc: zongou @.>; Comment @.> Subject: Re: [lzhiyong/termux-ndk] 考虑绕过llvm_android直接交叉编译 (Issue #143)

[Screenshot_2023-10-21-22-40-52-055_jackpal androidterm]https://user-images.githubusercontent.com/32544095/277114574-08abcc29-54a1-4225-b18d-32a6e8393e27.jpg

― Reply to this email directly, view it on GitHubhttps://github.com/lzhiyong/termux-ndk/issues/143#issuecomment-1773814611, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AFRAYUBKHCSD7QVNJRJBWO3YAPNUJAVCNFSM6AAAAAA5V3HCKWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONZTHAYTINRRGE. You are receiving this because you commented.Message ID: @.***>

xiaoxi-ij478 commented 11 months ago

你可以试试我的方法:找到llvm_android这个仓库,然后分析它都编译了什么库,和编译参数,把它们拿出来做一个脚本 但是这个方法需要太多调整 我可以给你看看我做的部分可用的脚本,NDK版本是25.2.9519653,编译的是和它同等版本的llvm (在ndk的toolchains下有一个manifest_9352603.xml,可以看那个找你需要的仓库地址) https://gist.github.com/xiaoxi-ij478/6b931559c9f935b610c3c0ec4ccd2367

lzhiyong commented 11 months ago

@xiaoxi-ij478 build.py配置成功后会生成cmake_invocation.sh,这个就是编译脚本 cmake_invocation.txt

# stage2阶段编译,源码已经配置过和打补丁了
# 所以可以直接 --skip-apply-patches --skip-source-setup
python build.py --no-build windows --skip-apply-patches --skip-source-setup --skip-tests --skip-runtimes --single-stage --lto --bolt --pgo --mlgo --sccache

你可以参考上面的cmake_invocation.txt,这是build.py默认生成的配置 这里面我加了两项: -DLLVM_TARGET_ARCH = AArch64 -DLLVM_HOST_TRIPLE = aarch64-unknown-linux-android

注意这个是ndk-r26b 不是r25, 开启mlgo(机器学习,ai)需要配置tensorflow,tensorflow-aarch64 开启pgo优化需要配置xxx.profdata文件

r26b我还没有编译成功,编译rumtimes时出现了错误,暂时还没找到解决方案

xiaoxi-ij478 commented 11 months ago

开启mlgo(机器学习,ai)需要配置tensorflow,tensorflow-aarch64 开启pgo优化需要配置xxx.profdata文件

这两个我没开,因为我裸机跑编译器用不到

r26b我还没有编译成功,编译rumtimes时出现了错误,暂时还没找到解决方案

等一等,我记得我也出现了错误,给你看一看,是不是和你遇到是一样的

xiaoxi-ij478 commented 11 months ago

@lzhiyong

CMake Error at /dev/shm/a/llvm-project/compiler-rt/cmake/config-ix.cmake:213 (message): Please use architecture with 4 or 8 byte pointers. Call Stack (most recent call first): /dev/shm/a/llvm-project/compiler-rt/CMakeLists.txt:251 (include)

上面都是一些什么 not found 和 Failed 的

xiaoxi-ij478 commented 11 months ago

我发现一个问题 你是不是直接改了 config.py,把主机编译配置改成了 AndroidConfig,因为 cmake_invocation.sh 里有一个路径 /home/llvm-toolchain/prebuilts/clang/host/linux-x86/clang-r487747/sysroot/usr/aarch64-linux-android/bin,这个我在我的目录里没找到,可能是因为这个才导致你编译不过的 ndk 默认是给 x86_64 编译的,如果要直接给安卓裸机编译需要像 ndk 一样加一些类似 --target=aarch64-linux-android28 的选项才能过

xiaoxi-ij478 commented 11 months ago

所以我觉得可以从 cmake_invocation.sh 里找到一些和 llvm 本身有关的参数,然后加 ndk 给我们的 cmake 工具链文件编译

zongou commented 11 months ago

我已经实现了用zig在安卓裸机上编译c以及c++ 效果图 Screenshot from 2023-10-27 10-32-36 配置zig的自动化脚本 https://github.com/zongou/zig-ndk

zongou commented 11 months ago

我发现一个项目 https://github.com/shengyun-zhou/llvm-cross-toolchains 我试了一下编译gnumake没有问题。 看了看代码只是整理了一下文件,所以我试着proot的Debian里,下载预编译的llvm工具链放到linux-64的ndk里,试了一下编译gnumake,没有问题。 所以有可能我们不需要下载30G的源码再解决一大堆bug去编译,直接替换整理一下文件就行了。 zig工具链是可以直接在安卓裸机上跑的,所以有可能,我们操作一下就能搞出直接在手机上直接跑的工具链,而且不会很麻烦。

我就是这么做的,已经做出来了,而且可以直接用,只不过很多文件的位置还得调整一下,不知道这一步可不可以写一个脚本

这几天搞zig我获取了一些经验 llvm工具链有两个东西比较重要,就是sysroot和resource_dir sysroot我们通过sysroot参数传递过去就行,resource dir 可以通过clang -print-resource-dir获取。 还有一些不太重要的比如runtime dir,不同的target可能会有不同的runetimedir,可以通过clang -print-runtime-dir获取

然后就是一些debug用的参数, -v,和-### 打印运行过程,可以看到内部在编译时的include dirs 和 和链接时的search dirs,这个search dirs 也可以通过clang -print-search-dirs打印

你可以看看我的脚本是怎么实现的