Browse Source

CMake: Support automatic linking of bundled libraries in modules

v6.1.6
reuk 3 years ago
parent
commit
6ed8065f70
No known key found for this signature in database GPG Key ID: 9ADCD339CFC98A11
10 changed files with 119 additions and 74 deletions
  1. +22
    -0
      BREAKING-CHANGES.txt
  2. +1
    -5
      CMakeLists.txt
  3. +4
    -5
      README.md
  4. +10
    -4
      docs/JUCE Module Format.md
  5. +1
    -1
      examples/CMake/ConsoleApp/CMakeLists.txt
  6. +1
    -1
      examples/CMake/GuiApp/CMakeLists.txt
  7. +68
    -8
      extras/Build/CMake/JUCEModuleSupport.cmake
  8. +6
    -49
      extras/Build/CMake/JUCEUtils.cmake
  9. +1
    -1
      extras/Projucer/Source/Project/Modules/jucer_Modules.cpp
  10. +5
    -0
      extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp

+ 22
- 0
BREAKING-CHANGES.txt View File

@@ -4,6 +4,28 @@ JUCE breaking changes
Develop Develop
======= =======


Change
------
The minimum support CMake version is now 3.15.

Possible Issues
---------------
It will no longer be possible to configure JUCE projects with CMake versions
between 3.12 and 3.14 inclusive.

Workaround
----------
No workaround is available.

Rationale
---------
Moving to 3.15 allows us to use target_link_directories and
target_link_options, which were introduced in 3.13, which in turn allows us to
provide support for bundled precompiled libraries in modules. Plugins already
required CMake 3.15, so this change just brings other target types in line with
the requirements for plugins.


Change Change
------ ------
The default value of JUCE_MODAL_LOOPS_PERMITTED has been changed from 1 to 0. The default value of JUCE_MODAL_LOOPS_PERMITTED has been changed from 1 to 0.


+ 1
- 5
CMakeLists.txt View File

@@ -21,11 +21,7 @@
# #
# ============================================================================== # ==============================================================================


cmake_minimum_required(VERSION 3.12)

if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.15)
cmake_policy(SET CMP0091 NEW)
endif()
cmake_minimum_required(VERSION 3.15)


project(JUCE VERSION 6.0.8 LANGUAGES C CXX) project(JUCE VERSION 6.0.8 LANGUAGES C CXX)




+ 4
- 5
README.md View File

@@ -36,13 +36,12 @@ For further help getting started, please refer to the JUCE


### CMake ### CMake


Version 3.15 or higher is required for plugin projects, and strongly
recommended for other project types. To use CMake, you will need to install it,
Version 3.15 or higher is required. To use CMake, you will need to install it,
either from your system package manager or from the [official download either from your system package manager or from the [official download
page](https://cmake.org/download/). For comprehensive documentation on JUCE's page](https://cmake.org/download/). For comprehensive documentation on JUCE's
CMake API, see the [JUCE CMake documentation](/docs/CMake%20API.md). For examples
which may be useful as starting points for new CMake projects, see the [CMake
examples directory](/examples/CMake).
CMake API, see the [JUCE CMake documentation](/docs/CMake%20API.md). For
examples which may be useful as starting points for new CMake projects, see the
[CMake examples directory](/examples/CMake).


#### Building Examples #### Building Examples




+ 10
- 4
docs/JUCE Module Format.md View File

@@ -99,8 +99,11 @@ windowsLibs, linuxLibs and mingwLibs keywords in the module declaration (see the
section). section).
- OS X - OS X
- libs/MacOSX/{arch}, where {arch} is the architecture you are targeting in Xcode ("x86_64" or
"i386", for example).
- libs/MacOSX - to support multiple architectures, you may place libraries built as universal
binaries at this location. For backwards compatibility, the Projucer will also include the
directories libs/MacOSX/{arch}, where {arch} is the architecture you are targeting in Xcode
("x86_64" or "i386", for example). When building with CMake, only libraries built as universal
binaries are supported and the arch subfolders are ignored.
- Visual Studio - Visual Studio
- libs/VisualStudio{year}/{arch}/{run-time}, where {year} is the four digit year of the Visual Studio - libs/VisualStudio{year}/{arch}/{run-time}, where {year} is the four digit year of the Visual Studio
@@ -116,8 +119,11 @@ section).
- libs/MinGW/{arch}, where {arch} can take the same values as Linux. - libs/MinGW/{arch}, where {arch} can take the same values as Linux.
- iOS - iOS
- libs/iOS/{arch}, where {arch} is the architecture you are targeting in Xcode ("arm64" or
"x86_64", for example).
- libs/iOS - to support multiple architectures, you may place libraries built as universal
binaries at this location. For backwards compatibility, the Projucer will also include the
directories libs/iOS/{arch}, where {arch} is the architecture you are targeting in Xcode
("arm64" or "x86_64", for example). When building with CMake, only libraries built as universal
binaries are supported and the arch subfolders are ignored.
- Android - Android
- libs/Android/{arch}, where {arch} is the architecture provided by the Android Studio variable - libs/Android/{arch}, where {arch} is the architecture provided by the Android Studio variable


