hxcpp icon indicating copy to clipboard operation
hxcpp copied to clipboard

Support Android NDKs higher than 21

Open player-03 opened this issue 2 years ago • 3 comments

Version 22 changed the NDK's structure, meaning some files and folders aren't where hxcpp expects them.


To test this, create the following three files, and compile with haxelib run hxcpp Build.xml -Dandroid.

  1. Hello.cpp:

    #include <stdio.h>
    
    #include <atomic>
    
    int main(int argc, char **argv) {
    	printf("Hello world\n");
    	return 0;
    }
    
  2. Build.xml:

    <xml>
    	<set name="HXCPP_ARM64" value="1" if="android" />
    
    	<files id="hello">
    		<file name="Hello.cpp" />
    	</files>
    
    	<target id="default" output="hello" tool="linker" toolid="${STD_MODULE_LINK}">
    		<outdir name="bin" />
    		<ext value="" />
    		<files id="hello" />
    	</target>
    </xml>
    
  3. Options.txt: (empty)


In my tests, NDK r21e worked fine, but r23 (edit: and r24) ran into multiple errors upon reaching #include <atomic>. (First it couldn't find the file, then it couldn't compile it.)

After applying the changes in this pull request, r21e, r23, and r24 all work correctly. I'm not certain there are no regressions elsewhere, but I tried to minimize that risk.

Potentially useful reference: https://developer.android.com/ndk/guides/other_build_systems


Closes #706.

player-03 avatar May 24 '22 05:05 player-03

This may close #998, #999, and #1000 as well. I tried compiling with NDK 24 just now and ran into a similar error to those three issues, but it went away when I merged this PR.

justin-espedal avatar Jun 14 '22 08:06 justin-espedal

I did have to modify one thing for NDK 24 to work.

android-toolchain-clang.xml sets the android platform in a few places.

<set name="PLATFORM_NUMBER" value="16" />

That caused the following compilation error:

 - Running command: clang++ -Iinclude --target=armv7a-linux-androideabi16 -DHXCPP_ARMV7 -DHXCPP_VISIT_ALLOCS -DHX_SMART_STRINGS -DHXCPP_API_LEVEL=400 -I/dev/haxelib/hxcpp/include -Iinclude -DANDROID=ANDROID -DHXCPP_CLANG -DHX_ANDROID -DHXCPP_ANDROID_PLATFORM=16 -fvisibility=hidden -ffunction-sections -fstack-protector -fexceptions -c -fpic -O2 -Wno-invalid-offsetof -Wno-return-type-c-linkage -Wno-parentheses -x c++-header -o "/dev/test game/Export/android/obj/obj/android-v7/__pch/haxe/hxcpp.h.gch" /dev/haxelib/hxcpp/include/hxcpp.h
In file included from /dev/haxelib/hxcpp/include/hxcpp.h:27:
In file included from /dev/android-ndk-r24/toolchains/llvm/prebuilt/darwin-x86_64/bin/../sysroot/usr/include/c++/v1/typeinfo:60:
In file included from /dev/android-ndk-r24/toolchains/llvm/prebuilt/darwin-x86_64/bin/../sysroot/usr/include/c++/v1/exception:81:
In file included from /dev/android-ndk-r24/toolchains/llvm/prebuilt/darwin-x86_64/bin/../sysroot/usr/include/c++/v1/cstdlib:85:
In file included from /dev/android-ndk-r24/toolchains/llvm/prebuilt/darwin-x86_64/bin/../sysroot/usr/include/c++/v1/stdlib.h:100:
/dev/android-ndk-r24/toolchains/llvm/prebuilt/darwin-x86_64/bin/../sysroot/usr/include/c++/v1/math.h:1377:93: error: no member named 'log2f' in the global namespace
inline _LIBCPP_INLINE_VISIBILITY float       log2(float __lcpp_x) _NOEXCEPT       {return ::log2f(__lcpp_x);}
                                                                                          ~~^
/dev/android-ndk-r24/toolchains/llvm/prebuilt/darwin-x86_64/bin/../sysroot/usr/include/c++/v1/math.h:1378:93: error: no member named 'log2l' in the global namespace
inline _LIBCPP_INLINE_VISIBILITY long double log2(long double __lcpp_x) _NOEXCEPT {return ::log2l(__lcpp_x);}
                                                                                          ~~^
/dev/android-ndk-r24/toolchains/llvm/prebuilt/darwin-x86_64/bin/../sysroot/usr/include/c++/v1/math.h:1383:38: error: call to 'log2' is ambiguous
log2(_A1 __lcpp_x) _NOEXCEPT {return ::log2((double)__lcpp_x);}
                                     ^~~~~~
/dev/android-ndk-r24/toolchains/llvm/prebuilt/darwin-x86_64/bin/../sysroot/usr/include/c++/v1/math.h:1377:46: note: candidate function
inline _LIBCPP_INLINE_VISIBILITY float       log2(float __lcpp_x) _NOEXCEPT       {return ::log2f(__lcpp_x);}
                                             ^
/dev/android-ndk-r24/toolchains/llvm/prebuilt/darwin-x86_64/bin/../sysroot/usr/include/c++/v1/math.h:1378:46: note: candidate function
inline _LIBCPP_INLINE_VISIBILITY long double log2(long double __lcpp_x) _NOEXCEPT {return ::log2l(__lcpp_x);}
                                             ^
3 errors generated.
Error: Error while running command
clang++ -Iinclude --target=armv7a-linux-androideabi16 -DHXCPP_ARMV7 -DHXCPP_VISIT_ALLOCS -DHX_SMART_STRINGS -DHXCPP_API_LEVEL=400 -I/dev/haxelib/hxcpp/include -Iinclude -DANDROID=ANDROID -DHXCPP_CLANG -DHX_ANDROID -DHXCPP_ANDROID_PLATFORM=16 -fvisibility=hidden -ffunction-sections -fstack-protector -fexceptions -c -fpic -O2 -Wno-invalid-offsetof -Wno-return-type-c-linkage -Wno-parentheses -x c++-header -o "/dev/test game/Export/android/obj/obj/android-v7/__pch/haxe/hxcpp.h.gch" /dev/haxelib/hxcpp/include/hxcpp.h

I assumed that it's related to NDK 24 dropping support for Jelly Bean (APIs 16, 17, and 18). When I changed the hardcoded platform to 19, it compiled successfully.

Allowing the platform to be passed in and/or changing the minimum value if ndk 24 is used may help.

edit: This seems to be covered by the sysroot section of the build system maintainers documentation. The API level determines what folder is included, so for each NDK we have to pass an API level that's within the expected range. Unfortunately I can't find a support matrix of any sort online. The min/max api levels can be seen in each ndk in meta/platforms.json, and api level additions/removals seem to be listed in the ndk changelogs as well.

edit2: No clue why NDK 24 worked for you without this change though!

justin-espedal avatar Jun 14 '22 08:06 justin-espedal

I'm fairly certain the FNF users all have the same problem, and it isn't this.


As for the platform number, good catch. Looks like it worked for me because I only compiled the arm64 version. If I tested something more complicated like Lime, it might have compiled 32-bit versions and caused the error.

player-03 avatar Jun 14 '22 16:06 player-03

What would it take to get this merged? Lime is now in a position where it can use more recent NDKs, but this is holding it back.

player-03 avatar Oct 29 '22 18:10 player-03