-
Notifications
You must be signed in to change notification settings - Fork 96
Use API 16 for armv7, x86 as current react-native spec #66
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
Use API 16 for armv7, x86 as current react-native spec #66
Conversation
Interesting approach. I'm not sure this is a good idea, implementing C getline yourself differently than what the POSIX api specifies.
|
How about changing the min API for 32-bit to 18, so that at least |
@DanielZlotin There are some libc implementation for your reference.
I do see most of implementation in order to do getdelim() and have a complicated code. For your further questions:
It is a try-error workflow. After patching this function, I can build on top of API 16 without other problems.
Android introduced 64 bits support after API 21, so that x64 min API will be 21. |
@newyankeecodeshop I just hope if jsc-android-buildscripts could be merged into official RN upstream. |
Some updates:
|
@Kudo This is unlikely to be merged in to RN upstream because RN is de-coupling the JavaScript runtime via a new "JSI" subsystem. They want to make it easier for people to use their own version of JavaScriptCore, or even use V8. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @Kudo ! Awesome job on this one. I'm fine with most of the changes and just have a suggestion re missing getline method. There is a chance we can use the builtin one just by providing declaration that's missing from the public headers in android-16 NDK. Can you try that approach and let me know how it goes?
patches/jsc.patch
Outdated
+// This is only for forEachLine() use. | ||
+// Just don't want to do strlen() calculating length again. | ||
+// | ||
+static ssize_t getline(char** linep, size_t* linecapp, FILE* stream) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I checked libc binaries from android-16 NDK and found getline symbols there. So there is a chance that getline definition is only missing from the headers. I suggest (and we used similar trick in the past several times) to try providing only a declaration of getline function which then should be linked with the implementation present in libc:
extern "C" ssize_t getline(char** linep, size_t* linecapp, FILE* stream);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kmagiera This is awesome that I did not think before.
BTW how do you check getline existed in android-16 NDK?
I cannot find it on my machine 😓
> pwd
android-ndk-r17c
> toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-readelf -Ws platforms/android-16/arch-arm/usr/lib/libc.so|grep getline
> toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-readelf -Ws platforms/android-18/arch-arm/usr/lib/libc.so|grep getline
10: 000081b5 2 FUNC GLOBAL DEFAULT 7 getline@@LIBC
1241: 000081b5 2 FUNC GLOBAL DEFAULT 7 getline
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used nm
instead of readelf
but that shouldn't matter. Also, I only checked static version of libc (that is libc.a
) but now I see the dynamic version doesn't have that symbol
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So sad. It would be great if getline is just a hidden symbol.
Let me propose one more favorable to getline fallback. forEachLine(file, [&] (char* buffer) {
{
...
int scannedCount = sscanf(buffer, "%lx-%lx %4s %lx %31s %lu %6s", &start, &end, perms, &offset, dev, &inode, path);
if (scannedCount == 6) {
isAnonymous = true;
return;
} |
I finally found the getline implementation in Android. https://android.googlesource.com/platform/bionic/+/master/libc/stdio/stdio.cpp#870 It's from OpenBSD and the dependency seems less than glibc (glibc based on libio) |
Thanks for looking more into it @Kudo Do you know how to trigger that JSC code which uses getline? So that we can test if it works ok? Another idea that I had is we could try using This would look sth like this (I havent compiled this code, just posting to hopefully make it clear):
|
It appears there are other issues when running your build on Android 4.1 as some other symbols are missing. Specifically we've run into an issue with missing See output from
We addressed that problem in the original version of JSC buildscripts this way: https://github.com/facebook/android-jsc/blob/master/jsc/BUCK#L39 Not sure what other problems we may encounter with this change but we should make sure to test it on 4.1 devices/emulators before we merge your changes in. |
@kmagiera Thanks for your help of the log2 missing symbol. To address the issue, I first to add Regarding back to the getline issue, I digged the WebKit source code and seems JavaScriptCore does not use it. |
@newyankeecodeshop I've updated the PR and fix the missing log2 issue. It could run on Android 4.1 now. |
@kmagiera I wrote a POC code for fgetln backed version. Please take a look first and see if it is okay to do it within JSC. |
Hey @Kudo ! Thanks so much for addressing all my comments and sorry for the back and forth on this. We tested your recent changes and everything appears to be working ok. But one thing we noticed is that MemoryFootprint methods are missing from the binary output. Which suggest (and you mentioned that earlier) that these methods aren't really being used. Given that I'd suggest that we don't add any implementation of |
scripts/compile/common.sh
Outdated
@@ -151,7 +153,7 @@ ICU_CXXFLAGS="$COMMON_CXXFLAGS $ICU_CFLAGS -Oz" | |||
ICU_LDFLAGS="$COMMON_LDFLAGS $PLATFORM_LDFLAGS -s" | |||
|
|||
JSC_LDFLAGS="$COMMON_LDFLAGS" | |||
JSC_CFLAGS="$COMMON_CFLAGS -DU_STATIC_IMPLEMENTATION=1 -DU_SHOW_CPLUSPLUS_API=0" | |||
JSC_CFLAGS="$COMMON_CFLAGS -DU_STATIC_IMPLEMENTATION=1 -DU_SHOW_CPLUSPLUS_API=0 -Wno-tautological-constant-compare" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this additional warning for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just want to suppress warning like that:
../../Source/WTF/wtf/text/StringImpl.h:967:18: warning: comparison 'size_t' (aka 'unsigned int') > 4294967295 is always false [-Wtautological-constant-compare]
if (size > std::numeric_limits<unsigned>::max())
~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I check the warning existed in previous build log from Jenkins CI.
Let me remove this and keep changes simple. Thank for your comment.
@kmagiera The idea of eliminating MemoryFootprint makes sense to me. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job @Kudo!
I'm accepting this and would love to hear if anyone else has some feedback before I merge this in (not sure if @DanielZlotin has time and availability to take a look)
Thanks @newyankeecodeshop for your comments 🙌 |
Also @DanielZlotin if you get a minute I wanted to give a tldr to respond to your previous comment. I believe this approach is correct cause 64bit builds use different sdk (21) for compiling (with precious sdk versions 64 architecture weren't supported). I think it is actually the best approach if we want to support all cpus with a single set of binaries (an alternative would be to have separate binaries per sdk which would complicated apk splitting, note that cpu splits are now automatic) As for getline we managed to get rid of it as the code which was using turned out to be unused. We tested @Kudo patch internally on Android 4.1 and arm64 devices. And will repeat the test once more before merging. I'm pretty confident about this solution and looking forward to it helping with upgrading jsc for all RN users. |
@kmagiera Thank you for reviewing my code with much patience. As the changes back and forth few times, please let me know if I should rebase and squash my commits before landed. |
working on it ;) |
Yes please rebase |
Summary: While building arm7, x86, use API 16. While building arm64, x86_64, use API 21. (Android introduced 64 bits support after API 21). There are some patches for missing symbols from NDK API 16. 1. log2() is supported until API 18. Solved this by introduced a log2() polyfill. 2. getline() is supported until API 18. As the WebKit WTF code is not being used in JSC, just comment out it. For discussion details, see the PR commants: react-native-community#66 (comment) 3. Add '-Wl,--no-undefined' ldflags to prevent missing NDK symbols in the future.
d94c6e5
to
28c6384
Compare
@DanielZlotin rebase done, please take a look. Thank you. |
Testing... |
When is this going to see the light? |
I messed up something with version numbers on CI and even so the builds from Circle are Ok (tested them on a number of different devices and emulator + on firebase test lab) I'll have to fix CirecleCI versioning before publishing this to npm. Merging this now and will publish an update likely tomorrow! Thanks @Kudo for working on this 🙌 |
Should minSdkVersion related part of the README be deleted? |
yes, definitely, will do it as soon as new version is published on NPM |
Thank you! |
One concern for jsc-android-buildscripts is about its minSdkVersion bumped to 21.
This PR follows current React Native Android's spec.
For armv7 and x86, the minimal API is 16.
For arm64 and x86_64, the minimal API is 21. (Android introduce 64 bits support after API 21).