+ 1
- 1
examples/CMake/ConsoleApp/CMakeLists.txt View File

@@ -10,7 +10,7 @@
# CMake's behaviour is compatible with the named version. This is a standard CMake command, so more # CMake's behaviour is compatible with the named version. This is a standard CMake command, so more
# information can be found in the CMake docs. # information can be found in the CMake docs.


cmake_minimum_required(VERSION 3.12)
cmake_minimum_required(VERSION 3.15)


# The top-level CMakeLists.txt file for a project must contain a literal, direct call to the # The top-level CMakeLists.txt file for a project must contain a literal, direct call to the
# `project()` command. `project()` sets up some helpful variables that describe source/binary # `project()` command. `project()` sets up some helpful variables that describe source/binary


+ 1
- 1
examples/CMake/GuiApp/CMakeLists.txt View File

@@ -9,7 +9,7 @@
# CMake's behaviour is compatible with the named version. This is a standard CMake command, so more # CMake's behaviour is compatible with the named version. This is a standard CMake command, so more
# information can be found in the CMake docs. # information can be found in the CMake docs.


cmake_minimum_required(VERSION 3.12)
cmake_minimum_required(VERSION 3.15)


# The top-level CMakeLists.txt file for a project must contain a literal, direct call to the # The top-level CMakeLists.txt file for a project must contain a literal, direct call to the
# `project()` command. `project()` sets up some helpful variables that describe source/binary # `project()` command. `project()` sets up some helpful variables that describe source/binary


+ 68
- 8
extras/Build/CMake/JUCEModuleSupport.cmake View File

@@ -33,14 +33,7 @@
# ================================================================================================== # ==================================================================================================


include_guard(GLOBAL) include_guard(GLOBAL)
cmake_minimum_required(VERSION 3.12)

# ==================================================================================================

function(_juce_add_interface_library target)
add_library(${target} INTERFACE)
target_sources(${target} INTERFACE ${ARGN})
endfunction()
cmake_minimum_required(VERSION 3.15)


# ================================================================================================== # ==================================================================================================


