diff --git a/BREAKING-CHANGES.txt b/BREAKING-CHANGES.txt index e7bd06426a..12372b0621 100644 --- a/BREAKING-CHANGES.txt +++ b/BREAKING-CHANGES.txt @@ -4,6 +4,28 @@ JUCE breaking changes 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 ------ The default value of JUCE_MODAL_LOOPS_PERMITTED has been changed from 1 to 0. diff --git a/CMakeLists.txt b/CMakeLists.txt index 958a9c131c..61267ca359 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/README.md b/README.md index 482da9d458..b2cc3b9ed2 100644 --- a/README.md +++ b/README.md @@ -36,13 +36,12 @@ For further help getting started, please refer to the JUCE ### 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 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 diff --git a/docs/JUCE Module Format.md b/docs/JUCE Module Format.md index 911b3e2d29..c342b61d59 100644 --- a/docs/JUCE Module Format.md +++ b/docs/JUCE Module Format.md @@ -99,8 +99,11 @@ windowsLibs, linuxLibs and mingwLibs keywords in the module declaration (see the section). - 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 - 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. - 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 - libs/Android/{arch}, where {arch} is the architecture provided by the Android Studio variable diff --git a/examples/CMake/ConsoleApp/CMakeLists.txt b/examples/CMake/ConsoleApp/CMakeLists.txt index 7d5564bc50..690bf09eee 100644 --- a/examples/CMake/ConsoleApp/CMakeLists.txt +++ b/examples/CMake/ConsoleApp/CMakeLists.txt @@ -10,7 +10,7 @@ # 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. -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 # `project()` command. `project()` sets up some helpful variables that describe source/binary diff --git a/examples/CMake/GuiApp/CMakeLists.txt b/examples/CMake/GuiApp/CMakeLists.txt index e449f8c003..fd90b08ada 100644 --- a/examples/CMake/GuiApp/CMakeLists.txt +++ b/examples/CMake/GuiApp/CMakeLists.txt @@ -9,7 +9,7 @@ # 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. -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 # `project()` command. `project()` sets up some helpful variables that describe source/binary diff --git a/extras/Build/CMake/JUCEModuleSupport.cmake b/extras/Build/CMake/JUCEModuleSupport.cmake index 1e09461eb6..17abb65b20 100644 --- a/extras/Build/CMake/JUCEModuleSupport.cmake +++ b/extras/Build/CMake/JUCEModuleSupport.cmake @@ -33,14 +33,7 @@ # ================================================================================================== 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}/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= + 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) @@ -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 "$,x64,Win32>") + + if(NOT CMAKE_GENERATOR_PLATFORM STREQUAL "") + set(arch ${CMAKE_GENERATOR_PLATFORM}) + endif() + + set(runtime_lib "$>") + set(subfolder "MDd") + set(subfolder "$,MTd,${subfolder}>") + set(subfolder "$,MD,${subfolder}>") + set(subfolder "$,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) set(one_value_args INSTALL_PATH ALIAS_NAMESPACE) cmake_parse_arguments(JUCE_ARG "" "${one_value_args}" "" ${ARGN}) @@ -510,6 +568,8 @@ function(juce_add_module module_path) endforeach() endif() + _juce_add_module_staticlib_paths("${module_name}" "${module_path}") + if(JUCE_ARG_INSTALL_PATH) install(DIRECTORY "${module_path}" DESTINATION "${JUCE_ARG_INSTALL_PATH}") endif() diff --git a/extras/Build/CMake/JUCEUtils.cmake b/extras/Build/CMake/JUCEUtils.cmake index 78c31120f4..d8ac3bc8d2 100644 --- a/extras/Build/CMake/JUCEUtils.cmake +++ b/extras/Build/CMake/JUCEUtils.cmake @@ -33,7 +33,7 @@ # ================================================================================================== include_guard(GLOBAL) -cmake_minimum_required(VERSION 3.12) +cmake_minimum_required(VERSION 3.15) define_property(TARGET PROPERTY JUCE_COMPANY_NAME INHERITED 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") 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")) _juce_create_pkgconfig_target(JUCE_CURL_LINUX_DEPS libcurl) _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= - 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") 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) string(REGEX REPLACE "\\." ";" version_list ${version_in}) 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) 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) 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")) set_target_properties(${target_name} PROPERTIES SUFFIX .so - LIBRARY_OUTPUT_DIRECTORY "${output_path}/Contents/${JUCE_LINUX_TARGET_ARCHITECTURE}-linux") + LIBRARY_OUTPUT_DIRECTORY "${output_path}/Contents/${JUCE_TARGET_ARCHITECTURE}-linux") endif() _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() 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() # 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() 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} $_SharedCode) 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_MODULE_AVAILABLE_ private compile definitions, and reexporting them in # the interface compile definitions. - # Unfortunately this requires CMake 3.15. _juce_get_module_definitions(${target} ON enabled_modules) target_compile_definitions(${target} INTERFACE ${enabled_modules}) @@ -1195,7 +1152,7 @@ function(_juce_configure_plugin_targets target) JucePlugin_Desc="$" JucePlugin_Version=${project_version_string} JucePlugin_VersionString="${project_version_string}" - JucePlugin_VersionCode=0x${project_version_hex} + JucePlugin_VersionCode=${project_version_hex} JucePlugin_VSTUniqueID=JucePlugin_PluginCode JucePlugin_VSTCategory=$ JucePlugin_Vst3Category="${vst3_category_string}" diff --git a/extras/Projucer/Source/Project/Modules/jucer_Modules.cpp b/extras/Projucer/Source/Project/Modules/jucer_Modules.cpp index 4b2b9ae239..e29d0b328d 100644 --- a/extras/Projucer/Source/Project/Modules/jucer_Modules.cpp +++ b/extras/Projucer/Source/Project/Modules/jucer_Modules.cpp @@ -73,7 +73,7 @@ void LibraryModule::addSearchPathsToExporter (ProjectExporter& exporter) const }(); auto libSubdirPath = moduleRelativePath.toUnixStyle() + "/libs/" + libDirPlatform; - auto moduleLibDir = File (exporter.getProject().getProjectFolder().getFullPathName() + "/" + libSubdirPath); + auto moduleLibDir = exporter.getProject().resolveFilename (libSubdirPath); if (moduleLibDir.exists()) exporter.addToModuleLibPaths ({ libSubdirPath, moduleRelativePath.getRoot() }); diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp index 25d785f0fd..0e6809f711 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp @@ -1025,7 +1025,12 @@ StringArray ProjectExporter::BuildConfiguration::getLibrarySearchPaths() const auto s = getSearchPathsFromString (getLibrarySearchPathString()); for (auto path : exporter.moduleLibSearchPaths) + { + if (exporter.isXcode()) + s.add (path); + s.add (path + separator + getModuleLibraryArchName()); + } return s; }