# How to generate a release build of a static library for Android?

**URL:** <https://forum.juce.com/t/how-to-generate-a-release-build-of-a-static-library-for-android/50342>\
**Category:** Android\
**Created:** [February 24, 2022, 9:30am UTC](https://forum.juce.com/t/how-to-generate-a-release-build-of-a-static-library-for-android/50342 "2022-02-24T09:30:38Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![matteoh](https://avatars.discourse-cdn.com/v4/letter/m/5f9b8f/32.png) [@matteoh](https://forum.juce.com/u/matteoh)\
**Post date:** [February 24, 2022, 9:30am UTC](https://forum.juce.com/t/how-to-generate-a-release-build-of-a-static-library-for-android/50342/1 "2022-02-24T09:30:38Z")

</div>

I’m trying to generate a static JUCE library for Android, but I can’t find any `.a` file anywhere.

Here is what I did:

- I open my project with Projucer
- I select Android in ‘Selected exporter’
- it opens Android Studio
- in Android Studio, I click on Build \> Make Project
- it generates `.aar` files, but no `.a` file

Did I miss something?

Thanks.

---

<div class="post-metadata">

**Author:** ![reuk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/reuk/32/21494_2.png) [@reuk](https://forum.juce.com/u/reuk)\
**Post date:** [February 24, 2022, 1:11pm UTC](https://forum.juce.com/t/how-to-generate-a-release-build-of-a-static-library-for-android/50342/2 "2022-02-24T13:11:08Z")

</div>

You may end up with multiple .a files, one for each target architecture.

On my system, after running the build, I can find the staticlib file in:

```auto
Builds/Android/lib/build/intermediates/cmake/debug_Debug/obj/<arch>

```

Where `<arch>` is the architecture for which the library was compiled.

---

<div class="post-metadata">

**Author:** ![matteoh](https://avatars.discourse-cdn.com/v4/letter/m/5f9b8f/32.png) [@matteoh](https://forum.juce.com/u/matteoh)\
**Post date:** [February 24, 2022, 1:58pm UTC](https://forum.juce.com/t/how-to-generate-a-release-build-of-a-static-library-for-android/50342/3 "2022-02-24T13:58:56Z")

</div>

Thanks, I found them.

Now, if I want to import those libraries in an Android project, I should need some `.h` header files at some point, right?

Where can I find them? Are they generated like the `.a` files?

---

<div class="post-metadata">

**Author:** ![reuk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/reuk/32/21494_2.png) [@reuk](https://forum.juce.com/u/reuk)\
**Post date:** [February 24, 2022, 2:00pm UTC](https://forum.juce.com/t/how-to-generate-a-release-build-of-a-static-library-for-android/50342/4 "2022-02-24T14:00:59Z")

</div>

You’d just use the JUCE headers directly. The Projucer will have generated a `JuceHeader.h` into `JuceLibraryCode` that you can use.

I’d also recommend enabling the “Use Global AppConfig” setting in the Projucer, as this will make it easier to ensure that the same preprocessor definitions are used inside the library, and by code including the library.

---

<div class="post-metadata">

**Author:** ![matteoh](https://avatars.discourse-cdn.com/v4/letter/m/5f9b8f/32.png) [@matteoh](https://forum.juce.com/u/matteoh)\
**Post date:** [February 24, 2022, 2:33pm UTC](https://forum.juce.com/t/how-to-generate-a-release-build-of-a-static-library-for-android/50342/5 "2022-02-24T14:33:17Z")

</div>

OK so here is what I did in my Android project:

- in `src/main/cpp/jucedemo/lib`, I added the 4 directories (`arm64-v8a`, `armeabi-v7a`, `x86`, `x86_64`), with the different version of my `libJuceDemo.a` in each directory
- I also added a `include` directory with `JuceHeader.h` and `AppConfig.h` in it
- in the `CMakeLists.txt` file of my Android project (located in the `app/` folder), here is what I added:

```auto
set(JuceDemo_DIR ${CMAKE_SOURCE_DIR}/src/main/cpp/jucedemo)
add_library(JuceDemo STATIC IMPORTED)
include_directories(${JuceDemo_DIR}/lib/include)

target_link_libraries(
        native-lib
        JuceDemo
        ${JuceDemo_DIR}/lib/${ANDROID_ABI}/libJuceDemo.a)

```

I’m not a `cmake` expert (far from it!), so maybe I did some silly mistakes.

But the thing is: my Android project doesn’t compile anymore: `error: 'JuceDemo-NOTFOUND'`.

I feel like I’m close, but I’m really struggling!

What did I miss?

Thanks.

---

<div class="post-metadata">

**Author:** ![reuk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/reuk/32/21494_2.png) [@reuk](https://forum.juce.com/u/reuk)\
**Post date:** [February 24, 2022, 2:43pm UTC](https://forum.juce.com/t/how-to-generate-a-release-build-of-a-static-library-for-android/50342/6 "2022-02-24T14:43:18Z")

</div>

It’s difficult to say given that information. Does the IDE tell you which line of the CMakeLists produced the `JuceDemo-NOTFOUND` error? That would be the place to start looking.

Other than that, there are a few things I’d change in the CMake snippet.

Normally, importing a staticlib looks like this:

```auto
add_library(foo STATIC IMPORTED)
set_property(TARGET foo PROPERTY
             IMPORTED_LOCATION "/path/to/libfoo.a")

```

I think you should probably use this approach, and avoid linking `libJuceDemo.a` directly in the `target_link_libraries(native-lib ...` call.

In addition, `include_directories` is generally discouraged. You can use `target_include_directories(JuceDemo PUBLIC` to set include directories that will only apply to `JuceDemo` and its dependent targets.

---

<div class="post-metadata">

**Author:** ![matteoh](https://avatars.discourse-cdn.com/v4/letter/m/5f9b8f/32.png) [@matteoh](https://forum.juce.com/u/matteoh)\
**Post date:** [February 24, 2022, 3:23pm UTC](https://forum.juce.com/t/how-to-generate-a-release-build-of-a-static-library-for-android/50342/7 "2022-02-24T15:23:04Z")

</div>

Thanks!

OK so to give you more details, here is how I added my `libJuceDemo.a` library in my Android project:

![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/b/b3fdd9294c773a18e895cfa1a5c69151d65ae641.png)

And here is what I did now in my `CMakeLists.txt` file:

```auto
add_library(JuceDemo STATIC IMPORTED)
set_property(TARGET JuceDemo PROPERTY
             IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/cpp/jucedemo/${ANDROID_ABI}/libJuceDemo.a)
target_include_directories(JuceDemo
                           PUBLIC ${CMAKE_SOURCE_DIR}/src/main/cpp/jucedemo/lib/include)

```

For the last line (`target_include_directories(...)`), I get the following error: `Cannot specify include directories for imported target "JuceDemo"`.  
If I remove that last line, it compiles.

So I have two questions:

- why do I have that error?
- in my JuceDemo library, I created a simple `JuceTest` class. How to include it in an existing C++ file in the “parent” project so I can use it?

Thanks.

---

<div class="post-metadata">

**Author:** ![reuk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/reuk/32/21494_2.png) [@reuk](https://forum.juce.com/u/reuk)\
**Post date:** [February 24, 2022, 3:32pm UTC](https://forum.juce.com/t/how-to-generate-a-release-build-of-a-static-library-for-android/50342/8 "2022-02-24T15:32:10Z")

</div>

> [@matteoh](#):
>
> why do I have that error?

My bad, it looks like `target_include_directories` doesn’t work on imported targets. I think that `set_target_properties(JuceDemo PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ...)` would work, though.

> [@matteoh](#):
>
> in my JuceDemo library, I created a simple `JuceTest` class. How to include it in an existing C++ file in the “parent” project so I can use it?

Your parent project will need to be set up to see the header file in which `JuceTest` is declared. This probably means adding the path to `JuceTest`’s header to the `INTERFACE_INCLUDE_DIRECTORIES` of the `JuceDemo` imported target.

---

<div class="post-metadata">

**Author:** ![matteoh](https://avatars.discourse-cdn.com/v4/letter/m/5f9b8f/32.png) [@matteoh](https://forum.juce.com/u/matteoh)\
**Post date:** [February 24, 2022, 4:08pm UTC](https://forum.juce.com/t/how-to-generate-a-release-build-of-a-static-library-for-android/50342/9 "2022-02-24T16:08:12Z")

</div>

> My bad, it looks like `target_include_directories` doesn’t work on imported targets. I think that `set_target_properties(JuceDemo PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ...)` would work, though.

Thanks, it compiles now!

> Your parent project will need to be set up to see the header file in which `JuceTest` is declared. This probably means adding the path to `JuceTest` 's header to the `INTERFACE_INCLUDE_DIRECTORIES` of the `JuceDemo` imported target.

That’s really what I don’t manage to understand: does it mean that I have to add something like this?

```auto
set_target_properties(JuceDemo PROPERTIES INTERFACE_INCLUDE_DIRECTORIES /path/to/JuceDemo/Source)

```

It looks really odd… And even by doing that, I still can’t include anything, so I guess I get something wrong again 😕

---

<div class="post-metadata">

**Author:** ![reuk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/reuk/32/21494_2.png) [@reuk](https://forum.juce.com/u/reuk)\
**Post date:** [February 24, 2022, 4:26pm UTC](https://forum.juce.com/t/how-to-generate-a-release-build-of-a-static-library-for-android/50342/10 "2022-02-24T16:26:54Z")

</div>

> [@matteoh](#):
>
> does it mean that I have to add something like this?

That’s what I was thinking, yes.

> [@matteoh](#):
>
> It looks really odd… And even by doing that, I still can’t include anything, so I guess I get something wrong again 😕

How are you trying to use the class? If you’re trying to use it directly from java/kotlin etc. that won’t work, and you’ll need to read up on the JNI.

---

<div class="post-metadata">

**Author:** ![matteoh](https://avatars.discourse-cdn.com/v4/letter/m/5f9b8f/32.png) [@matteoh](https://forum.juce.com/u/matteoh)\
**Post date:** [February 24, 2022, 4:37pm UTC](https://forum.juce.com/t/how-to-generate-a-release-build-of-a-static-library-for-android/50342/11 "2022-02-24T16:37:40Z")

</div>

> How are you trying to use the class? If you’re trying to use it directly from java/kotlin etc. that won’t work, and you’ll need to read up on the JNI.

No, I’m trying to use it in the JNI (so in my C++ code).

But then, if I have to point to the original JUCE project, what’s the point of adding the `libJuceDemo.a` files? Isn’t my `JuceTest` class supposed to be in that library?

I mean, a few years ago, I managed to compile the libogg/libvorbis libraries and added them in my app (as explained [here](https://github.com/mregnauld/ogg-vorbis-libraries-android)), and I just had to add the `.a` library files, a few headers, add some stuff in `CMakeFiles.txt` and that it!

Isn’t that possible to do something similar with a JUCE static (or maybe dynamic) library?

---

<div class="post-metadata">

**Author:** ![reuk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/reuk/32/21494_2.png) [@reuk](https://forum.juce.com/u/reuk)\
**Post date:** [February 24, 2022, 8:18pm UTC](https://forum.juce.com/t/how-to-generate-a-release-build-of-a-static-library-for-android/50342/12 "2022-02-24T20:18:53Z")

</div>

> [@matteoh](#):
>
> But then, if I have to point to the original JUCE project, what’s the point of adding the `libJuceDemo.a` files? Isn’t my `JuceTest` class supposed to be in that library?

The build process for JUCE is a little bit special (generates some files, sets some preprocessor flags etc.). Using the .a generated by a Projucer build might be easier than including the JUCE sources directly in some cases. At the same time, there’s nothing stopping you from including the JUCE module sources directly in the Android project.

The JuceTest class will be in the library, but dependent code won’t know anything about the symbols in the library unless it includes the headers from the library. That includes headers that you write yourself.

---

<div class="post-metadata">

**Author:** ![matteoh](https://avatars.discourse-cdn.com/v4/letter/m/5f9b8f/32.png) [@matteoh](https://forum.juce.com/u/matteoh)\
**Post date:** [February 24, 2022, 9:08pm UTC](https://forum.juce.com/t/how-to-generate-a-release-build-of-a-static-library-for-android/50342/13 "2022-02-24T21:08:47Z")

</div>

Ooh ok, I have to write my own header files, makes more sense now. That being said, it’s a shame Projucer doesn’t do it automatically (unless it’s too complicated).

Anyway, I’ll try that.  
Thanks for your answers and your time!
