Fix android ndk clang#21222
Fix android ndk clang#21222holmesconan wants to merge 13 commits intomicrosoft:masterfrom holmesconan:fix-android-ndk-clang
Conversation
|
The only notification is that, please add Android NDK toolchain executable path:
|
dg0yt
left a comment
There was a problem hiding this comment.
Thanks for the PR. This is just a quick review in Github.
| # Android - cross-compiling support | ||
| if(VCPKG_TARGET_IS_ANDROID) | ||
| if (VCPKG_DETECTED_CMAKE_CXX_COMPILER_ID MATCHES "^Clang$") | ||
| string(REPLACE "-static-libstdc++" "-lc++_static" VCPKG_DETECTED_CMAKE_CXX_STANDARD_LIBRARIES ${VCPKG_DETECTED_CMAKE_CXX_STANDARD_LIBRARIES}) |
There was a problem hiding this comment.
I wonder why this should be wrong in the detected libraries. IIRC, the NDK's toolchain has variables to configure the C++ runtime. Can't we hook into chainloading and configuring this toolchain, and then leave the detected values untouched?
There was a problem hiding this comment.
I cannot answer this. I have tried to hook the <VCPKG_ROOT>/scripts/toolchains/android.cmake for adding some util variables, but it seems that vcpkg_configure_make.cmake do not reference that file. So I have to specify the ANDROID_API_LEVEL again. So I do not think it is easy to hook NDK's toolchain file to obtain the detected. Or if I could fully understand how to do it.
There was a problem hiding this comment.
This export should be done in the CMakeLists.txt of vcpkg_get_cmake_vars so that meson and other buildsystems are also informed about the required flags.
| set(ANDROID_API_LEVEL $ENV{ANDROID_API_LEVEL} CACHE STRING "") | ||
| else() | ||
| set(ANDROID_API_LEVEL ${VCPKG_DETECTED_CMAKE_SYSTEM_VERSION} CACHE STRING "") | ||
| endif() |
There was a problem hiding this comment.
I wonder if respecting ENV{ANDROID_API_LEVEL} at this point may break binary caching.
There was a problem hiding this comment.
I think yes, it would be. Since different API level may have different ABI, especially for the libc++. If one library is compiled with ANDROID_API_LEVEL equals 21, but others with 23, for example. They could not be linked into the final .so file.
There was a problem hiding this comment.
I don't see why we should consider ENV{ANDROID_API_LEVEL} here?
| set(base_cmd) | ||
| if(CMAKE_HOST_WIN32) | ||
| set(base_cmd ${bash_executable} --noprofile --norc --debug) | ||
| set(base_cmd ${BASH} --noprofile --norc --debug) |
There was a problem hiding this comment.
There is no BASH here. I think this was renamed to bash_executable as part of the script audit, parallel to your work.
There was a problem hiding this comment.
Yes, I checked the upstream version, I will fix it. It was caused by merging without check. shame.
There was a problem hiding this comment.
This caused the CI to fail. fixed.
| # -avoid-version is handled specially by libtool link mode, this flag is not forwarded to linker, | ||
| # and libtool tries to avoid versioning for shared libraries and no symbolic links are created. | ||
| if(VCPKG_TARGET_IS_ANDROID) | ||
| if(VCPKG_TARGET_IS_ANDROID AND VCPKG_DETECTED_CMAKE_C_COMPILER_ID MATCHES "^GNU$") |
There was a problem hiding this comment.
Isn't it needed, or does it break, with clang?
There was a problem hiding this comment.
PS: STREQUAL "GNU" would suffice.
There was a problem hiding this comment.
actually, it just generated a warning for argument unused during compilation.
There was a problem hiding this comment.
This is removed. God bless no weird problems happen.
1. ${BASH} -> ${bash_executable}
2. -avoid-version patch ignored
…o fix-android-ndk-clang
dg0yt
left a comment
There was a problem hiding this comment.
We should not unconditionally override (set) arg_BUILD_TRIPLET for Android. It is a valid argument to be supplied by the calling portfile, and it may be overridden by the triplet file. Even if not used in vcpg at the moment, this is public interface possibly used in user's ports or triplets.
The pattern for windows and macos is:
if(VCPKG_TARGET_IS_ANDROID)
if(arg_DETERMINE_BUILD_TRIPLET OR NOT arg_BUILD_TRIPLET)
...
set(arg_BUILD_TRIPLET ...
| # shell which will be otherwise identified as ${BUILD_ARCH}-pc-msys | ||
| elseif(VCPKG_HOST_IS_OSX) | ||
| z_vcpkg_determine_autotools_host_arch_mac(BUILD_ARCH) # machine you are building on => --build= | ||
| set(arg_BUILD_TRIPLET "--build=${BUILD_ARCH}-apple-darwin${VCPKG_CMAKE_HOST_SYSTEM_VERSION}") |
There was a problem hiding this comment.
I guess the last variable is named VCPKG_DETECTED_CMAKE_HOST_SYSTEM_VERSION.
|
Failed to build |
I wonder how this PR can have a side effect on |
Well, there is one changed line which is unrelated to android, but very much related to x64-osx: This change is reasonable, but maybe it needs investigation in a separate PR. By changing host detection, the cross-build property will change to, and this can uncover bugs in other ports. |
|
made a little changes for the z_vcpkg_determine_autotools_host_cpu. if it doesn't resolve the problem, I cannot fix it now. My Macbook is dead..... |
|
More tests on Android libraries are needed. Anyone who have problems are welcome. |
|
Please ping me if this PR is ready for review. Also, cc @Neumann-A for review the configure_make part. |
|
@JackBoosY Yes, it is ready for review. @Neumann-A |
| set(ANDROID_API_LEVEL $ENV{ANDROID_API_LEVEL} CACHE STRING "") | ||
| else() | ||
| set(ANDROID_API_LEVEL ${VCPKG_DETECTED_CMAKE_SYSTEM_VERSION} CACHE STRING "") | ||
| endif() |
There was a problem hiding this comment.
I don't see why we should consider ENV{ANDROID_API_LEVEL} here?
| if (TARGET_ARCH MATCHES "armv7-a") | ||
| string(APPEND configure_env " CC=armv7a-linux-androideabi${ANDROID_API_LEVEL}-clang") | ||
| string(APPEND configure_env " CXX=armv7a-linux-androideabi${ANDROID_API_LEVEL}-clang++") | ||
| else() | ||
| string(APPEND configure_env " CC=${TARGET_ARCH}-linux-android${ANDROID_API_LEVEL}-clang") | ||
| string(APPEND configure_env " CXX=${TARGET_ARCH}-linux-android${ANDROID_API_LEVEL}-clang++") | ||
| endif() | ||
|
|
||
| string(APPEND configure_env " AR=llvm-ar") | ||
| string(APPEND configure_env " RANLIB=llvm-ranlib") | ||
| string(APPEND configure_env " READELF=llvm-readelf") | ||
| string(APPEND configure_env " STRIP=llvm-strip") |
There was a problem hiding this comment.
Simply no. Setup the toolchain correctly..... CC and CXX and the rest of the programs should be correctly setup by cmake.
There was a problem hiding this comment.
I use the ENV{ANDROID_API_LEVEL} since I don't want to add another argument for vcpkg_configure_make. It needs more consideration about the general purpose. It seems that an argument is reasonable? One need to customize the ANDROID API LEVEL instead of the detected version.
There was a problem hiding this comment.
Actually, the CC and CXX environment variables are the core patch of this PR. Without that, the autotools configure script could not find the compiler properly.
There was a problem hiding this comment.
Actually, the CC and CXX environment variables are the core patch of this PR
but not in this way because it is too specific. If necessary there needs to be a simple branch which setups all progs correctly to the VCPKG_DETECTED_ variables (like in the windows branch)
There was a problem hiding this comment.
The toolchain did not correctly setup by cmake since it was out of control. When reading config-x86-android-dbg-out.txt in buildtree//, I found that most cross-compile toolchains are grabbed from the system, not in the NDK. It won't work. So I need to manually specify the toolchain through configure_env.
There was a problem hiding this comment.
I would say that is not a problem for vcpkg_configure_make to solve.
| CMAKE_HOST_SYSTEM_PROCESSOR) | ||
| CMAKE_HOST_SYSTEM_PROCESSOR | ||
| CMAKE_SYSTEM_VERSION | ||
| CMAKE_HOST_SYSTEM_VERSION) |
There was a problem hiding this comment.
| CMAKE_HOST_SYSTEM_VERSION) |
don't see why we should care about CMAKE_HOST_SYSTEM_VERSION. vcpkg should only focus on building for the target.
There was a problem hiding this comment.
When cross-compile python3, one needs to specify the --build option and on osx, it will be x86_64-apple-darwin20.6.0, where 20.6.0 is the host system version in cmake. In other words, when cross-compile some libraries on osx, one may need that variable. Yes I will shrink it to CMAKE_HOST_SYSTEM_VERSION only.
There was a problem hiding this comment.
When cross-compile python3
that seems oddly specific to python3. The typically configure scripts don't care about anything after *-darwin*
| if (DEFINED ENV{ANDROID_API_LEVEL}) | ||
| set(ANDROID_NATIVE_API_LEVEL $ENV{ANDROID_API_LEVEL} CACHE STRING "") | ||
| set(ANDROID_PLATFORM $ENV{ANDROID_API_LEVEL} CACHE STRING "") | ||
| else() | ||
| set(ANDROID_NATIVE_API_LEVEL ${CMAKE_SYSTEM_VERSION} CACHE STRING "") | ||
| set(ANDROID_PLATFORM ${CMAKE_SYSTEM_VERSION} CACHE STRING "") | ||
| endif() | ||
|
|
There was a problem hiding this comment.
without env passthrough in the triplet ENV{ANDROID_API_LEVEL} will be always empty on windows. So a custom triplet will be necessary anyway and if that is already necessary having a custom specialized toolchain is also not too far away. (I really hate this all purpose android toolchain which includes all possible arches .... )
There was a problem hiding this comment.
Yes, that is why I add the ENV here. The first time I use it, the previous version only set the ANDROID_NATIVE_API_LEVEL with an empty value. I don't know how to fix this.
|
Again I feel like the default android toolchain vcpkg provides should be removed and replaced with specialized toolchains for each architecture and case. There seems to be a bigger misunderstanding of vcpkg is supposed to work and what work should be done by the configure scripts. |
|
@holmescn You just closed this PR while I was writing a comment. I actively invited this PR, and I hoped we could help to form an acceptable result, no matter how hard it is to get Android right in vcpkg. I don't see another effort to move things for Android in vcpkg. |
|
@dg0yt Thank you for your invitation. Since @Neumann-A made a difficult goal that needs to solve the problem generically. I don't think I have the time and skill to accomplish that target. This is a temporary solution that has many problems unknown. I hope any successor could find more elegant ways to touch the goal, maybe inspired by this effort or not. I would like to give any help if I could. |
|
As a generic solution, we need to consider from scratch that how vcpkg passthrough each detected variable down to the build system and why they are not catched by the Android NDK toolchain. It needs more knowledge about how vcpkg works. |
This is a fix of Android triplets that using clang as the default compiler.
What does your PR fix?
Fix vcpkg_configure_make based port cannot find gcc (aka clang) compiler during config stage
Fix ANDROID_NATIVE_API_LEVEL only detected from CMAKE_SYSTEM_VERSION, add ENV{ANDROID_API_LEVEL} for customizing
Which triplets are supported/not supported? Have you updated the CI baseline?
android, No
Does your PR follow the maintainer guide?
YesIf you have added/updated a port: Have you run
./vcpkg x-add-version --alland committed the result?No
If you are still working on the PR, open it as a Draft: https://github.blog/2019-02-14-introducing-draft-pull-requests/