@@ -50,6 +43,33 @@ set(JUCE_CMAKE_UTILS_DIR ${CMAKE_CURRENT_LIST_DIR}
include("${JUCE_CMAKE_UTILS_DIR}/JUCEHelperTargets.cmake") include("${JUCE_CMAKE_UTILS_DIR}/JUCEHelperTargets.cmake")
include("${JUCE_CMAKE_UTILS_DIR}/JUCECheckAtomic.cmake") include("${JUCE_CMAKE_UTILS_DIR}/JUCECheckAtomic.cmake")


# Tries to discover the target platform architecture, which is necessary for
# naming VST3 bundle folders and including bundled libraries from modules
function(_juce_find_target_architecture result)
set(test_file "${JUCE_CMAKE_UTILS_DIR}/juce_runtime_arch_detection.cpp")
try_compile(compile_result "${CMAKE_CURRENT_BINARY_DIR}" "${test_file}"
OUTPUT_VARIABLE compile_output)
string(REGEX REPLACE ".*JUCE_ARCH ([a-zA-Z0-9_-]*).*" "\\1" match_result "${compile_output}")
set("${result}" "${match_result}" PARENT_SCOPE)
endfunction()

if((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD") OR MSYS OR MINGW)
# If you really need to override the detected arch for some reason,
# you can configure the build with -DJUCE_TARGET_ARCHITECTURE=<custom arch>
if(NOT DEFINED JUCE_TARGET_ARCHITECTURE)
_juce_find_target_architecture(target_arch)
set(JUCE_TARGET_ARCHITECTURE "${target_arch}"
CACHE INTERNAL "The target architecture, used to name internal folders in VST3 bundles, and to locate bundled libraries in modules")
endif()
endif()

# ==================================================================================================

function(_juce_add_interface_library target)
add_library(${target} INTERFACE)
target_sources(${target} INTERFACE ${ARGN})
endfunction()

# ================================================================================================== # ==================================================================================================


function(_juce_add_standard_defs juce_target) function(_juce_add_standard_defs juce_target)
@@ -340,6 +360,44 @@ endfunction()


# ================================================================================================== # ==================================================================================================


function(_juce_add_library_path target path)
if(EXISTS "${path}")
target_link_directories(${target} INTERFACE ${path})
endif()
endfunction()

function(_juce_add_module_staticlib_paths module_target module_path)
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
_juce_add_library_path(${module_target} "${module_path}/libs/MacOSX")
elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
_juce_add_library_path(${module_target} "${module_path}/libs/iOS")
elseif((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD"))
_juce_add_library_path(${module_target} "${module_path}/libs/Linux/${JUCE_TARGET_ARCHITECTURE}")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
if(CMAKE_GENERATOR MATCHES "Visual Studio [0-9]+ (20[0-9]+)")
set(arch "$<IF:$<EQUAL:${CMAKE_SIZEOF_VOID_P},8>,x64,Win32>")

if(NOT CMAKE_GENERATOR_PLATFORM STREQUAL "")
set(arch ${CMAKE_GENERATOR_PLATFORM})
endif()

set(runtime_lib "$<GENEX_EVAL:$<TARGET_PROPERTY:MSVC_RUNTIME_LIBRARY>>")
set(subfolder "MDd")
set(subfolder "$<IF:$<STREQUAL:${runtime_lib},MultiThreadedDebug>,MTd,${subfolder}>")
set(subfolder "$<IF:$<STREQUAL:${runtime_lib},MultiThreadedDLL>,MD,${subfolder}>")
set(subfolder "$<IF:$<STREQUAL:${runtime_lib},MultiThreaded>,MT,${subfolder}>")
target_link_directories(${module_target} INTERFACE
"${module_path}/libs/VisualStudio${CMAKE_MATCH_1}/${arch}/${subfolder}")
elseif(MSYS OR MINGW)
_juce_add_library_path(${module_target} "${module_path}/libs/MinGW/${JUCE_TARGET_ARCHITECTURE}")
endif()
elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
_juce_add_library_path(${module_target} "${module_path}/libs/Android/${CMAKE_ANDROID_ARCH_ABI}")
endif()
endfunction()

# ==================================================================================================

function(juce_add_module module_path) function(juce_add_module module_path)
set(one_value_args INSTALL_PATH ALIAS_NAMESPACE) set(one_value_args INSTALL_PATH ALIAS_NAMESPACE)
cmake_parse_arguments(JUCE_ARG "" "${one_value_args}" "" ${ARGN}) cmake_parse_arguments(JUCE_ARG "" "${one_value_args}" "" ${ARGN})
@@ -510,6 +568,8 @@ function(juce_add_module module_path)
endforeach() endforeach()
endif() endif()


_juce_add_module_staticlib_paths("${module_name}" "${module_path}")

if(JUCE_ARG_INSTALL_PATH) if(JUCE_ARG_INSTALL_PATH)
install(DIRECTORY "${module_path}" DESTINATION "${JUCE_ARG_INSTALL_PATH}") install(DIRECTORY "${module_path}" DESTINATION "${JUCE_ARG_INSTALL_PATH}")
endif() endif()


+ 6
- 49
extras/Build/CMake/JUCEUtils.cmake View File

@@ -33,7 +33,7 @@
# ================================================================================================== # ==================================================================================================


include_guard(GLOBAL) include_guard(GLOBAL)
cmake_minimum_required(VERSION 3.12)
cmake_minimum_required(VERSION 3.15)


define_property(TARGET PROPERTY JUCE_COMPANY_NAME INHERITED define_property(TARGET PROPERTY JUCE_COMPANY_NAME INHERITED
BRIEF_DOCS "The company name for a particular target" BRIEF_DOCS "The company name for a particular target"
@@ -80,29 +80,9 @@ define_property(TARGET PROPERTY JUCE_COPY_PLUGIN_AFTER_BUILD INHERITED
FULL_DOCS "Whether or not plugins should be copied after building") FULL_DOCS "Whether or not plugins should be copied after building")
set_property(GLOBAL PROPERTY JUCE_COPY_PLUGIN_AFTER_BUILD FALSE) set_property(GLOBAL PROPERTY JUCE_COPY_PLUGIN_AFTER_BUILD FALSE)


# ==================================================================================================

# Tries to discover the target platform architecture, which is necessary for
# naming VST3 bundle folders correctly.
function(_juce_find_linux_target_architecture result)
set(test_file "${JUCE_CMAKE_UTILS_DIR}/juce_runtime_arch_detection.cpp")
try_compile(compile_result "${CMAKE_CURRENT_BINARY_DIR}" "${test_file}"
OUTPUT_VARIABLE compile_output)
string(REGEX REPLACE ".*JUCE_ARCH ([a-zA-Z0-9_-]*).*" "\\1" match_result "${compile_output}")
set("${result}" "${match_result}" PARENT_SCOPE)
endfunction()

if((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD")) if((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD"))
_juce_create_pkgconfig_target(JUCE_CURL_LINUX_DEPS libcurl) _juce_create_pkgconfig_target(JUCE_CURL_LINUX_DEPS libcurl)
_juce_create_pkgconfig_target(JUCE_BROWSER_LINUX_DEPS webkit2gtk-4.0 gtk+-x11-3.0) _juce_create_pkgconfig_target(JUCE_BROWSER_LINUX_DEPS webkit2gtk-4.0 gtk+-x11-3.0)

# If you really need to override the detected arch for some reason,
# you can configure the build with -DJUCE_LINUX_TARGET_ARCHITECTURE=<custom arch>
if(NOT DEFINED JUCE_LINUX_TARGET_ARCHITECTURE)
_juce_find_linux_target_architecture(target_arch)
set(JUCE_LINUX_TARGET_ARCHITECTURE "${target_arch}"
CACHE INTERNAL "The target architecture, used to name internal folders in VST3 bundles")
endif()
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
find_program(JUCE_XCRUN xcrun) find_program(JUCE_XCRUN xcrun)


@@ -441,24 +421,6 @@ endfunction()


# ================================================================================================== # ==================================================================================================


# math(EXPR ... OUTPUT_FORMAT HEXADECIMAL) wasn't added until 3.13, but we need 3.12 for vcpkg
# compatibility
function(_juce_dec_to_hex num out_var)
while(num)
math(EXPR digit "${num} % 16")
math(EXPR num "${num} / 16")

if(digit GREATER_EQUAL 10)
math(EXPR ascii_code "${digit} + 55")
string(ASCII "${ascii_code}" digit)
endif()

set(result "${digit}${result}")
endwhile()

set(${out_var} "${result}" PARENT_SCOPE)
endfunction()

function(_juce_version_code version_in out_var) function(_juce_version_code version_in out_var)
string(REGEX REPLACE "\\." ";" version_list ${version_in}) string(REGEX REPLACE "\\." ";" version_list ${version_in})
list(LENGTH version_list num_version_components) list(LENGTH version_list num_version_components)
@@ -479,8 +441,8 @@ function(_juce_version_code version_in out_var)
list(GET version_list 2 version_patch) list(GET version_list 2 version_patch)
endif() endif()


math(EXPR decimal "(${version_major} << 16) + (${version_minor} << 8) + ${version_patch}")
_juce_dec_to_hex(${decimal} hex)
math(EXPR hex "(${version_major} << 16) + (${version_minor} << 8) + ${version_patch}"
OUTPUT_FORMAT HEXADECIMAL)
set(${out_var} "${hex}" PARENT_SCOPE) set(${out_var} "${hex}" PARENT_SCOPE)
endfunction() endfunction()


@@ -929,7 +891,7 @@ function(_juce_set_plugin_target_properties shared_code_target kind)
if((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD")) if((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD"))
set_target_properties(${target_name} PROPERTIES set_target_properties(${target_name} PROPERTIES
SUFFIX .so SUFFIX .so
LIBRARY_OUTPUT_DIRECTORY "${output_path}/Contents/${JUCE_LINUX_TARGET_ARCHITECTURE}-linux")
LIBRARY_OUTPUT_DIRECTORY "${output_path}/Contents/${JUCE_TARGET_ARCHITECTURE}-linux")
endif() endif()


_juce_set_copy_properties(${shared_code_target} ${target_name} "${output_path}" JUCE_VST3_COPY_DIR) _juce_set_copy_properties(${shared_code_target} ${target_name} "${output_path}" JUCE_VST3_COPY_DIR)
@@ -1060,7 +1022,7 @@ function(_juce_link_plugin_wrapper shared_code_target kind)
endif() endif()


if((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD")) if((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD"))
target_link_libraries(${target_name} PRIVATE "-Wl,--no-undefined")
target_link_options(${target_name} PRIVATE "-Wl,--no-undefined")
endif() endif()


# We re-export the shared code's private include dirs, because the wrapper targets need to # We re-export the shared code's private include dirs, because the wrapper targets need to
@@ -1124,10 +1086,6 @@ function(_juce_get_vst3_category_string target out_var)
endfunction() endfunction()


function(_juce_configure_plugin_targets target) function(_juce_configure_plugin_targets target)
if(CMAKE_VERSION VERSION_LESS "3.15.0")
message(FATAL_ERROR "Plugin targets require CMake 3.15 or higher")
endif()

_juce_set_output_name(${target} $<TARGET_PROPERTY:${target},JUCE_PRODUCT_NAME>_SharedCode) _juce_set_output_name(${target} $<TARGET_PROPERTY:${target},JUCE_PRODUCT_NAME>_SharedCode)


target_link_libraries(${target} PRIVATE juce::juce_audio_plugin_client_utils) target_link_libraries(${target} PRIVATE juce::juce_audio_plugin_client_utils)
@@ -1156,7 +1114,6 @@ function(_juce_configure_plugin_targets target)
# juce_audio_utils and juce_gui_basics. We achieve this by searching for # juce_audio_utils and juce_gui_basics. We achieve this by searching for
# JUCE_MODULE_AVAILABLE_ private compile definitions, and reexporting them in # JUCE_MODULE_AVAILABLE_ private compile definitions, and reexporting them in
# the interface compile definitions. # the interface compile definitions.
# Unfortunately this requires CMake 3.15.
_juce_get_module_definitions(${target} ON enabled_modules) _juce_get_module_definitions(${target} ON enabled_modules)
target_compile_definitions(${target} INTERFACE ${enabled_modules}) target_compile_definitions(${target} INTERFACE ${enabled_modules})


@@ -1195,7 +1152,7 @@ function(_juce_configure_plugin_targets target)
JucePlugin_Desc="$<TARGET_PROPERTY:${target},JUCE_DESCRIPTION>" JucePlugin_Desc="$<TARGET_PROPERTY:${target},JUCE_DESCRIPTION>"
JucePlugin_Version=${project_version_string} JucePlugin_Version=${project_version_string}
JucePlugin_VersionString="${project_version_string}" JucePlugin_VersionString="${project_version_string}"
JucePlugin_VersionCode=0x${project_version_hex}
JucePlugin_VersionCode=${project_version_hex}
JucePlugin_VSTUniqueID=JucePlugin_PluginCode JucePlugin_VSTUniqueID=JucePlugin_PluginCode
JucePlugin_VSTCategory=$<TARGET_PROPERTY:${target},JUCE_VST2_CATEGORY> JucePlugin_VSTCategory=$<TARGET_PROPERTY:${target},JUCE_VST2_CATEGORY>
JucePlugin_Vst3Category="${vst3_category_string}" JucePlugin_Vst3Category="${vst3_category_string}"


+ 1
- 1
extras/Projucer/Source/Project/Modules/jucer_Modules.cpp View File

@@ -73,7 +73,7 @@ void LibraryModule::addSearchPathsToExporter (ProjectExporter& exporter) const
}(); }();
auto libSubdirPath = moduleRelativePath.toUnixStyle() + "/libs/" + libDirPlatform; auto libSubdirPath = moduleRelativePath.toUnixStyle() + "/libs/" + libDirPlatform;
auto moduleLibDir = File (exporter.getProject().getProjectFolder().getFullPathName() + "/" + libSubdirPath);
auto moduleLibDir = exporter.getProject().resolveFilename (libSubdirPath);
if (moduleLibDir.exists()) if (moduleLibDir.exists())
exporter.addToModuleLibPaths ({ libSubdirPath, moduleRelativePath.getRoot() }); exporter.addToModuleLibPaths ({ libSubdirPath, moduleRelativePath.getRoot() });


+ 5
- 0
extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp View File

@@ -1025,7 +1025,12 @@ StringArray ProjectExporter::BuildConfiguration::getLibrarySearchPaths() const
auto s = getSearchPathsFromString (getLibrarySearchPathString()); auto s = getSearchPathsFromString (getLibrarySearchPathString());
for (auto path : exporter.moduleLibSearchPaths) for (auto path : exporter.moduleLibSearchPaths)
{
if (exporter.isXcode())
s.add (path);
s.add (path + separator + getModuleLibraryArchName()); s.add (path + separator + getModuleLibraryArchName());
}
return s; return s;
} }


Loading…
Cancel
Save