Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[question] Detect NDK r19 or later. #1029

Closed
MikuAuahDark opened this issue Jun 29, 2019 · 15 comments
Closed

[question] Detect NDK r19 or later. #1029

MikuAuahDark opened this issue Jun 29, 2019 · 15 comments
Labels

Comments

@MikuAuahDark
Copy link

MikuAuahDark commented Jun 29, 2019

I have an Android.mk which does work on NDK r18 and earlier but not when using NDK r19 due to conflicting functions.

Scenario: I have library that is compiled with ndk-build. The library itself is using autoconf/autotools/whatever you call it to generate config.h but since it's simple enough, I can create dummy config.h and define everything using LOCAL_C_FLAGS and write the Android.mk. Now the problem with NDK r19 is that it defines log2f regardless of API level, but in previous version this is not the case, so I'm getting conflicting functions regarding log2f. If I made the changes to always add -DHAVE_LOG2F (standard convention for autotools config.h) unconditionally, the library is uncompileable in older NDK version because log2f is undefined. But if I didn't add it, it fails to build in r19 because conflicting log2f (let alone r20). The problematic arch is armeabi-v7a as this problem simply non-existent in x86 and arm64-v8a (log2f always defined regardless).

I'd like to make sure my Android.mk support older NDK version to support more older devices but at this point it's no longer possible? How would I detect for such case and what action is the best I can take?

@alexcohn
Copy link

alexcohn commented Jul 1, 2019

To detect the current version of NDK, you can read the file source.properties at ${NDK_ROOT}. This is how the official Cmake toolchain file sniffs the version. You can also check the version of your clang (7.0.2 for NDK r18).

@MikuAuahDark
Copy link
Author

MikuAuahDark commented Jul 1, 2019 via email

@alexcohn
Copy link

alexcohn commented Jul 1, 2019

Sure you can parse source.properties file in your Android.mk:

include $(ANDROID_NDK_ROOT)/source.properties
$(info $(Pkg.Revision))

gives me 19.1.5304403

@MikuAuahDark
Copy link
Author

Then how would I check if it's r19 or later?

I was thinking of writing little Python script which checks for user-supplied NDK version and return output yes or no based on NDK source.properties and execute the script at top-level Android.mk. Is this foolproof solution?

@enh
Copy link
Contributor

enh commented Jul 1, 2019

i don't think you should be trying to detect the NDK version at all... why not try to fix the real problem?

here's what's in <math.h>:

float log2f(float __x) __INTRODUCED_IN(18);

and that hasn't changed since bionic SHA 50cda38 in 2017-09-14, so something doesn't make sense here.

so it seems like your configure file is wrong, and is just looking for the function in libc.so, not the header?

@MikuAuahDark
Copy link
Author

They're somehow defined later when using R19 (after looking, I think it's R17) by android_support which somehow implicitly added.

@enh
Copy link
Contributor

enh commented Jul 1, 2019

okay. but why's that a problem? if you have a working log2f (and the the android_support one is the latest OS version), that's fine, right?

@MikuAuahDark
Copy link
Author

No. It result in conflicting function.

The Android.mk adds -DHAVE_LOG2F for ARM64 build so it's not a problem. But not for ARMv7 build because the app targets minimum-possible Android API-level (for r16, it's 14). In NDK r19, it's minimum to Android-16 so it targets Android-16 and as your code tell that log2f is defined for Android-18, but nope.

  In file included from D:/Data/Development/love-dev/love-android/love/src/jni/openal-soft-1.18.2/Alc/ALc.c:33:
  In file included from D:/Data/Development/love-dev/love-android/love/src/jni/openal-soft-1.18.2/OpenAL32/Include\alSource.h:6:
  In file included from D:/Data/Development/love-dev/love-android/love/src/jni/openal-soft-1.18.2/OpenAL32/Include/alu.h:15:
  In file included from D:/Data/Development/love-dev/love-android/love/src/jni/openal-soft-1.18.2/OpenAL32/Include/alFilter.h:6:
  D:/Data/Development/love-dev/love-android/love/src/jni/openal-soft-1.18.2/common\math_defs.h:26:21: error: static declaration of 'log2f' follows non-static declaration
  static inline float log2f(float f)
                      ^
  D:/Application/android-ndk-r19c/build//../toolchains/llvm/prebuilt/windows-x86_64/sysroot/usr/local/include\math.h:38:15: note: previous declaration is here
  float         log2f(float);
                ^
  In file included from D:/Data/Development/love-dev/love-android/love/src/jni/openal-soft-1.18.2/Alc/ALu.c:30:
  In file included from D:/Data/Development/love-dev/love-android/love/src/jni/openal-soft-1.18.2/OpenAL32/Include\alSource.h:6:
  In file included from D:/Data/Development/love-dev/love-android/love/src/jni/openal-soft-1.18.2/OpenAL32/Include/alu.h:15:
  In file included from D:/Data/Development/love-dev/love-android/love/src/jni/openal-soft-1.18.2/OpenAL32/Include/alFilter.h:6:
  D:/Data/Development/love-dev/love-android/love/src/jni/openal-soft-1.18.2/common\math_defs.h:26:21: error: static declaration of 'log2f' follows non-static declaration
  static inline float log2f(float f)
                      ^
  D:/Application/android-ndk-r19c/build//../toolchains/llvm/prebuilt/windows-x86_64/sysroot/usr/local/include\math.h:38:15: note: previous declaration is here
  float         log2f(float);
                ^
  1 error generated.
  make: *** [D:/Data/Development/love-dev/love-android/love/build/intermediates/ndkBuild/release/obj/local/armeabi-v7a/objs/openal/Alc/ALu.o] Error 1
  make: *** Waiting for unfinished jobs....
  1 error generated.
  make: *** [D:/Data/Development/love-dev/love-android/love/build/intermediates/ndkBuild/release/obj/local/armeabi-v7a/objs/openal/Alc/ALc.o] Error 1

Checking that file math.h in NDK r19 shows these.

#if __ANDROID_API__ < __ANDROID_API_J_MR2__
double        log2(double);
float         log2f(float);
long double   log2l(long double);
long double   logbl(long double);
float         tgammaf(float);
#endif

Which tells it to define log2f regardless of Android API level.

@enh
Copy link
Contributor

enh commented Jul 1, 2019

right, so the problem is in your "math_defs.h". luckily it looks like that's already been fixed upstream, so you just need to update to a newer version of openal:

kcat/openal-soft@27fbccf#diff-f9f627f11d5acea65cc397aaff3fbc73

@enh enh closed this as completed Jul 1, 2019
@MikuAuahDark
Copy link
Author

Sadly it doesn't make it into OpenAL-soft 1.19.1.

Back again, does this solution foolproof?

@DanAlbert
Copy link
Member

DanAlbert commented Jul 2, 2019

If you can't fix openal-soft, the right way to do it would be to set that define conditionally based on __NDK_MAJOR__.

@MikuAuahDark
Copy link
Author

I would just plug that into the config.h. Thank you very much.

@DanAlbert
Copy link
Member

(depending on how old of an NDK you need to support, you may want to be aware that __NDK_MAJOR__ hasn't always been available, but it's safe to assume that if it isn't defined then you're using an old NDK and can fall back to the pre-r19 behavior)

@MikuAuahDark
Copy link
Author

MikuAuahDark commented Jul 2, 2019

The project minimum supported NDK is r16. According to #407, it should be available in r16 (also can confirm it exist in r16b).

@DanAlbert
Copy link
Member

Yeah, not something you have to worry about then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants