# Build juce shared library for Android, stuck

**URL:** <https://forum.juce.com/t/build-juce-shared-library-for-android-stuck/17005>\
**Category:** Android\
**Created:** [March 25, 2016, 12:08am UTC](https://forum.juce.com/t/build-juce-shared-library-for-android-stuck/17005 "2016-03-25T00:08:05Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![kitetaka](https://avatars.discourse-cdn.com/v4/letter/k/ecccb3/32.png) [@kitetaka](https://forum.juce.com/u/kitetaka)\
**Post date:** [March 25, 2016, 12:08am UTC](https://forum.juce.com/t/build-juce-shared-library-for-android-stuck/17005/1 "2016-03-25T00:08:05Z")

</div>

Dear Juce Experts,

I'm trying to compile Juce library for Android, so I can link to something like libjuce.so and my C++ code can utilize awesome classes like AudioSampleBuffer etc. &nbsp;So here's what I did:

1. Projucer an Android gui application, compiled it with Android Studio successfully.&nbsp;

2. in path\_to\_my\_folder\AndroidStudio\app\build\intermediates\binaries\debug\armeabi-v7a\lib\armeabi-v7a, I found&nbsp;libjuce\_jni.so

3. Write an Android.mk to link to this libjuce\_jni.so, while including JuceHeader.h in the correct folder&nbsp;

4. Then when I'm trying to link to it this way, I got:

"/../../JuceLibraryCode/modules/juce\_opengl/../../../../JUCE/modules/juce\_opengl/juce\_opengl.h:59:20: fatal error: GL/gl.h: No such file or directory&nbsp; #include \<GL/gl.h\>&nbsp;"

Apparently in this juce\_opengl.h, it think JUCE\_WINDOWS is active and not JUCE\_ANDROID flag.&nbsp;

&nbsp;

At this point I'm banging my head and stuck, CouldJu&nbsp;help? Am I doing this whole thing right, or did I miss the correct way to set some flag to get around this?

Thanks in advance.

---

<div class="post-metadata">

**Author:** ![adamwilson](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/adamwilson/32/1387_2.png) [@adamwilson](https://forum.juce.com/u/adamwilson)\
**Post date:** [March 25, 2016, 12:07pm UTC](https://forum.juce.com/t/build-juce-shared-library-for-android-stuck/17005/2 "2016-03-25T12:07:04Z")

</div>

Another option might be to import your existing C++ code into your JUCE project (maybe wrap it in a JUCE module) and compile it for Android... that way you save messing around with static libraries which in my experience can be a bit of a pain.

---

<div class="post-metadata">

**Author:** ![fr810](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/fr810/32/841_2.png) [@fr810](https://forum.juce.com/u/fr810)\
**Post date:** [March 29, 2016, 10:22am UTC](https://forum.juce.com/t/build-juce-shared-library-for-android-stuck/17005/3 "2016-03-29T10:22:52Z")

</div>

It seems like you are not defining JUCE\_ANDROID. Try setting this from the compiler command line.

---

<div class="post-metadata">

**Author:** ![timur](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/timur/32/541_2.png) [@timur](https://forum.juce.com/u/timur)\
**Post date:** [April 1, 2016, 10:51am UTC](https://forum.juce.com/t/build-juce-shared-library-for-android-stuck/17005/4 "2016-04-01T10:51:24Z")

</div>

Building C++ libraries for&nbsp;Android, whether static or dynamic,&nbsp;is currently not supported.

The reason is that a lot of&nbsp;JUCE functionality on Android relies on our JUCE AppActivity class written in Java. But if you are building a library, you don't have that activity class.

I'll put an assert or error message into the Introjucer making clear that this is not supposed to work.

---

<div class="post-metadata">

**Author:** ![jrrossi](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jrrossi/32/140_2.png) [@jrrossi](https://forum.juce.com/u/jrrossi)\
**Post date:** [February 12, 2018, 5:18pm UTC](https://forum.juce.com/t/build-juce-shared-library-for-android-stuck/17005/5 "2018-02-12T17:18:42Z")

</div>

> [@timur](#):
>
> Building C++ libraries for Android, whether static or dynamic, is currently not supported.

Is this still true?

---

<div class="post-metadata">

**Author:** ![fr810](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/fr810/32/841_2.png) [@fr810](https://forum.juce.com/u/fr810)\
**Post date:** [February 14, 2018, 3:35pm UTC](https://forum.juce.com/t/build-juce-shared-library-for-android-stuck/17005/6 "2018-02-14T15:35:31Z")

</div>

Well it’s semi-true. Timur is right that a lot of JUCE code needs JUCE’s `AppActivity` to be the app activity of your android app. Basically (almost) any code that needs to call into java will likely fail when linked as a shared/static library.

Off the top of my head you won’t be able to use the following:

- `juce_gui_basics`/`juce_gui_extra`: everything
- `juce_graphics`: all font and text stuff
- `juce_events`: anything to do with the message loop
- `juce_core`: anything that requires loading a URL, realtime audio threading priorities, some stuff in SystemStats (a lot of stuff in JUCE indirectly uses SystemStats ☹)
- `juce_audio_devices`: everything
- `juce_opengl`: everything

I think most of the stuff in `juce_audio_basics`, `juce_audio_processors` and `juce_dsp` should be fine.

---

<div class="post-metadata">

**Author:** ![garrilla](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/garrilla/32/103_2.png) [@garrilla](https://forum.juce.com/u/garrilla)\
**Post date:** [June 17, 2019, 10:31am UTC](https://forum.juce.com/t/build-juce-shared-library-for-android-stuck/17005/7 "2019-06-17T10:31:58Z")

</div>

is this still true?

It was suggested above the issue was the dependence on the `App Activity` class… does this later announcement - [Breaking Changes in JUCE’s low-level Android code](https://forum.juce.com/t/breaking-changes-in-juce-s-low-level-android-code/30338) - suggest this changed the situation?

what is current status for building Android Static/Dynamic Libraries?

---

<div class="post-metadata">

**Author:** ![fr810](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/fr810/32/841_2.png) [@fr810](https://forum.juce.com/u/fr810)\
**Post date:** [June 17, 2019, 11:05am UTC](https://forum.juce.com/t/build-juce-shared-library-for-android-stuck/17005/8 "2019-06-17T11:05:17Z")

</div>

> [@illagarr](#):
>
> is this still true?

No this is not true anymore. You can now build Android Static/Dynamic libraries as long as you observer some of the notes mentioned in the post you linked:

> [@Breaking Changes in JUCE’s low-level Android code](https://forum.juce.com/t/breaking-changes-in-juce-s-low-level-android-code/30338):
>
> With commit [9a4548a](https://github.com/WeAreROLI/JUCE/commit/008b7a9ab2960f265c6ca305edfba29859a4548a) (on develop), we have completely re-structured JUCE’s low-level Android code. Although no public JUCE APIs (any APIs listed on [docs.juce.com](http://docs.juce.com)) have changed, this commit will likely introduce breaking changes if you used any of JUCE’s internal JNI helper macros (modules/juce\_core/juce\_android\_JNIHelpers.h), invoked native android code directly or relied on JUCE’s auto-generated java code. Before any JUCE API function is called, you must now invoke the Threads::initialiseJUCE …

---

<div class="post-metadata">

**Author:** ![garrilla](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/garrilla/32/103_2.png) [@garrilla](https://forum.juce.com/u/garrilla)\
**Post date:** [June 17, 2019, 11:06am UTC](https://forum.juce.com/t/build-juce-shared-library-for-android-stuck/17005/9 "2019-06-17T11:06:21Z")

</div>

Thank you for the prompt answer @fabian, much appreciated

---

<div class="post-metadata">

**Author:** ![leehu](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/leehu/32/3280_2.png) [@leehu](https://forum.juce.com/u/leehu)\
**Post date:** [July 26, 2023, 8:42pm UTC](https://forum.juce.com/t/build-juce-shared-library-for-android-stuck/17005/10 "2023-07-26T20:42:46Z")

</div>

Hi, having problems initialising JUCE in a shared library. Anyone got any pointers on this? thx

---

<div class="post-metadata">

**Author:** ![fr810](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/fr810/32/841_2.png) [@fr810](https://forum.juce.com/u/fr810)\
**Post date:** [July 27, 2023, 12:58pm UTC](https://forum.juce.com/t/build-juce-shared-library-for-android-stuck/17005/11 "2023-07-27T12:58:04Z")

</div>

Using JUCE inside a native shared library on Android depends on how your shared library is used by your Android app. There are three common options:

1. Your android app is a JUCE app. Then you really shouldn’t need to do anything. Let the Projucer create your android project and simply add the shared libraries you want to use to the Projucer. Once your android project is created, you could choose to continue in Android Studio, for example.

2. You android app is a native kotlin/java app and **directly** loads your native shared library which uses JUCE. For this, you will probably have created your native android app with Android Studio. For the shared library, create a shared library JUCE project with the Projucer (or cmake). Make sure that your JUCE project compiles fine. Then your native android app will need to load the shared library from Java/Kotlin via `System.loadLibrary`. After this you will need to call `com.roli.juce.Java.initialiseJUCE()` from Java on every thread that will call into your native shared library.

3. Your android app is a native kotlin/java app which loads some third-party shared library which in turn loads your shared library which uses JUCE. Here, in addition to calling `com.roli.juce.Java.initialiseJUCE()` on every thread, you first need to call `JNI_OnLoad` (which is defined in JUCE) before calling anything else (including `com.roli.juce.Java.initialiseJUCE()`). This is because Java/Kotlin’s `System.loadLibrary` normally does this automatically (as in 2) but here, your shared library isn’t being loaded by Java/Kotlin but by another native library.

See this thread for more information:

> [@"jmethodID was NULL" error when calling DeviceManager.initialiseWithDefaultDevices()](https://forum.juce.com/t/jmethodid-was-null-error-when-calling-devicemanager-initialisewithdefaultdevices/53506):
>
> Using Projucer, I created a very basic library for Android, so I can play audio in a third party Android app (actually a Flutter app). I initiate my player like the following: AudioSamplePlayer::AudioSamplePlayer() { player = std::make\_unique\<juce::AudioSourcePlayer\>(); player-\>setSource(this); deviceManager.addAudioCallback(player.get()); } When I want to start playing audio, I call the following function of my library, from my app: void AudioSamplePlayer::demarrer() { deviceManager.ini…

---

<div class="post-metadata">

**Author:** ![leehu](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/leehu/32/3280_2.png) [@leehu](https://forum.juce.com/u/leehu)\
**Post date:** [July 27, 2023, 1:13pm UTC](https://forum.juce.com/t/build-juce-shared-library-for-android-stuck/17005/12 "2023-07-27T13:13:44Z")

</div>

ok, thanks. So the situation I’m currently trying to get working is a JUCE android app and a shared library using juce. I’ve been using DynamicLibrary to load the library though - which ultimately calls dylib - are you saying that I shouldn’t be doing this but should should load the library from java?

( I don’t know exactly what the final target architecture will be yet, it’ll probably be 2 I would imagine, but would like to get this use case working as a POC)

Thx

---

<div class="post-metadata">

**Author:** ![fr810](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/fr810/32/841_2.png) [@fr810](https://forum.juce.com/u/fr810)\
**Post date:** [July 27, 2023, 1:57pm UTC](https://forum.juce.com/t/build-juce-shared-library-for-android-stuck/17005/13 "2023-07-27T13:57:28Z")

</div>

Hmm probably a dumb question, but if your android app is already a JUCE app, why not just copy the code of your DynamicLibrary into the JUCE app’s project?

> I’ve been using DynamicLibrary to load the library though - which ultimately calls dylib - are you saying that I shouldn’t be doing this but should should load the library from java?

It’s ok for you to do it this way. Then you essentially have the third case that I mentioned above, i.e. you need to call `JNI_OnLoad` symbol inside the loaded dynamic library (you can do this from JUCE) and then call `JNIClassBase::initialiseAllClasses (env, context)` once and then `Thread::initialiseJUCE (env, context)` for any thread that needs it. Make sure to always call the symbol inside the loaded library and not the symbol in the JUCE app’s copy of JUCE.

I’m not entirely sure that this will work smoothly though as you now have two instances of JUCE trying to register Java classes. Java will call into these classes and potentially be routed into the wrong JUCE shared library instance. I’ve never tried this before.

---

<div class="post-metadata">

**Author:** ![leehu](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/leehu/32/3280_2.png) [@leehu](https://forum.juce.com/u/leehu)\
**Post date:** [July 27, 2023, 2:31pm UTC](https://forum.juce.com/t/build-juce-shared-library-for-android-stuck/17005/14 "2023-07-27T14:31:51Z")

</div>

No, a sensible question, but we want to mimic the target environment as much as possible which will be loading a dynamic library and having to deal with the fact that it’s running juce. We want the setup to be able to run on Mac as well as Java as we’ll be doing most of our dev that way due to Android being a pain to develop with :).

Ok, looks like the piece I’ve been missing in the JNI\_OnLoad. I’ve just looked at this and it requires a java VM pointer to be passed in - how do I get this in the C++ that’s loading the library to pass across to the first function call into the library?

So, heres an example of what I’m currently trying implement:

```auto
auto library = std::make_unique<juce::DynamicLibrary>();
library->open( "mylib.so" );

auto *p_init_fn = ( void ( * )( void ) )m_p_library->getFunction( "init_fn" );
( *p_init_fn )();

```

on the calling side which calls into a function in the library

```auto
void init_fn() {
#if JUCE_ANDROID
// juce::JNI_OnLoad( (JavaVM *)p_vm, nullptr );
// juce::JNIClassBase::initialiseAllClasses( (JNIEnv *)p_jni_env, (jobject)p_context );
// juce::Thread::initialiseJUCE( p_jni_env, p_context );
#endif

    juce::MessageManager::getInstance();
    do_stuff;
}

```

so this works fine mac, windows etc as doesn’t need to do the JNI stuff - however, for Android I don’t have the vm, jni env, or the context needed to call these functions.

thx

---

<div class="post-metadata">

**Author:** ![fr810](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/fr810/32/841_2.png) [@fr810](https://forum.juce.com/u/fr810)\
**Post date:** [July 28, 2023, 2:47pm UTC](https://forum.juce.com/t/build-juce-shared-library-for-android-stuck/17005/15 "2023-07-28T14:47:58Z")

</div>

The app that’s loading the `mylib.so` will already have a pointer to the VM here:

> <https://github.com/juce-framework/JUCE/blob/master/modules/juce_core/native/juce_android_Threads.cpp#L38>

---

<div class="post-metadata">

**Author:** ![leehu](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/leehu/32/3280_2.png) [@leehu](https://forum.juce.com/u/leehu)\
**Post date:** [August 2, 2023, 7:14am UTC](https://forum.juce.com/t/build-juce-shared-library-for-android-stuck/17005/16 "2023-08-02T07:14:53Z")

</div>

Thx, got the OnLoad working, but still don’t have a context for the call to initialiseAllClasses(), should this be passed over from the loading process also? We’re not actually going with the dynamic loading so this isn’t actually necessary any more, but would like to get it working for completeness and understanding on my part.

THx

---

<div class="post-metadata">

**Author:** ![fr810](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/fr810/32/841_2.png) [@fr810](https://forum.juce.com/u/fr810)\
**Post date:** [August 2, 2023, 7:53am UTC](https://forum.juce.com/t/build-juce-shared-library-for-android-stuck/17005/17 "2023-08-02T07:53:40Z")

</div>

Yes, you would also pass the context over.
