Although it’s quite easy to build a C++ shared library for Android using CMake, building a full Android app is quite a bit more involved, as it requires some interop with Java, and the Java stuff is built with Gradle. So, to get a working Android project you need a working CMake build, and some slightly edited Java files, and a Gradle file to build the Java code and pass the right options to the CMake build. Gradle expects to invoke the CMake build itself, so if we wanted to have CMake run the show we’d end up with a chain where
CMake generates a Gradle file, configures some Java sources, and calls Gradle
Gradle builds the Java sources, and reinvokes CMake
CMake builds a shared library containing JUCE
Finding a way to do this that isn’t horrendously confusing and error-prone is very tricky!
In that case you may be able to build something suitable with the current CMake support. Assuming you have Android Studio installed, you can configure CMake like this:
Thanks!
The regex replace trick does exactly what I want. I didn’t think that this would work since the properties are set on files that are “different” from the INTERFACE_SOURCES , but I guess I still don’t fully get the spirit of CMake.
Such a no-generator-expression option sure would be hacky.
Would it be possible to use the non-installed Juce without add_subdirectory? I.e. add a function that generates JUCE.cmake and JUCEUtils.cmake that reference the sources so that this could be used exactly like the installed Juce:
I don’t know how well this plays with the generated juceaide binary and how hard it is to force a regeneration when Juce is updated. Anyhow, I’m fine for now with the current solution.
I’ve never used the Projucer and I’m relatively new to Juce. A while back I used hand rolled CMake for a fixed set of modules to build a static library according to the Projucer generated makefiles. So I could just use different flags for that library.
I think there is a way to get CMake to treat the build directory as an install directory, but that would be awkward to use because you’d still have to get CMake to run the build somehow. At that point, you may as well go a step further and install JUCE locally to your build tree, something like this:
include(FetchContent)
# If JUCE is a submodule you could use SOURCE_DIR here instead of the GIT_* args
FetchContent_Declare(juce
GIT_REPOSITORY "https://github.com/juce-framework/juce"
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE
GIT_TAG "origin/juce6")
# This is our local install dir for JUCE
set(install_dir "${CMAKE_CURRENT_BINARY_DIR}/install")
# Check whether we already set up JUCE during a previous configure
FetchContent_GetProperties(juce)
if(NOT juce_POPULATED)
# Clone repo if necessary, record that JUCE has been populated
FetchContent_Populate(juce)
# Configure JUCE
execute_process(
COMMAND "${CMAKE_COMMAND}" -S "${juce_SOURCE_DIR}" -B "${juce_BINARY_DIR}" "-DCMAKE_INSTALL_PREFIX=${install_dir}")
# Install JUCE locally to the build tree
execute_process(
COMMAND "${CMAKE_COMMAND}" --build "${juce_BINARY_DIR}" --target install)
endif()
# Tell CMake where to find our local JUCE install
set(JUCE_ROOT "${install_dir}")
find_package(JUCE CONFIG REQUIRED)
@McMartin I think string(GENEX_STRIP) doesn’t work in this cause, because I need to retain the BUILD_INTERFACE part of the generator expression, which is the path to the modules directory.
There are some things I don’t like about actually installing Juce to the build tree:
The unnecessary copy of all the files (This is probably neglectable compared to the time consumed for building juceaide)
I want to compile the Juce code with a high warning level because I want to identify and possibly fix potential issues. If I would install Juce, my changes would be made to the copy and not the checked out code.
Thanks for the detailed FetchContent example. I didn’t know of this module and this will come in handy somewhere else
Makes sense, I’ll take a look at adding the necessary exports so that the JUCE build tree can be treated as an install tree. That should simplify the FetchContent stuff a little bit too.
I’ve put together a commit that allows the build tree to be used as a pseudo-install-tree. Usage looks like this:
include(FetchContent)
# You could also use `GIT_*` args to clone directly from github
FetchContent_Declare(juce SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/JUCE")
# Check whether we already set up JUCE during a previous configure
FetchContent_GetProperties(juce)
if(NOT juce_POPULATED)
# Clone repo if necessary, record that JUCE has been populated
FetchContent_Populate(juce)
# Configure JUCE
execute_process(COMMAND "${CMAKE_COMMAND}" -S "${juce_SOURCE_DIR}" -B "${juce_BINARY_DIR}")
# Build JUCE
execute_process(COMMAND "${CMAKE_COMMAND}" --build "${juce_BINARY_DIR}")
endif()
# Import JUCE targets directly from the build tree
include("${juce_BINARY_DIR}/JUCEExportConfig.cmake")
# juce:: targets are now available, as if `find_package(JUCE)` had been called
I was just giving CMake + CLion a spin on a project that uses a personal juce module, but ran into missing symbols linker errors. The custom module links to a third-party static lib passed in the “OSXLibs” module declaration metadata, but that doesn’t seem to be handled in JUCEUtils.cmake. Is that omitted on purpose? Am I missing something?
(I got it working by adding the path to the lib through my project’s target_link_libraries in CMakeList.txt, but most likely not the right approach)
One addition that i would really fancy is a way to name plugin development builds differently (including AU Plugin Codes) so we can use stable versions of our own plugins to make music.
If your JUCE license allows you to disable the splash screen, you may add JUCE_DISPLAY_SPLASH_SCREEN=0 in your target’s compile definitions. This will turn off the splash screen for that target.
I’m new to CMake, the -DJUCE_BUILD_EXAMPLES=ON option from the document seems to cause the below error with CMake 3.17.2:
CMake Error at extras/Build/CMake/JUCEUtils.cmake:1958 (message):
PIP headers must declare a name field
Call Stack (most recent call first):
examples/CMakeLists.txt:26 (juce_add_pip)
examples/Audio/CMakeLists.txt:17 (_juce_add_pips)
That’s strange, I just tried building with CMake 3.17.2 and the latest juce6 branch on macOS 10.15.4 and Xcode 11.4.1 and configuration succeeded with no issues. Can you give any more details about what caused the issue? Some info that could be useful: