Skip to content

Commit

Permalink
CMake: Use juce_add_modules to import modules from install tree
Browse files Browse the repository at this point in the history
This change means that imported juce modules will be made available both
with and without a namespace prefix, e.g. `juce_core` and
`juce::juce_core` will both be created.

This change allows custom modules to specify dependencies without a
juce:: prefix, which allows the modules to be used with the Projucer, or
under CMake with JUCE in a subdirectory, or under CMake with JUCE
installed to the system.
  • Loading branch information
reuk committed May 5, 2020
1 parent 6f016aa commit bf51d2c
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 34 deletions.
6 changes: 4 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,20 +88,22 @@ set(JUCE_INSTALL_DESTINATION "lib/cmake/JUCE-${JUCE_VERSION}" CACHE STRING

install(EXPORT JUCE NAMESPACE juce:: DESTINATION "${JUCE_INSTALL_DESTINATION}")
set(JUCE_EXPORT_FILE_NAME "JUCE.cmake")
set(JUCE_MODULE_PATH "include/JUCE-${JUCE_VERSION}/modules")
set(UTILS_INSTALL_DIR "${JUCE_INSTALL_DESTINATION}")
set(JUCEAIDE_PATH "${JUCE_TOOL_INSTALL_DIR}/${JUCE_JUCEAIDE_NAME}")
configure_package_config_file("${JUCE_CMAKE_UTILS_DIR}/JUCEConfig.cmake.in"
"${JUCE_BINARY_DIR}/JUCEConfig.cmake"
PATH_VARS UTILS_INSTALL_DIR JUCEAIDE_PATH
PATH_VARS UTILS_INSTALL_DIR JUCEAIDE_PATH JUCE_MODULE_PATH
INSTALL_DESTINATION "${JUCE_INSTALL_DESTINATION}")

set(JUCE_EXPORT_FILE_NAME "JUCEBuildTree.cmake")
set(JUCE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/modules")
export(EXPORT JUCE NAMESPACE juce:: FILE "${JUCE_EXPORT_FILE_NAME}")
set(UTILS_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extras/Build/CMake")
get_target_property(JUCEAIDE_PATH juceaide IMPORTED_LOCATION)
configure_package_config_file("${JUCE_CMAKE_UTILS_DIR}/JUCEConfig.cmake.in"
"${JUCE_BINARY_DIR}/JUCEExportConfig.cmake"
PATH_VARS UTILS_INSTALL_DIR JUCEAIDE_PATH
PATH_VARS UTILS_INSTALL_DIR JUCEAIDE_PATH JUCE_MODULE_PATH
INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}"
INSTALL_DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")

Expand Down
14 changes: 5 additions & 9 deletions examples/CMake/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -491,15 +491,11 @@ both to the target's `SOURCES` and `INTERFACE_SOURCES`, which may result in many
module being built into a single target, which would cause build failures in the best case and
silent ODR violations in the worst case. Scary stuff!

This command has a few optional arguments: `INSTALL_PATH` and `INSTALL_EXPORT` should be provided if
you want the module to be installable through the CMake installation mechanism. `INSTALL_PATH` is a
path, relative to the install prefix, to which the module sources will be copied. `INSTALL_EXPORT`
specifies the CMake export group for the installed module. ALIAS_NAMESPACE will add an alias for the
target(s) with the provided namespace. For example, the following invocation will add a module
target named `my_module`, along with an alias named `company::my_module`.
```
juce_add_module(my_module ALIAS_NAMESPACE company)`
```
This command has a few optional arguments: `INSTALL_PATH` is a path, relative to the install prefix,
to which the module sources will be copied during installation of the module. ALIAS_NAMESPACE will
add an alias for the module target(s) with the provided namespace. For example, the following
invocation will add a module target named `my_module`, along with an alias named
`company::my_module`. ``` juce_add_module(my_module ALIAS_NAMESPACE company)` ```

`juce_add_modules` is a convenience function that can be used to add multiple JUCE modules at once.
This version accepts many module paths, rather than just one. For an example of usage, see the
Expand Down
56 changes: 56 additions & 0 deletions extras/Build/CMake/JUCEConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,59 @@ endif()
check_required_components("@PROJECT_NAME@")

include("@PACKAGE_UTILS_INSTALL_DIR@/JUCEUtils.cmake")

set(_juce_modules
juce_analytics
juce_audio_basics
juce_audio_devices
juce_audio_formats
juce_audio_plugin_client
juce_audio_processors
juce_audio_utils
juce_blocks_basics
juce_box2d
juce_core
juce_cryptography
juce_data_structures
juce_dsp
juce_events
juce_graphics
juce_gui_basics
juce_gui_extra
juce_opengl
juce_osc
juce_product_unlocking
juce_video)

set(_targets_defined)
set(_targets_expected)

foreach(_juce_module IN LISTS _juce_modules)
list(APPEND _targets_expected ${_juce_module} juce::${_juce_modules})
if(TARGET ${_juce_module})
list(APPEND _targets_defined ${_juce_module})
endif()

if(TARGET juce::${_juce_module})
list(APPEND _targets_defined juce::${_juce_module})
endif()
endforeach()

if("${_targets_defined}" STREQUAL "${_targets_expected}")
unset(_targets_defined)
unset(_targets_expected)
return()
endif()

if(NOT "${_targets_defined}" STREQUAL "")
message(FATAL_ERROR "Some targets in this export set were already defined.")
endif()

unset(_targets_defined)
unset(_targets_expected)

foreach(_juce_module IN LISTS _juce_modules)
juce_add_module("@PACKAGE_JUCE_MODULE_PATH@/${_juce_module}" ALIAS_NAMESPACE juce)
endforeach()

unset(_juce_modules)
26 changes: 4 additions & 22 deletions extras/Build/CMake/JUCEUtils.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ endfunction()
# ==================================================================================================

function(juce_add_module module_path)
set(one_value_args INSTALL_PATH INSTALL_EXPORT ALIAS_NAMESPACE)
set(one_value_args INSTALL_PATH ALIAS_NAMESPACE)
cmake_parse_arguments(JUCE_ARG "" "${one_value_args}" "" ${ARGN})

_juce_make_absolute(module_path)
Expand All @@ -455,20 +455,13 @@ function(juce_add_module module_path)

list(APPEND all_module_sources "${base_path}/${module_name}/${module_header_name}")

set(install_export_args)

if(JUCE_ARG_INSTALL_EXPORT)
set(install_export_args INSTALL_EXPORT "${JUCE_ARG_INSTALL_EXPORT}")
endif()

if(${module_name} STREQUAL "juce_audio_plugin_client")
_juce_get_platform_plugin_kinds(plugin_kinds)

foreach(kind IN LISTS plugin_kinds)
_juce_add_plugin_wrapper_target(FORMAT ${kind}
PATH "${module_path}"
OUT_PATH "${base_path}"
${install_export_args})
OUT_PATH "${base_path}")
endforeach()

list(APPEND all_module_sources "${base_path}/${module_name}/juce_audio_plugin_client_utils.cpp")
Expand Down Expand Up @@ -497,10 +490,6 @@ function(juce_add_module module_path)
"${base_path}/juce_audio_processors/format_types/VST3_SDK")
target_link_libraries(juce_audio_processors INTERFACE juce_vst3_headers)

if(JUCE_ARG_INSTALL_EXPORT)
install(TARGETS juce_vst3_headers EXPORT "${JUCE_ARG_INSTALL_EXPORT}")
endif()

if(JUCE_ARG_ALIAS_NAMESPACE)
add_library(${JUCE_ARG_ALIAS_NAMESPACE}::juce_vst3_headers ALIAS juce_vst3_headers)
endif()
Expand Down Expand Up @@ -568,9 +557,8 @@ function(juce_add_module module_path)
_juce_get_metadata("${metadata_dict}" dependencies module_dependencies)
target_link_libraries(${module_name} INTERFACE ${module_dependencies})

if(JUCE_ARG_INSTALL_PATH OR JUCE_ARG_INSTALL_EXPORT)
if(installed_module_path)
install(DIRECTORY "${module_path}" DESTINATION "${installed_module_path}")
install(TARGETS ${module_name} EXPORT "${JUCE_ARG_INSTALL_EXPORT}")
endif()

if(JUCE_ARG_ALIAS_NAMESPACE)
Expand All @@ -579,13 +567,12 @@ function(juce_add_module module_path)
endfunction()

function(juce_add_modules)
set(one_value_args INSTALL_PATH INSTALL_EXPORT ALIAS_NAMESPACE)
set(one_value_args INSTALL_PATH ALIAS_NAMESPACE)
cmake_parse_arguments(JUCE_ARG "" "${one_value_args}" "" ${ARGN})

foreach(path IN LISTS JUCE_ARG_UNPARSED_ARGUMENTS)
juce_add_module(${path}
INSTALL_PATH "${JUCE_ARG_INSTALL_PATH}"
INSTALL_EXPORT "${JUCE_ARG_INSTALL_EXPORT}"
ALIAS_NAMESPACE "${JUCE_ARG_ALIAS_NAMESPACE}")
endforeach()
endfunction()
Expand Down Expand Up @@ -2063,13 +2050,8 @@ function(juce_add_pip header)

set(discovered_module)

# If we're building a PIP from outside the current build tree, the JUCE modules
# might be namespaced, so we try adding a namespace if we can't find a target with
# the name given in the metadata block.
if(TARGET "${module}")
set(discovered_module "${module}")
elseif(TARGET "juce::${module}")
set(discovered_module "juce::${module}")
else()
message(FATAL_ERROR "No such module: ${module}")
endif()
Expand Down
1 change: 0 additions & 1 deletion modules/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

juce_add_modules(
INSTALL_PATH "include/JUCE-${JUCE_VERSION}/modules"
INSTALL_EXPORT JUCE
ALIAS_NAMESPACE juce
juce_analytics
juce_audio_basics
Expand Down

0 comments on commit bf51d2c

Please sign in to comment.