Does the LWJGL3 support arm platform still?
I can't Build it successful on ARM platform.
Not yet. Support for ARM is scheduled for the 3.0.2 release. We're currently working on #100 for the 3.0.1 release.
Thanks,I think we can add a schedule on the website.
Maybe with release of kotlin native it'll be easier? do you plan to support kotlin native btw?
It's hard to tell without knowing more specifics about it. But yes, projects like Kotlin native, Scala native and JEP 295 are very interesting.
In slack they shown video of kotlin native running on iOS, and Raspberry Pi (Tetris game using SDL2), exciting news!!
https://files.slack.com/files-tmb/T09229ZC6-F4LKMA03U-237bd9b959/attachment-1_360.gif
Slack -> #kotlin-native
Kotlin Native Technical Preview released: https://blog.jetbrains.com/kotlin/2017/04/kotlinnative-tech-preview-kotlin-without-a-vm/
i tried 3.1.3 on Nvidea Jetson TX2 which has aarch64 but there doesn't seem to be the right binary available
java.lang.UnsatisfiedLinkError: /tmp/lwjglidsc/3.1.3-SNAPSHOT/liblwjgl.so: /tmp/lwjglidsc/3.1.3-SNAPSHOT/liblwjgl.so: cannot open shared object file: No such file or directory (Possible cause: architecture word width mismatch)
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
The project is here
https://github.com/idsc-frazzoli/owly3d
Please let me know, if I am making an obvious mistake. Is arm supported by lwjgl?
Support for Android & ARM is a (very slow) work-in-progress. It currently lives in the android branch. See the android-test repository for build instructions and demos.
@Spasi thank you for the reply!
for now, I only would like to read out a joystick, so I probably will look for a simple, quick alternative.
Where can I check when lwjgl will be supported on arm?
When you say "(very slow) work-in-progress", do you have any idea how slow it will be? (several months, several years, unlikely to ever exist?)
Is there a version of lwjgl2 that works on arm?
I'm not very good at all this, but from what I understood the code is currently compiled for different OS, but appart from compiling it for a device using arm are there other things to do? (would it be possible to do this work myself? I read that several years ago some people did so, but they did not provide a download link for it)
Is there a version of lwjgl2 that works on arm?
No.
are there other things to do? (would it be possible to do this work myself?)
You can find build instructions in android-test. Assuming you have Android Studio installed and you're experienced with building Android programs, it should be straightforward.
Note that this produces binaries for the core library and native libraries whose code is included in the LWJGL repository (stb, nuklear, nanovg, etc). Libraries built separately (jemalloc, OpenAL Soft, etc.) are currently not supported. This is the biggest piece of the puzzle missing atm.
Also note that this produces a build that is Android-specific. It won't work on a generic ARM device. But most of the work done for Android will be useful for generic ARM builds.
do you have any idea how slow it will be? (several months, several years, unlikely to ever exist?)
Several months at best. Reasons:
Thank you for the quick and detailed answer!
I'm not working on android actually, I'm working on raspberry.
So when you say "It won't work on a generic ARM device.", I guess raspberries are included in "generic ARM device"?
I don't know about android, but I think lwjgl is still very interesting for raspberries.
I guess raspberries are included in "generic ARM device"?
Yes. Any device that can run a Linux ARM JDK (e.g. Oracle JDK, Zulu Embedded).
I think lwjgl is still very interesting for raspberries.
Indeed. And with a Hotspot JVM it should run great as is.
After spending some time trying to figure out what would be the best solution for me I found this tutorial : http://rogerallen.github.io/jetson/2014/07/31/minecraft-on-jetson-tk1/
The second point explains how to build lwjgl for arm (raspberry), but it is 3 years old. I'll try this as soon as I get my raspberry back, but until then could you tell me if it seems to be a proper way to do it? (I guess things have change in 3 years, maybe it's not a good idea to do it anymore, if it actually ever worked)
That article is for lwjgl2, so not applicable to lwjgl3.
Building LWJGL for ARM locally should be simple. The existing scripts should work out-of-the-box, or may require minimal changes. If you try it and encounter problems, please open a new issue and they will be addressed.
In order to have official support though, the build needs to be practical. For LWJGL, this means the ARM builds must run on Travis CI. The script that builds the Linux x64 binaries is here. We need a script that installs a cross-compiling toolchain for ARM and then builds LWJGL using it. Then we need the same for (some of) LWJGL's dependencies.
If anyone wants to try that, the process is:
1) Fork lwjgl3.
2) Register your forked repository with travis-ci.
3) Push a .travis.yml file with the build script you wrote.
4) ...repeat 3 until it works.
You're done when ant compile-native succeeds. Ignore ant upload-native (you don't need awscli and the secure variables either).
Oh sorry, I forgot it was for LWJGL3.
So you're saying if I follow the steps described on this link: https://www.lwjgl.org/guide#build-instructions
with my raspberry it should actually compile the natives correctly and I'll have a working LWJGL on my raspberry? (I just want to make sure I'm following the right instructions, I'm really not familiar with all this yet)
it should actually compile the natives correctly and I'll have a working LWJGL on my raspberry?
I'm saying it's a good starting point. The master branch doesn't know anything about ARM atm, so it'll think it's doing an x86 or x64 build. This will likely be problematic, but it shouldn't take many changes to make it work. Better build instructions:
ant compile-templates (this compiles the Kotlin code, it will take a while)ant compile (generates the Java/C code, compiles the Java code)ant compile-nativeThe last one will probably fail with an ARM toolchain. You'll have to modify config/build-definitions.xml and config/linux/build.xml to make it work. You can use the android branch as a reference and see what changes were required there. Note that the Android build has its own config/android/build.xml but you won't need to do that for a Raspberry build.
I finally found some time to try this!
The first build takes approximately 2 hours, but does not reach the end because of a java.lang.OutOfMemoryError: Java heap space.
Apparently in order to increase this space and avoid the issue I have to add -Xmx<space> to the java command lines. So I added <jvmarg value="-Xmx800m"/> each time I could in the build.xml file (probably not the best way to solve the issue, but it could've work I think), but I ended up with the same issue.
As 800MB should be enough for the build to succeed, I guess I did not add the arguments at the necessary places, but I don't have any idea where to put it.
And then I thought "hey, this is not compiling the C code, this doesn't have to be done on the raspberry!". Am I right? If I compile the Kotlin on my pc, then transfer the library to my raspberry to proceed to the next two commands is it going to be ok? (sadfully it's hard for me to test this, because the last steps will generate errors, and I need to be sure the error is not a consequences of the first step that I might've done the wrong way)
Hmm, yes, doing the Kotlin compilation on a Raspberry is a waste of time. It's very slow, even on a high-end workstation, and there's no support for incremental compilation via the cli. It also needs around 1G of memory, not sure if the Raspberry has enough.
If I compile the Kotlin on my pc, then transfer the library to my raspberry to proceed to the next two commands is it going to be ok?
It should. Also copy any touch.txt files and make sure the last modified timestamps are maintained. You should be able to run the following targets on the PC:
ant compile-templates (Kotlin compilation)ant generate (Java/C code generation)ant compile (Java compilation)Then copy the modules/core/src/generated/ and bin/ folders to the Raspberry.
I also recommend disabling most bindings in config/build-bindings.xml (set the corresponding properties to false) until you have the core build working. It should significantly speed-up the build process.
Here I am again.
I tried several thing, nothing worked... As I mentioned before I really don't have any skill in packaging and building projects so I kinda try things whithout actually knowing what I'm doing...
I guess it's better for me to wait until an arm version is released, even if it takes a long time.
By the way if anyone has an arm compiled version of lwjgl3 that he can share (or even just the right config files to build it) don't hesitate to share it!
I got this to complete the build on my Pi3 albeit with 1 error.
Increase the swapfile size:
sudo nano /etc/dphys-swapfile
Change CONF_SWAPSIZE=100 to CONF_SWAPSIZE=1024
Reboot
Set an ant environment variable to allow java more memory:
export ANT_OPTS="-Xmx1g"
ant
Use ‘free -h’ in a separate terminal window to see how much swap space gets used.
The result of building on the Pi:
compile-native-platform:
[Compiler] gcc: error: unrecognized command line option ‘-m32’
[Compiler] gcc: error: unrecognized command line option ‘-mfpmath=sse’
[Compiler] gcc: error: unrecognized command line option ‘-msse’; did you mean ‘-fdse’?
[Compiler] gcc: error: unrecognized command line option ‘-msse2’BUILD FAILED
/home/pi/lwjgl3/build.xml:388: The following error occurred while executing this line:
/home/pi/lwjgl3/config/linux/build.xml:101: The following error occurred while executing this line:
/home/pi/lwjgl3/config/linux/build.xml:30: apply returned: 1Total time: 3 seconds
The Raspberry Pi 3 is a 64 bit system and you probably do not have a cross-compile toolchain installed, but also don't need any. Just leave the "-m32" out. It should produce 64 bit binaries then.
The Pi also has an ARM cpu and no x86, so it has no SSE. Try -mfpmath=neon or -mfpmath=vfp. Also remove the -msse and -msse2.
Although the Pi is 64bit, I'm using raspbian which is only 32bit. I've removed the unrecognised flags but still get errors reported though no detail. The -mfpmath flags didn't work. Any way to get more detail?
Buildfile: /home/pi/lwjgl3/build.xml
init:
check-dependencies:
bindings:
generate:
-init-compile:
compile:
compile-native:
compile-native-platform:
BUILD FAILED
/home/pi/lwjgl3/build.xml:388: The following error occurred while executing this line:
/home/pi/lwjgl3/config/linux/build.xml:178: The following error occurred while executing this line:
/home/pi/lwjgl3/config/linux/build.xml:182: exec returned: 1Total time: 3 seconds
build.xml:182, it is checking for gtk-3.0.
You can try install the libgtk-3-dev package.
I got the master branch to compile on aarch64.
I have commented out some flags in build script, replaced dyncall libraries using offline build mode LWJGL_BUILD_OFFLINE=true.
```diff
diff --git a/config/linux/build.xml b/config/linux/build.xml
index 41f340d..8d8e6ce 100644
--- a/config/linux/build.xml
+++ b/config/linux/build.xml
@@ -30,7 +30,7 @@
-
+
@@ -51,7 +51,7 @@
-
+
@@ -77,7 +77,7 @@
-
+
<arg line="-z noexecstack"/>
@@ -256,13 +256,13 @@
<!-- SSE -->
-
+
<!-- stb -->
<build name="lwjgl_stb" dest="${bin.native}/stb" if:true="${binding.stb}">
diff --git a/modules/core/src/main/c/system/linux/wrap_memcpy.c b/modules/core/src/main/c/system/linux/wrap_memcpy.c
index 239c958..a71effb 100644
--- a/modules/core/src/main/c/system/linux/wrap_memcpy.c
+++ b/modules/core/src/main/c/system/linux/wrap_memcpy.c
@@ -2,7 +2,7 @@
void *old_memcpy(void *, const void *, size_t);
-__asm__(".symver old_memcpy,memcpy@GLIBC_2.2.5");
+//__asm__(".symver old_memcpy,memcpy@GLIBC_2.2.5");
void *__wrap_memcpy(void *dest, const void *src, size_t n) {
return old_memcpy(dest, src, n);```
Has there been any progress on running lwjgl 3 on a raspberry pi 3 without putting too much effort into configuring etc (although I would do it anyway with effort)? If so, can someone give me a tutorial on how to make it work? If not, could someone point me to an alternative I can use as a openGL wrapper until lwjgl supports arm?
Using Pi3 Raspbian Stretch (32bit)
After commenting out the following in the build xml :
line 36:
<!-- <arg line="-m32 -mfpmath=sse -msse -msse2" unless:true="${build.arch.x64}"/> -->
line 88:
<!-- <arg value="-m32" unless:true="${build.arch.x64}"/> -->
line 266:
```
I get this far :
Buildfile: /home/pi/lwjgl3/build.xml
init:
check-dependencies:
-compile-generator:
bindings:
compile-templates:
generate:
-init-compile:
compile:
compile-tests:
compile-native:
compile-native-platform:
[gcc] Linking lwjgl_rpmalloc
[Linker] /tmp/ccWmgx5U.s: Assembler messages:
[Linker] /tmp/ccWmgx5U.s:26: Error: selected processor does not support dmb ish' in ARM mode
[Linker] /tmp/ccWmgx5U.s:101: Error: selected processor does not supportdmb ishst' in ARM mode
[Linker] /tmp/ccWmgx5U.s:642: Error: selected processor does not support dmb ish' in ARM mode
[Linker] /tmp/ccWmgx5U.s:755: Error: selected processor does not supportdmb ish' in ARM mode
[Linker] /tmp/ccWmgx5U.s:956: Error: selected processor does not support dmb ish' in ARM mode
[Linker] /tmp/ccWmgx5U.s:1017: Error: selected processor does not supportdmb ish' in ARM mode
[Linker] /tmp/ccWmgx5U.s:1146: Error: selected processor does not support dmb ish' in ARM mode
[Linker] /tmp/ccWmgx5U.s:1211: Error: selected processor does not supportdmb ish' in ARM mode
[Linker] /tmp/ccWmgx5U.s:1333: Error: selected processor does not support dmb ish' in ARM mode
[Linker] /tmp/ccWmgx5U.s:1394: Error: selected processor does not supportdmb ish' in ARM mode
[Linker] /tmp/ccWmgx5U.s:1525: Error: selected processor does not support dmb ish' in ARM mode
[Linker] /tmp/ccWmgx5U.s:1552: Error: selected processor does not supportdmb ish' in ARM mode
[Linker] /tmp/ccWmgx5U.s:1726: Error: selected processor does not support dmb ishst' in ARM mode
[Linker] /tmp/ccWmgx5U.s:1945: Error: selected processor does not supportdmb ishst' in ARM mode
[Linker] /tmp/ccWmgx5U.s:2011: Error: selected processor does not support dmb ish' in ARM mode
[Linker] /tmp/ccWmgx5U.s:2139: Error: selected processor does not supportdmb ish' in ARM mode
[Linker] /tmp/ccWmgx5U.s:2160: Error: selected processor does not support dmb ish' in ARM mode
[Linker] /tmp/ccWmgx5U.s:2193: Error: selected processor does not supportdmb ish' in ARM mode
[Linker] /tmp/ccWmgx5U.s:2246: Error: selected processor does not support dmb ishst' in ARM mode
[Linker] /tmp/ccWmgx5U.s:2274: Error: selected processor does not supportdmb ishst' in ARM mode
[Linker] /tmp/ccWmgx5U.s:2320: Error: selected processor does not support dmb ishst' in ARM mode
[Linker] /tmp/ccWmgx5U.s:2385: Error: selected processor does not supportdmb ish' in ARM mode
[Linker] /tmp/ccWmgx5U.s:2419: Error: selected processor does not support dmb ish' in ARM mode
[Linker] /tmp/ccWmgx5U.s:2481: Error: selected processor does not supportdmb ishst' in ARM mode
[Linker] /tmp/ccWmgx5U.s:2495: Error: selected processor does not support dmb ish' in ARM mode
[Linker] /tmp/ccWmgx5U.s:2521: Error: selected processor does not supportdmb ish' in ARM mode
[Linker] /tmp/ccWmgx5U.s:2557: Error: selected processor does not support dmb ish' in ARM mode
[Linker] /tmp/ccWmgx5U.s:2598: Error: selected processor does not supportdmb ishst' in ARM mode
[Linker] /tmp/ccWmgx5U.s:2627: Error: selected processor does not support dmb ishst' in ARM mode
[Linker] /tmp/ccWmgx5U.s:2646: Error: selected processor does not supportdmb ishst' in ARM mode
[Linker] /tmp/ccWmgx5U.s:2726: Error: selected processor does not support dmb ishst' in ARM mode
[Linker] /tmp/ccWmgx5U.s:2760: Error: selected processor does not supportdmb ishst' in ARM mode
[Linker] lto-wrapper: fatal error: gcc returned 1 exit status
[Linker] compilation terminated.
[Linker] /usr/bin/ld: error: lto-wrapper failed
[Linker] collect2: error: ld returned 1 exit status
BUILD FAILED
/home/pi/lwjgl3/build.xml:403: The following error occurred while executing this line:
/home/pi/lwjgl3/config/linux/build.xml:258: The following error occurred while executing this line:
/home/pi/lwjgl3/config/linux/build.xml:84: apply returned: 1
Total time: 25 seconds
```
I haven't tried compiling rpmalloc on ARM yet, not sure what the problem is. It seems to support ARM, but you may want to disable it for now (it's optional). Bindings can be disabled in build-bindings.xml.
That seemed to work, had to disable 'tootle' as well.
I was expecting libglfw32.so to also be created - is this not the case ?
Buildfile: /home/pi/lwjgl3/build.xml
init:
check-dependencies:
-compile-generator:
bindings:
compile-templates:
generate:
-init-compile:
compile:
[javac: Core] Compiling 1865 source files to /home/pi/lwjgl3/bin/Core
compile-tests:
compile-native:
compile-native-platform:
-init-runtime:
tests:
[Tests] [LWJGL] Version: 3.1.6 SNAPSHOT
[Tests] [LWJGL] OS: Linux v4.9.59-v7+
[Tests] [LWJGL] JRE: 1.8.0_65 arm
[Tests] [LWJGL] JVM: Java HotSpot(TM) Client VM v25.65-b01 by Oracle Corporation
[Tests] [LWJGL] Loading library (system): lwjgl32
[Tests] [LWJGL] Loaded from java.library.path: libs/liblwjgl32.so
[Tests] [LWJGL] Loading library: lwjgl32
[Tests] [LWJGL] MemoryUtil accessor: MemoryAccessorUnsafe
[Tests] [LWJGL] Loaded from java.library.path: libs/liblwjgl32.so
[Tests] /usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt/jre/bin/java: symbol lookup error: /home/pi/lwjgl3/libs/liblwjgl32.so: undefined symbol: dcNewCallVM
[Tests] The tests failed.
all:
BUILD SUCCESSFUL
Total time: 3 minutes 22 seconds
The following bindings are built externally (see the LWJGL-CI repositories):
The lwjgl3 Ant script downloads them as necessary, in shared or static library form.
Currently there are no CI scripts to build the above for ARM. Only dyncall has been ported to Android/ARM (example .travis.yml), because it's the only binding that the lwjgl3 core requires (that's why you're getting the symbol lookup error above).
Did you make a program using lwjgl3 work on rasp using this configuration for the build?
Is it just about commentating these 3 lines from build.xml and disable lines 41 (tootle) and 36 (rpmalloc) from build-binding.xml ?
I'm trying to get the latest experimental build of Minecraft working. Its now got past the liblwjgl32.so requirement, but now needs libglfw32.so The only other change was commenting out the threadsPerProcessor="4"
Did you manage to get it to work?
I'm currently trying to crosscompile for my raspberry pi using this docker image https://github.com/sdt/docker-raspberry-pi-cross-compiler . I'm currently having some setup-problems but I hope to solve those by the weekend.
I finally got NanoVG running on my Pi:
https://twitter.com/intrigus_/status/951588386002874369
@Spasi are you fine with using docker to cross-compile the binaries or do you prefer another solution?
are you fine with using docker to cross-compile the binaries or do you prefer another solution?
It must be in the form of a .travis.yml script that can run on Travis CI. For example, this is the script that builds and uploads* lwjgl's linux binaries.
Docker is supported on Travis CI and I have no objections if that's what you want to use. As long as it works and is not a maintenance nightmare.
* if you go for it, ignore the uploading part (awscli and the secure vars)
I got all but one external binding building.
The remaining one should also build soon.
The lwjgl3 build should work, but there are some open problems that need to be solved as some of my solutions are hard-coded.
@intrigus has almost completed an LWJGL port to ARMv6. This is the CPU architecture of the original Raspberry Pi.
I'm worried that we'll end up wasting a lot of time and effort on supporting builds that very few people will use. Is it reasonable to support ARMv6 these days?
What are the top architectures in widespread use today? We should focus on those, for both the Android/ARM builds and the generic ARM builds.
@Spasi In my opinion it would probably be better to support ARMv7 since all bindings would work with it. (Excluding tootle and sse)
I'm not __sure__ but I think that for using opengl es on pi's before model 2, you had to use a __pi specific__ api. (Please correct me if I'm wrong)
The pi 2 is also ARMv7.
So I've gotten everything to build except for a few modules (Mainly Tootle, which I don't use so that's fine) However after going through and removing some methods from GLFW which are no longer used in the repo I've ran into this error which I have yet to figure out since it's so general.
/usr/local/jdk1.8.0_161/bin/java: symbol lookup error: /home/alarm/NetBeansProjects/OpenGL/libs/natives/liblwjgl32.so: undefined symbol: dcbNewCallback
I have yet to edit any of the natives except my own drop in glfw.so
liblwjgl must be linked with dyncall (as a static library).
That would make sense, so how would I go about doing that?
Download and build dyncall library, replace the pre-built binaries in LWJGL, then build LWJGL use offline mode:
LWJGL_BUILD_OFFLINE=true
So I've build dyncall, where are the pre-built's to replace?
Nevermind, simple find | grep dyn helped.
Can't remember, but you can try build in online mode once, then search for libdyncall.a (should be downloaded automatically, but for i386/amd64)
I've been running online mode this whole time, I had to build kotlin on my windows computer as don't have enough ram on my laptop. Not even sure how to turn online mode off, I don't really use ant very often
I have yet to find a libdyncall.a
I actually deleted the c code from the lwjgl3/modules/core/ and it still compiles which makes me kinda wonder however it could be picking up the headers from /usr/include/
Found something useful to me:
<link>
<fileset dir="${lib}/${platform}/${build.arch}/">
<include name="libdyn*.a"/>
</fileset>
</link>
I was building lwjgl3 natively (on aarch64). In my build, I can find libdyncallback_s.a libdyncall_s.a libdynload_s.a in libs/linux/x64. However, if I use online mode, it seems to overwrite those binaries every time, so I need to use offline mode.
the bin/libs/linux/x86 folder doesn't even get used for me, it uses bin/linux/x86/
It's not in the bin folder
What folder is it in? I'm not seeing any .a's being generated. I've got a bunch of .o's
I just checked my echo command from the build and my stuff is getting placed in bin
Edit 2: I think I fixed it, I had to place the built .a's into bin/libs/linux/x86 for it to link them, about to replace my .so and see if it works now.
Edit 3: Got it to work and make a window just gotta fix something that seems to return null now.
I could be using an outdated version, but for my build, they are directly in repo/libs/linux/x64:
$ ls
bin gradlew.bat
build.gradle libs
build.xml LICENSE.md
config modules
doc README.md
gradle settings.gradle
gradle.properties update-dependencies.xml
gradlew
$ ls libs/linux/x64/
libdyncallback_s.a libdyncall_s.a libdynload_s.a
They are not generated, the binaries are downloaded directly from a server somewhere.
Yeah mine never seemed to download hence why it wasn't loading. I got it to work now, however I had to inject myself into library class, so at the moment I'm fixing libGL.so.1 path resolve and then I'll know if it works to render my 3d playground
Not even sure how to turn online mode off
The LWJGL repository doesn't contain the source code for all libraries it supports. Some are too big or have complex build systems. These libraries are built externally on Travis CI and AppVeyor. The Ant script downloads the prebuilt binaries as necessary.
Any attempt to do an ARM build should be done in offline mode, simply because there is no CI infrastructure for ARM yet and no binaries available to download. It's also useful when working with a custom build of a supported library and want to be sure it won't be overwritten.
You run export LWJGL_BUILD_OFFLINE=true and then the Ant build will not attempt to download anything.
but for my build, they are directly in
repo/libs/linux/x64
Sorry for the confusion, but there's been a major change to the project's directory layout 2 weeks ago (00e1f52cf95c16b0cea34c83372145532b4745ba and 06e044e7bc5eecc841dff78a242dd3f0e453db16). Previously libs was a top-level directory (relative to the repository root), but now lives under bin/. This is cleaner and makes it easier to get the repo to a clean state (simply delete the bin folder).
bin/libs/ is where all (Java & native) dependencies are downloaded and where linked shared libraries are copied to.bin/${platform}/${build.arch} is where compiled object files are stored.The mali drivers came with libEGL.so only so there is no libGL do I need to not be using GL11.* GL12.* etc. calls in my code or what am I missing?
There is no simple answer, it depends on the driver used and what you're trying to achieve. Without knowing more details, here are some things you can try:
opengles module. org.lwjgl.opengles.GLES , GLESCapabilities, GLES20, etc.-Dorg.lwjgl.util.Debug=true and -Dorg.lwjgl.util.DebugLoader=true. It will print out which shared libraries are being loaded at startup.org.lwjgl.system.Configuration class. It supports both system properties and programmatic access. Useful options in your case EGL_LIBRARY_NAME, OPENGL(ES)_LIBRARY_NAME (these can be relative/absolute paths to shared libraries, makes things easier).Thanks for the detailed steps and what not, currently I'm trying to get accelerated graphics going that way I'm not stuck at 5fps. LWJGL3 built and runs great.
What all do you guys have left to push ARM support 100% out?
@mikehooper @Spasi Regarding rpmalloc on ARM, should work fine but if the target processor doesn't have the instructions I used for atomic fences you could try using c11 atomics instead.
Which processor are you targeting? Could you post the compiler flags so I could incorporate this into the rpmalloc build tests?
Try replacing line 106 & 107 in rpmalloc
# define atomic_thread_fence_acquire() __asm volatile("dmb ish" ::: "memory")
# define atomic_thread_fence_release() __asm volatile("dmb ishst" ::: "memory")
with the following C11 atomics instead
# include <stdatomic.h>
# define atomic_thread_fence_acquire() __atomic_thread_fence(memory_order_acquire)
# define atomic_thread_fence_release() __atomic_thread_fence(memory_order_release)
@Spasi I have followed your directions and am attempting to get this project and its dependencies building on ARM through Travis CI, so looking for your guidance on a few things.
Here is where I am at - I have successfully used an ARM cross compiler (provided by Raspberry Pi) to get this project building - I had to also get Dyncall (CI repo) built with the cross compiler and have it building - code here and its also building on Travis CI.
I didn't have to build any of the other 3rd party projects you mentioned for an LWJGL build to succeed, but shouldn't be too difficult to get them building in a similar fashion (I'm happy to take that on).
In the LWJGL project, I've created a new platform (arm) and created various sub-directories based on the linux platform to get it working - changes here. I haven't tested the built native libraries on a Pi yet, but that is my next step - I'm guessing I might have to tweak some compiler options etc but at least the build succeeds.
Looks like the various branches in the CI projects are named in a specific fashion - I just went with "arm" and "arm64" to start but if you have suggestions on naming etc. let me know and I can clean it all up and make pull requests on the dependent projects first.
Any other guidance or tips are appreciated.
Ideally, the ARM builds would reuse the current Linux setup (build.xml, version.script, custom headers, etc). Duplicating all that and maintaining it long-term would be a pain. Then there'd be some kind of flag that enables the cross-platform compilation for the target architecture (it would override build.arch, at least).
Android will probably require a separate setup though. So, long-term, we should end up with the following platform/architecture matrix:
|Platform|x86|x64|ARMv7/AArch32|ARMv8/AArch64|
|-|-|-|-|-|
|Android|||X|X|
|Linux||X|X|X|
|macOS||X|||
|Windows|X|X|||
The preferred naming for branches is master-<platform>-<abi>. I don't think we'll support more than one 32-bit ARM ABI (i.e. v7 hard-float), so the generic aarch32/aarch64 can be used for the ARM branches.
Btw, there's a branch per platform/ABI because I hate the .travis.yml syntax for running matrix builds. Not sure if it has been improved lately, but if you can write a script that produces both 32 & 64-bit binaries with good readability, go for it and use a single master-linux-arm branch.
Thanks for the quick reply and that all makes sense. I'll start with the Dyncall CI project first to make sure I'm on the right track.
How far is the progress with ARM support? Because I'd very much like to use LWJGL in a project with a Raspberry PI 3B. I'm just using very few of the modules, Assimp, OpenGL & OpenGL ES is what is necessary for me.
And I would like to offer my help. If I can. (pretty much no experience with this at all)
I updated a few of the dependent libraries to use a x-compiler within Travis CI but ran into an issue where the x-compiler doesn't recognize an assembler command (memcpy is wrapped and points to a specific version of glibc). I tried a simple file on the Pi itself and it also doesn't recognize this compiler command. For 32 bit build, this might not be necessary, but that is where I left it. You can look at the forks in my repo (look for the repos forked from LWJGL-CI and then look at the arm branches).
Trying to build this on the Pi again. (Pi3B+ Raspbian 32bit OS)
Why would I get missing header files when they do exist?
pi@raspberrypi:~/lwjgl3 $ ant compile-native
Buildfile: /home/pi/lwjgl3/build.xml
bindings:
init:
[override] Build offline: true
check-dependencies:
generate:
compile:
compile-native:
compile-native-platform:
[Compiler] /home/pi/lwjgl3/modules/lwjgl/nanovg/src/generated/c/org_lwjgl_nanovg_NanoSVG.c:13:21: fatal error: nanosvg.h: No such file or directory
[Compiler] #include "nanosvg.h"
File exists here:
pi@raspberrypi:~/lwjgl3 $ find . -name nanosvg.h
./modules/lwjgl/nanovg/src/main/c/nanosvg.h
pi@raspberrypi:~/lwjgl3 $
I'm having some troubles compiling because of header files not found. Are there some dependencies to install beforehands?
[Compiler] lwjgl3/modules/lwjgl/tootle/src/main/c/RayTracer/JRT/JRTH2KDTreeBuilder.cpp:6:23: fatal error: TootlePCH.h: No such file or directory
But...
find . -name TootlePCH.h
./modules/lwjgl/tootle/src/main/c/TootlePCH.h
Any idea?
Thanks.
Is anyone able to explain this missing header files issue ? Are we missing a library path or some dependency?
Seem to have more success setting relative="false" in every occurrence in config/linux/build.xml
These patches seem to solve the missing header files issue:
#!/bin/bash
file=~/lwjgl3/config/linux/build.xml
# set relative to false
sed -i -e 's+<attribute name="relative" default="true"/>+<attribute name="relative" default="false"/>+g' $file
sed -i -e 's+relative="true"+relative="false"+g' $file
# set threads to 1
sed -i -e 's+threadsPerProcessor="2"+threadsPerProcessor="1"+g' $file
sed -i -e 's+threadsPerProcessor="4"+threadsPerProcessor="1"+g' $file
# set path
sed -i -e 's+<property name="module.lwjgl.rel" value="../../../../${module.lwjgl}"/>+<property name="module.lwjgl.rel" value="/home/pi/lwjgl3/${module.lwjgl}"/>+g' $file
# comment out -m32
sed -i -e 's+<arg line="-m32 -mfpmath=sse -msse -msse2" unless:true="${build.arch.x64}"/>+<!-- <arg line="-m32 -mfpmath=sse -msse -msse2" unless:true="${build.arch.x64}"/> -->+g' $file
sed -i -e 's+<arg value="-m32" unless:true="${build.arch.x64}"/>+<!-- <arg value="-m32" unless:true="${build.arch.x64}"/> -->+g' $file
http://fxzjshm.github.io/blog/Build-LWJGL-On-Raspberry-Pi/ these instructions are good enought to build them for rpi3
http://fxzjshm.github.io/blog/Build-LWJGL-On-Raspberry-Pi/ these instructions are good enought to build them for rpi3
Thats for lwjgl2 not lwjgl3
yeah... I need to build the lwjgl-3.1.6.jar armhf one for rpi3. how I get that one? I download the source of the 3.1.6 than I need and I am failing on building it. please, help me with this nightmare.
I went further, but will have to try it on another machine:
[kotlinc] info: kotlinc-jvm 1.3.21 (JRE 1.8.0_181-8u181-b13-2~deb9u1-b13)
[kotlinc] exception: java.lang.OutOfMemoryError: Java heap space
If you building on a Pi you can increase the swap file size https://github.com/LWJGL/lwjgl3/issues/206#issuecomment-345512525
Zram?
Thanks. I tried on another machine and got:
compile-native:
[mkdir] Created dir: /root/lwjgl3/bin/linux/x64
compile-native-platform:
[Compiler] gcc: error: unrecognized command line option ‘-m64’
BUILD FAILED
/root/lwjgl3/build.xml:406: The following error occurred while executing this line:
/root/lwjgl3/config/linux/build.xml:149: The following error occurred while executing this line:
/root/lwjgl3/config/linux/build.xml:39: apply returned: 1
Total time: 8 minutes 10 seconds
gcc --version
gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
uname -a
Linux machine 4.15.0-34-generic #37~16.04.1-Ubuntu SMP Tue Aug 28 10:44:16 UTC 2018 aarch64 aarch64 aarch64 GNU/Linux
So, has anyone build successfully lwjgl3 for the pi3 and other armhf and arm64 devices? If any. Please give us a precompiled lib sources. Sorry if I am repetitive.
Hello,
I managed to get a cross-compile to aarch64 working on a Linux x64 host. I have no idea how to integrate this nicely with the build system so my changes play well with others, but I did hack up the ant build files to make the cross-compilation work in my case. If that's of any use to anyone trying to get ARM binaries, I'll post my diffs here. Or maybe this could serve as an inspiration for how to integrate an aarch64 target into the build system properly. Who knows, but I hope it helps someone.
diff --git a/config/linux/build.xml b/config/linux/build.xml
index 77eeac633..a8968eb76 100644
--- a/config/linux/build.xml
+++ b/config/linux/build.xml
@@ -13,6 +13,15 @@
<equals arg1="${build.arch}" arg2="x64"/>
</condition>
+ <!-- add cross-compilation toolchain -->
+ <!-- TODO: how to configure? -->
+ <property name="toolchain" value="/path/to/your/cross/compiling/toolchain"/>
+ <property name="toolchain.prefix" value="${toolchain}/bin/aarch64-linux-"/>
+ <property name="toolchain.sysroot" value="${toolchain}/aarch64-cortexa53-linux-gnu/sysroot"/>
+ <property name="toolchain.include" value="${toolchain.sysroot}/usr/include"/>
+ <property name="toolchain.lib" value="${toolchain.sysroot}/usr/lib"/>
+ <property name="system.include" value="/usr/include"/>
+
<condition property="gcc.suffix" value="-${gcc.version}" else="">
<isset property="gcc.version"/>
</condition>
@@ -22,8 +31,8 @@
<macrodef name="compile">
<attribute name="dest" default="${dest}"/>
<attribute name="lang" default="c"/>
- <attribute name="gcc.exec" default="gcc${gcc.suffix}"/>
- <attribute name="gpp.exec" default="g++${gcc.suffix}"/>
+ <attribute name="gcc.exec" default="${toolchain.prefix}gcc${gcc.suffix}"/>
+ <attribute name="gpp.exec" default="${toolchain.prefix}g++${gcc.suffix}"/>
<attribute name="lto" default="-flto"/>
<attribute name="flags" default=""/>
<attribute name="simple" default="false"/>
@@ -39,8 +48,10 @@
<apply dir="@{dest}" executable="${gcc}" dest="@{dest}" skipemptyfilesets="true" failonerror="true" parallel="true" taskname="Compiler">
<arg line="-c -std=c11" unless:set="cpp"/>
<arg line="-c -std=c++11" if:set="cpp"/>
+ <!-- TODO: -m64 -m32 not accepted by aarch64-linux-gcc, how to configure?
<arg line="-m64" if:true="${build.arch.x64}"/>
<arg line="-m32 -mfpmath=sse -msse -msse2" unless:true="${build.arch.x64}"/>
+ -->
<arg line="-O3 @{lto} -fPIC @{flags} -pthread -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 -D_GNU_SOURCE -DNDEBUG -DLWJGL_LINUX -DLWJGL_${build.arch}"/>
<arg value="-I${jni.headers}"/>
@@ -51,6 +62,11 @@
<arg value="-I${src.main.rel}" if:true="@{simple}"/>
+ <!-- include toolchain headers BEFORE system headers -->
+ <!-- TODO: how to configure? -->
+ <arg line="-isystem ${toolchain.include}"/>
+ <arg line="-isystem ${system.include}"/>
+
<source/>
<fileset dir="." includes="${src.generated}/*" if:true="@{simple}"/>
@@ -63,8 +79,8 @@
<attribute name="module"/>
<attribute name="linker" default="gcc"/>
<attribute name="lang" default="c"/>
- <attribute name="gcc.exec" default="gcc${gcc.suffix}"/>
- <attribute name="gpp.exec" default="g++${gcc.suffix}"/>
+ <attribute name="gcc.exec" default="${toolchain.prefix}gcc${gcc.suffix}"/>
+ <attribute name="gpp.exec" default="${toolchain.prefix}g++${gcc.suffix}"/>
<attribute name="flags" default="-Werror -Wfatal-errors"/>
<attribute name="simple" default="false"/>
<element name="beforeCompile" optional="true"/>
@@ -122,8 +138,10 @@
<apply executable="${gcc}" failonerror="true" parallel="true" taskname="Linker" unless:set="lib-uptodate">
<srcfile/>
<arg value="-shared"/>
+ <!-- TODO: -m64 -m32 not accepted by aarch64-linux-gcc, how to configure?
<arg value="-m64" if:true="${build.arch.x64}"/>
<arg value="-m32" unless:true="${build.arch.x64}"/>
+ -->
<arg line="-z noexecstack"/>
<arg line="-O3 -flto -fPIC -pthread -o ${lib}/lib${name}${LIB_POSTFIX}.so"/>
@@ -136,7 +154,7 @@
<link/>
</apply>
- <apply executable="strip" failonerror="true" taskname="Symbol strip" unless:set="lib-uptodate">
+ <apply executable="${toolchain.prefix}strip" failonerror="true" taskname="Symbol strip" unless:set="lib-uptodate">
<filelist dir="${lib}" files="lib${name}${LIB_POSTFIX}.so"/>
</apply>
<delete file="${lib}/touch_${platform}.txt" quiet="true" unless:set="lib-uptodate"/>
@@ -145,8 +163,8 @@
<macrodef name="build_simple">
<attribute name="module"/>
- <attribute name="gcc.exec" default="gcc${gcc.suffix}"/>
- <attribute name="gpp.exec" default="g++${gcc.suffix}"/>
+ <attribute name="gcc.exec" default="${toolchain.prefix}gcc${gcc.suffix}"/>
+ <attribute name="gpp.exec" default="${toolchain.prefix}g++${gcc.suffix}"/>
<sequential>
<build module="@{module}" gcc.exec="@{gcc.exec}" gpp.exec="@{gpp.exec}" simple="true" if:true="${binding.@{module}}"/>
</sequential>
diff --git a/modules/lwjgl/core/src/main/c/linux/wrap_memcpy.c b/modules/lwjgl/core/src/main/c/linux/wrap_memcpy.c
index 239c95817..e1abc29db 100644
--- a/modules/lwjgl/core/src/main/c/linux/wrap_memcpy.c
+++ b/modules/lwjgl/core/src/main/c/linux/wrap_memcpy.c
@@ -2,7 +2,9 @@
void *old_memcpy(void *, const void *, size_t);
-__asm__(".symver old_memcpy,memcpy@GLIBC_2.2.5");
+// aarch64 toolchain seems to have a different symbol version
+//__asm__(".symver old_memcpy,memcpy@GLIBC_2.2.5");
+__asm__(".symver old_memcpy,memcpy@GLIBC_2.17");
void *__wrap_memcpy(void *dest, const void *src, size_t n) {
return old_memcpy(dest, src, n);
I only built and tested the core liblwjgl.so on my ARM board, but I bet lots of the other modules would work this way too.
Oh, and I had to build dyncall for aarch64 too. Here's a helper script I used to do that:
#!/bin/sh
AARCH64=/path/to/your/cross/compiling/toolchain
AARCH64_SYSROOT=${AARCH64}/aarch64-cortexa53-linux-gnu/sysroot
AARCH64_PREFIX=/bin/aarch64-linux-
\
AS="${AARCH64}${AARCH64_PREFIX}gcc"\
CC="${AARCH64}${AARCH64_PREFIX}gcc"\
CXX="${AARCH64}${AARCH64_PREFIX}g++"\
LD="${AARCH64}${AARCH64_PREFIX}ld"\
ASFLAGS="-isysroot ${AARCH64_SYSROOT}"\
CFLAGS="-isysroot ${AARCH64_SYSROOT}"\
CXXFLAGS="-isysroot ${AARCH64_SYSROOT}"\
LDFLAGS="-Wl,-syslibroot ${AARCH64_SYSROOT}"\
make all
Run this script after cloning the dyncall repo and configuring the build. I ran this as an out-of-source build in a build-aarch64 subfolder, but you could run it in the project root too. Then copy the static libs (*.a) to <lwjgl>/bin/libs/linux/x64. I think putting the lwjgl build in offline mode helps ensure your custom dyncall build doesn't get overwritten, but it looks like lwjgl's build doesn't overwrite the custom dyncall libs unless you explicitly clean them. So just copying them to the right folder seemed to work for me.
Oh, and here's the aarch64 toolchain I used. It's supplied by my dev board mfr and there's not much in the way of documentation, but it seems to work just fine.
https://github.com/friendlyarm/prebuilts
I used the gcc-x64/aarch64-cortexa53-linux-gnu-6.4.tar.xz toolchain specifically.
Hope that helps!
You probably want to use debian's built in toolchains and multiarch support.
#Add support for multiarch environments.
dpkg --add-architecture armhf
dpkg --add-architecture arm64
#install toolchains
apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
#Afterward you can install dependencies for other archs like
apt install libgl1-mesa-dev:arm64 libgl1-mesa-dev:armhf
I've made some extremely quick and dirty build.xml modifications which will build some natives in offline mode a941cf361ff713a8e8fbd82ba15dd81eb71440cc
It still needs more work in installing/managing dependencies, fixing a few module specific flags (see meow) but it's fairly simple. Just export LWJGL_BUILD_ARCH=aarch64 beforehand.
For other reference/limitations see https://github.com/libgdx/libgdx/pull/5556
Initial PR's for building most LWJGL-CI modules created. Uses ubuntu's armhf/aarch64 toolchains to build produce arm32/arm64. There's a lot of copy/paste so there may be silly mistakes still.
CI Module | Status
------------|:-------------:
assimp | :heavy_check_mark:
bgfx | TODO: requires gcc5+
bullet3 | :heavy_check_mark:
dyncall | :heavy_check_mark:
jemalloc | :heavy_check_mark:
glfw | :heavy_check_mark:
glfw wayland | :heavy_check_mark:
openal | :heavy_check_mark:
openvr | No travis config in repo?
opus | :heavy_check_mark: (Untested)
OpenVR for ARM is not necessary or useful. There is no ARM OpenVR runtime and the probably never will be (that would then be handled with OpenXR, if it ever happened)
Every LWJGL dependency now has armhf & aarch64 builds. Many thanks to @PokeMMO!
Will work on #463 next.
@Spasi good!!! Many thanks to @PokeMMO . could you give me some info of how to compile master offline (its needed to be offline now?) With ant ( or any othher way) .
ok, so, it will only compile on crosscompiling?? because I replace the build.xml on linux with the @PokeMMO one , set arm32 to true and the rest to false and it starts but crash after some time.
pi@pi:~/Desktop/lwjgl3/config/linux $ ant compile-native-platform
Buildfile: /home/pi/Desktop/lwjgl3/config/linux/build.xml
compile-native-platform:
[gcc] Linking lwjgl_libdivide
[gcc] Linking lwjgl_lmdb
[gcc] Linking lwjgl_nanovg
[gcc] Linking lwjgl_nuklear
[gcc] Linking lwjgl
[gcc] Linking lwjgl_lz4
[gcc] Linking lwjgl_nfd
[Compiler] /home/pi/Desktop/lwjgl3/modules/lwjgl/llvm/src/generated/c/org_lwjgl_llvm_ClangDocumentation.c: En la función ‘JavaCritical_org_lwjgl_llvm_ClangDocumentation_nclang_1Cursor_1getParsedComment’:
[Compiler] /home/pi/Desktop/lwjgl3/modules/lwjgl/llvm/src/generated/c/org_lwjgl_llvm_ClangDocumentation.c:32:19: error: conversión a puntero desde un entero de tamaño diferente [-Werror=int-to-pointer-cast]
[Compiler] CXCursor *C = (CXCursor *)CAddress;
[Compiler] ^
[Compiler] compilación terminada debido a -Wfatal-errors.
[Compiler] cc1: todos los avisos se tratan como errores
[Compiler] /home/pi/Desktop/lwjgl3/modules/lwjgl/llvm/src/generated/c/org_lwjgl_llvm_ClangIndex.c: En la función ‘JavaCritical_org_lwjgl_llvm_ClangIndex_nclang_1getRange’:
[Compiler] /home/pi/Desktop/lwjgl3/modules/lwjgl/llvm/src/generated/c/org_lwjgl_llvm_ClangIndex.c:165:31: error: conversión a puntero desde un entero de tamaño diferente [-Werror=int-to-pointer-cast]
[Compiler] CXSourceLocation *begin = (CXSourceLocation *)beginAddress;
[Compiler] ^
[Compiler] compilación terminada debido a -Wfatal-errors.
[Compiler] cc1: todos los avisos se tratan como errores
[gcc] Linking lwjgl_opengl
[gcc] Linking lwjgl_opengles
[gcc] Linking lwjgl_openvr
[gcc] Linking lwjgl_par
[gcc] Linking lwjgl_remotery
[gcc] Linking lwjgl_rpmalloc
[gcc] Linking lwjgl_stb
[g++] Linking lwjgl_tinyexr
[gcc] Linking lwjgl_tinyfd
[g++] Linking lwjgl_vma
[gcc] Linking lwjgl_xxhash
[g++] Linking lwjgl_yoga
[gcc] Linking lwjgl_zstd
BUILD FAILED
/home/pi/Desktop/lwjgl3/config/linux/build.xml:200:
The following error occurred while executing this line:
/home/pi/Desktop/lwjgl3/config/linux/build.xml:213: The following error occurred while executing this line:
/home/pi/Desktop/lwjgl3/config/build-definitions.xml:302: The following error occurred while executing this line:
/home/pi/Desktop/lwjgl3/config/build-definitions.xml:277: The following error occurred while executing this line:
/home/pi/Desktop/lwjgl3/config/build-definitions.xml:278: Can't get https://build.lwjgl.org/nightly/linux/x86/libdyncall_s.a to /home/pi/Desktop/lwjgl3/bin/libs/linux/x86/libdyncall_s.a
The following error occurred while executing this line:
/home/pi/Desktop/lwjgl3/config/linux/build.xml:188: The following error occurred while executing this line:
/home/pi/Desktop/lwjgl3/config/linux/build.xml:128: The following error occurred while executing this line:
/home/pi/Desktop/lwjgl3/config/linux/build.xml:76: apply returned: 1
The following error occurred while executing this line:
/home/pi/Desktop/lwjgl3/config/linux/build.xml:159: apply returned: 1
The following error occurred while executing this line:
/home/pi/Desktop/lwjgl3/config/linux/build.xml:128: The following error occurred while executing this line:
/home/pi/Desktop/lwjgl3/config/linux/build.xml:76: no resources specified
The following error occurred while executing this line:
/home/pi/Desktop/lwjgl3/config/linux/build.xml:128: The following error occurred while executing this line:
/home/pi/Desktop/lwjgl3/config/linux/build.xml:76: apply returned: 1
The following error occurred while executing this line:
/home/pi/Desktop/lwjgl3/config/linux/build.xml:413: The following error occurred while executing this line:
/home/pi/Desktop/lwjgl3/config/linux/build.xml:76: apply returned: 1
Total time: 3 minutes 37 seconds
sorry for the ignorance, maybe you could give me some tip of whats happens here.
The build.xml changes are still incomplete.
The CROSSBUILD flag handling needs added, certain modules need skipped, certain modules need fixes for build flags, and build package dependencies need documented.
Closed with 9bd6e6046c6098c1f905e3681f32b95c7ec3f532.
Starting with 3.2.3 build 3, LWJGL now supports ARMv8/AArch64 and ARMv7/armhf builds! The build customizer on the website has also been updated, you can download the ARM binaries directly or via Maven/Gradle.
Please open new issues to report problems you encounter. Progress on Android builds will also be tracked separately.
I've downloaded the 3.2.3 zip file containing the jars, should there be a liblwjgl.so file?
Shared libraries are inside jar files. E.g. the shared library for LWJGL core is in lwjgl-natives-linux.jar for x64 and in lwjgl-natives-linux-arm64.jar for arm64.
Most helpful comment
Closed with 9bd6e6046c6098c1f905e3681f32b95c7ec3f532.
Starting with 3.2.3 build 3, LWJGL now supports ARMv8/AArch64 and ARMv7/armhf builds! The build customizer on the website has also been updated, you can download the ARM binaries directly or via Maven/Gradle.
Please open new issues to report problems you encounter. Progress on Android builds will also be tracked separately.