migrating to the latest JUCE version
This commit is contained in:
@ -1,15 +1,15 @@
|
||||
# ==============================================================================
|
||||
#
|
||||
# This file is part of the JUCE library.
|
||||
# Copyright (c) 2020 - Raw Material Software Limited
|
||||
# Copyright (c) 2022 - Raw Material Software Limited
|
||||
#
|
||||
# JUCE is an open source library subject to commercial or open-source
|
||||
# licensing.
|
||||
#
|
||||
# By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
# By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
# Agreement and JUCE Privacy Policy.
|
||||
#
|
||||
# End User License Agreement: www.juce.com/juce-6-licence
|
||||
# End User License Agreement: www.juce.com/juce-7-licence
|
||||
# Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
#
|
||||
# Or: You may also use this code under the terms of the GPL v3 (see
|
||||
@ -29,7 +29,19 @@ function(_juce_create_atomic_target target_name)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(test_file_contents
|
||||
set(test_atomic_with_is_lock_free_file_contents
|
||||
[[
|
||||
#include <atomic>
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
std::atomic<long long> ll { static_cast<long long> (argc) };
|
||||
ll ^= static_cast<long long> (ll.is_lock_free());
|
||||
return static_cast<int> (ll);
|
||||
}
|
||||
]])
|
||||
|
||||
set(test_simple_atomic_file_contents
|
||||
[[
|
||||
#include <atomic>
|
||||
|
||||
@ -47,7 +59,7 @@ function(_juce_create_atomic_target target_name)
|
||||
string(RANDOM LENGTH 16 random_dir_string)
|
||||
set(test_bindir "${CMAKE_CURRENT_BINARY_DIR}/check_atomic_dir_${random_dir_string}")
|
||||
|
||||
file(WRITE "${test_file_name}" "${test_file_contents}")
|
||||
file(WRITE "${test_file_name}" "${test_atomic_with_is_lock_free_file_contents}")
|
||||
|
||||
try_compile(compile_result "${test_bindir}" "${test_file_name}"
|
||||
OUTPUT_VARIABLE test_build_output_0
|
||||
@ -64,15 +76,37 @@ function(_juce_create_atomic_target target_name)
|
||||
CXX_EXTENSIONS FALSE)
|
||||
|
||||
if (NOT compile_result)
|
||||
message(FATAL_ERROR
|
||||
"First build output:\n"
|
||||
"${test_build_output_0}"
|
||||
"\n\nSecond build output:\n"
|
||||
"${test_build_output_1}"
|
||||
"\n\nJUCE requires support for std::atomic, but this system cannot "
|
||||
"successfully compile a program which uses std::atomic. "
|
||||
"You may need to install a dedicated libatomic package using your "
|
||||
"system's package manager.")
|
||||
file(WRITE "${test_file_name}" "${test_simple_atomic_file_contents}")
|
||||
|
||||
try_compile(compile_result "${test_bindir}" "${test_file_name}"
|
||||
OUTPUT_VARIABLE test_build_output_2
|
||||
LINK_LIBRARIES atomic
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD_REQUIRED TRUE
|
||||
CXX_EXTENSIONS FALSE)
|
||||
|
||||
if (NOT compile_result)
|
||||
message(FATAL_ERROR
|
||||
"First build output:\n"
|
||||
"${test_build_output_0}"
|
||||
"\n\nSecond build output:\n"
|
||||
"${test_build_output_1}"
|
||||
"\n\nThird build output:\n"
|
||||
"${test_build_output_2}"
|
||||
"\n\nJUCE requires support for std::atomic, but this system cannot "
|
||||
"successfully compile a program which uses std::atomic. "
|
||||
"You may need to install a dedicated libatomic package using your "
|
||||
"system's package manager.")
|
||||
else()
|
||||
message(WARNING
|
||||
"First build output:\n"
|
||||
"${test_build_output_0}"
|
||||
"\n\nSecond build output:\n"
|
||||
"${test_build_output_1}"
|
||||
"\n\nIf you are seeing this warning it means that the libatomic library"
|
||||
"on this system doesn't support is_lock_free."
|
||||
"Please let the JUCE team know.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_link_libraries("${target_name}" INTERFACE atomic)
|
||||
|
@ -20,6 +20,8 @@
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/LV2_HELPER.cmake")
|
||||
|
||||
if(NOT TARGET juce::juceaide)
|
||||
add_executable(juce::juceaide IMPORTED)
|
||||
set_target_properties(juce::juceaide PROPERTIES
|
||||
|
@ -1,3 +1,26 @@
|
||||
# ==============================================================================
|
||||
#
|
||||
# This file is part of the JUCE library.
|
||||
# Copyright (c) 2022 - Raw Material Software Limited
|
||||
#
|
||||
# JUCE is an open source library subject to commercial or open-source
|
||||
# licensing.
|
||||
#
|
||||
# By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
# Agreement and JUCE Privacy Policy.
|
||||
#
|
||||
# End User License Agreement: www.juce.com/juce-7-licence
|
||||
# Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
#
|
||||
# Or: You may also use this code under the terms of the GPL v3 (see
|
||||
# www.gnu.org/licenses).
|
||||
#
|
||||
# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
# DISCLAIMED.
|
||||
#
|
||||
# ==============================================================================
|
||||
|
||||
add_library(juce_recommended_warning_flags INTERFACE)
|
||||
add_library(juce::juce_recommended_warning_flags ALIAS juce_recommended_warning_flags)
|
||||
|
||||
@ -9,19 +32,21 @@ elseif((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") OR (CMAKE_CXX_COMPILER_ID STREQU
|
||||
-Wuninitialized -Wunused-parameter -Wconversion -Wsign-compare
|
||||
-Wint-conversion -Wconditional-uninitialized -Wconstant-conversion
|
||||
-Wsign-conversion -Wbool-conversion -Wextra-semi -Wunreachable-code
|
||||
-Wcast-align -Wshift-sign-overflow -Wno-missing-field-initializers
|
||||
-Wcast-align -Wshift-sign-overflow -Wmissing-prototypes
|
||||
-Wnullable-to-nonnull-conversion -Wno-ignored-qualifiers -Wswitch-enum
|
||||
-Wpedantic
|
||||
-Wpedantic -Wdeprecated
|
||||
$<$<OR:$<COMPILE_LANGUAGE:CXX>,$<COMPILE_LANGUAGE:OBJCXX>>:
|
||||
-Wzero-as-null-pointer-constant -Wunused-private-field
|
||||
-Woverloaded-virtual -Wreorder
|
||||
-Winconsistent-missing-destructor-override>)
|
||||
-Winconsistent-missing-destructor-override>
|
||||
$<$<OR:$<COMPILE_LANGUAGE:OBJC>,$<COMPILE_LANGUAGE:OBJCXX>>:
|
||||
-Wunguarded-availability -Wunguarded-availability-new>)
|
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
target_compile_options(juce_recommended_warning_flags INTERFACE
|
||||
-Wall -Wextra -Wpedantic -Wstrict-aliasing -Wuninitialized
|
||||
-Wunused-parameter -Wsign-compare -Wsign-conversion -Wunreachable-code
|
||||
-Wcast-align -Wno-implicit-fallthrough -Wno-maybe-uninitialized
|
||||
-Wno-missing-field-initializers -Wno-ignored-qualifiers -Wswitch-enum
|
||||
-Wno-ignored-qualifiers -Wswitch-enum
|
||||
-Wredundant-decls -Wno-strict-overflow -Wshadow
|
||||
$<$<COMPILE_LANGUAGE:CXX>:
|
||||
-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant>)
|
||||
@ -53,9 +78,9 @@ if((CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR (CMAKE_CXX_COMPILER_FRONTEND_VARIA
|
||||
$<$<CONFIG:Release>:$<IF:$<STREQUAL:"${CMAKE_CXX_COMPILER_ID}","MSVC">,-GL,-flto>>)
|
||||
target_link_libraries(juce_recommended_lto_flags INTERFACE
|
||||
$<$<CONFIG:Release>:$<$<STREQUAL:"${CMAKE_CXX_COMPILER_ID}","MSVC">:-LTCG>>)
|
||||
elseif((CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
OR (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
||||
OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU"))
|
||||
elseif((NOT MINGW) AND ((CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
OR (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
||||
OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")))
|
||||
target_compile_options(juce_recommended_lto_flags INTERFACE $<$<CONFIG:Release>:-flto>)
|
||||
target_link_libraries(juce_recommended_lto_flags INTERFACE $<$<CONFIG:Release>:-flto>)
|
||||
endif()
|
||||
|
138
deps/juce/extras/Build/CMake/JUCEModuleSupport.cmake
vendored
138
deps/juce/extras/Build/CMake/JUCEModuleSupport.cmake
vendored
@ -1,15 +1,15 @@
|
||||
# ==============================================================================
|
||||
#
|
||||
# This file is part of the JUCE library.
|
||||
# Copyright (c) 2020 - Raw Material Software Limited
|
||||
# Copyright (c) 2022 - Raw Material Software Limited
|
||||
#
|
||||
# JUCE is an open source library subject to commercial or open-source
|
||||
# licensing.
|
||||
#
|
||||
# By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
# By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
# Agreement and JUCE Privacy Policy.
|
||||
#
|
||||
# End User License Agreement: www.juce.com/juce-6-licence
|
||||
# End User License Agreement: www.juce.com/juce-7-licence
|
||||
# Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
#
|
||||
# Or: You may also use this code under the terms of the GPL v3 (see
|
||||
@ -83,8 +83,10 @@ endfunction()
|
||||
|
||||
macro(_juce_make_absolute path)
|
||||
if(NOT IS_ABSOLUTE "${${path}}")
|
||||
get_filename_component("${path}" "${${path}}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
|
||||
get_filename_component(${path} "${${path}}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
|
||||
endif()
|
||||
|
||||
string(REGEX REPLACE "\\\\" "/" ${path} "${${path}}")
|
||||
endmacro()
|
||||
|
||||
macro(_juce_make_absolute_and_check path)
|
||||
@ -120,23 +122,23 @@ function(_juce_extract_metadata_block delim_str file_with_block out_dict)
|
||||
|
||||
foreach(line IN LISTS module_header_contents)
|
||||
if(NOT append)
|
||||
if(line MATCHES " *BEGIN_${delim_str} *")
|
||||
if(line MATCHES "[\t ]*BEGIN_${delim_str}[\t ]*")
|
||||
set(append YES)
|
||||
endif()
|
||||
|
||||
continue()
|
||||
endif()
|
||||
|
||||
if(append AND (line MATCHES " *END_${delim_str} *"))
|
||||
if(append AND (line MATCHES "[\t ]*END_${delim_str}[\t ]*"))
|
||||
break()
|
||||
endif()
|
||||
|
||||
if(line MATCHES "^ *([a-zA-Z]+):")
|
||||
if(line MATCHES "^[\t ]*([a-zA-Z]+):")
|
||||
set(last_written_key "${CMAKE_MATCH_1}")
|
||||
endif()
|
||||
|
||||
string(REGEX REPLACE "^ *${last_written_key}: *" "" line "${line}")
|
||||
string(REGEX REPLACE "[ ,]+" ";" line "${line}")
|
||||
string(REGEX REPLACE "^[\t ]*${last_written_key}:[\t ]*" "" line "${line}")
|
||||
string(REGEX REPLACE "[\t ,]+" ";" line "${line}")
|
||||
|
||||
set_property(TARGET ${target_name} APPEND PROPERTY
|
||||
"INTERFACE_JUCE_${last_written_key}" "${line}")
|
||||
@ -234,7 +236,7 @@ endfunction()
|
||||
# ==================================================================================================
|
||||
|
||||
function(_juce_get_all_plugin_kinds out)
|
||||
set(${out} AU AUv3 AAX Standalone Unity VST VST3 PARENT_SCOPE)
|
||||
set(${out} AU AUv3 AAX LV2 Standalone Unity VST VST3 PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(_juce_get_platform_plugin_kinds out)
|
||||
@ -249,7 +251,11 @@ function(_juce_get_platform_plugin_kinds out)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_SYSTEM_NAME STREQUAL "iOS" AND NOT CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
list(APPEND result AAX Unity VST VST3)
|
||||
list(APPEND result Unity VST VST3 LV2)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
list(APPEND result AAX)
|
||||
endif()
|
||||
|
||||
set(${out} ${result} PARENT_SCOPE)
|
||||
@ -272,22 +278,29 @@ endfunction()
|
||||
|
||||
# ==================================================================================================
|
||||
|
||||
# Takes a target, a link visibility, and a variable-length list of framework
|
||||
# names. On macOS, finds the requested frameworks using `find_library` and
|
||||
# links them. On iOS, links directly with `-framework Name`.
|
||||
# Takes a target, a link visibility, if it should be a weak link, and a variable-length list of
|
||||
# framework names. On macOS, for non-weak links, this finds the requested frameworks using
|
||||
# `find_library`.
|
||||
function(_juce_link_frameworks target visibility)
|
||||
foreach(framework IN LISTS ARGN)
|
||||
set(options WEAK)
|
||||
cmake_parse_arguments(JUCE_LINK_FRAMEWORKS "${options}" "" "" ${ARGN})
|
||||
foreach(framework IN LISTS JUCE_LINK_FRAMEWORKS_UNPARSED_ARGUMENTS)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
find_library("juce_found_${framework}" "${framework}" REQUIRED)
|
||||
target_link_libraries("${target}" "${visibility}" "${juce_found_${framework}}")
|
||||
if(JUCE_LINK_FRAMEWORKS_WEAK)
|
||||
set(framework_flags "-weak_framework ${framework}")
|
||||
else()
|
||||
find_library("juce_found_${framework}" "${framework}" REQUIRED)
|
||||
set(framework_flags "${juce_found_${framework}}")
|
||||
endif()
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||
# CoreServices is only available on iOS 12+, we must link it weakly on earlier platforms
|
||||
if((framework STREQUAL "CoreServices") AND (CMAKE_OSX_DEPLOYMENT_TARGET LESS 12.0))
|
||||
if(JUCE_LINK_FRAMEWORKS_WEAK OR ((framework STREQUAL "CoreServices") AND (CMAKE_OSX_DEPLOYMENT_TARGET LESS 12.0)))
|
||||
set(framework_flags "-weak_framework ${framework}")
|
||||
else()
|
||||
set(framework_flags "-framework ${framework}")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
if(NOT framework_flags STREQUAL "")
|
||||
target_link_libraries("${target}" "${visibility}" "${framework_flags}")
|
||||
endif()
|
||||
endforeach()
|
||||
@ -398,6 +411,11 @@ endfunction()
|
||||
|
||||
# ==================================================================================================
|
||||
|
||||
function(_juce_remove_empty_list_elements arg)
|
||||
list(FILTER ${arg} EXCLUDE REGEX "^$")
|
||||
set(${arg} ${${arg}} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(juce_add_module module_path)
|
||||
set(one_value_args INSTALL_PATH ALIAS_NAMESPACE)
|
||||
cmake_parse_arguments(JUCE_ARG "" "${one_value_args}" "" ${ARGN})
|
||||
@ -484,8 +502,30 @@ function(juce_add_module module_path)
|
||||
|
||||
target_link_libraries(juce_audio_processors INTERFACE juce_vst3_headers)
|
||||
|
||||
add_library(juce_lilv_headers INTERFACE)
|
||||
set(lv2_base_path "${base_path}/juce_audio_processors/format_types/LV2_SDK")
|
||||
target_include_directories(juce_lilv_headers INTERFACE
|
||||
"${lv2_base_path}"
|
||||
"${lv2_base_path}/lv2"
|
||||
"${lv2_base_path}/serd"
|
||||
"${lv2_base_path}/sord"
|
||||
"${lv2_base_path}/sord/src"
|
||||
"${lv2_base_path}/sratom"
|
||||
"${lv2_base_path}/lilv"
|
||||
"${lv2_base_path}/lilv/src")
|
||||
target_link_libraries(juce_audio_processors INTERFACE juce_lilv_headers)
|
||||
|
||||
add_library(juce_ara_headers INTERFACE)
|
||||
|
||||
target_include_directories(juce_ara_headers INTERFACE
|
||||
"$<$<TARGET_EXISTS:juce_ara_sdk>:$<TARGET_PROPERTY:juce_ara_sdk,INTERFACE_INCLUDE_DIRECTORIES>>")
|
||||
|
||||
target_link_libraries(juce_audio_processors INTERFACE juce_ara_headers)
|
||||
|
||||
if(JUCE_ARG_ALIAS_NAMESPACE)
|
||||
add_library(${JUCE_ARG_ALIAS_NAMESPACE}::juce_vst3_headers ALIAS juce_vst3_headers)
|
||||
add_library(${JUCE_ARG_ALIAS_NAMESPACE}::juce_lilv_headers ALIAS juce_lilv_headers)
|
||||
add_library(${JUCE_ARG_ALIAS_NAMESPACE}::juce_ara_headers ALIAS juce_ara_headers)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@ -497,6 +537,25 @@ function(juce_add_module module_path)
|
||||
target_compile_definitions(${module_name} INTERFACE LINUX=1)
|
||||
endif()
|
||||
|
||||
if((${module_name} STREQUAL "juce_audio_devices") AND (CMAKE_SYSTEM_NAME STREQUAL "Android"))
|
||||
add_subdirectory("${module_path}/native/oboe")
|
||||
target_link_libraries(${module_name} INTERFACE oboe)
|
||||
endif()
|
||||
|
||||
if((${module_name} STREQUAL "juce_opengl") AND (CMAKE_SYSTEM_NAME STREQUAL "Android"))
|
||||
set(platform_supports_gl3 0)
|
||||
|
||||
if(CMAKE_SYSTEM_VERSION VERSION_GREATER_EQUAL 18)
|
||||
set(platform_supports_gl3 1)
|
||||
endif()
|
||||
|
||||
if(platform_supports_gl3)
|
||||
target_compile_definitions(${module_name} INTERFACE JUCE_ANDROID_GL_ES_VERSION_3_0=1)
|
||||
endif()
|
||||
|
||||
target_link_libraries(${module_name} INTERFACE EGL $<IF:${platform_supports_gl3},GLESv3,GLESv2>)
|
||||
endif()
|
||||
|
||||
_juce_extract_metadata_block(JUCE_MODULE_DECLARATION "${module_path}/${module_header_name}" metadata_dict)
|
||||
|
||||
_juce_get_metadata("${metadata_dict}" minimumCppStandard module_cpp_standard)
|
||||
@ -510,26 +569,34 @@ function(juce_add_module module_path)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
_juce_get_metadata("${metadata_dict}" OSXFrameworks module_osxframeworks)
|
||||
|
||||
_juce_remove_empty_list_elements(module_osxframeworks)
|
||||
foreach(module_framework IN LISTS module_osxframeworks)
|
||||
if(module_framework STREQUAL "")
|
||||
continue()
|
||||
endif()
|
||||
|
||||
_juce_link_frameworks("${module_name}" INTERFACE "${module_framework}")
|
||||
endforeach()
|
||||
|
||||
_juce_get_metadata("${metadata_dict}" WeakOSXFrameworks module_weakosxframeworks)
|
||||
|
||||
_juce_remove_empty_list_elements(module_weakosxframeworks)
|
||||
foreach(module_framework IN LISTS module_weakosxframeworks)
|
||||
_juce_link_frameworks("${module_name}" INTERFACE WEAK "${module_framework}")
|
||||
endforeach()
|
||||
|
||||
_juce_link_libs_from_metadata("${module_name}" "${metadata_dict}" OSXLibs)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||
_juce_get_metadata("${metadata_dict}" iOSFrameworks module_iosframeworks)
|
||||
|
||||
_juce_remove_empty_list_elements(module_iosframeworks)
|
||||
foreach(module_framework IN LISTS module_iosframeworks)
|
||||
if(module_framework STREQUAL "")
|
||||
continue()
|
||||
endif()
|
||||
|
||||
_juce_link_frameworks("${module_name}" INTERFACE "${module_framework}")
|
||||
endforeach()
|
||||
|
||||
_juce_get_metadata("${metadata_dict}" WeakiOSFrameworks module_weakiosframeworks)
|
||||
|
||||
_juce_remove_empty_list_elements(module_weakiosframeworks)
|
||||
foreach(module_framework IN LISTS module_weakiosframeworks)
|
||||
_juce_link_frameworks("${module_name}" INTERFACE WEAK "${module_framework}")
|
||||
endforeach()
|
||||
|
||||
_juce_link_libs_from_metadata("${module_name}" "${metadata_dict}" iOSLibs)
|
||||
elseif((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD"))
|
||||
_juce_get_metadata("${metadata_dict}" linuxPackages module_linuxpackages)
|
||||
@ -590,3 +657,18 @@ function(juce_add_modules)
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# When source groups are enabled, this function sets the HEADER_FILE_ONLY property on any module
|
||||
# source files that should not be built. This is called automatically by the juce_add_* functions.
|
||||
function(_juce_fixup_module_source_groups)
|
||||
if(JUCE_ENABLE_MODULE_SOURCE_GROUPS)
|
||||
get_property(all_modules GLOBAL PROPERTY _juce_module_names)
|
||||
|
||||
foreach(module_name IN LISTS all_modules)
|
||||
get_target_property(path ${module_name} INTERFACE_JUCE_MODULE_PATH)
|
||||
get_target_property(header_files ${module_name} INTERFACE_JUCE_MODULE_HEADERS)
|
||||
get_target_property(source_files ${module_name} INTERFACE_JUCE_MODULE_SOURCES)
|
||||
source_group(TREE ${path} PREFIX "JUCE Modules" FILES ${header_files} ${source_files})
|
||||
set_source_files_properties(${header_files} PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
|
282
deps/juce/extras/Build/CMake/JUCEUtils.cmake
vendored
282
deps/juce/extras/Build/CMake/JUCEUtils.cmake
vendored
@ -1,15 +1,15 @@
|
||||
# ==============================================================================
|
||||
#
|
||||
# This file is part of the JUCE library.
|
||||
# Copyright (c) 2020 - Raw Material Software Limited
|
||||
# Copyright (c) 2022 - Raw Material Software Limited
|
||||
#
|
||||
# JUCE is an open source library subject to commercial or open-source
|
||||
# licensing.
|
||||
#
|
||||
# By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
# By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
# Agreement and JUCE Privacy Policy.
|
||||
#
|
||||
# End User License Agreement: www.juce.com/juce-6-licence
|
||||
# End User License Agreement: www.juce.com/juce-7-licence
|
||||
# Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
#
|
||||
# Or: You may also use this code under the terms of the GPL v3 (see
|
||||
@ -75,6 +75,10 @@ define_property(TARGET PROPERTY JUCE_UNITY_COPY_DIR INHERITED
|
||||
BRIEF_DOCS "Install location for Unity plugins"
|
||||
FULL_DOCS "This is where the plugin will be copied if plugin copying is enabled")
|
||||
|
||||
define_property(TARGET PROPERTY JUCE_LV2_COPY_DIR INHERITED
|
||||
BRIEF_DOCS "Install location for LV2 plugins"
|
||||
FULL_DOCS "This is where the plugin will be copied if plugin copying is enabled")
|
||||
|
||||
define_property(TARGET PROPERTY JUCE_COPY_PLUGIN_AFTER_BUILD INHERITED
|
||||
BRIEF_DOCS "Whether or not plugins should be copied after building"
|
||||
FULL_DOCS "Whether or not plugins should be copied after building")
|
||||
@ -97,10 +101,12 @@ endif()
|
||||
|
||||
function(_juce_set_default_properties)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
set_property(GLOBAL PROPERTY JUCE_VST_COPY_DIR "$ENV{HOME}/Library/Audio/Plug-Ins/VST")
|
||||
set_property(GLOBAL PROPERTY JUCE_VST3_COPY_DIR "$ENV{HOME}/Library/Audio/Plug-Ins/VST3")
|
||||
set_property(GLOBAL PROPERTY JUCE_AU_COPY_DIR "$ENV{HOME}/Library/Audio/Plug-Ins/Components")
|
||||
set_property(GLOBAL PROPERTY JUCE_AAX_COPY_DIR "/Library/Application Support/Avid/Audio/Plug-Ins")
|
||||
set_property(GLOBAL PROPERTY JUCE_LV2_COPY_DIR "$ENV{HOME}/Library/Audio/Plug-Ins/LV2")
|
||||
set_property(GLOBAL PROPERTY JUCE_VST_COPY_DIR "$ENV{HOME}/Library/Audio/Plug-Ins/VST")
|
||||
set_property(GLOBAL PROPERTY JUCE_VST3_COPY_DIR "$ENV{HOME}/Library/Audio/Plug-Ins/VST3")
|
||||
set_property(GLOBAL PROPERTY JUCE_AU_COPY_DIR "$ENV{HOME}/Library/Audio/Plug-Ins/Components")
|
||||
set_property(GLOBAL PROPERTY JUCE_UNITY_COPY_DIR "$ENV{HOME}/Library/Audio/Plug-Ins/Unity")
|
||||
set_property(GLOBAL PROPERTY JUCE_AAX_COPY_DIR "/Library/Application Support/Avid/Audio/Plug-Ins")
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set_property(GLOBAL PROPERTY JUCE_VST_COPY_DIR "$ENV{ProgramW6432}/Steinberg/Vstplugins")
|
||||
@ -110,11 +116,15 @@ function(_juce_set_default_properties)
|
||||
set(prefix "$ENV{CommonProgramFiles\(x86\)}")
|
||||
endif()
|
||||
|
||||
set_property(GLOBAL PROPERTY JUCE_VST3_COPY_DIR "${prefix}/VST3")
|
||||
set_property(GLOBAL PROPERTY JUCE_AAX_COPY_DIR "${prefix}/Avid/Audio/Plug-Ins")
|
||||
set_property(GLOBAL PROPERTY JUCE_VST3_COPY_DIR "${prefix}/VST3")
|
||||
set_property(GLOBAL PROPERTY JUCE_AAX_COPY_DIR "${prefix}/Avid/Audio/Plug-Ins")
|
||||
set_property(GLOBAL PROPERTY JUCE_LV2_COPY_DIR "$ENV{APPDATA}/LV2")
|
||||
set_property(GLOBAL PROPERTY JUCE_UNITY_COPY_DIR "$ENV{APPDATA}/Unity")
|
||||
elseif((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD"))
|
||||
set_property(GLOBAL PROPERTY JUCE_VST_COPY_DIR "$ENV{HOME}/.vst")
|
||||
set_property(GLOBAL PROPERTY JUCE_VST3_COPY_DIR "$ENV{HOME}/.vst3")
|
||||
set_property(GLOBAL PROPERTY JUCE_LV2_COPY_DIR "$ENV{HOME}/.lv2")
|
||||
set_property(GLOBAL PROPERTY JUCE_VST_COPY_DIR "$ENV{HOME}/.vst")
|
||||
set_property(GLOBAL PROPERTY JUCE_VST3_COPY_DIR "$ENV{HOME}/.vst3")
|
||||
set_property(GLOBAL PROPERTY JUCE_UNITY_COPY_DIR "$ENV{HOME}/.unity")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
@ -312,12 +322,17 @@ function(_juce_write_configure_time_info target)
|
||||
_juce_append_target_property(file_content PLUGIN_AU_MAIN_TYPE ${target} JUCE_AU_MAIN_TYPE_CODE)
|
||||
_juce_append_target_property(file_content IS_AU_SANDBOX_SAFE ${target} JUCE_AU_SANDBOX_SAFE)
|
||||
_juce_append_target_property(file_content IS_PLUGIN_SYNTH ${target} JUCE_IS_SYNTH)
|
||||
_juce_append_target_property(file_content IS_PLUGIN_ARA_EFFECT ${target} JUCE_IS_ARA_EFFECT)
|
||||
_juce_append_target_property(file_content SUPPRESS_AU_PLIST_RESOURCE_USAGE ${target} JUCE_SUPPRESS_AU_PLIST_RESOURCE_USAGE)
|
||||
_juce_append_target_property(file_content HARDENED_RUNTIME_ENABLED ${target} JUCE_HARDENED_RUNTIME_ENABLED)
|
||||
_juce_append_target_property(file_content APP_SANDBOX_ENABLED ${target} JUCE_APP_SANDBOX_ENABLED)
|
||||
_juce_append_target_property(file_content APP_SANDBOX_INHERIT ${target} JUCE_APP_SANDBOX_INHERIT)
|
||||
_juce_append_target_property(file_content HARDENED_RUNTIME_OPTIONS ${target} JUCE_HARDENED_RUNTIME_OPTIONS)
|
||||
_juce_append_target_property(file_content APP_SANDBOX_OPTIONS ${target} JUCE_APP_SANDBOX_OPTIONS)
|
||||
_juce_append_target_property(file_content APP_SANDBOX_FILE_ACCESS_HOME_RO ${target} JUCE_APP_SANDBOX_FILE_ACCESS_HOME_RO)
|
||||
_juce_append_target_property(file_content APP_SANDBOX_FILE_ACCESS_HOME_RW ${target} JUCE_APP_SANDBOX_FILE_ACCESS_HOME_RW)
|
||||
_juce_append_target_property(file_content APP_SANDBOX_FILE_ACCESS_ABS_RO ${target} JUCE_APP_SANDBOX_FILE_ACCESS_ABS_RO)
|
||||
_juce_append_target_property(file_content APP_SANDBOX_FILE_ACCESS_ABS_RW ${target} JUCE_APP_SANDBOX_FILE_ACCESS_ABS_RW)
|
||||
_juce_append_target_property(file_content APP_GROUPS_ENABLED ${target} JUCE_APP_GROUPS_ENABLED)
|
||||
_juce_append_target_property(file_content APP_GROUP_IDS ${target} JUCE_APP_GROUP_IDS)
|
||||
_juce_append_target_property(file_content IS_PLUGIN ${target} JUCE_IS_PLUGIN)
|
||||
@ -451,7 +466,7 @@ function(_juce_to_char_literal str out_var help_text)
|
||||
string(LENGTH "${str}" string_length)
|
||||
|
||||
if(NOT "${string_length}" EQUAL "4")
|
||||
message(FATAL_ERROR "The ${help_text} code must contain exactly four characters, but it was set to '${str}'")
|
||||
message(WARNING "The ${help_text} code must contain exactly four characters, but it was set to '${str}'")
|
||||
endif()
|
||||
|
||||
# Round-tripping through a file is the simplest way to convert a string to hex...
|
||||
@ -463,7 +478,8 @@ function(_juce_to_char_literal str out_var help_text)
|
||||
file(READ "${scratch_file}" four_chars_hex HEX)
|
||||
file(REMOVE "${scratch_file}")
|
||||
|
||||
set(${out_var} ${four_chars_hex} PARENT_SCOPE)
|
||||
string(SUBSTRING "${four_chars_hex}00000000" 0 8 four_chars_hex)
|
||||
set(${out_var} "${four_chars_hex}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# ==================================================================================================
|
||||
@ -501,10 +517,13 @@ function(_juce_execute_juceaide)
|
||||
message(FATAL_ERROR "juceaide was imported, but it doesn't exist!")
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND "${juceaide_location}" ${ARGN} RESULT_VARIABLE result_variable)
|
||||
execute_process(COMMAND "${juceaide_location}" ${ARGN}
|
||||
RESULT_VARIABLE result_variable
|
||||
OUTPUT_VARIABLE output
|
||||
ERROR_VARIABLE output)
|
||||
|
||||
if(result_variable)
|
||||
message(FATAL_ERROR "Running juceaide failed")
|
||||
message(FATAL_ERROR "Running juceaide failed:\n${output}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
@ -855,7 +874,15 @@ function(juce_enable_copy_plugin_step shared_code_target)
|
||||
get_target_property(source "${target}" JUCE_PLUGIN_ARTEFACT_FILE)
|
||||
|
||||
if(source)
|
||||
get_target_property(dest "${target}" JUCE_PLUGIN_COPY_DIR)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
add_custom_command(TARGET ${target} POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
"-Dsrc=${source}"
|
||||
"-P" "${JUCE_CMAKE_UTILS_DIR}/checkBundleSigning.cmake"
|
||||
VERBATIM)
|
||||
endif()
|
||||
|
||||
get_target_property(dest "${target}" JUCE_PLUGIN_COPY_DIR)
|
||||
|
||||
if(dest)
|
||||
_juce_copy_dir("${target}" "${source}" "$<GENEX_EVAL:${dest}>")
|
||||
@ -979,6 +1006,29 @@ function(_juce_set_plugin_target_properties shared_code_target kind)
|
||||
"${script_file}"
|
||||
JUCE_UNITY_COPY_DIR)
|
||||
endif()
|
||||
elseif(kind STREQUAL "LV2")
|
||||
set_target_properties(${target_name} PROPERTIES BUNDLE FALSE)
|
||||
|
||||
get_target_property(JUCE_LV2URI "${shared_code_target}" JUCE_LV2URI)
|
||||
|
||||
if(NOT JUCE_LV2URI MATCHES "https?://.*")
|
||||
message(WARNING
|
||||
"LV2URI should be well-formed with an 'http' prefix. "
|
||||
"Check the LV2URI argument to juce_add_plugin.")
|
||||
endif()
|
||||
|
||||
set(source_header "${JUCE_CMAKE_UTILS_DIR}/JuceLV2Defines.h.in")
|
||||
get_target_property(juce_library_code "${shared_code_target}" JUCE_GENERATED_SOURCES_DIRECTORY)
|
||||
configure_file("${source_header}" "${juce_library_code}/JuceLV2Defines.h")
|
||||
|
||||
set(output_path "${products_folder}/${product_name}.lv2")
|
||||
set_target_properties(${target_name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${output_path}")
|
||||
|
||||
add_custom_command(TARGET ${target_name} POST_BUILD
|
||||
COMMAND juce::juce_lv2_helper "$<TARGET_FILE:${target_name}>"
|
||||
VERBATIM)
|
||||
|
||||
_juce_set_copy_properties(${shared_code_target} ${target_name} "${output_path}" JUCE_LV2_COPY_DIR)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
@ -1004,6 +1054,8 @@ function(_juce_get_plugin_kind_name kind out_var)
|
||||
set(${out_var} "AUv3 AppExtension" PARENT_SCOPE)
|
||||
elseif(kind STREQUAL "AAX")
|
||||
set(${out_var} "AAX" PARENT_SCOPE)
|
||||
elseif(kind STREQUAL "LV2")
|
||||
set(${out_var} "LV2" PARENT_SCOPE)
|
||||
elseif(kind STREQUAL "Standalone")
|
||||
set(${out_var} "Standalone Plugin" PARENT_SCOPE)
|
||||
elseif(kind STREQUAL "Unity")
|
||||
@ -1064,7 +1116,10 @@ function(_juce_link_plugin_wrapper shared_code_target kind)
|
||||
|
||||
add_dependencies(${shared_code_target}_All ${target_name})
|
||||
|
||||
_juce_configure_bundle(${shared_code_target} ${target_name})
|
||||
if(NOT kind STREQUAL "LV2")
|
||||
_juce_configure_bundle(${shared_code_target} ${target_name})
|
||||
endif()
|
||||
|
||||
_juce_set_plugin_target_properties(${shared_code_target} ${kind})
|
||||
endfunction()
|
||||
|
||||
@ -1183,7 +1238,13 @@ function(_juce_configure_plugin_targets target)
|
||||
JucePlugin_AAXDisableBypass=$<BOOL:$<TARGET_PROPERTY:${target},JUCE_DISABLE_AAX_BYPASS>>
|
||||
JucePlugin_AAXDisableMultiMono=$<BOOL:$<TARGET_PROPERTY:${target},JUCE_DISABLE_AAX_MULTI_MONO>>
|
||||
JucePlugin_VSTNumMidiInputs=$<TARGET_PROPERTY:${target},JUCE_VST_NUM_MIDI_INS>
|
||||
JucePlugin_VSTNumMidiOutputs=$<TARGET_PROPERTY:${target},JUCE_VST_NUM_MIDI_OUTS>)
|
||||
JucePlugin_VSTNumMidiOutputs=$<TARGET_PROPERTY:${target},JUCE_VST_NUM_MIDI_OUTS>
|
||||
JucePlugin_Enable_ARA=$<BOOL:$<TARGET_PROPERTY:${target},JUCE_IS_ARA_EFFECT>>
|
||||
JucePlugin_ARAFactoryID=$<TARGET_PROPERTY:${target},JUCE_ARA_FACTORY_ID>
|
||||
JucePlugin_ARADocumentArchiveID=$<TARGET_PROPERTY:${target},JUCE_ARA_DOCUMENT_ARCHIVE_ID>
|
||||
JucePlugin_ARACompatibleArchiveIDs=$<TARGET_PROPERTY:${target},JUCE_ARA_COMPATIBLE_ARCHIVE_IDS>
|
||||
JucePlugin_ARAContentTypes=$<TARGET_PROPERTY:${target},JUCE_ARA_ANALYSIS_TYPES>
|
||||
JucePlugin_ARATransformationFlags=$<TARGET_PROPERTY:${target},JUCE_ARA_TRANSFORMATION_FLAGS>)
|
||||
|
||||
set_target_properties(${target} PROPERTIES
|
||||
POSITION_INDEPENDENT_CODE TRUE
|
||||
@ -1283,10 +1344,11 @@ function(_juce_set_fallback_properties target)
|
||||
_juce_set_property_if_not_set(${target} BUILD_VERSION "${final_version}")
|
||||
|
||||
get_target_property(custom_xcassets ${target} JUCE_CUSTOM_XCASSETS_FOLDER)
|
||||
get_target_property(custom_storyboard ${target} JUCE_LAUNCH_STORYBOARD_FILE)
|
||||
|
||||
set(needs_storyboard TRUE)
|
||||
|
||||
if(custom_xcassets)
|
||||
if((NOT custom_storyboard) AND custom_xcassets AND (EXISTS "${custom_xcassets}/LaunchImage.launchimage"))
|
||||
set(needs_storyboard FALSE)
|
||||
endif()
|
||||
|
||||
@ -1458,6 +1520,90 @@ function(_juce_set_fallback_properties target)
|
||||
if(NOT aax_category_int STREQUAL "")
|
||||
set_target_properties(${target} PROPERTIES JUCE_AAX_CATEGORY ${aax_category_int})
|
||||
endif()
|
||||
|
||||
# Ensure this matches the Projucer implementation
|
||||
get_target_property(company_website ${target} JUCE_COMPANY_WEBSITE)
|
||||
get_target_property(plugin_name ${target} JUCE_PLUGIN_NAME)
|
||||
string(MAKE_C_IDENTIFIER "${plugin_name}" plugin_name_sanitised)
|
||||
_juce_set_property_if_not_set(${target} LV2URI "${company_website}/plugins/${plugin_name_sanitised}")
|
||||
|
||||
# ARA configuration
|
||||
# Analysis types
|
||||
set(ara_analysis_type_strings
|
||||
kARAContentTypeNotes
|
||||
kARAContentTypeTempoEntries
|
||||
kARAContentTypeBarSignatures
|
||||
kARAContentTypeStaticTuning
|
||||
kARAContentTypeKeySignatures
|
||||
kARAContentTypeSheetChords)
|
||||
|
||||
get_target_property(actual_ara_analysis_types ${target} JUCE_ARA_ANALYSIS_TYPES)
|
||||
|
||||
set(ara_analysis_types_int "")
|
||||
|
||||
foreach(category_string IN LISTS actual_ara_analysis_types)
|
||||
list(FIND ara_analysis_type_strings ${category_string} ara_index)
|
||||
|
||||
if(ara_index GREATER_EQUAL 0)
|
||||
set(ara_analysis_types_bit "1 << ${ara_index}")
|
||||
|
||||
if(ara_analysis_types_int STREQUAL "")
|
||||
set(ara_analysis_types_int 0)
|
||||
endif()
|
||||
|
||||
math(EXPR ara_analysis_types_int "${ara_analysis_types_int} | (${ara_analysis_types_bit})")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(NOT ara_analysis_types_int STREQUAL "")
|
||||
set_target_properties(${target} PROPERTIES JUCE_ARA_ANALYSIS_TYPES ${ara_analysis_types_int})
|
||||
endif()
|
||||
|
||||
_juce_set_property_if_not_set(${target} ARA_ANALYSIS_TYPES 0)
|
||||
|
||||
# Transformation flags
|
||||
set(ara_transformation_flags_strings
|
||||
kARAPlaybackTransformationNoChanges
|
||||
kARAPlaybackTransformationTimestretch
|
||||
kARAPlaybackTransformationTimestretchReflectingTempo
|
||||
kARAPlaybackTransformationContentBasedFadeAtTail
|
||||
kARAPlaybackTransformationContentBasedFadeAtHead)
|
||||
|
||||
set(default_ara_transformation_flags kARAPlaybackTransformationNoChanges)
|
||||
|
||||
_juce_set_property_if_not_set(${target} ARA_TRANSFORMATION_FLAGS ${default_ara_transformation_flags})
|
||||
|
||||
get_target_property(actual_ara_transformation_flags ${target} JUCE_ARA_TRANSFORMATION_FLAGS)
|
||||
|
||||
set(ara_transformation_flags_int "")
|
||||
|
||||
foreach(transformation_string IN LISTS actual_ara_transformation_flags)
|
||||
list(FIND ara_transformation_flags_strings ${transformation_string} ara_transformation_index)
|
||||
|
||||
if(ara_transformation_index GREATER_EQUAL 0)
|
||||
if(ara_transformation_index EQUAL 0)
|
||||
set(ara_transformation_bit 0)
|
||||
else()
|
||||
set(ara_transformation_bit "1 << (${ara_transformation_index} - 1)")
|
||||
endif()
|
||||
|
||||
if(ara_transformation_flags_int STREQUAL "")
|
||||
set(ara_transformation_flags_int 0)
|
||||
endif()
|
||||
|
||||
math(EXPR ara_transformation_flags_int "${ara_transformation_flags_int} | (${ara_transformation_bit})")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(NOT ara_transformation_flags_int STREQUAL "")
|
||||
set_target_properties(${target} PROPERTIES JUCE_ARA_TRANSFORMATION_FLAGS ${ara_transformation_flags_int})
|
||||
endif()
|
||||
|
||||
_juce_set_property_if_not_set(${target} IS_ARA_EFFECT FALSE)
|
||||
get_target_property(final_bundle_id ${target} JUCE_BUNDLE_ID)
|
||||
_juce_set_property_if_not_set(${target} ARA_FACTORY_ID "\"${final_bundle_id}.arafactory.${final_version}\"")
|
||||
_juce_set_property_if_not_set(${target} ARA_DOCUMENT_ARCHIVE_ID "\"${final_bundle_id}.aradocumentarchive.1\"")
|
||||
_juce_set_property_if_not_set(${target} ARA_COMPATIBLE_ARCHIVE_IDS "\"\"")
|
||||
endfunction()
|
||||
|
||||
# ==================================================================================================
|
||||
@ -1524,6 +1670,10 @@ function(_juce_initialise_target target)
|
||||
SUPPRESS_AU_PLIST_RESOURCE_USAGE
|
||||
PLUGINHOST_AU # Set this true if you want to host AU plugins
|
||||
USE_LEGACY_COMPATIBILITY_PLUGIN_CODE
|
||||
LV2URI
|
||||
IS_ARA_EFFECT
|
||||
ARA_FACTORY_ID
|
||||
ARA_DOCUMENT_ARCHIVE_ID
|
||||
|
||||
VST_COPY_DIR
|
||||
VST3_COPY_DIR
|
||||
@ -1537,11 +1687,18 @@ function(_juce_initialise_target target)
|
||||
VST3_CATEGORIES
|
||||
HARDENED_RUNTIME_OPTIONS
|
||||
APP_SANDBOX_OPTIONS
|
||||
APP_SANDBOX_FILE_ACCESS_HOME_RO
|
||||
APP_SANDBOX_FILE_ACCESS_HOME_RW
|
||||
APP_SANDBOX_FILE_ACCESS_ABS_RO
|
||||
APP_SANDBOX_FILE_ACCESS_ABS_RW
|
||||
DOCUMENT_EXTENSIONS
|
||||
AAX_CATEGORY
|
||||
IPHONE_SCREEN_ORIENTATIONS # iOS only
|
||||
IPAD_SCREEN_ORIENTATIONS # iOS only
|
||||
APP_GROUP_IDS) # iOS only
|
||||
APP_GROUP_IDS # iOS only
|
||||
ARA_COMPATIBLE_ARCHIVE_IDS
|
||||
ARA_ANALYSIS_TYPES
|
||||
ARA_TRANSFORMATION_FLAGS)
|
||||
|
||||
cmake_parse_arguments(JUCE_ARG "" "${one_value_args}" "${multi_value_args}" ${ARGN})
|
||||
|
||||
@ -1611,18 +1768,7 @@ function(_juce_initialise_target target)
|
||||
|
||||
_juce_write_generate_time_info(${target})
|
||||
_juce_link_optional_libraries(${target})
|
||||
|
||||
if(JUCE_ENABLE_MODULE_SOURCE_GROUPS)
|
||||
get_property(all_modules GLOBAL PROPERTY _juce_module_names)
|
||||
|
||||
foreach(module_name IN LISTS all_modules)
|
||||
get_target_property(path ${module_name} INTERFACE_JUCE_MODULE_PATH)
|
||||
get_target_property(header_files ${module_name} INTERFACE_JUCE_MODULE_HEADERS)
|
||||
get_target_property(source_files ${module_name} INTERFACE_JUCE_MODULE_SOURCES)
|
||||
source_group(TREE ${path} PREFIX "JUCE Modules" FILES ${header_files} ${source_files})
|
||||
set_source_files_properties(${header_files} PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
endforeach()
|
||||
endif()
|
||||
_juce_fixup_module_source_groups()
|
||||
endfunction()
|
||||
|
||||
# ==================================================================================================
|
||||
@ -1746,27 +1892,49 @@ function(juce_add_pip header)
|
||||
NEEDS_STORE_KIT TRUE)
|
||||
endif()
|
||||
|
||||
if("JUCE_PLUGINHOST_AU=1" IN_LIST pip_moduleflags)
|
||||
list(APPEND extra_target_args PLUGINHOST_AU TRUE)
|
||||
endif()
|
||||
|
||||
if(pip_kind STREQUAL "AudioProcessor")
|
||||
set(source_main "${JUCE_CMAKE_UTILS_DIR}/PIPAudioProcessor.cpp.in")
|
||||
_juce_get_metadata("${metadata_dict}" documentControllerClass JUCE_PIP_DOCUMENTCONTROLLER_CLASS)
|
||||
|
||||
# We add AAX/VST2 targets too, if the user has set up those SDKs
|
||||
if(JUCE_PIP_DOCUMENTCONTROLLER_CLASS)
|
||||
if(NOT TARGET juce_ara_sdk)
|
||||
message(WARNING
|
||||
"${header} specifies a documentControllerClass, but the ARA SDK could not be located. "
|
||||
"Use juce_set_ara_sdk_path to specify the ARA SDK location. "
|
||||
"This PIP will not be configured.")
|
||||
endif()
|
||||
|
||||
set(extra_formats)
|
||||
set(source_main "${JUCE_CMAKE_UTILS_DIR}/PIPAudioProcessorWithARA.cpp.in")
|
||||
|
||||
if(TARGET juce_aax_sdk)
|
||||
list(APPEND extra_formats AAX)
|
||||
juce_add_plugin(${JUCE_PIP_NAME}
|
||||
FORMATS AU VST3
|
||||
IS_ARA_EFFECT TRUE
|
||||
${extra_target_args})
|
||||
else()
|
||||
set(source_main "${JUCE_CMAKE_UTILS_DIR}/PIPAudioProcessor.cpp.in")
|
||||
|
||||
# We add AAX/VST2 targets too, if the user has set up those SDKs
|
||||
|
||||
set(extra_formats)
|
||||
|
||||
if(TARGET juce_aax_sdk)
|
||||
list(APPEND extra_formats AAX)
|
||||
endif()
|
||||
|
||||
if(TARGET juce_vst2_sdk)
|
||||
list(APPEND extra_formats VST)
|
||||
endif()
|
||||
|
||||
# Standalone plugins might want to access the mic
|
||||
list(APPEND extra_target_args MICROPHONE_PERMISSION_ENABLED TRUE)
|
||||
|
||||
juce_add_plugin(${JUCE_PIP_NAME}
|
||||
FORMATS AU AUv3 LV2 Standalone Unity VST3 ${extra_formats}
|
||||
${extra_target_args})
|
||||
endif()
|
||||
|
||||
if(TARGET juce_vst2_sdk)
|
||||
list(APPEND extra_formats VST)
|
||||
endif()
|
||||
|
||||
# Standalone plugins might want to access the mic
|
||||
list(APPEND extra_target_args MICROPHONE_PERMISSION_ENABLED TRUE)
|
||||
|
||||
juce_add_plugin(${JUCE_PIP_NAME}
|
||||
FORMATS AU AUv3 VST3 Unity Standalone ${extra_formats}
|
||||
${extra_target_args})
|
||||
elseif(pip_kind STREQUAL "Component")
|
||||
set(source_main "${JUCE_CMAKE_UTILS_DIR}/PIPComponent.cpp.in")
|
||||
juce_add_gui_app(${JUCE_PIP_NAME} ${extra_target_args})
|
||||
@ -1918,6 +2086,22 @@ function(juce_set_vst3_sdk_path path)
|
||||
target_include_directories(juce_vst3_sdk INTERFACE "${path}")
|
||||
endfunction()
|
||||
|
||||
function(juce_set_ara_sdk_path path)
|
||||
if(TARGET juce_ara_sdk)
|
||||
message(FATAL_ERROR "juce_set_ara_sdk_path should only be called once")
|
||||
endif()
|
||||
|
||||
_juce_make_absolute(path)
|
||||
|
||||
if(NOT EXISTS "${path}")
|
||||
message(FATAL_ERROR "Could not find ARA SDK at the specified path: ${path}")
|
||||
endif()
|
||||
|
||||
add_library(juce_ara_sdk INTERFACE IMPORTED GLOBAL)
|
||||
|
||||
target_include_directories(juce_ara_sdk INTERFACE "${path}")
|
||||
endfunction()
|
||||
|
||||
# ==================================================================================================
|
||||
|
||||
function(juce_disable_default_flags)
|
||||
|
5
deps/juce/extras/Build/CMake/JuceLV2Defines.h.in
vendored
Normal file
5
deps/juce/extras/Build/CMake/JuceLV2Defines.h.in
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef JucePlugin_LV2URI
|
||||
#define JucePlugin_LV2URI "${JUCE_LV2URI}"
|
||||
#endif
|
23
deps/juce/extras/Build/CMake/PIPAudioProcessorWithARA.cpp.in
vendored
Normal file
23
deps/juce/extras/Build/CMake/PIPAudioProcessorWithARA.cpp.in
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file was auto-generated and contains the startup code for a PIP.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include <JuceHeader.h>
|
||||
#include "${JUCE_PIP_HEADER}"
|
||||
|
||||
//==============================================================================
|
||||
juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter()
|
||||
{
|
||||
return new ${JUCE_PIP_MAIN_CLASS}();
|
||||
}
|
||||
|
||||
#if JucePlugin_Enable_ARA
|
||||
const ARA::ARAFactory* JUCE_CALLTYPE createARAFactory()
|
||||
{
|
||||
return juce::ARADocumentControllerSpecialisation::createARAFactory<${JUCE_PIP_DOCUMENTCONTROLLER_CLASS}>();
|
||||
}
|
||||
#endif
|
37
deps/juce/extras/Build/CMake/checkBundleSigning.cmake
vendored
Normal file
37
deps/juce/extras/Build/CMake/checkBundleSigning.cmake
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
# ==============================================================================
|
||||
#
|
||||
# This file is part of the JUCE library.
|
||||
# Copyright (c) 2022 - Raw Material Software Limited
|
||||
#
|
||||
# JUCE is an open source library subject to commercial or open-source
|
||||
# licensing.
|
||||
#
|
||||
# By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
# Agreement and JUCE Privacy Policy.
|
||||
#
|
||||
# End User License Agreement: www.juce.com/juce-7-licence
|
||||
# Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
#
|
||||
# Or: You may also use this code under the terms of the GPL v3 (see
|
||||
# www.gnu.org/licenses).
|
||||
#
|
||||
# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
# DISCLAIMED.
|
||||
#
|
||||
# ==============================================================================
|
||||
|
||||
find_program(JUCE_XCRUN xcrun)
|
||||
|
||||
if(NOT JUCE_XCRUN)
|
||||
return()
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND "${JUCE_XCRUN}" codesign --verify "${src}"
|
||||
RESULT_VARIABLE result)
|
||||
|
||||
if(result)
|
||||
message(STATUS "Replacing invalid signature with ad-hoc signature")
|
||||
execute_process(COMMAND "${JUCE_XCRUN}" codesign -s - "${src}")
|
||||
endif()
|
8
deps/juce/extras/Build/CMake/copyDir.cmake
vendored
8
deps/juce/extras/Build/CMake/copyDir.cmake
vendored
@ -1,15 +1,15 @@
|
||||
# ==============================================================================
|
||||
#
|
||||
# This file is part of the JUCE library.
|
||||
# Copyright (c) 2020 - Raw Material Software Limited
|
||||
# Copyright (c) 2022 - Raw Material Software Limited
|
||||
#
|
||||
# JUCE is an open source library subject to commercial or open-source
|
||||
# licensing.
|
||||
#
|
||||
# By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
# By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
# Agreement and JUCE Privacy Policy.
|
||||
#
|
||||
# End User License Agreement: www.juce.com/juce-6-licence
|
||||
# End User License Agreement: www.juce.com/juce-7-licence
|
||||
# Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
#
|
||||
# Or: You may also use this code under the terms of the GPL v3 (see
|
||||
|
@ -1,57 +1,82 @@
|
||||
#if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__)
|
||||
|
||||
#if defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__)
|
||||
#error JUCE_ARCH aarch64
|
||||
#elif (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM == 8) || defined(__ARMv8__) || defined(__ARMv8_A__)
|
||||
#error JUCE_ARCH armv8l
|
||||
#elif (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM == 7) || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) || defined(_ARM_ARCH_7) || defined(__CORE_CORTEXA__)
|
||||
#error JUCE_ARCH armv7l
|
||||
#elif (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM == 6) || defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6M__)
|
||||
#error JUCE_ARCH armv6l
|
||||
#elif (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM == 5) || defined(__ARM_ARCH_5TEJ__)
|
||||
#error JUCE_ARCH armv5l
|
||||
#else
|
||||
#error JUCE_ARCH arm
|
||||
#endif
|
||||
|
||||
#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
|
||||
|
||||
#error JUCE_ARCH i386
|
||||
|
||||
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
|
||||
|
||||
#error JUCE_ARCH x86_64
|
||||
|
||||
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
|
||||
|
||||
#error JUCE_ARCH ia64
|
||||
|
||||
#elif defined(__mips) || defined(__mips__) || defined(_M_MRX000)
|
||||
|
||||
#if defined(_MIPS_ARCH_MIPS64) || defined(__mips64)
|
||||
#error JUCE_ARCH mips64
|
||||
#else
|
||||
#error JUCE_ARCH mips
|
||||
#endif
|
||||
|
||||
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) || defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_M_MPPC) || defined(_M_PPC)
|
||||
|
||||
#if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__)
|
||||
#error JUCE_ARCH ppc64
|
||||
#else
|
||||
#error JUCE_ARCH ppc
|
||||
#endif
|
||||
|
||||
#elif defined(__riscv)
|
||||
|
||||
#if __riscv_xlen == 64
|
||||
#error JUCE_ARCH riscv64
|
||||
#else
|
||||
#error JUCE_ARCH riscv
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#error JUCE_ARCH unknown
|
||||
|
||||
#endif
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__)
|
||||
|
||||
#if defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__)
|
||||
#error JUCE_ARCH aarch64
|
||||
#elif (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM == 8) || defined(__ARMv8__) || defined(__ARMv8_A__)
|
||||
#error JUCE_ARCH armv8l
|
||||
#elif (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM == 7) || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) || defined(_ARM_ARCH_7) || defined(__CORE_CORTEXA__)
|
||||
#error JUCE_ARCH armv7l
|
||||
#elif (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM == 6) || defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6M__)
|
||||
#error JUCE_ARCH armv6l
|
||||
#elif (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM == 5) || defined(__ARM_ARCH_5TEJ__)
|
||||
#error JUCE_ARCH armv5l
|
||||
#else
|
||||
#error JUCE_ARCH arm
|
||||
#endif
|
||||
|
||||
#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
|
||||
|
||||
#error JUCE_ARCH i386
|
||||
|
||||
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
|
||||
|
||||
#error JUCE_ARCH x86_64
|
||||
|
||||
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
|
||||
|
||||
#error JUCE_ARCH ia64
|
||||
|
||||
#elif defined(__mips) || defined(__mips__) || defined(_M_MRX000)
|
||||
|
||||
#if defined(_MIPS_ARCH_MIPS64) || defined(__mips64)
|
||||
#error JUCE_ARCH mips64
|
||||
#else
|
||||
#error JUCE_ARCH mips
|
||||
#endif
|
||||
|
||||
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) || defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_M_MPPC) || defined(_M_PPC)
|
||||
|
||||
#if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__)
|
||||
#error JUCE_ARCH ppc64
|
||||
#else
|
||||
#error JUCE_ARCH ppc
|
||||
#endif
|
||||
|
||||
#elif defined(__riscv)
|
||||
|
||||
#if __riscv_xlen == 64
|
||||
#error JUCE_ARCH riscv64
|
||||
#else
|
||||
#error JUCE_ARCH riscv
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#error JUCE_ARCH unknown
|
||||
|
||||
#endif
|
||||
|
8
deps/juce/extras/Build/CMakeLists.txt
vendored
8
deps/juce/extras/Build/CMakeLists.txt
vendored
@ -1,15 +1,15 @@
|
||||
# ==============================================================================
|
||||
#
|
||||
# This file is part of the JUCE library.
|
||||
# Copyright (c) 2020 - Raw Material Software Limited
|
||||
# Copyright (c) 2022 - Raw Material Software Limited
|
||||
#
|
||||
# JUCE is an open source library subject to commercial or open-source
|
||||
# licensing.
|
||||
#
|
||||
# By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
# By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
# Agreement and JUCE Privacy Policy.
|
||||
#
|
||||
# End User License Agreement: www.juce.com/juce-6-licence
|
||||
# End User License Agreement: www.juce.com/juce-7-licence
|
||||
# Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
#
|
||||
# Or: You may also use this code under the terms of the GPL v3 (see
|
||||
|
@ -1,47 +1,47 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifdef JUCE_BUILD_TOOLS_H_INCLUDED
|
||||
/* When you add this cpp file to your project, you mustn't include it in a file where you've
|
||||
already included any other headers - just put it inside a file on its own, possibly with your config
|
||||
flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix
|
||||
header files that the compiler may be using.
|
||||
*/
|
||||
#error "Incorrect use of JUCE cpp file"
|
||||
#endif
|
||||
|
||||
#include "juce_build_tools.h"
|
||||
|
||||
#include <numeric>
|
||||
|
||||
#include "utils/juce_CppTokeniserFunctions.cpp"
|
||||
#include "utils/juce_BuildHelperFunctions.cpp"
|
||||
#include "utils/juce_BinaryResourceFile.cpp"
|
||||
#include "utils/juce_Icons.cpp"
|
||||
#include "utils/juce_PlistOptions.cpp"
|
||||
#include "utils/juce_ResourceFileHelpers.cpp"
|
||||
#include "utils/juce_ResourceRc.cpp"
|
||||
#include "utils/juce_VersionNumbers.cpp"
|
||||
#include "utils/juce_Entitlements.cpp"
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#ifdef JUCE_BUILD_TOOLS_H_INCLUDED
|
||||
/* When you add this cpp file to your project, you mustn't include it in a file where you've
|
||||
already included any other headers - just put it inside a file on its own, possibly with your config
|
||||
flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix
|
||||
header files that the compiler may be using.
|
||||
*/
|
||||
#error "Incorrect use of JUCE cpp file"
|
||||
#endif
|
||||
|
||||
#include "juce_build_tools.h"
|
||||
|
||||
#include <numeric>
|
||||
|
||||
#include "utils/juce_CppTokeniserFunctions.cpp"
|
||||
#include "utils/juce_BuildHelperFunctions.cpp"
|
||||
#include "utils/juce_BinaryResourceFile.cpp"
|
||||
#include "utils/juce_Icons.cpp"
|
||||
#include "utils/juce_PlistOptions.cpp"
|
||||
#include "utils/juce_ResourceFileHelpers.cpp"
|
||||
#include "utils/juce_ResourceRc.cpp"
|
||||
#include "utils/juce_VersionNumbers.cpp"
|
||||
#include "utils/juce_Entitlements.cpp"
|
||||
|
@ -1,67 +1,67 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
The block below describes the properties of this module, and is read by
|
||||
the Projucer to automatically generate project code that uses it.
|
||||
For details about the syntax and how to create or use a module, see the
|
||||
JUCE Module Format.md file.
|
||||
|
||||
|
||||
BEGIN_JUCE_MODULE_DECLARATION
|
||||
|
||||
ID: juce_build_tools
|
||||
vendor: juce
|
||||
version: 6.1.2
|
||||
name: JUCE Build Tools
|
||||
description: Classes for generating intermediate files for JUCE projects.
|
||||
website: http://www.juce.com/juce
|
||||
license: GPL/Commercial
|
||||
|
||||
dependencies: juce_gui_basics
|
||||
|
||||
END_JUCE_MODULE_DECLARATION
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// This module is shared by juceaide and the Projucer, but should not be
|
||||
// considered 'public'. That is, its API, functionality, and contents (and
|
||||
// existence!) may change between releases without warning.
|
||||
|
||||
#pragma once
|
||||
#define JUCE_BUILD_TOOLS_H_INCLUDED
|
||||
|
||||
#include <juce_gui_basics/juce_gui_basics.h>
|
||||
|
||||
#include "utils/juce_ProjectType.h"
|
||||
#include "utils/juce_BuildHelperFunctions.h"
|
||||
#include "utils/juce_BinaryResourceFile.h"
|
||||
#include "utils/juce_RelativePath.h"
|
||||
#include "utils/juce_Icons.h"
|
||||
#include "utils/juce_PlistOptions.h"
|
||||
#include "utils/juce_ResourceFileHelpers.h"
|
||||
#include "utils/juce_ResourceRc.h"
|
||||
#include "utils/juce_VersionNumbers.h"
|
||||
#include "utils/juce_Entitlements.h"
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
The block below describes the properties of this module, and is read by
|
||||
the Projucer to automatically generate project code that uses it.
|
||||
For details about the syntax and how to create or use a module, see the
|
||||
JUCE Module Format.md file.
|
||||
|
||||
|
||||
BEGIN_JUCE_MODULE_DECLARATION
|
||||
|
||||
ID: juce_build_tools
|
||||
vendor: juce
|
||||
version: 7.0.2
|
||||
name: JUCE Build Tools
|
||||
description: Classes for generating intermediate files for JUCE projects.
|
||||
website: http://www.juce.com/juce
|
||||
license: GPL/Commercial
|
||||
|
||||
dependencies: juce_gui_basics
|
||||
|
||||
END_JUCE_MODULE_DECLARATION
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
// This module is shared by juceaide and the Projucer, but should not be
|
||||
// considered 'public'. That is, its API, functionality, and contents (and
|
||||
// existence!) may change between releases without warning.
|
||||
|
||||
#pragma once
|
||||
#define JUCE_BUILD_TOOLS_H_INCLUDED
|
||||
|
||||
#include <juce_gui_basics/juce_gui_basics.h>
|
||||
|
||||
#include "utils/juce_ProjectType.h"
|
||||
#include "utils/juce_BuildHelperFunctions.h"
|
||||
#include "utils/juce_BinaryResourceFile.h"
|
||||
#include "utils/juce_RelativePath.h"
|
||||
#include "utils/juce_Icons.h"
|
||||
#include "utils/juce_PlistOptions.h"
|
||||
#include "utils/juce_ResourceFileHelpers.h"
|
||||
#include "utils/juce_ResourceRc.h"
|
||||
#include "utils/juce_VersionNumbers.h"
|
||||
#include "utils/juce_Entitlements.h"
|
||||
|
@ -1,289 +1,289 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
static const char* resourceFileIdentifierString = "JUCER_BINARY_RESOURCE";
|
||||
|
||||
//==============================================================================
|
||||
void ResourceFile::setClassName (const String& name)
|
||||
{
|
||||
className = name;
|
||||
}
|
||||
|
||||
void ResourceFile::addFile (const File& file)
|
||||
{
|
||||
files.add (file);
|
||||
|
||||
auto variableNameRoot = makeBinaryDataIdentifierName (file);
|
||||
auto variableName = variableNameRoot;
|
||||
|
||||
int suffix = 2;
|
||||
|
||||
while (variableNames.contains (variableName))
|
||||
variableName = variableNameRoot + String (suffix++);
|
||||
|
||||
variableNames.add (variableName);
|
||||
}
|
||||
|
||||
String ResourceFile::getDataVariableFor (const File& file) const
|
||||
{
|
||||
const auto index = files.indexOf (file);
|
||||
jassert (index >= 0);
|
||||
return variableNames[index];
|
||||
}
|
||||
|
||||
String ResourceFile::getSizeVariableFor (const File& file) const
|
||||
{
|
||||
return getDataVariableFor (file) + "Size";
|
||||
}
|
||||
|
||||
int64 ResourceFile::getTotalDataSize() const
|
||||
{
|
||||
return std::accumulate (files.begin(),
|
||||
files.end(),
|
||||
int64 { 0 },
|
||||
[] (int64 acc, const File& f) { return acc + f.getSize(); });
|
||||
}
|
||||
|
||||
static void writeComment (MemoryOutputStream& mo)
|
||||
{
|
||||
mo << newLine << newLine
|
||||
<< " This is an auto-generated file: Any edits you make may be overwritten!" << newLine
|
||||
<< newLine
|
||||
<< "*/" << newLine
|
||||
<< newLine;
|
||||
}
|
||||
|
||||
Result ResourceFile::writeHeader (MemoryOutputStream& header)
|
||||
{
|
||||
header << "/* =========================================================================================";
|
||||
writeComment (header);
|
||||
header << "#pragma once" << newLine
|
||||
<< newLine
|
||||
<< "namespace " << className << newLine
|
||||
<< "{" << newLine;
|
||||
|
||||
for (int i = 0; i < files.size(); ++i)
|
||||
{
|
||||
auto& file = files.getReference(i);
|
||||
|
||||
if (! file.existsAsFile())
|
||||
return Result::fail ("Can't open resource file: " + file.getFullPathName());
|
||||
|
||||
auto dataSize = file.getSize();
|
||||
|
||||
auto variableName = variableNames[i];
|
||||
|
||||
FileInputStream fileStream (file);
|
||||
|
||||
if (fileStream.openedOk())
|
||||
{
|
||||
header << " extern const char* " << variableName << ";" << newLine;
|
||||
header << " const int " << variableName << "Size = " << (int) dataSize << ";" << newLine << newLine;
|
||||
}
|
||||
}
|
||||
|
||||
header << " // Number of elements in the namedResourceList and originalFileNames arrays." << newLine
|
||||
<< " const int namedResourceListSize = " << files.size() << ";" << newLine
|
||||
<< newLine
|
||||
<< " // Points to the start of a list of resource names." << newLine
|
||||
<< " extern const char* namedResourceList[];" << newLine
|
||||
<< newLine
|
||||
<< " // Points to the start of a list of resource filenames." << newLine
|
||||
<< " extern const char* originalFilenames[];" << newLine
|
||||
<< newLine
|
||||
<< " // If you provide the name of one of the binary resource variables above, this function will" << newLine
|
||||
<< " // return the corresponding data and its size (or a null pointer if the name isn't found)." << newLine
|
||||
<< " const char* getNamedResource (const char* resourceNameUTF8, int& dataSizeInBytes);" << newLine
|
||||
<< newLine
|
||||
<< " // If you provide the name of one of the binary resource variables above, this function will" << newLine
|
||||
<< " // return the corresponding original, non-mangled filename (or a null pointer if the name isn't found)." << newLine
|
||||
<< " const char* getNamedResourceOriginalFilename (const char* resourceNameUTF8);" << newLine
|
||||
<< "}" << newLine;
|
||||
|
||||
return Result::ok();
|
||||
}
|
||||
|
||||
Result ResourceFile::writeCpp (MemoryOutputStream& cpp, const File& headerFile, int& i, const int maxFileSize)
|
||||
{
|
||||
bool isFirstFile = (i == 0);
|
||||
|
||||
cpp << "/* ==================================== " << resourceFileIdentifierString << " ====================================";
|
||||
writeComment (cpp);
|
||||
cpp << "namespace " << className << newLine
|
||||
<< "{" << newLine;
|
||||
|
||||
while (i < files.size())
|
||||
{
|
||||
auto& file = files.getReference(i);
|
||||
auto variableName = variableNames[i];
|
||||
|
||||
FileInputStream fileStream (file);
|
||||
|
||||
if (fileStream.openedOk())
|
||||
{
|
||||
auto tempVariable = "temp_binary_data_" + String (i);
|
||||
|
||||
cpp << newLine << "//================== " << file.getFileName() << " ==================" << newLine
|
||||
<< "static const unsigned char " << tempVariable << "[] =" << newLine;
|
||||
|
||||
{
|
||||
MemoryBlock data;
|
||||
fileStream.readIntoMemoryBlock (data);
|
||||
writeDataAsCppLiteral (data, cpp, true, true);
|
||||
}
|
||||
|
||||
cpp << newLine << newLine
|
||||
<< "const char* " << variableName << " = (const char*) " << tempVariable << ";" << newLine;
|
||||
}
|
||||
|
||||
++i;
|
||||
|
||||
if (cpp.getPosition() > maxFileSize)
|
||||
break;
|
||||
}
|
||||
|
||||
if (isFirstFile)
|
||||
{
|
||||
if (i < files.size())
|
||||
{
|
||||
cpp << newLine
|
||||
<< "}" << newLine
|
||||
<< newLine
|
||||
<< "#include \"" << headerFile.getFileName() << "\"" << newLine
|
||||
<< newLine
|
||||
<< "namespace " << className << newLine
|
||||
<< "{";
|
||||
}
|
||||
|
||||
cpp << newLine
|
||||
<< newLine
|
||||
<< "const char* getNamedResource (const char* resourceNameUTF8, int& numBytes);" << newLine
|
||||
<< "const char* getNamedResource (const char* resourceNameUTF8, int& numBytes)" << newLine
|
||||
<< "{" << newLine;
|
||||
|
||||
StringArray returnCodes;
|
||||
for (auto& file : files)
|
||||
{
|
||||
auto dataSize = file.getSize();
|
||||
returnCodes.add ("numBytes = " + String (dataSize) + "; return " + variableNames[files.indexOf (file)] + ";");
|
||||
}
|
||||
|
||||
createStringMatcher (cpp, "resourceNameUTF8", variableNames, returnCodes, 4);
|
||||
|
||||
cpp << " numBytes = 0;" << newLine
|
||||
<< " return nullptr;" << newLine
|
||||
<< "}" << newLine
|
||||
<< newLine;
|
||||
|
||||
cpp << "const char* namedResourceList[] =" << newLine
|
||||
<< "{" << newLine;
|
||||
|
||||
for (int j = 0; j < files.size(); ++j)
|
||||
cpp << " " << variableNames[j].quoted() << (j < files.size() - 1 ? "," : "") << newLine;
|
||||
|
||||
cpp << "};" << newLine << newLine;
|
||||
|
||||
cpp << "const char* originalFilenames[] =" << newLine
|
||||
<< "{" << newLine;
|
||||
|
||||
for (auto& f : files)
|
||||
cpp << " " << f.getFileName().quoted() << (files.indexOf (f) < files.size() - 1 ? "," : "") << newLine;
|
||||
|
||||
cpp << "};" << newLine << newLine;
|
||||
|
||||
cpp << "const char* getNamedResourceOriginalFilename (const char* resourceNameUTF8);" << newLine
|
||||
<< "const char* getNamedResourceOriginalFilename (const char* resourceNameUTF8)" << newLine
|
||||
<< "{" << newLine
|
||||
<< " for (unsigned int i = 0; i < (sizeof (namedResourceList) / sizeof (namedResourceList[0])); ++i)" << newLine
|
||||
<< " {" << newLine
|
||||
<< " if (namedResourceList[i] == resourceNameUTF8)" << newLine
|
||||
<< " return originalFilenames[i];" << newLine
|
||||
<< " }" << newLine
|
||||
<< newLine
|
||||
<< " return nullptr;" << newLine
|
||||
<< "}" << newLine
|
||||
<< newLine;
|
||||
}
|
||||
|
||||
cpp << "}" << newLine;
|
||||
|
||||
return Result::ok();
|
||||
}
|
||||
|
||||
ResourceFile::WriteResult ResourceFile::write (int maxFileSize,
|
||||
String projectLineFeed,
|
||||
File headerFile,
|
||||
std::function<File (int)> getCppFile)
|
||||
{
|
||||
Array<File> filesCreated;
|
||||
|
||||
{
|
||||
MemoryOutputStream mo;
|
||||
mo.setNewLineString (projectLineFeed);
|
||||
|
||||
auto r = writeHeader (mo);
|
||||
|
||||
if (r.failed())
|
||||
return { r, {} };
|
||||
|
||||
if (! overwriteFileWithNewDataIfDifferent (headerFile, mo))
|
||||
return { Result::fail ("Can't write to file: " + headerFile.getFullPathName()), {} };
|
||||
|
||||
filesCreated.add (headerFile);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
int fileIndex = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
auto cpp = getCppFile (fileIndex);
|
||||
|
||||
MemoryOutputStream mo;
|
||||
mo.setNewLineString (projectLineFeed);
|
||||
|
||||
auto r = writeCpp (mo, headerFile, i, maxFileSize);
|
||||
|
||||
if (r.failed())
|
||||
return { r, std::move (filesCreated) };
|
||||
|
||||
if (! overwriteFileWithNewDataIfDifferent (cpp, mo))
|
||||
return { Result::fail ("Can't write to file: " + cpp.getFullPathName()), std::move (filesCreated) };
|
||||
|
||||
filesCreated.add (cpp);
|
||||
++fileIndex;
|
||||
|
||||
if (i >= files.size())
|
||||
break;
|
||||
}
|
||||
|
||||
return { Result::ok(), std::move (filesCreated) };
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
static const char* resourceFileIdentifierString = "JUCER_BINARY_RESOURCE";
|
||||
|
||||
//==============================================================================
|
||||
void ResourceFile::setClassName (const String& name)
|
||||
{
|
||||
className = name;
|
||||
}
|
||||
|
||||
void ResourceFile::addFile (const File& file)
|
||||
{
|
||||
files.add (file);
|
||||
|
||||
auto variableNameRoot = makeBinaryDataIdentifierName (file);
|
||||
auto variableName = variableNameRoot;
|
||||
|
||||
int suffix = 2;
|
||||
|
||||
while (variableNames.contains (variableName))
|
||||
variableName = variableNameRoot + String (suffix++);
|
||||
|
||||
variableNames.add (variableName);
|
||||
}
|
||||
|
||||
String ResourceFile::getDataVariableFor (const File& file) const
|
||||
{
|
||||
const auto index = files.indexOf (file);
|
||||
jassert (index >= 0);
|
||||
return variableNames[index];
|
||||
}
|
||||
|
||||
String ResourceFile::getSizeVariableFor (const File& file) const
|
||||
{
|
||||
return getDataVariableFor (file) + "Size";
|
||||
}
|
||||
|
||||
int64 ResourceFile::getTotalDataSize() const
|
||||
{
|
||||
return std::accumulate (files.begin(),
|
||||
files.end(),
|
||||
int64 { 0 },
|
||||
[] (int64 acc, const File& f) { return acc + f.getSize(); });
|
||||
}
|
||||
|
||||
static void writeComment (MemoryOutputStream& mo)
|
||||
{
|
||||
mo << newLine << newLine
|
||||
<< " This is an auto-generated file: Any edits you make may be overwritten!" << newLine
|
||||
<< newLine
|
||||
<< "*/" << newLine
|
||||
<< newLine;
|
||||
}
|
||||
|
||||
Result ResourceFile::writeHeader (MemoryOutputStream& header)
|
||||
{
|
||||
header << "/* =========================================================================================";
|
||||
writeComment (header);
|
||||
header << "#pragma once" << newLine
|
||||
<< newLine
|
||||
<< "namespace " << className << newLine
|
||||
<< "{" << newLine;
|
||||
|
||||
for (int i = 0; i < files.size(); ++i)
|
||||
{
|
||||
auto& file = files.getReference(i);
|
||||
|
||||
if (! file.existsAsFile())
|
||||
return Result::fail ("Can't open resource file: " + file.getFullPathName());
|
||||
|
||||
auto dataSize = file.getSize();
|
||||
|
||||
auto variableName = variableNames[i];
|
||||
|
||||
FileInputStream fileStream (file);
|
||||
|
||||
if (fileStream.openedOk())
|
||||
{
|
||||
header << " extern const char* " << variableName << ";" << newLine;
|
||||
header << " const int " << variableName << "Size = " << (int) dataSize << ";" << newLine << newLine;
|
||||
}
|
||||
}
|
||||
|
||||
header << " // Number of elements in the namedResourceList and originalFileNames arrays." << newLine
|
||||
<< " const int namedResourceListSize = " << files.size() << ";" << newLine
|
||||
<< newLine
|
||||
<< " // Points to the start of a list of resource names." << newLine
|
||||
<< " extern const char* namedResourceList[];" << newLine
|
||||
<< newLine
|
||||
<< " // Points to the start of a list of resource filenames." << newLine
|
||||
<< " extern const char* originalFilenames[];" << newLine
|
||||
<< newLine
|
||||
<< " // If you provide the name of one of the binary resource variables above, this function will" << newLine
|
||||
<< " // return the corresponding data and its size (or a null pointer if the name isn't found)." << newLine
|
||||
<< " const char* getNamedResource (const char* resourceNameUTF8, int& dataSizeInBytes);" << newLine
|
||||
<< newLine
|
||||
<< " // If you provide the name of one of the binary resource variables above, this function will" << newLine
|
||||
<< " // return the corresponding original, non-mangled filename (or a null pointer if the name isn't found)." << newLine
|
||||
<< " const char* getNamedResourceOriginalFilename (const char* resourceNameUTF8);" << newLine
|
||||
<< "}" << newLine;
|
||||
|
||||
return Result::ok();
|
||||
}
|
||||
|
||||
Result ResourceFile::writeCpp (MemoryOutputStream& cpp, const File& headerFile, int& i, const int maxFileSize)
|
||||
{
|
||||
bool isFirstFile = (i == 0);
|
||||
|
||||
cpp << "/* ==================================== " << resourceFileIdentifierString << " ====================================";
|
||||
writeComment (cpp);
|
||||
cpp << "#include <cstring>" << newLine
|
||||
<< newLine
|
||||
<< "namespace " << className << newLine
|
||||
<< "{" << newLine;
|
||||
|
||||
while (i < files.size())
|
||||
{
|
||||
auto& file = files.getReference(i);
|
||||
auto variableName = variableNames[i];
|
||||
|
||||
FileInputStream fileStream (file);
|
||||
|
||||
if (fileStream.openedOk())
|
||||
{
|
||||
auto tempVariable = "temp_binary_data_" + String (i);
|
||||
|
||||
cpp << newLine << "//================== " << file.getFileName() << " ==================" << newLine
|
||||
<< "static const unsigned char " << tempVariable << "[] =" << newLine;
|
||||
|
||||
{
|
||||
MemoryBlock data;
|
||||
fileStream.readIntoMemoryBlock (data);
|
||||
writeDataAsCppLiteral (data, cpp, true, true);
|
||||
}
|
||||
|
||||
cpp << newLine << newLine
|
||||
<< "const char* " << variableName << " = (const char*) " << tempVariable << ";" << newLine;
|
||||
}
|
||||
|
||||
++i;
|
||||
|
||||
if (cpp.getPosition() > maxFileSize)
|
||||
break;
|
||||
}
|
||||
|
||||
if (isFirstFile)
|
||||
{
|
||||
if (i < files.size())
|
||||
{
|
||||
cpp << newLine
|
||||
<< "}" << newLine
|
||||
<< newLine
|
||||
<< "#include \"" << headerFile.getFileName() << "\"" << newLine
|
||||
<< newLine
|
||||
<< "namespace " << className << newLine
|
||||
<< "{";
|
||||
}
|
||||
|
||||
cpp << newLine
|
||||
<< newLine
|
||||
<< "const char* getNamedResource (const char* resourceNameUTF8, int& numBytes);" << newLine
|
||||
<< "const char* getNamedResource (const char* resourceNameUTF8, int& numBytes)" << newLine
|
||||
<< "{" << newLine;
|
||||
|
||||
StringArray returnCodes;
|
||||
for (auto& file : files)
|
||||
{
|
||||
auto dataSize = file.getSize();
|
||||
returnCodes.add ("numBytes = " + String (dataSize) + "; return " + variableNames[files.indexOf (file)] + ";");
|
||||
}
|
||||
|
||||
createStringMatcher (cpp, "resourceNameUTF8", variableNames, returnCodes, 4);
|
||||
|
||||
cpp << " numBytes = 0;" << newLine
|
||||
<< " return nullptr;" << newLine
|
||||
<< "}" << newLine
|
||||
<< newLine;
|
||||
|
||||
cpp << "const char* namedResourceList[] =" << newLine
|
||||
<< "{" << newLine;
|
||||
|
||||
for (int j = 0; j < files.size(); ++j)
|
||||
cpp << " " << variableNames[j].quoted() << (j < files.size() - 1 ? "," : "") << newLine;
|
||||
|
||||
cpp << "};" << newLine << newLine;
|
||||
|
||||
cpp << "const char* originalFilenames[] =" << newLine
|
||||
<< "{" << newLine;
|
||||
|
||||
for (auto& f : files)
|
||||
cpp << " " << f.getFileName().quoted() << (files.indexOf (f) < files.size() - 1 ? "," : "") << newLine;
|
||||
|
||||
cpp << "};" << newLine << newLine;
|
||||
|
||||
cpp << "const char* getNamedResourceOriginalFilename (const char* resourceNameUTF8);" << newLine
|
||||
<< "const char* getNamedResourceOriginalFilename (const char* resourceNameUTF8)" << newLine
|
||||
<< "{" << newLine
|
||||
<< " for (unsigned int i = 0; i < (sizeof (namedResourceList) / sizeof (namedResourceList[0])); ++i)" << newLine
|
||||
<< " if (strcmp (namedResourceList[i], resourceNameUTF8) == 0)" << newLine
|
||||
<< " return originalFilenames[i];" << newLine
|
||||
<< newLine
|
||||
<< " return nullptr;" << newLine
|
||||
<< "}" << newLine
|
||||
<< newLine;
|
||||
}
|
||||
|
||||
cpp << "}" << newLine;
|
||||
|
||||
return Result::ok();
|
||||
}
|
||||
|
||||
ResourceFile::WriteResult ResourceFile::write (int maxFileSize,
|
||||
String projectLineFeed,
|
||||
File headerFile,
|
||||
std::function<File (int)> getCppFile)
|
||||
{
|
||||
Array<File> filesCreated;
|
||||
|
||||
{
|
||||
MemoryOutputStream mo;
|
||||
mo.setNewLineString (projectLineFeed);
|
||||
|
||||
auto r = writeHeader (mo);
|
||||
|
||||
if (r.failed())
|
||||
return { r, {} };
|
||||
|
||||
if (! overwriteFileWithNewDataIfDifferent (headerFile, mo))
|
||||
return { Result::fail ("Can't write to file: " + headerFile.getFullPathName()), {} };
|
||||
|
||||
filesCreated.add (headerFile);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
int fileIndex = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
auto cpp = getCppFile (fileIndex);
|
||||
|
||||
MemoryOutputStream mo;
|
||||
mo.setNewLineString (projectLineFeed);
|
||||
|
||||
auto r = writeCpp (mo, headerFile, i, maxFileSize);
|
||||
|
||||
if (r.failed())
|
||||
return { r, std::move (filesCreated) };
|
||||
|
||||
if (! overwriteFileWithNewDataIfDifferent (cpp, mo))
|
||||
return { Result::fail ("Can't write to file: " + cpp.getFullPathName()), std::move (filesCreated) };
|
||||
|
||||
filesCreated.add (cpp);
|
||||
++fileIndex;
|
||||
|
||||
if (i >= files.size())
|
||||
break;
|
||||
}
|
||||
|
||||
return { Result::ok(), std::move (filesCreated) };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,74 +1,74 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
class ResourceFile
|
||||
{
|
||||
public:
|
||||
ResourceFile() = default;
|
||||
|
||||
void setClassName (const String& className);
|
||||
|
||||
String getClassName() const { return className; }
|
||||
|
||||
void addFile (const File& file);
|
||||
|
||||
String getDataVariableFor (const File& file) const;
|
||||
|
||||
String getSizeVariableFor (const File& file) const;
|
||||
|
||||
int getNumFiles() const { return files.size (); }
|
||||
|
||||
const File& getFile (int index) const { return files.getReference (index); }
|
||||
|
||||
int64 getTotalDataSize() const;
|
||||
|
||||
struct WriteResult
|
||||
{
|
||||
Result result;
|
||||
Array<File> filesCreated;
|
||||
};
|
||||
|
||||
WriteResult write (int maxFileSize,
|
||||
String projectLineFeed,
|
||||
File headerFile,
|
||||
std::function<File (int)> getCppFile);
|
||||
|
||||
private:
|
||||
Array<File> files;
|
||||
StringArray variableNames;
|
||||
String className { "BinaryData" };
|
||||
|
||||
Result writeHeader (MemoryOutputStream&);
|
||||
|
||||
Result writeCpp (MemoryOutputStream&, const File&, int&, int);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ResourceFile)
|
||||
};
|
||||
}
|
||||
}
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
class ResourceFile
|
||||
{
|
||||
public:
|
||||
ResourceFile() = default;
|
||||
|
||||
void setClassName (const String& className);
|
||||
|
||||
String getClassName() const { return className; }
|
||||
|
||||
void addFile (const File& file);
|
||||
|
||||
String getDataVariableFor (const File& file) const;
|
||||
|
||||
String getSizeVariableFor (const File& file) const;
|
||||
|
||||
int getNumFiles() const { return files.size (); }
|
||||
|
||||
const File& getFile (int index) const { return files.getReference (index); }
|
||||
|
||||
int64 getTotalDataSize() const;
|
||||
|
||||
struct WriteResult
|
||||
{
|
||||
Result result;
|
||||
Array<File> filesCreated;
|
||||
};
|
||||
|
||||
WriteResult write (int maxFileSize,
|
||||
String projectLineFeed,
|
||||
File headerFile,
|
||||
std::function<File (int)> getCppFile);
|
||||
|
||||
private:
|
||||
Array<File> files;
|
||||
StringArray variableNames;
|
||||
String className { "BinaryData" };
|
||||
|
||||
Result writeHeader (MemoryOutputStream&);
|
||||
|
||||
Result writeCpp (MemoryOutputStream&, const File&, int&, int);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ResourceFile)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,355 +1,357 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
void overwriteFileIfDifferentOrThrow (const File& file, const MemoryOutputStream& newData)
|
||||
{
|
||||
if (! overwriteFileWithNewDataIfDifferent (file, newData))
|
||||
throw SaveError (file);
|
||||
}
|
||||
|
||||
void overwriteFileIfDifferentOrThrow (const File& file, const String& newData)
|
||||
{
|
||||
if (! overwriteFileWithNewDataIfDifferent (file, newData))
|
||||
throw SaveError (file);
|
||||
}
|
||||
|
||||
String replacePreprocessorDefs (const StringPairArray& definitions, String sourceString)
|
||||
{
|
||||
for (int i = 0; i < definitions.size(); ++i)
|
||||
{
|
||||
const String key (definitions.getAllKeys()[i]);
|
||||
const String value (definitions.getAllValues()[i]);
|
||||
|
||||
sourceString = sourceString.replace ("${" + key + "}", value);
|
||||
}
|
||||
|
||||
return sourceString;
|
||||
}
|
||||
|
||||
String getXcodePackageType (ProjectType::Target::Type type)
|
||||
{
|
||||
using Type = ProjectType::Target::Type;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Type::GUIApp:
|
||||
case Type::StandalonePlugIn:
|
||||
return "APPL";
|
||||
|
||||
case Type::VSTPlugIn:
|
||||
case Type::VST3PlugIn:
|
||||
case Type::AudioUnitPlugIn:
|
||||
case Type::UnityPlugIn:
|
||||
return "BNDL";
|
||||
|
||||
case Type::AudioUnitv3PlugIn:
|
||||
return "XPC!";
|
||||
|
||||
case Type::AAXPlugIn:
|
||||
case Type::RTASPlugIn:
|
||||
return "TDMw";
|
||||
|
||||
case Type::ConsoleApp:
|
||||
case Type::StaticLibrary:
|
||||
case Type::DynamicLibrary:
|
||||
case Type::SharedCodeTarget:
|
||||
case Type::AggregateTarget:
|
||||
case Type::unspecified:
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
String getXcodeBundleSignature (ProjectType::Target::Type type)
|
||||
{
|
||||
using Type = ProjectType::Target::Type;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Type::GUIApp:
|
||||
case Type::VSTPlugIn:
|
||||
case Type::VST3PlugIn:
|
||||
case Type::AudioUnitPlugIn:
|
||||
case Type::StandalonePlugIn:
|
||||
case Type::AudioUnitv3PlugIn:
|
||||
case Type::UnityPlugIn:
|
||||
return "????";
|
||||
|
||||
case Type::AAXPlugIn:
|
||||
case Type::RTASPlugIn:
|
||||
return "PTul";
|
||||
|
||||
case Type::ConsoleApp:
|
||||
case Type::StaticLibrary:
|
||||
case Type::DynamicLibrary:
|
||||
case Type::SharedCodeTarget:
|
||||
case Type::AggregateTarget:
|
||||
case Type::unspecified:
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int calculateHash (const String& s, const unsigned int hashMultiplier)
|
||||
{
|
||||
auto t = s.toUTF8();
|
||||
unsigned int hash = 0;
|
||||
|
||||
while (*t != 0)
|
||||
hash = hashMultiplier * hash + (unsigned int) *t++;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static unsigned int findBestHashMultiplier (const StringArray& strings)
|
||||
{
|
||||
unsigned int v = 31;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
SortedSet<unsigned int> hashes;
|
||||
bool collision = false;
|
||||
|
||||
for (int i = strings.size(); --i >= 0;)
|
||||
{
|
||||
auto hash = calculateHash (strings[i], v);
|
||||
|
||||
if (hashes.contains (hash))
|
||||
{
|
||||
collision = true;
|
||||
break;
|
||||
}
|
||||
|
||||
hashes.add (hash);
|
||||
}
|
||||
|
||||
if (! collision)
|
||||
break;
|
||||
|
||||
v += 2;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
String makeValidIdentifier (String s, bool makeCamelCase, bool removeColons, bool allowTemplates, bool allowAsterisks)
|
||||
{
|
||||
if (s.isEmpty())
|
||||
return "unknown";
|
||||
|
||||
if (removeColons)
|
||||
s = s.replaceCharacters (".,;:/@", "______");
|
||||
else
|
||||
s = s.replaceCharacters (".,;/@", "_____");
|
||||
|
||||
for (int i = s.length(); --i > 0;)
|
||||
if (CharacterFunctions::isLetter (s[i])
|
||||
&& CharacterFunctions::isLetter (s[i - 1])
|
||||
&& CharacterFunctions::isUpperCase (s[i])
|
||||
&& ! CharacterFunctions::isUpperCase (s[i - 1]))
|
||||
s = s.substring (0, i) + " " + s.substring (i);
|
||||
|
||||
String allowedChars ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ 0123456789");
|
||||
if (allowTemplates)
|
||||
allowedChars += "<>";
|
||||
|
||||
if (! removeColons)
|
||||
allowedChars += ":";
|
||||
|
||||
if (allowAsterisks)
|
||||
allowedChars += "*";
|
||||
|
||||
StringArray words;
|
||||
words.addTokens (s.retainCharacters (allowedChars), false);
|
||||
words.trim();
|
||||
|
||||
auto n = words[0];
|
||||
|
||||
if (makeCamelCase)
|
||||
n = n.toLowerCase();
|
||||
|
||||
for (int i = 1; i < words.size(); ++i)
|
||||
{
|
||||
if (makeCamelCase && words[i].length() > 1)
|
||||
n << words[i].substring (0, 1).toUpperCase()
|
||||
<< words[i].substring (1).toLowerCase();
|
||||
else
|
||||
n << words[i];
|
||||
}
|
||||
|
||||
if (CharacterFunctions::isDigit (n[0]))
|
||||
n = "_" + n;
|
||||
|
||||
if (isReservedKeyword (n))
|
||||
n << '_';
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
String makeBinaryDataIdentifierName (const File& file)
|
||||
{
|
||||
return makeValidIdentifier (file.getFileName()
|
||||
.replaceCharacters (" .", "__")
|
||||
.retainCharacters ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789"),
|
||||
false, true, false);
|
||||
}
|
||||
|
||||
void writeDataAsCppLiteral (const MemoryBlock& mb, OutputStream& out,
|
||||
bool breakAtNewLines, bool allowStringBreaks)
|
||||
{
|
||||
const int maxCharsOnLine = 250;
|
||||
|
||||
auto data = (const unsigned char*) mb.getData();
|
||||
int charsOnLine = 0;
|
||||
|
||||
bool canUseStringLiteral = mb.getSize() < 32768; // MS compilers can't handle big string literals..
|
||||
|
||||
if (canUseStringLiteral)
|
||||
{
|
||||
unsigned int numEscaped = 0;
|
||||
|
||||
for (size_t i = 0; i < mb.getSize(); ++i)
|
||||
{
|
||||
auto num = (unsigned int) data[i];
|
||||
|
||||
if (! ((num >= 32 && num < 127) || num == '\t' || num == '\r' || num == '\n'))
|
||||
{
|
||||
if (++numEscaped > mb.getSize() / 4)
|
||||
{
|
||||
canUseStringLiteral = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! canUseStringLiteral)
|
||||
{
|
||||
out << "{ ";
|
||||
|
||||
for (size_t i = 0; i < mb.getSize(); ++i)
|
||||
{
|
||||
auto num = (int) (unsigned int) data[i];
|
||||
out << num << ',';
|
||||
|
||||
charsOnLine += 2;
|
||||
|
||||
if (num >= 10)
|
||||
{
|
||||
++charsOnLine;
|
||||
|
||||
if (num >= 100)
|
||||
++charsOnLine;
|
||||
}
|
||||
|
||||
if (charsOnLine >= maxCharsOnLine)
|
||||
{
|
||||
charsOnLine = 0;
|
||||
out << newLine;
|
||||
}
|
||||
}
|
||||
|
||||
out << "0,0 };";
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "\"";
|
||||
writeEscapeChars (out, (const char*) data, (int) mb.getSize(),
|
||||
maxCharsOnLine, breakAtNewLines, false, allowStringBreaks);
|
||||
out << "\";";
|
||||
}
|
||||
}
|
||||
|
||||
void createStringMatcher (OutputStream& out, const String& utf8PointerVariable,
|
||||
const StringArray& strings, const StringArray& codeToExecute, const int indentLevel)
|
||||
{
|
||||
jassert (strings.size() == codeToExecute.size());
|
||||
auto indent = String::repeatedString (" ", indentLevel);
|
||||
auto hashMultiplier = findBestHashMultiplier (strings);
|
||||
|
||||
out << indent << "unsigned int hash = 0;" << newLine
|
||||
<< newLine
|
||||
<< indent << "if (" << utf8PointerVariable << " != nullptr)" << newLine
|
||||
<< indent << " while (*" << utf8PointerVariable << " != 0)" << newLine
|
||||
<< indent << " hash = " << (int) hashMultiplier << " * hash + (unsigned int) *" << utf8PointerVariable << "++;" << newLine
|
||||
<< newLine
|
||||
<< indent << "switch (hash)" << newLine
|
||||
<< indent << "{" << newLine;
|
||||
|
||||
for (int i = 0; i < strings.size(); ++i)
|
||||
{
|
||||
out << indent << " case 0x" << hexString8Digits ((int) calculateHash (strings[i], hashMultiplier))
|
||||
<< ": " << codeToExecute[i] << newLine;
|
||||
}
|
||||
|
||||
out << indent << " default: break;" << newLine
|
||||
<< indent << "}" << newLine << newLine;
|
||||
}
|
||||
|
||||
String unixStylePath (const String& path) { return path.replaceCharacter ('\\', '/'); }
|
||||
String windowsStylePath (const String& path) { return path.replaceCharacter ('/', '\\'); }
|
||||
|
||||
String currentOSStylePath (const String& path)
|
||||
{
|
||||
#if JUCE_WINDOWS
|
||||
return windowsStylePath (path);
|
||||
#else
|
||||
return unixStylePath (path);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isAbsolutePath (const String& path)
|
||||
{
|
||||
return File::isAbsolutePath (path)
|
||||
|| path.startsWithChar ('/') // (needed because File::isAbsolutePath will ignore forward-slashes on Windows)
|
||||
|| path.startsWithChar ('$')
|
||||
|| path.startsWithChar ('~')
|
||||
|| (CharacterFunctions::isLetter (path[0]) && path[1] == ':')
|
||||
|| path.startsWithIgnoreCase ("smb:");
|
||||
}
|
||||
|
||||
String getRelativePathFrom (const File& file, const File& sourceFolder)
|
||||
{
|
||||
#if ! JUCE_WINDOWS
|
||||
// On a non-windows machine, we can't know if a drive-letter path may be relative or not.
|
||||
if (CharacterFunctions::isLetter (file.getFullPathName()[0]) && file.getFullPathName()[1] == ':')
|
||||
return file.getFullPathName();
|
||||
#endif
|
||||
|
||||
return file.getRelativePathFrom (sourceFolder);
|
||||
}
|
||||
|
||||
void writeStreamToFile (const File& file, const std::function<void (MemoryOutputStream&)>& writer)
|
||||
{
|
||||
MemoryOutputStream mo;
|
||||
writer (mo);
|
||||
overwriteFileIfDifferentOrThrow (file, mo);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
void overwriteFileIfDifferentOrThrow (const File& file, const MemoryOutputStream& newData)
|
||||
{
|
||||
if (! overwriteFileWithNewDataIfDifferent (file, newData))
|
||||
throw SaveError (file);
|
||||
}
|
||||
|
||||
void overwriteFileIfDifferentOrThrow (const File& file, const String& newData)
|
||||
{
|
||||
if (! overwriteFileWithNewDataIfDifferent (file, newData))
|
||||
throw SaveError (file);
|
||||
}
|
||||
|
||||
String replacePreprocessorDefs (const StringPairArray& definitions, String sourceString)
|
||||
{
|
||||
for (int i = 0; i < definitions.size(); ++i)
|
||||
{
|
||||
const String key (definitions.getAllKeys()[i]);
|
||||
const String value (definitions.getAllValues()[i]);
|
||||
|
||||
sourceString = sourceString.replace ("${" + key + "}", value);
|
||||
}
|
||||
|
||||
return sourceString;
|
||||
}
|
||||
|
||||
String getXcodePackageType (ProjectType::Target::Type type)
|
||||
{
|
||||
using Type = ProjectType::Target::Type;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Type::GUIApp:
|
||||
case Type::StandalonePlugIn:
|
||||
return "APPL";
|
||||
|
||||
case Type::VSTPlugIn:
|
||||
case Type::VST3PlugIn:
|
||||
case Type::AudioUnitPlugIn:
|
||||
case Type::UnityPlugIn:
|
||||
return "BNDL";
|
||||
|
||||
case Type::AudioUnitv3PlugIn:
|
||||
return "XPC!";
|
||||
|
||||
case Type::AAXPlugIn:
|
||||
return "TDMw";
|
||||
|
||||
case Type::ConsoleApp:
|
||||
case Type::StaticLibrary:
|
||||
case Type::DynamicLibrary:
|
||||
case Type::LV2PlugIn:
|
||||
case Type::LV2TurtleProgram:
|
||||
case Type::SharedCodeTarget:
|
||||
case Type::AggregateTarget:
|
||||
case Type::unspecified:
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
String getXcodeBundleSignature (ProjectType::Target::Type type)
|
||||
{
|
||||
using Type = ProjectType::Target::Type;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Type::GUIApp:
|
||||
case Type::VSTPlugIn:
|
||||
case Type::VST3PlugIn:
|
||||
case Type::AudioUnitPlugIn:
|
||||
case Type::StandalonePlugIn:
|
||||
case Type::AudioUnitv3PlugIn:
|
||||
case Type::UnityPlugIn:
|
||||
return "????";
|
||||
|
||||
case Type::AAXPlugIn:
|
||||
return "PTul";
|
||||
|
||||
case Type::ConsoleApp:
|
||||
case Type::StaticLibrary:
|
||||
case Type::DynamicLibrary:
|
||||
case Type::LV2PlugIn:
|
||||
case Type::LV2TurtleProgram:
|
||||
case Type::SharedCodeTarget:
|
||||
case Type::AggregateTarget:
|
||||
case Type::unspecified:
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int calculateHash (const String& s, const unsigned int hashMultiplier)
|
||||
{
|
||||
auto t = s.toUTF8();
|
||||
unsigned int hash = 0;
|
||||
|
||||
while (*t != 0)
|
||||
hash = hashMultiplier * hash + (unsigned int) *t++;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static unsigned int findBestHashMultiplier (const StringArray& strings)
|
||||
{
|
||||
unsigned int v = 31;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
SortedSet<unsigned int> hashes;
|
||||
bool collision = false;
|
||||
|
||||
for (int i = strings.size(); --i >= 0;)
|
||||
{
|
||||
auto hash = calculateHash (strings[i], v);
|
||||
|
||||
if (hashes.contains (hash))
|
||||
{
|
||||
collision = true;
|
||||
break;
|
||||
}
|
||||
|
||||
hashes.add (hash);
|
||||
}
|
||||
|
||||
if (! collision)
|
||||
break;
|
||||
|
||||
v += 2;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
String makeValidIdentifier (String s, bool makeCamelCase, bool removeColons, bool allowTemplates, bool allowAsterisks)
|
||||
{
|
||||
if (s.isEmpty())
|
||||
return "unknown";
|
||||
|
||||
if (removeColons)
|
||||
s = s.replaceCharacters (".,;:/@", "______");
|
||||
else
|
||||
s = s.replaceCharacters (".,;/@", "_____");
|
||||
|
||||
for (int i = s.length(); --i > 0;)
|
||||
if (CharacterFunctions::isLetter (s[i])
|
||||
&& CharacterFunctions::isLetter (s[i - 1])
|
||||
&& CharacterFunctions::isUpperCase (s[i])
|
||||
&& ! CharacterFunctions::isUpperCase (s[i - 1]))
|
||||
s = s.substring (0, i) + " " + s.substring (i);
|
||||
|
||||
String allowedChars ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ 0123456789");
|
||||
if (allowTemplates)
|
||||
allowedChars += "<>";
|
||||
|
||||
if (! removeColons)
|
||||
allowedChars += ":";
|
||||
|
||||
if (allowAsterisks)
|
||||
allowedChars += "*";
|
||||
|
||||
StringArray words;
|
||||
words.addTokens (s.retainCharacters (allowedChars), false);
|
||||
words.trim();
|
||||
|
||||
auto n = words[0];
|
||||
|
||||
if (makeCamelCase)
|
||||
n = n.toLowerCase();
|
||||
|
||||
for (int i = 1; i < words.size(); ++i)
|
||||
{
|
||||
if (makeCamelCase && words[i].length() > 1)
|
||||
n << words[i].substring (0, 1).toUpperCase()
|
||||
<< words[i].substring (1).toLowerCase();
|
||||
else
|
||||
n << words[i];
|
||||
}
|
||||
|
||||
if (CharacterFunctions::isDigit (n[0]))
|
||||
n = "_" + n;
|
||||
|
||||
if (isReservedKeyword (n))
|
||||
n << '_';
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
String makeBinaryDataIdentifierName (const File& file)
|
||||
{
|
||||
return makeValidIdentifier (file.getFileName()
|
||||
.replaceCharacters (" .", "__")
|
||||
.retainCharacters ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789"),
|
||||
false, true, false);
|
||||
}
|
||||
|
||||
void writeDataAsCppLiteral (const MemoryBlock& mb, OutputStream& out,
|
||||
bool breakAtNewLines, bool allowStringBreaks)
|
||||
{
|
||||
const int maxCharsOnLine = 250;
|
||||
|
||||
auto data = (const unsigned char*) mb.getData();
|
||||
int charsOnLine = 0;
|
||||
|
||||
bool canUseStringLiteral = mb.getSize() < 32768; // MS compilers can't handle big string literals..
|
||||
|
||||
if (canUseStringLiteral)
|
||||
{
|
||||
unsigned int numEscaped = 0;
|
||||
|
||||
for (size_t i = 0; i < mb.getSize(); ++i)
|
||||
{
|
||||
auto num = (unsigned int) data[i];
|
||||
|
||||
if (! ((num >= 32 && num < 127) || num == '\t' || num == '\r' || num == '\n'))
|
||||
{
|
||||
if (++numEscaped > mb.getSize() / 4)
|
||||
{
|
||||
canUseStringLiteral = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! canUseStringLiteral)
|
||||
{
|
||||
out << "{ ";
|
||||
|
||||
for (size_t i = 0; i < mb.getSize(); ++i)
|
||||
{
|
||||
auto num = (int) (unsigned int) data[i];
|
||||
out << num << ',';
|
||||
|
||||
charsOnLine += 2;
|
||||
|
||||
if (num >= 10)
|
||||
{
|
||||
++charsOnLine;
|
||||
|
||||
if (num >= 100)
|
||||
++charsOnLine;
|
||||
}
|
||||
|
||||
if (charsOnLine >= maxCharsOnLine)
|
||||
{
|
||||
charsOnLine = 0;
|
||||
out << newLine;
|
||||
}
|
||||
}
|
||||
|
||||
out << "0,0 };";
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "\"";
|
||||
writeEscapeChars (out, (const char*) data, (int) mb.getSize(),
|
||||
maxCharsOnLine, breakAtNewLines, false, allowStringBreaks);
|
||||
out << "\";";
|
||||
}
|
||||
}
|
||||
|
||||
void createStringMatcher (OutputStream& out, const String& utf8PointerVariable,
|
||||
const StringArray& strings, const StringArray& codeToExecute, const int indentLevel)
|
||||
{
|
||||
jassert (strings.size() == codeToExecute.size());
|
||||
auto indent = String::repeatedString (" ", indentLevel);
|
||||
auto hashMultiplier = findBestHashMultiplier (strings);
|
||||
|
||||
out << indent << "unsigned int hash = 0;" << newLine
|
||||
<< newLine
|
||||
<< indent << "if (" << utf8PointerVariable << " != nullptr)" << newLine
|
||||
<< indent << " while (*" << utf8PointerVariable << " != 0)" << newLine
|
||||
<< indent << " hash = " << (int) hashMultiplier << " * hash + (unsigned int) *" << utf8PointerVariable << "++;" << newLine
|
||||
<< newLine
|
||||
<< indent << "switch (hash)" << newLine
|
||||
<< indent << "{" << newLine;
|
||||
|
||||
for (int i = 0; i < strings.size(); ++i)
|
||||
{
|
||||
out << indent << " case 0x" << hexString8Digits ((int) calculateHash (strings[i], hashMultiplier))
|
||||
<< ": " << codeToExecute[i] << newLine;
|
||||
}
|
||||
|
||||
out << indent << " default: break;" << newLine
|
||||
<< indent << "}" << newLine << newLine;
|
||||
}
|
||||
|
||||
String unixStylePath (const String& path) { return path.replaceCharacter ('\\', '/'); }
|
||||
String windowsStylePath (const String& path) { return path.replaceCharacter ('/', '\\'); }
|
||||
|
||||
String currentOSStylePath (const String& path)
|
||||
{
|
||||
#if JUCE_WINDOWS
|
||||
return windowsStylePath (path);
|
||||
#else
|
||||
return unixStylePath (path);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isAbsolutePath (const String& path)
|
||||
{
|
||||
return File::isAbsolutePath (path)
|
||||
|| path.startsWithChar ('/') // (needed because File::isAbsolutePath will ignore forward-slashes on Windows)
|
||||
|| path.startsWithChar ('$')
|
||||
|| path.startsWithChar ('~')
|
||||
|| (CharacterFunctions::isLetter (path[0]) && path[1] == ':')
|
||||
|| path.startsWithIgnoreCase ("smb:");
|
||||
}
|
||||
|
||||
String getRelativePathFrom (const File& file, const File& sourceFolder)
|
||||
{
|
||||
#if ! JUCE_WINDOWS
|
||||
// On a non-windows machine, we can't know if a drive-letter path may be relative or not.
|
||||
if (CharacterFunctions::isLetter (file.getFullPathName()[0]) && file.getFullPathName()[1] == ':')
|
||||
return file.getFullPathName();
|
||||
#endif
|
||||
|
||||
return file.getRelativePathFrom (sourceFolder);
|
||||
}
|
||||
|
||||
void writeStreamToFile (const File& file, const std::function<void (MemoryOutputStream&)>& writer)
|
||||
{
|
||||
MemoryOutputStream mo;
|
||||
writer (mo);
|
||||
overwriteFileIfDifferentOrThrow (file, mo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,86 +1,86 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
void overwriteFileIfDifferentOrThrow (const File& file, const MemoryOutputStream& newData);
|
||||
void overwriteFileIfDifferentOrThrow (const File& file, const String& newData);
|
||||
|
||||
class SaveError
|
||||
{
|
||||
public:
|
||||
SaveError (const String& error) : message (error)
|
||||
{}
|
||||
|
||||
SaveError (const File& fileThatFailedToWrite)
|
||||
: message ("Can't write to the file: " + fileThatFailedToWrite.getFullPathName())
|
||||
{}
|
||||
|
||||
String message;
|
||||
};
|
||||
|
||||
String replacePreprocessorDefs (const StringPairArray& definitions, String sourceString);
|
||||
|
||||
String getXcodePackageType (ProjectType::Target::Type);
|
||||
String getXcodeBundleSignature (ProjectType::Target::Type);
|
||||
|
||||
inline String hexString8Digits (int value)
|
||||
{
|
||||
return String::toHexString (value).paddedLeft ('0', 8);
|
||||
}
|
||||
|
||||
String makeValidIdentifier (String s,
|
||||
bool makeCamelCase,
|
||||
bool removeColons,
|
||||
bool allowTemplates,
|
||||
bool allowAsterisks = false);
|
||||
|
||||
String makeBinaryDataIdentifierName (const File& file);
|
||||
|
||||
void writeDataAsCppLiteral (const MemoryBlock& mb,
|
||||
OutputStream& out,
|
||||
bool breakAtNewLines,
|
||||
bool allowStringBreaks);
|
||||
|
||||
void createStringMatcher (OutputStream& out,
|
||||
const String& utf8PointerVariable,
|
||||
const StringArray& strings,
|
||||
const StringArray& codeToExecute,
|
||||
const int indentLevel);
|
||||
|
||||
String unixStylePath (const String& path);
|
||||
String windowsStylePath (const String& path);
|
||||
String currentOSStylePath (const String& path);
|
||||
|
||||
bool isAbsolutePath (const String& path);
|
||||
|
||||
// A windows-aware version of File::getRelativePath()
|
||||
String getRelativePathFrom (const File& file, const File& sourceFolder);
|
||||
|
||||
void writeStreamToFile (const File& file, const std::function<void (MemoryOutputStream&)>& writer);
|
||||
}
|
||||
}
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
void overwriteFileIfDifferentOrThrow (const File& file, const MemoryOutputStream& newData);
|
||||
void overwriteFileIfDifferentOrThrow (const File& file, const String& newData);
|
||||
|
||||
class SaveError
|
||||
{
|
||||
public:
|
||||
SaveError (const String& error) : message (error)
|
||||
{}
|
||||
|
||||
SaveError (const File& fileThatFailedToWrite)
|
||||
: message ("Can't write to the file: " + fileThatFailedToWrite.getFullPathName())
|
||||
{}
|
||||
|
||||
String message;
|
||||
};
|
||||
|
||||
String replacePreprocessorDefs (const StringPairArray& definitions, String sourceString);
|
||||
|
||||
String getXcodePackageType (ProjectType::Target::Type);
|
||||
String getXcodeBundleSignature (ProjectType::Target::Type);
|
||||
|
||||
inline String hexString8Digits (int value)
|
||||
{
|
||||
return String::toHexString (value).paddedLeft ('0', 8);
|
||||
}
|
||||
|
||||
String makeValidIdentifier (String s,
|
||||
bool makeCamelCase,
|
||||
bool removeColons,
|
||||
bool allowTemplates,
|
||||
bool allowAsterisks = false);
|
||||
|
||||
String makeBinaryDataIdentifierName (const File& file);
|
||||
|
||||
void writeDataAsCppLiteral (const MemoryBlock& mb,
|
||||
OutputStream& out,
|
||||
bool breakAtNewLines,
|
||||
bool allowStringBreaks);
|
||||
|
||||
void createStringMatcher (OutputStream& out,
|
||||
const String& utf8PointerVariable,
|
||||
const StringArray& strings,
|
||||
const StringArray& codeToExecute,
|
||||
const int indentLevel);
|
||||
|
||||
String unixStylePath (const String& path);
|
||||
String windowsStylePath (const String& path);
|
||||
String currentOSStylePath (const String& path);
|
||||
|
||||
bool isAbsolutePath (const String& path);
|
||||
|
||||
// A windows-aware version of File::getRelativePath()
|
||||
String getRelativePathFrom (const File& file, const File& sourceFolder);
|
||||
|
||||
void writeStreamToFile (const File& file, const std::function<void (MemoryOutputStream&)>& writer);
|
||||
}
|
||||
}
|
||||
|
@ -1,206 +1,206 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
static bool isReservedKeyword (String::CharPointerType token, const int tokenLength) noexcept
|
||||
{
|
||||
static const char* const keywords2Char[] =
|
||||
{ "do", "if", "or", nullptr };
|
||||
|
||||
static const char* const keywords3Char[] =
|
||||
{ "and", "asm", "for", "int", "new", "not", "try", "xor", nullptr };
|
||||
|
||||
static const char* const keywords4Char[] =
|
||||
{ "auto", "bool", "case", "char", "else", "enum", "goto",
|
||||
"long", "this", "true", "void", nullptr };
|
||||
|
||||
static const char* const keywords5Char[] =
|
||||
{ "bitor", "break", "catch", "class", "compl", "const", "false", "final",
|
||||
"float", "or_eq", "short", "throw", "union", "using", "while", nullptr };
|
||||
|
||||
static const char* const keywords6Char[] =
|
||||
{ "and_eq", "bitand", "delete", "double", "export", "extern", "friend",
|
||||
"import", "inline", "module", "not_eq", "public", "return", "signed",
|
||||
"sizeof", "static", "struct", "switch", "typeid", "xor_eq", nullptr };
|
||||
|
||||
static const char* const keywords7Char[] =
|
||||
{ "__cdecl", "_Pragma", "alignas", "alignof", "concept", "default",
|
||||
"mutable", "nullptr", "private", "typedef", "uint8_t", "virtual",
|
||||
"wchar_t", nullptr };
|
||||
|
||||
static const char* const keywordsOther[] =
|
||||
{ "@class", "@dynamic", "@end", "@implementation", "@interface", "@public",
|
||||
"@private", "@protected", "@property", "@synthesize", "__fastcall", "__stdcall",
|
||||
"atomic_cancel", "atomic_commit", "atomic_noexcept", "char16_t", "char32_t",
|
||||
"co_await", "co_return", "co_yield", "const_cast", "constexpr", "continue",
|
||||
"decltype", "dynamic_cast", "explicit", "namespace", "noexcept", "operator", "override",
|
||||
"protected", "register", "reinterpret_cast", "requires", "static_assert",
|
||||
"static_cast", "synchronized", "template", "thread_local", "typename", "unsigned",
|
||||
"volatile", nullptr };
|
||||
|
||||
const char* const* k;
|
||||
|
||||
switch (tokenLength)
|
||||
{
|
||||
case 2: k = keywords2Char; break;
|
||||
case 3: k = keywords3Char; break;
|
||||
case 4: k = keywords4Char; break;
|
||||
case 5: k = keywords5Char; break;
|
||||
case 6: k = keywords6Char; break;
|
||||
case 7: k = keywords7Char; break;
|
||||
|
||||
default:
|
||||
if (tokenLength < 2 || tokenLength > 16)
|
||||
return false;
|
||||
|
||||
k = keywordsOther;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; k[i] != nullptr; ++i)
|
||||
if (token.compare (CharPointer_ASCII (k[i])) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isReservedKeyword (const String& token) noexcept
|
||||
{
|
||||
return isReservedKeyword (token.getCharPointer(), token.length());
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Takes a UTF8 string and writes it to a stream using standard C++ escape sequences for any
|
||||
non-ascii bytes.
|
||||
|
||||
Although not strictly a tokenising function, this is still a function that often comes in
|
||||
handy when working with C++ code!
|
||||
|
||||
Note that addEscapeChars() is easier to use than this function if you're working with Strings.
|
||||
|
||||
@see addEscapeChars
|
||||
*/
|
||||
static void writeEscapeChars (OutputStream& out, const char* utf8, const int numBytesToRead,
|
||||
const int maxCharsOnLine, const bool breakAtNewLines,
|
||||
const bool replaceSingleQuotes, const bool allowStringBreaks)
|
||||
{
|
||||
int charsOnLine = 0;
|
||||
bool lastWasHexEscapeCode = false;
|
||||
bool trigraphDetected = false;
|
||||
|
||||
for (int i = 0; i < numBytesToRead || numBytesToRead < 0; ++i)
|
||||
{
|
||||
auto c = (unsigned char) utf8[i];
|
||||
bool startNewLine = false;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
|
||||
case '\t': out << "\\t"; trigraphDetected = false; lastWasHexEscapeCode = false; charsOnLine += 2; break;
|
||||
case '\r': out << "\\r"; trigraphDetected = false; lastWasHexEscapeCode = false; charsOnLine += 2; break;
|
||||
case '\n': out << "\\n"; trigraphDetected = false; lastWasHexEscapeCode = false; charsOnLine += 2; startNewLine = breakAtNewLines; break;
|
||||
case '\\': out << "\\\\"; trigraphDetected = false; lastWasHexEscapeCode = false; charsOnLine += 2; break;
|
||||
case '\"': out << "\\\""; trigraphDetected = false; lastWasHexEscapeCode = false; charsOnLine += 2; break;
|
||||
|
||||
case '?':
|
||||
if (trigraphDetected)
|
||||
{
|
||||
out << "\\?";
|
||||
charsOnLine++;
|
||||
trigraphDetected = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "?";
|
||||
trigraphDetected = true;
|
||||
}
|
||||
|
||||
lastWasHexEscapeCode = false;
|
||||
charsOnLine++;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
if (numBytesToRead < 0)
|
||||
return;
|
||||
|
||||
out << "\\0";
|
||||
lastWasHexEscapeCode = true;
|
||||
trigraphDetected = false;
|
||||
charsOnLine += 2;
|
||||
break;
|
||||
|
||||
case '\'':
|
||||
if (replaceSingleQuotes)
|
||||
{
|
||||
out << "\\\'";
|
||||
lastWasHexEscapeCode = false;
|
||||
trigraphDetected = false;
|
||||
charsOnLine += 2;
|
||||
break;
|
||||
}
|
||||
|
||||
// deliberate fall-through...
|
||||
|
||||
default:
|
||||
if (c >= 32 && c < 127 && ! (lastWasHexEscapeCode // (have to avoid following a hex escape sequence with a valid hex digit)
|
||||
&& CharacterFunctions::getHexDigitValue (c) >= 0))
|
||||
{
|
||||
out << (char) c;
|
||||
lastWasHexEscapeCode = false;
|
||||
trigraphDetected = false;
|
||||
++charsOnLine;
|
||||
}
|
||||
else if (allowStringBreaks && lastWasHexEscapeCode && c >= 32 && c < 127)
|
||||
{
|
||||
out << "\"\"" << (char) c;
|
||||
lastWasHexEscapeCode = false;
|
||||
trigraphDetected = false;
|
||||
charsOnLine += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
out << (c < 16 ? "\\x0" : "\\x") << String::toHexString ((int) c);
|
||||
lastWasHexEscapeCode = true;
|
||||
trigraphDetected = false;
|
||||
charsOnLine += 4;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ((startNewLine || (maxCharsOnLine > 0 && charsOnLine >= maxCharsOnLine))
|
||||
&& (numBytesToRead < 0 || i < numBytesToRead - 1))
|
||||
{
|
||||
charsOnLine = 0;
|
||||
out << "\"" << newLine << "\"";
|
||||
lastWasHexEscapeCode = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
static bool isReservedKeyword (String::CharPointerType token, const int tokenLength) noexcept
|
||||
{
|
||||
static const char* const keywords2Char[] =
|
||||
{ "do", "if", "or", nullptr };
|
||||
|
||||
static const char* const keywords3Char[] =
|
||||
{ "and", "asm", "for", "int", "new", "not", "try", "xor", nullptr };
|
||||
|
||||
static const char* const keywords4Char[] =
|
||||
{ "auto", "bool", "case", "char", "else", "enum", "goto",
|
||||
"long", "this", "true", "void", nullptr };
|
||||
|
||||
static const char* const keywords5Char[] =
|
||||
{ "bitor", "break", "catch", "class", "compl", "const", "false", "final",
|
||||
"float", "or_eq", "short", "throw", "union", "using", "while", nullptr };
|
||||
|
||||
static const char* const keywords6Char[] =
|
||||
{ "and_eq", "bitand", "delete", "double", "export", "extern", "friend",
|
||||
"import", "inline", "module", "not_eq", "public", "return", "signed",
|
||||
"sizeof", "static", "struct", "switch", "typeid", "xor_eq", nullptr };
|
||||
|
||||
static const char* const keywords7Char[] =
|
||||
{ "__cdecl", "_Pragma", "alignas", "alignof", "concept", "default",
|
||||
"mutable", "nullptr", "private", "typedef", "uint8_t", "virtual",
|
||||
"wchar_t", nullptr };
|
||||
|
||||
static const char* const keywordsOther[] =
|
||||
{ "@class", "@dynamic", "@end", "@implementation", "@interface", "@public",
|
||||
"@private", "@protected", "@property", "@synthesize", "__fastcall", "__stdcall",
|
||||
"atomic_cancel", "atomic_commit", "atomic_noexcept", "char16_t", "char32_t",
|
||||
"co_await", "co_return", "co_yield", "const_cast", "constexpr", "continue",
|
||||
"decltype", "dynamic_cast", "explicit", "namespace", "noexcept", "operator", "override",
|
||||
"protected", "register", "reinterpret_cast", "requires", "static_assert",
|
||||
"static_cast", "synchronized", "template", "thread_local", "typename", "unsigned",
|
||||
"volatile", nullptr };
|
||||
|
||||
const char* const* k;
|
||||
|
||||
switch (tokenLength)
|
||||
{
|
||||
case 2: k = keywords2Char; break;
|
||||
case 3: k = keywords3Char; break;
|
||||
case 4: k = keywords4Char; break;
|
||||
case 5: k = keywords5Char; break;
|
||||
case 6: k = keywords6Char; break;
|
||||
case 7: k = keywords7Char; break;
|
||||
|
||||
default:
|
||||
if (tokenLength < 2 || tokenLength > 16)
|
||||
return false;
|
||||
|
||||
k = keywordsOther;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; k[i] != nullptr; ++i)
|
||||
if (token.compare (CharPointer_ASCII (k[i])) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isReservedKeyword (const String& token) noexcept
|
||||
{
|
||||
return isReservedKeyword (token.getCharPointer(), token.length());
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** Takes a UTF8 string and writes it to a stream using standard C++ escape sequences for any
|
||||
non-ascii bytes.
|
||||
|
||||
Although not strictly a tokenising function, this is still a function that often comes in
|
||||
handy when working with C++ code!
|
||||
|
||||
Note that addEscapeChars() is easier to use than this function if you're working with Strings.
|
||||
|
||||
@see addEscapeChars
|
||||
*/
|
||||
static void writeEscapeChars (OutputStream& out, const char* utf8, const int numBytesToRead,
|
||||
const int maxCharsOnLine, const bool breakAtNewLines,
|
||||
const bool replaceSingleQuotes, const bool allowStringBreaks)
|
||||
{
|
||||
int charsOnLine = 0;
|
||||
bool lastWasHexEscapeCode = false;
|
||||
bool trigraphDetected = false;
|
||||
|
||||
for (int i = 0; i < numBytesToRead || numBytesToRead < 0; ++i)
|
||||
{
|
||||
auto c = (unsigned char) utf8[i];
|
||||
bool startNewLine = false;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
|
||||
case '\t': out << "\\t"; trigraphDetected = false; lastWasHexEscapeCode = false; charsOnLine += 2; break;
|
||||
case '\r': out << "\\r"; trigraphDetected = false; lastWasHexEscapeCode = false; charsOnLine += 2; break;
|
||||
case '\n': out << "\\n"; trigraphDetected = false; lastWasHexEscapeCode = false; charsOnLine += 2; startNewLine = breakAtNewLines; break;
|
||||
case '\\': out << "\\\\"; trigraphDetected = false; lastWasHexEscapeCode = false; charsOnLine += 2; break;
|
||||
case '\"': out << "\\\""; trigraphDetected = false; lastWasHexEscapeCode = false; charsOnLine += 2; break;
|
||||
|
||||
case '?':
|
||||
if (trigraphDetected)
|
||||
{
|
||||
out << "\\?";
|
||||
charsOnLine++;
|
||||
trigraphDetected = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "?";
|
||||
trigraphDetected = true;
|
||||
}
|
||||
|
||||
lastWasHexEscapeCode = false;
|
||||
charsOnLine++;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
if (numBytesToRead < 0)
|
||||
return;
|
||||
|
||||
out << "\\0";
|
||||
lastWasHexEscapeCode = true;
|
||||
trigraphDetected = false;
|
||||
charsOnLine += 2;
|
||||
break;
|
||||
|
||||
case '\'':
|
||||
if (replaceSingleQuotes)
|
||||
{
|
||||
out << "\\\'";
|
||||
lastWasHexEscapeCode = false;
|
||||
trigraphDetected = false;
|
||||
charsOnLine += 2;
|
||||
break;
|
||||
}
|
||||
|
||||
// deliberate fall-through...
|
||||
|
||||
default:
|
||||
if (c >= 32 && c < 127 && ! (lastWasHexEscapeCode // (have to avoid following a hex escape sequence with a valid hex digit)
|
||||
&& CharacterFunctions::getHexDigitValue (c) >= 0))
|
||||
{
|
||||
out << (char) c;
|
||||
lastWasHexEscapeCode = false;
|
||||
trigraphDetected = false;
|
||||
++charsOnLine;
|
||||
}
|
||||
else if (allowStringBreaks && lastWasHexEscapeCode && c >= 32 && c < 127)
|
||||
{
|
||||
out << "\"\"" << (char) c;
|
||||
lastWasHexEscapeCode = false;
|
||||
trigraphDetected = false;
|
||||
charsOnLine += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
out << (c < 16 ? "\\x0" : "\\x") << String::toHexString ((int) c);
|
||||
lastWasHexEscapeCode = true;
|
||||
trigraphDetected = false;
|
||||
charsOnLine += 4;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ((startNewLine || (maxCharsOnLine > 0 && charsOnLine >= maxCharsOnLine))
|
||||
&& (numBytesToRead < 0 || i < numBytesToRead - 1))
|
||||
{
|
||||
charsOnLine = 0;
|
||||
out << "\"" << newLine << "\"";
|
||||
lastWasHexEscapeCode = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,119 +1,133 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
String EntitlementOptions::getEntitlementsFileContent() const
|
||||
{
|
||||
String content =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
|
||||
"<plist version=\"1.0\">\n"
|
||||
"<dict>\n";
|
||||
|
||||
const auto entitlements = getEntitlements();
|
||||
|
||||
for (auto& key : entitlements.getAllKeys())
|
||||
content += "\t<key>" + key + "</key>\n\t" + entitlements[key] + "\n";
|
||||
|
||||
return content + "</dict>\n</plist>\n";
|
||||
}
|
||||
|
||||
StringPairArray EntitlementOptions::getEntitlements() const
|
||||
{
|
||||
StringPairArray entitlements;
|
||||
|
||||
if (isiOS)
|
||||
{
|
||||
if (isAudioPluginProject && shouldEnableIAA)
|
||||
entitlements.set ("inter-app-audio", "<true/>");
|
||||
|
||||
if (isiCloudPermissionsEnabled)
|
||||
{
|
||||
entitlements.set ("com.apple.developer.icloud-container-identifiers",
|
||||
"<array>\n"
|
||||
" <string>iCloud.$(CFBundleIdentifier)</string>\n"
|
||||
" </array>");
|
||||
|
||||
entitlements.set ("com.apple.developer.icloud-services",
|
||||
"<array>\n"
|
||||
" <string>CloudDocuments</string>\n"
|
||||
" </array>");
|
||||
|
||||
entitlements.set ("com.apple.developer.ubiquity-container-identifiers",
|
||||
"<array>\n"
|
||||
" <string>iCloud.$(CFBundleIdentifier)</string>\n"
|
||||
" </array>");
|
||||
}
|
||||
}
|
||||
|
||||
if (isPushNotificationsEnabled)
|
||||
entitlements.set (isiOS ? "aps-environment"
|
||||
: "com.apple.developer.aps-environment",
|
||||
"<string>development</string>");
|
||||
|
||||
if (isAppGroupsEnabled)
|
||||
{
|
||||
auto appGroups = StringArray::fromTokens (appGroupIdString, ";", {});
|
||||
auto groups = String ("<array>");
|
||||
|
||||
for (auto group : appGroups)
|
||||
groups += "\n\t\t<string>" + group.trim() + "</string>";
|
||||
|
||||
groups += "\n\t</array>";
|
||||
|
||||
entitlements.set ("com.apple.security.application-groups", groups);
|
||||
}
|
||||
|
||||
if (isHardenedRuntimeEnabled)
|
||||
for (auto& option : hardenedRuntimeOptions)
|
||||
entitlements.set (option, "<true/>");
|
||||
|
||||
if (isAppSandboxEnabled || (! isiOS && isAudioPluginProject && type == ProjectType::Target::AudioUnitv3PlugIn))
|
||||
{
|
||||
entitlements.set ("com.apple.security.app-sandbox", "<true/>");
|
||||
|
||||
if (isAppSandboxInhertianceEnabled)
|
||||
{
|
||||
// no other sandbox options can be specified if sandbox inheritance is enabled!
|
||||
jassert (appSandboxOptions.isEmpty());
|
||||
|
||||
entitlements.set ("com.apple.security.inherit", "<true/>");
|
||||
}
|
||||
|
||||
if (isAppSandboxEnabled)
|
||||
for (auto& option : appSandboxOptions)
|
||||
entitlements.set (option, "<true/>");
|
||||
}
|
||||
|
||||
if (isNetworkingMulticastEnabled)
|
||||
entitlements.set ("com.apple.developer.networking.multicast", "<true/>");
|
||||
|
||||
return entitlements;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
String EntitlementOptions::getEntitlementsFileContent() const
|
||||
{
|
||||
String content =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
|
||||
"<plist version=\"1.0\">\n"
|
||||
"<dict>\n";
|
||||
|
||||
const auto entitlements = getEntitlements();
|
||||
|
||||
for (auto& key : entitlements.getAllKeys())
|
||||
content += "\t<key>" + key + "</key>\n\t" + entitlements[key] + "\n";
|
||||
|
||||
return content + "</dict>\n</plist>\n";
|
||||
}
|
||||
|
||||
StringPairArray EntitlementOptions::getEntitlements() const
|
||||
{
|
||||
StringPairArray entitlements;
|
||||
|
||||
if (isiOS)
|
||||
{
|
||||
if (isAudioPluginProject && shouldEnableIAA)
|
||||
entitlements.set ("inter-app-audio", "<true/>");
|
||||
|
||||
if (isiCloudPermissionsEnabled)
|
||||
{
|
||||
entitlements.set ("com.apple.developer.icloud-container-identifiers",
|
||||
"<array>\n"
|
||||
" <string>iCloud.$(CFBundleIdentifier)</string>\n"
|
||||
" </array>");
|
||||
|
||||
entitlements.set ("com.apple.developer.icloud-services",
|
||||
"<array>\n"
|
||||
" <string>CloudDocuments</string>\n"
|
||||
" </array>");
|
||||
|
||||
entitlements.set ("com.apple.developer.ubiquity-container-identifiers",
|
||||
"<array>\n"
|
||||
" <string>iCloud.$(CFBundleIdentifier)</string>\n"
|
||||
" </array>");
|
||||
}
|
||||
}
|
||||
|
||||
if (isPushNotificationsEnabled)
|
||||
entitlements.set (isiOS ? "aps-environment"
|
||||
: "com.apple.developer.aps-environment",
|
||||
"<string>development</string>");
|
||||
|
||||
if (isAppGroupsEnabled)
|
||||
{
|
||||
auto appGroups = StringArray::fromTokens (appGroupIdString, ";", {});
|
||||
String groups = "<array>";
|
||||
|
||||
for (auto group : appGroups)
|
||||
groups += "\n\t\t<string>" + group.trim() + "</string>";
|
||||
|
||||
groups += "\n\t</array>";
|
||||
|
||||
entitlements.set ("com.apple.security.application-groups", groups);
|
||||
}
|
||||
|
||||
if (isHardenedRuntimeEnabled)
|
||||
for (auto& option : hardenedRuntimeOptions)
|
||||
entitlements.set (option, "<true/>");
|
||||
|
||||
if (isAppSandboxEnabled || (! isiOS && isAudioPluginProject && type == ProjectType::Target::AudioUnitv3PlugIn))
|
||||
{
|
||||
entitlements.set ("com.apple.security.app-sandbox", "<true/>");
|
||||
|
||||
if (isAppSandboxInhertianceEnabled)
|
||||
{
|
||||
// no other sandbox options can be specified if sandbox inheritance is enabled!
|
||||
jassert (appSandboxOptions.isEmpty());
|
||||
jassert (appSandboxTemporaryPaths.empty());
|
||||
|
||||
entitlements.set ("com.apple.security.inherit", "<true/>");
|
||||
}
|
||||
|
||||
if (isAppSandboxEnabled)
|
||||
{
|
||||
for (auto& option : appSandboxOptions)
|
||||
entitlements.set (option, "<true/>");
|
||||
|
||||
for (auto& option : appSandboxTemporaryPaths)
|
||||
{
|
||||
String paths = "<array>";
|
||||
|
||||
for (const auto& path : option.values)
|
||||
paths += "\n\t\t<string>" + path + "</string>";
|
||||
|
||||
paths += "\n\t</array>";
|
||||
entitlements.set (option.key, paths);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isNetworkingMulticastEnabled)
|
||||
entitlements.set ("com.apple.developer.networking.multicast", "<true/>");
|
||||
|
||||
return entitlements;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,56 +1,64 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
struct EntitlementOptions final
|
||||
{
|
||||
String getEntitlementsFileContent() const;
|
||||
|
||||
ProjectType::Target::Type type = ProjectType::Target::GUIApp;
|
||||
|
||||
bool isiOS = false;
|
||||
bool isAudioPluginProject = false;
|
||||
bool shouldEnableIAA = false;
|
||||
bool isiCloudPermissionsEnabled = false;
|
||||
bool isPushNotificationsEnabled = false;
|
||||
bool isAppGroupsEnabled = false;
|
||||
bool isHardenedRuntimeEnabled = false;
|
||||
bool isAppSandboxEnabled = false;
|
||||
bool isAppSandboxInhertianceEnabled = false;
|
||||
bool isNetworkingMulticastEnabled = false;
|
||||
|
||||
String appGroupIdString;
|
||||
|
||||
StringArray hardenedRuntimeOptions;
|
||||
StringArray appSandboxOptions;
|
||||
|
||||
private:
|
||||
StringPairArray getEntitlements() const;
|
||||
};
|
||||
}
|
||||
}
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
struct EntitlementOptions final
|
||||
{
|
||||
String getEntitlementsFileContent() const;
|
||||
|
||||
ProjectType::Target::Type type = ProjectType::Target::GUIApp;
|
||||
|
||||
bool isiOS = false;
|
||||
bool isAudioPluginProject = false;
|
||||
bool shouldEnableIAA = false;
|
||||
bool isiCloudPermissionsEnabled = false;
|
||||
bool isPushNotificationsEnabled = false;
|
||||
bool isAppGroupsEnabled = false;
|
||||
bool isHardenedRuntimeEnabled = false;
|
||||
bool isAppSandboxEnabled = false;
|
||||
bool isAppSandboxInhertianceEnabled = false;
|
||||
bool isNetworkingMulticastEnabled = false;
|
||||
|
||||
String appGroupIdString;
|
||||
|
||||
StringArray hardenedRuntimeOptions;
|
||||
StringArray appSandboxOptions;
|
||||
|
||||
struct KeyAndStringArray
|
||||
{
|
||||
String key;
|
||||
StringArray values;
|
||||
};
|
||||
|
||||
std::vector<KeyAndStringArray> appSandboxTemporaryPaths;
|
||||
|
||||
private:
|
||||
StringPairArray getEntitlements() const;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,49 +1,49 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
struct Icons
|
||||
{
|
||||
std::unique_ptr<Drawable> small;
|
||||
std::unique_ptr<Drawable> big;
|
||||
};
|
||||
|
||||
Array<Drawable*> asArray (const Icons&);
|
||||
void writeMacIcon (const Icons&, const File&);
|
||||
void writeWinIcon (const Icons&, const File&);
|
||||
|
||||
Image getBestIconForSize (const Icons& icons,
|
||||
int size,
|
||||
bool returnNullIfNothingBigEnough);
|
||||
Image rescaleImageForIcon (Drawable& d, const int size);
|
||||
|
||||
RelativePath createXcassetsFolderFromIcons (const Icons& icons,
|
||||
const File& targetFolder,
|
||||
String projectFilenameRootString);
|
||||
}
|
||||
}
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
struct Icons
|
||||
{
|
||||
std::unique_ptr<Drawable> small;
|
||||
std::unique_ptr<Drawable> big;
|
||||
};
|
||||
|
||||
Array<Drawable*> asArray (const Icons&);
|
||||
void writeMacIcon (const Icons&, const File&);
|
||||
void writeWinIcon (const Icons&, const File&);
|
||||
|
||||
Image getBestIconForSize (const Icons& icons,
|
||||
int size,
|
||||
bool returnNullIfNothingBigEnough);
|
||||
Image rescaleImageForIcon (Drawable& d, const int size);
|
||||
|
||||
RelativePath createXcassetsFolderFromIcons (const Icons& icons,
|
||||
const File& targetFolder,
|
||||
String projectFilenameRootString);
|
||||
}
|
||||
}
|
||||
|
@ -1,370 +1,378 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
//==============================================================================
|
||||
static XmlElement* getKeyWithName (XmlElement& xml, const String& key)
|
||||
{
|
||||
for (auto* element : xml.getChildWithTagNameIterator ("key"))
|
||||
if (element->getAllSubText().trim().equalsIgnoreCase (key))
|
||||
return element;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static bool keyFoundAndNotSequentialDuplicate (XmlElement& xml, const String& key)
|
||||
{
|
||||
if (auto* element = getKeyWithName (xml, key))
|
||||
{
|
||||
if (element->getNextElement() != nullptr && element->getNextElement()->hasTagName ("key"))
|
||||
{
|
||||
// found broken plist format (sequential duplicate), fix by removing
|
||||
xml.removeChildElement (element, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
// key found (not sequential duplicate)
|
||||
return true;
|
||||
}
|
||||
|
||||
// key not found
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool addKeyIfNotFound (XmlElement& xml, const String& key)
|
||||
{
|
||||
if (! keyFoundAndNotSequentialDuplicate (xml, key))
|
||||
{
|
||||
xml.createNewChildElement ("key")->addTextElement (key);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void addPlistDictionaryKey (XmlElement& xml, const String& key, const String& value)
|
||||
{
|
||||
if (addKeyIfNotFound (xml, key))
|
||||
xml.createNewChildElement ("string")->addTextElement (value);
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
static void addPlistDictionaryKey (XmlElement& xml, const String& key, const char (&value) [N])
|
||||
{
|
||||
addPlistDictionaryKey (xml, key, String { value });
|
||||
}
|
||||
|
||||
static void addPlistDictionaryKey (XmlElement& xml, const String& key, const bool value)
|
||||
{
|
||||
if (addKeyIfNotFound (xml, key))
|
||||
xml.createNewChildElement (value ? "true" : "false");
|
||||
}
|
||||
|
||||
static void addPlistDictionaryKey (XmlElement& xml, const String& key, int value)
|
||||
{
|
||||
if (addKeyIfNotFound (xml, key))
|
||||
xml.createNewChildElement ("integer")->addTextElement (String (value));
|
||||
}
|
||||
|
||||
static void addArrayToPlist (XmlElement& dict, String arrayKey, const StringArray& arrayElements)
|
||||
{
|
||||
if (getKeyWithName (dict, arrayKey) != nullptr)
|
||||
return;
|
||||
|
||||
dict.createNewChildElement ("key")->addTextElement (arrayKey);
|
||||
auto* plistStringArray = dict.createNewChildElement ("array");
|
||||
|
||||
for (auto& e : arrayElements)
|
||||
plistStringArray->createNewChildElement ("string")->addTextElement (e);
|
||||
}
|
||||
|
||||
static int getAUVersionAsHexInteger (const PlistOptions& opts)
|
||||
{
|
||||
const auto segments = getVersionSegments (opts.marketingVersion);
|
||||
const StringArray trimmed (segments.strings.getRawDataPointer(), jmin (segments.size(), 3));
|
||||
return getVersionAsHexIntegerFromParts (trimmed);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void PlistOptions::write (const File& infoPlistFile) const
|
||||
{
|
||||
writeStreamToFile (infoPlistFile, [&] (MemoryOutputStream& mo) { write (mo); });
|
||||
}
|
||||
|
||||
void PlistOptions::write (MemoryOutputStream& mo) const
|
||||
{
|
||||
XmlElement::TextFormat format;
|
||||
format.dtd = "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">";
|
||||
createXML()->writeTo (mo, format);
|
||||
}
|
||||
|
||||
std::unique_ptr<XmlElement> PlistOptions::createXML() const
|
||||
{
|
||||
auto plist = parseXML (plistToMerge);
|
||||
|
||||
if (plist == nullptr || ! plist->hasTagName ("plist"))
|
||||
plist.reset (new XmlElement ("plist"));
|
||||
|
||||
auto* dict = plist->getChildByName ("dict");
|
||||
|
||||
if (dict == nullptr)
|
||||
dict = plist->createNewChildElement ("dict");
|
||||
|
||||
if (microphonePermissionEnabled)
|
||||
addPlistDictionaryKey (*dict, "NSMicrophoneUsageDescription", microphonePermissionText);
|
||||
|
||||
if (cameraPermissionEnabled)
|
||||
addPlistDictionaryKey (*dict, "NSCameraUsageDescription", cameraPermissionText);
|
||||
|
||||
if (bluetoothPermissionEnabled)
|
||||
addPlistDictionaryKey (*dict, "NSBluetoothAlwaysUsageDescription", bluetoothPermissionText);
|
||||
|
||||
if (iOS)
|
||||
{
|
||||
if (bluetoothPermissionEnabled)
|
||||
addPlistDictionaryKey (*dict, "NSBluetoothPeripheralUsageDescription", bluetoothPermissionText); // needed for pre iOS 13.0
|
||||
|
||||
addPlistDictionaryKey (*dict, "LSRequiresIPhoneOS", true);
|
||||
addPlistDictionaryKey (*dict, "UIViewControllerBasedStatusBarAppearance", true);
|
||||
|
||||
if (shouldAddStoryboardToProject)
|
||||
addPlistDictionaryKey (*dict, "UILaunchStoryboardName", storyboardName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sendAppleEventsPermissionEnabled)
|
||||
addPlistDictionaryKey (*dict, "NSAppleEventsUsageDescription", sendAppleEventsPermissionText);
|
||||
}
|
||||
|
||||
addPlistDictionaryKey (*dict, "CFBundleExecutable", executableName);
|
||||
|
||||
if (! iOS) // (NB: on iOS this causes error ITMS-90032 during publishing)
|
||||
addPlistDictionaryKey (*dict, "CFBundleIconFile", iconFile.exists() ? iconFile.getFileName() : String());
|
||||
|
||||
addPlistDictionaryKey (*dict, "CFBundleIdentifier", bundleIdentifier);
|
||||
addPlistDictionaryKey (*dict, "CFBundleName", projectName);
|
||||
|
||||
// needed by NSExtension on iOS
|
||||
addPlistDictionaryKey (*dict, "CFBundleDisplayName", projectName);
|
||||
addPlistDictionaryKey (*dict, "CFBundlePackageType", getXcodePackageType (type));
|
||||
addPlistDictionaryKey (*dict, "CFBundleSignature", getXcodeBundleSignature (type));
|
||||
addPlistDictionaryKey (*dict, "CFBundleShortVersionString", marketingVersion);
|
||||
addPlistDictionaryKey (*dict, "CFBundleVersion", currentProjectVersion);
|
||||
addPlistDictionaryKey (*dict, "NSHumanReadableCopyright", companyCopyright);
|
||||
addPlistDictionaryKey (*dict, "NSHighResolutionCapable", true);
|
||||
|
||||
if (applicationCategory.isNotEmpty())
|
||||
addPlistDictionaryKey (*dict, "LSApplicationCategoryType", applicationCategory);
|
||||
|
||||
auto replacedDocExtensions = StringArray::fromTokens (replacePreprocessorDefs (allPreprocessorDefs,
|
||||
documentExtensions), ",", {});
|
||||
replacedDocExtensions.trim();
|
||||
replacedDocExtensions.removeEmptyStrings (true);
|
||||
|
||||
if (! replacedDocExtensions.isEmpty() && type != ProjectType::Target::AudioUnitv3PlugIn)
|
||||
{
|
||||
dict->createNewChildElement ("key")->addTextElement ("CFBundleDocumentTypes");
|
||||
auto* dict2 = dict->createNewChildElement ("array")->createNewChildElement ("dict");
|
||||
XmlElement* arrayTag = nullptr;
|
||||
|
||||
for (auto ex : replacedDocExtensions)
|
||||
{
|
||||
if (ex.startsWithChar ('.'))
|
||||
ex = ex.substring (1);
|
||||
|
||||
if (arrayTag == nullptr)
|
||||
{
|
||||
dict2->createNewChildElement ("key")->addTextElement ("CFBundleTypeExtensions");
|
||||
arrayTag = dict2->createNewChildElement ("array");
|
||||
|
||||
addPlistDictionaryKey (*dict2, "CFBundleTypeName", ex);
|
||||
addPlistDictionaryKey (*dict2, "CFBundleTypeRole", "Editor");
|
||||
addPlistDictionaryKey (*dict2, "CFBundleTypeIconFile", "Icon");
|
||||
addPlistDictionaryKey (*dict2, "NSPersistentStoreTypeKey", "XML");
|
||||
}
|
||||
|
||||
arrayTag->createNewChildElement ("string")->addTextElement (ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (fileSharingEnabled && type != ProjectType::Target::AudioUnitv3PlugIn)
|
||||
addPlistDictionaryKey (*dict, "UIFileSharingEnabled", true);
|
||||
|
||||
if (documentBrowserEnabled)
|
||||
addPlistDictionaryKey (*dict, "UISupportsDocumentBrowser", true);
|
||||
|
||||
if (iOS)
|
||||
{
|
||||
if (type != ProjectType::Target::AudioUnitv3PlugIn)
|
||||
{
|
||||
if (statusBarHidden)
|
||||
addPlistDictionaryKey (*dict, "UIStatusBarHidden", true);
|
||||
|
||||
addPlistDictionaryKey (*dict, "UIRequiresFullScreen", requiresFullScreen);
|
||||
|
||||
addIosScreenOrientations (*dict);
|
||||
addIosBackgroundModes (*dict);
|
||||
}
|
||||
|
||||
if (type == ProjectType::Target::StandalonePlugIn && enableIAA)
|
||||
{
|
||||
XmlElement audioComponentsPlistKey ("key");
|
||||
audioComponentsPlistKey.addTextElement ("AudioComponents");
|
||||
|
||||
dict->addChildElement (new XmlElement (audioComponentsPlistKey));
|
||||
|
||||
XmlElement audioComponentsPlistEntry ("array");
|
||||
auto* audioComponentsDict = audioComponentsPlistEntry.createNewChildElement ("dict");
|
||||
|
||||
addPlistDictionaryKey (*audioComponentsDict, "name", IAAPluginName);
|
||||
addPlistDictionaryKey (*audioComponentsDict, "manufacturer", pluginManufacturerCode.substring (0, 4));
|
||||
addPlistDictionaryKey (*audioComponentsDict, "type", IAATypeCode);
|
||||
addPlistDictionaryKey (*audioComponentsDict, "subtype", pluginCode.substring (0, 4));
|
||||
addPlistDictionaryKey (*audioComponentsDict, "version", getVersionAsHexInteger (marketingVersion));
|
||||
|
||||
dict->addChildElement (new XmlElement (audioComponentsPlistEntry));
|
||||
}
|
||||
}
|
||||
|
||||
const auto extraOptions = [&]() -> Array<XmlElement>
|
||||
{
|
||||
if (type == ProjectType::Target::Type::AudioUnitPlugIn)
|
||||
return createExtraAudioUnitTargetPlistOptions();
|
||||
|
||||
if (type == ProjectType::Target::Type::AudioUnitv3PlugIn)
|
||||
return createExtraAudioUnitV3TargetPlistOptions();
|
||||
|
||||
return {};
|
||||
}();
|
||||
|
||||
for (auto& e : extraOptions)
|
||||
dict->addChildElement (new XmlElement (e));
|
||||
|
||||
return plist;
|
||||
}
|
||||
|
||||
void PlistOptions::addIosScreenOrientations (XmlElement& dict) const
|
||||
{
|
||||
addArrayToPlist (dict, "UISupportedInterfaceOrientations", iPhoneScreenOrientations);
|
||||
|
||||
if (iPadScreenOrientations != iPhoneScreenOrientations)
|
||||
addArrayToPlist (dict, "UISupportedInterfaceOrientations~ipad", iPadScreenOrientations);
|
||||
}
|
||||
|
||||
void PlistOptions::addIosBackgroundModes (XmlElement& dict) const
|
||||
{
|
||||
StringArray iosBackgroundModes;
|
||||
if (backgroundAudioEnabled) iosBackgroundModes.add ("audio");
|
||||
if (backgroundBleEnabled) iosBackgroundModes.add ("bluetooth-central");
|
||||
if (pushNotificationsEnabled) iosBackgroundModes.add ("remote-notification");
|
||||
|
||||
addArrayToPlist (dict, "UIBackgroundModes", iosBackgroundModes);
|
||||
}
|
||||
|
||||
Array<XmlElement> PlistOptions::createExtraAudioUnitTargetPlistOptions() const
|
||||
{
|
||||
XmlElement plistKey ("key");
|
||||
plistKey.addTextElement ("AudioComponents");
|
||||
|
||||
XmlElement plistEntry ("array");
|
||||
auto* dict = plistEntry.createNewChildElement ("dict");
|
||||
|
||||
auto truncatedCode = pluginManufacturerCode.substring (0, 4);
|
||||
auto pluginSubType = pluginCode.substring (0, 4);
|
||||
|
||||
if (truncatedCode.toLowerCase() == truncatedCode)
|
||||
{
|
||||
throw SaveError ("AudioUnit plugin code identifiers invalid!\n\n"
|
||||
"You have used only lower case letters in your AU plugin manufacturer identifier. "
|
||||
"You must have at least one uppercase letter in your AU plugin manufacturer "
|
||||
"identifier code.");
|
||||
}
|
||||
|
||||
addPlistDictionaryKey (*dict, "name", pluginManufacturer + ": " + pluginName);
|
||||
addPlistDictionaryKey (*dict, "description", pluginDescription);
|
||||
addPlistDictionaryKey (*dict, "factoryFunction", pluginAUExportPrefix + "Factory");
|
||||
addPlistDictionaryKey (*dict, "manufacturer", truncatedCode);
|
||||
addPlistDictionaryKey (*dict, "type", auMainType.removeCharacters ("'"));
|
||||
addPlistDictionaryKey (*dict, "subtype", pluginSubType);
|
||||
addPlistDictionaryKey (*dict, "version", getAUVersionAsHexInteger (*this));
|
||||
|
||||
if (isAuSandboxSafe)
|
||||
{
|
||||
addPlistDictionaryKey (*dict, "sandboxSafe", true);
|
||||
}
|
||||
else if (! suppressResourceUsage)
|
||||
{
|
||||
dict->createNewChildElement ("key")->addTextElement ("resourceUsage");
|
||||
auto* resourceUsageDict = dict->createNewChildElement ("dict");
|
||||
|
||||
addPlistDictionaryKey (*resourceUsageDict, "network.client", true);
|
||||
addPlistDictionaryKey (*resourceUsageDict, "temporary-exception.files.all.read-write", true);
|
||||
}
|
||||
|
||||
return { plistKey, plistEntry };
|
||||
}
|
||||
|
||||
Array<XmlElement> PlistOptions::createExtraAudioUnitV3TargetPlistOptions() const
|
||||
{
|
||||
XmlElement plistKey ("key");
|
||||
plistKey.addTextElement ("NSExtension");
|
||||
|
||||
XmlElement plistEntry ("dict");
|
||||
|
||||
addPlistDictionaryKey (plistEntry, "NSExtensionPrincipalClass", pluginAUExportPrefix + "FactoryAUv3");
|
||||
addPlistDictionaryKey (plistEntry, "NSExtensionPointIdentifier", "com.apple.AudioUnit-UI");
|
||||
plistEntry.createNewChildElement ("key")->addTextElement ("NSExtensionAttributes");
|
||||
|
||||
auto* dict = plistEntry.createNewChildElement ("dict");
|
||||
dict->createNewChildElement ("key")->addTextElement ("AudioComponents");
|
||||
auto* componentArray = dict->createNewChildElement ("array");
|
||||
|
||||
auto* componentDict = componentArray->createNewChildElement ("dict");
|
||||
|
||||
addPlistDictionaryKey (*componentDict, "name", pluginManufacturer + ": " + pluginName);
|
||||
addPlistDictionaryKey (*componentDict, "description", pluginDescription);
|
||||
addPlistDictionaryKey (*componentDict, "factoryFunction", pluginAUExportPrefix + "FactoryAUv3");
|
||||
addPlistDictionaryKey (*componentDict, "manufacturer", pluginManufacturerCode.substring (0, 4));
|
||||
addPlistDictionaryKey (*componentDict, "type", auMainType.removeCharacters ("'"));
|
||||
addPlistDictionaryKey (*componentDict, "subtype", pluginCode.substring (0, 4));
|
||||
addPlistDictionaryKey (*componentDict, "version", getAUVersionAsHexInteger (*this));
|
||||
addPlistDictionaryKey (*componentDict, "sandboxSafe", true);
|
||||
|
||||
componentDict->createNewChildElement ("key")->addTextElement ("tags");
|
||||
auto* tagsArray = componentDict->createNewChildElement ("array");
|
||||
|
||||
tagsArray->createNewChildElement ("string")
|
||||
->addTextElement (isPluginSynth ? "Synth" : "Effects");
|
||||
|
||||
if (auMainType.removeCharacters ("'") == "aumi")
|
||||
tagsArray->createNewChildElement ("string")->addTextElement ("MIDI");
|
||||
|
||||
return { plistKey, plistEntry };
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
//==============================================================================
|
||||
static XmlElement* getKeyWithName (XmlElement& xml, const String& key)
|
||||
{
|
||||
for (auto* element : xml.getChildWithTagNameIterator ("key"))
|
||||
if (element->getAllSubText().trim().equalsIgnoreCase (key))
|
||||
return element;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static bool keyFoundAndNotSequentialDuplicate (XmlElement& xml, const String& key)
|
||||
{
|
||||
if (auto* element = getKeyWithName (xml, key))
|
||||
{
|
||||
if (element->getNextElement() != nullptr && element->getNextElement()->hasTagName ("key"))
|
||||
{
|
||||
// found broken plist format (sequential duplicate), fix by removing
|
||||
xml.removeChildElement (element, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
// key found (not sequential duplicate)
|
||||
return true;
|
||||
}
|
||||
|
||||
// key not found
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool addKeyIfNotFound (XmlElement& xml, const String& key)
|
||||
{
|
||||
if (! keyFoundAndNotSequentialDuplicate (xml, key))
|
||||
{
|
||||
xml.createNewChildElement ("key")->addTextElement (key);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void addPlistDictionaryKey (XmlElement& xml, const String& key, const String& value)
|
||||
{
|
||||
if (addKeyIfNotFound (xml, key))
|
||||
xml.createNewChildElement ("string")->addTextElement (value);
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
static void addPlistDictionaryKey (XmlElement& xml, const String& key, const char (&value) [N])
|
||||
{
|
||||
addPlistDictionaryKey (xml, key, String { value });
|
||||
}
|
||||
|
||||
static void addPlistDictionaryKey (XmlElement& xml, const String& key, const bool value)
|
||||
{
|
||||
if (addKeyIfNotFound (xml, key))
|
||||
xml.createNewChildElement (value ? "true" : "false");
|
||||
}
|
||||
|
||||
static void addPlistDictionaryKey (XmlElement& xml, const String& key, int value)
|
||||
{
|
||||
if (addKeyIfNotFound (xml, key))
|
||||
xml.createNewChildElement ("integer")->addTextElement (String (value));
|
||||
}
|
||||
|
||||
static void addArrayToPlist (XmlElement& dict, String arrayKey, const StringArray& arrayElements)
|
||||
{
|
||||
if (getKeyWithName (dict, arrayKey) != nullptr)
|
||||
return;
|
||||
|
||||
dict.createNewChildElement ("key")->addTextElement (arrayKey);
|
||||
auto* plistStringArray = dict.createNewChildElement ("array");
|
||||
|
||||
for (auto& e : arrayElements)
|
||||
plistStringArray->createNewChildElement ("string")->addTextElement (e);
|
||||
}
|
||||
|
||||
static int getAUVersionAsHexInteger (const PlistOptions& opts)
|
||||
{
|
||||
const auto segments = getVersionSegments (opts.marketingVersion);
|
||||
const StringArray trimmed (segments.strings.getRawDataPointer(), jmin (segments.size(), 3));
|
||||
return getVersionAsHexIntegerFromParts (trimmed);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void PlistOptions::write (const File& infoPlistFile) const
|
||||
{
|
||||
writeStreamToFile (infoPlistFile, [&] (MemoryOutputStream& mo) { write (mo); });
|
||||
}
|
||||
|
||||
void PlistOptions::write (MemoryOutputStream& mo) const
|
||||
{
|
||||
XmlElement::TextFormat format;
|
||||
format.dtd = "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">";
|
||||
createXML()->writeTo (mo, format);
|
||||
}
|
||||
|
||||
std::unique_ptr<XmlElement> PlistOptions::createXML() const
|
||||
{
|
||||
auto plist = parseXML (plistToMerge);
|
||||
|
||||
if (plist == nullptr || ! plist->hasTagName ("plist"))
|
||||
plist.reset (new XmlElement ("plist"));
|
||||
|
||||
auto* dict = plist->getChildByName ("dict");
|
||||
|
||||
if (dict == nullptr)
|
||||
dict = plist->createNewChildElement ("dict");
|
||||
|
||||
if (microphonePermissionEnabled)
|
||||
addPlistDictionaryKey (*dict, "NSMicrophoneUsageDescription", microphonePermissionText);
|
||||
|
||||
if (cameraPermissionEnabled)
|
||||
addPlistDictionaryKey (*dict, "NSCameraUsageDescription", cameraPermissionText);
|
||||
|
||||
if (bluetoothPermissionEnabled)
|
||||
addPlistDictionaryKey (*dict, "NSBluetoothAlwaysUsageDescription", bluetoothPermissionText);
|
||||
|
||||
if (iOS)
|
||||
{
|
||||
if (bluetoothPermissionEnabled)
|
||||
addPlistDictionaryKey (*dict, "NSBluetoothPeripheralUsageDescription", bluetoothPermissionText); // needed for pre iOS 13.0
|
||||
|
||||
addPlistDictionaryKey (*dict, "LSRequiresIPhoneOS", true);
|
||||
addPlistDictionaryKey (*dict, "UIViewControllerBasedStatusBarAppearance", true);
|
||||
|
||||
if (shouldAddStoryboardToProject)
|
||||
addPlistDictionaryKey (*dict, "UILaunchStoryboardName", storyboardName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sendAppleEventsPermissionEnabled)
|
||||
addPlistDictionaryKey (*dict, "NSAppleEventsUsageDescription", sendAppleEventsPermissionText);
|
||||
}
|
||||
|
||||
addPlistDictionaryKey (*dict, "CFBundleExecutable", executableName);
|
||||
|
||||
if (! iOS) // (NB: on iOS this causes error ITMS-90032 during publishing)
|
||||
addPlistDictionaryKey (*dict, "CFBundleIconFile", iconFile.exists() ? iconFile.getFileName() : String());
|
||||
|
||||
addPlistDictionaryKey (*dict, "CFBundleIdentifier", bundleIdentifier);
|
||||
addPlistDictionaryKey (*dict, "CFBundleName", projectName);
|
||||
|
||||
// needed by NSExtension on iOS
|
||||
addPlistDictionaryKey (*dict, "CFBundleDisplayName", projectName);
|
||||
addPlistDictionaryKey (*dict, "CFBundlePackageType", getXcodePackageType (type));
|
||||
addPlistDictionaryKey (*dict, "CFBundleSignature", getXcodeBundleSignature (type));
|
||||
addPlistDictionaryKey (*dict, "CFBundleShortVersionString", marketingVersion);
|
||||
addPlistDictionaryKey (*dict, "CFBundleVersion", currentProjectVersion);
|
||||
addPlistDictionaryKey (*dict, "NSHumanReadableCopyright", companyCopyright);
|
||||
addPlistDictionaryKey (*dict, "NSHighResolutionCapable", true);
|
||||
|
||||
if (applicationCategory.isNotEmpty())
|
||||
addPlistDictionaryKey (*dict, "LSApplicationCategoryType", applicationCategory);
|
||||
|
||||
auto replacedDocExtensions = StringArray::fromTokens (replacePreprocessorDefs (allPreprocessorDefs,
|
||||
documentExtensions), ",", {});
|
||||
replacedDocExtensions.trim();
|
||||
replacedDocExtensions.removeEmptyStrings (true);
|
||||
|
||||
if (! replacedDocExtensions.isEmpty() && type != ProjectType::Target::AudioUnitv3PlugIn)
|
||||
{
|
||||
dict->createNewChildElement ("key")->addTextElement ("CFBundleDocumentTypes");
|
||||
auto* dict2 = dict->createNewChildElement ("array")->createNewChildElement ("dict");
|
||||
XmlElement* arrayTag = nullptr;
|
||||
|
||||
for (auto ex : replacedDocExtensions)
|
||||
{
|
||||
if (ex.startsWithChar ('.'))
|
||||
ex = ex.substring (1);
|
||||
|
||||
if (arrayTag == nullptr)
|
||||
{
|
||||
dict2->createNewChildElement ("key")->addTextElement ("CFBundleTypeExtensions");
|
||||
arrayTag = dict2->createNewChildElement ("array");
|
||||
|
||||
addPlistDictionaryKey (*dict2, "CFBundleTypeName", ex);
|
||||
addPlistDictionaryKey (*dict2, "CFBundleTypeRole", "Editor");
|
||||
addPlistDictionaryKey (*dict2, "CFBundleTypeIconFile", "Icon");
|
||||
addPlistDictionaryKey (*dict2, "NSPersistentStoreTypeKey", "XML");
|
||||
addPlistDictionaryKey (*dict2, "LSHandlerRank", "Default");
|
||||
}
|
||||
|
||||
arrayTag->createNewChildElement ("string")->addTextElement (ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (fileSharingEnabled && type != ProjectType::Target::AudioUnitv3PlugIn)
|
||||
addPlistDictionaryKey (*dict, "UIFileSharingEnabled", true);
|
||||
|
||||
if (documentBrowserEnabled)
|
||||
addPlistDictionaryKey (*dict, "UISupportsDocumentBrowser", true);
|
||||
|
||||
if (iOS)
|
||||
{
|
||||
if (type != ProjectType::Target::AudioUnitv3PlugIn)
|
||||
{
|
||||
if (statusBarHidden)
|
||||
addPlistDictionaryKey (*dict, "UIStatusBarHidden", true);
|
||||
|
||||
addPlistDictionaryKey (*dict, "UIRequiresFullScreen", requiresFullScreen);
|
||||
|
||||
addIosScreenOrientations (*dict);
|
||||
addIosBackgroundModes (*dict);
|
||||
}
|
||||
|
||||
if (type == ProjectType::Target::StandalonePlugIn && enableIAA)
|
||||
{
|
||||
XmlElement audioComponentsPlistKey ("key");
|
||||
audioComponentsPlistKey.addTextElement ("AudioComponents");
|
||||
|
||||
dict->addChildElement (new XmlElement (audioComponentsPlistKey));
|
||||
|
||||
XmlElement audioComponentsPlistEntry ("array");
|
||||
auto* audioComponentsDict = audioComponentsPlistEntry.createNewChildElement ("dict");
|
||||
|
||||
addPlistDictionaryKey (*audioComponentsDict, "name", IAAPluginName);
|
||||
addPlistDictionaryKey (*audioComponentsDict, "manufacturer", pluginManufacturerCode.substring (0, 4));
|
||||
addPlistDictionaryKey (*audioComponentsDict, "type", IAATypeCode);
|
||||
addPlistDictionaryKey (*audioComponentsDict, "subtype", pluginCode.substring (0, 4));
|
||||
addPlistDictionaryKey (*audioComponentsDict, "version", getVersionAsHexInteger (marketingVersion));
|
||||
|
||||
dict->addChildElement (new XmlElement (audioComponentsPlistEntry));
|
||||
}
|
||||
}
|
||||
|
||||
const auto extraOptions = [&]() -> Array<XmlElement>
|
||||
{
|
||||
if (type == ProjectType::Target::Type::AudioUnitPlugIn)
|
||||
return createExtraAudioUnitTargetPlistOptions();
|
||||
|
||||
if (type == ProjectType::Target::Type::AudioUnitv3PlugIn)
|
||||
return createExtraAudioUnitV3TargetPlistOptions();
|
||||
|
||||
return {};
|
||||
}();
|
||||
|
||||
for (auto& e : extraOptions)
|
||||
dict->addChildElement (new XmlElement (e));
|
||||
|
||||
return plist;
|
||||
}
|
||||
|
||||
void PlistOptions::addIosScreenOrientations (XmlElement& dict) const
|
||||
{
|
||||
addArrayToPlist (dict, "UISupportedInterfaceOrientations", iPhoneScreenOrientations);
|
||||
|
||||
if (iPadScreenOrientations != iPhoneScreenOrientations)
|
||||
addArrayToPlist (dict, "UISupportedInterfaceOrientations~ipad", iPadScreenOrientations);
|
||||
}
|
||||
|
||||
void PlistOptions::addIosBackgroundModes (XmlElement& dict) const
|
||||
{
|
||||
StringArray iosBackgroundModes;
|
||||
if (backgroundAudioEnabled) iosBackgroundModes.add ("audio");
|
||||
if (backgroundBleEnabled) iosBackgroundModes.add ("bluetooth-central");
|
||||
if (pushNotificationsEnabled) iosBackgroundModes.add ("remote-notification");
|
||||
|
||||
addArrayToPlist (dict, "UIBackgroundModes", iosBackgroundModes);
|
||||
}
|
||||
|
||||
Array<XmlElement> PlistOptions::createExtraAudioUnitTargetPlistOptions() const
|
||||
{
|
||||
XmlElement plistKey ("key");
|
||||
plistKey.addTextElement ("AudioComponents");
|
||||
|
||||
XmlElement plistEntry ("array");
|
||||
auto* dict = plistEntry.createNewChildElement ("dict");
|
||||
|
||||
auto truncatedCode = pluginManufacturerCode.substring (0, 4);
|
||||
auto pluginSubType = pluginCode.substring (0, 4);
|
||||
|
||||
if (truncatedCode.toLowerCase() == truncatedCode)
|
||||
{
|
||||
throw SaveError ("AudioUnit plugin code identifiers invalid!\n\n"
|
||||
"You have used only lower case letters in your AU plugin manufacturer identifier. "
|
||||
"You must have at least one uppercase letter in your AU plugin manufacturer "
|
||||
"identifier code.");
|
||||
}
|
||||
|
||||
addPlistDictionaryKey (*dict, "name", pluginManufacturer + ": " + pluginName);
|
||||
addPlistDictionaryKey (*dict, "description", pluginDescription);
|
||||
addPlistDictionaryKey (*dict, "factoryFunction", pluginAUExportPrefix + "Factory");
|
||||
addPlistDictionaryKey (*dict, "manufacturer", truncatedCode);
|
||||
addPlistDictionaryKey (*dict, "type", auMainType.removeCharacters ("'"));
|
||||
addPlistDictionaryKey (*dict, "subtype", pluginSubType);
|
||||
addPlistDictionaryKey (*dict, "version", getAUVersionAsHexInteger (*this));
|
||||
|
||||
if (isAuSandboxSafe)
|
||||
{
|
||||
addPlistDictionaryKey (*dict, "sandboxSafe", true);
|
||||
}
|
||||
else if (! suppressResourceUsage)
|
||||
{
|
||||
dict->createNewChildElement ("key")->addTextElement ("resourceUsage");
|
||||
auto* resourceUsageDict = dict->createNewChildElement ("dict");
|
||||
|
||||
addPlistDictionaryKey (*resourceUsageDict, "network.client", true);
|
||||
addPlistDictionaryKey (*resourceUsageDict, "temporary-exception.files.all.read-write", true);
|
||||
}
|
||||
|
||||
if (isPluginARAEffect)
|
||||
{
|
||||
dict->createNewChildElement ("key")->addTextElement ("tags");
|
||||
auto* tagsArray = dict->createNewChildElement ("array");
|
||||
tagsArray->createNewChildElement ("string")->addTextElement ("ARA");
|
||||
}
|
||||
|
||||
return { plistKey, plistEntry };
|
||||
}
|
||||
|
||||
Array<XmlElement> PlistOptions::createExtraAudioUnitV3TargetPlistOptions() const
|
||||
{
|
||||
XmlElement plistKey ("key");
|
||||
plistKey.addTextElement ("NSExtension");
|
||||
|
||||
XmlElement plistEntry ("dict");
|
||||
|
||||
addPlistDictionaryKey (plistEntry, "NSExtensionPrincipalClass", pluginAUExportPrefix + "FactoryAUv3");
|
||||
addPlistDictionaryKey (plistEntry, "NSExtensionPointIdentifier", "com.apple.AudioUnit-UI");
|
||||
plistEntry.createNewChildElement ("key")->addTextElement ("NSExtensionAttributes");
|
||||
|
||||
auto* dict = plistEntry.createNewChildElement ("dict");
|
||||
dict->createNewChildElement ("key")->addTextElement ("AudioComponents");
|
||||
auto* componentArray = dict->createNewChildElement ("array");
|
||||
|
||||
auto* componentDict = componentArray->createNewChildElement ("dict");
|
||||
|
||||
addPlistDictionaryKey (*componentDict, "name", pluginManufacturer + ": " + pluginName);
|
||||
addPlistDictionaryKey (*componentDict, "description", pluginDescription);
|
||||
addPlistDictionaryKey (*componentDict, "factoryFunction", pluginAUExportPrefix + "FactoryAUv3");
|
||||
addPlistDictionaryKey (*componentDict, "manufacturer", pluginManufacturerCode.substring (0, 4));
|
||||
addPlistDictionaryKey (*componentDict, "type", auMainType.removeCharacters ("'"));
|
||||
addPlistDictionaryKey (*componentDict, "subtype", pluginCode.substring (0, 4));
|
||||
addPlistDictionaryKey (*componentDict, "version", getAUVersionAsHexInteger (*this));
|
||||
addPlistDictionaryKey (*componentDict, "sandboxSafe", true);
|
||||
|
||||
componentDict->createNewChildElement ("key")->addTextElement ("tags");
|
||||
auto* tagsArray = componentDict->createNewChildElement ("array");
|
||||
|
||||
tagsArray->createNewChildElement ("string")
|
||||
->addTextElement (isPluginSynth ? "Synth" : "Effects");
|
||||
|
||||
if (auMainType.removeCharacters ("'") == "aumi")
|
||||
tagsArray->createNewChildElement ("string")->addTextElement ("MIDI");
|
||||
|
||||
return { plistKey, plistEntry };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,106 +1,107 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
class PlistOptions final
|
||||
{
|
||||
public:
|
||||
void write (const File& infoPlistFile) const;
|
||||
|
||||
//==============================================================================
|
||||
ProjectType::Target::Type type = ProjectType::Target::Type::GUIApp;
|
||||
|
||||
String executableName;
|
||||
String bundleIdentifier;
|
||||
|
||||
String plistToMerge;
|
||||
|
||||
bool iOS = false;
|
||||
|
||||
bool microphonePermissionEnabled = false;
|
||||
String microphonePermissionText;
|
||||
|
||||
bool cameraPermissionEnabled = false;
|
||||
String cameraPermissionText;
|
||||
|
||||
bool bluetoothPermissionEnabled = false;
|
||||
String bluetoothPermissionText;
|
||||
|
||||
bool sendAppleEventsPermissionEnabled = false;
|
||||
String sendAppleEventsPermissionText;
|
||||
|
||||
bool shouldAddStoryboardToProject = false;
|
||||
String storyboardName;
|
||||
|
||||
File iconFile;
|
||||
String projectName;
|
||||
String marketingVersion;
|
||||
String currentProjectVersion;
|
||||
String companyCopyright;
|
||||
|
||||
String applicationCategory;
|
||||
|
||||
StringPairArray allPreprocessorDefs;
|
||||
String documentExtensions;
|
||||
|
||||
bool fileSharingEnabled = false;
|
||||
bool documentBrowserEnabled = false;
|
||||
bool statusBarHidden = false;
|
||||
bool requiresFullScreen = false;
|
||||
bool backgroundAudioEnabled = false;
|
||||
bool backgroundBleEnabled = false;
|
||||
bool pushNotificationsEnabled = false;
|
||||
|
||||
bool enableIAA = false;
|
||||
String IAAPluginName;
|
||||
String pluginManufacturerCode;
|
||||
String IAATypeCode;
|
||||
String pluginCode;
|
||||
|
||||
StringArray iPhoneScreenOrientations;
|
||||
StringArray iPadScreenOrientations;
|
||||
|
||||
String pluginName;
|
||||
String pluginManufacturer;
|
||||
String pluginDescription;
|
||||
String pluginAUExportPrefix;
|
||||
String auMainType;
|
||||
bool isAuSandboxSafe = false;
|
||||
bool isPluginSynth = false;
|
||||
bool suppressResourceUsage = false;
|
||||
|
||||
private:
|
||||
void write (MemoryOutputStream&) const;
|
||||
std::unique_ptr<XmlElement> createXML() const;
|
||||
void addIosScreenOrientations (XmlElement&) const;
|
||||
void addIosBackgroundModes (XmlElement&) const;
|
||||
Array<XmlElement> createExtraAudioUnitTargetPlistOptions() const;
|
||||
Array<XmlElement> createExtraAudioUnitV3TargetPlistOptions() const;
|
||||
};
|
||||
}
|
||||
}
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
class PlistOptions final
|
||||
{
|
||||
public:
|
||||
void write (const File& infoPlistFile) const;
|
||||
|
||||
//==============================================================================
|
||||
ProjectType::Target::Type type = ProjectType::Target::Type::GUIApp;
|
||||
|
||||
String executableName;
|
||||
String bundleIdentifier;
|
||||
|
||||
String plistToMerge;
|
||||
|
||||
bool iOS = false;
|
||||
|
||||
bool microphonePermissionEnabled = false;
|
||||
String microphonePermissionText;
|
||||
|
||||
bool cameraPermissionEnabled = false;
|
||||
String cameraPermissionText;
|
||||
|
||||
bool bluetoothPermissionEnabled = false;
|
||||
String bluetoothPermissionText;
|
||||
|
||||
bool sendAppleEventsPermissionEnabled = false;
|
||||
String sendAppleEventsPermissionText;
|
||||
|
||||
bool shouldAddStoryboardToProject = false;
|
||||
String storyboardName;
|
||||
|
||||
File iconFile;
|
||||
String projectName;
|
||||
String marketingVersion;
|
||||
String currentProjectVersion;
|
||||
String companyCopyright;
|
||||
|
||||
String applicationCategory;
|
||||
|
||||
StringPairArray allPreprocessorDefs;
|
||||
String documentExtensions;
|
||||
|
||||
bool fileSharingEnabled = false;
|
||||
bool documentBrowserEnabled = false;
|
||||
bool statusBarHidden = false;
|
||||
bool requiresFullScreen = false;
|
||||
bool backgroundAudioEnabled = false;
|
||||
bool backgroundBleEnabled = false;
|
||||
bool pushNotificationsEnabled = false;
|
||||
|
||||
bool enableIAA = false;
|
||||
String IAAPluginName;
|
||||
String pluginManufacturerCode;
|
||||
String IAATypeCode;
|
||||
String pluginCode;
|
||||
|
||||
StringArray iPhoneScreenOrientations;
|
||||
StringArray iPadScreenOrientations;
|
||||
|
||||
String pluginName;
|
||||
String pluginManufacturer;
|
||||
String pluginDescription;
|
||||
String pluginAUExportPrefix;
|
||||
String auMainType;
|
||||
bool isAuSandboxSafe = false;
|
||||
bool isPluginSynth = false;
|
||||
bool suppressResourceUsage = false;
|
||||
bool isPluginARAEffect = false;
|
||||
|
||||
private:
|
||||
void write (MemoryOutputStream&) const;
|
||||
std::unique_ptr<XmlElement> createXML() const;
|
||||
void addIosScreenOrientations (XmlElement&) const;
|
||||
void addIosBackgroundModes (XmlElement&) const;
|
||||
Array<XmlElement> createExtraAudioUnitTargetPlistOptions() const;
|
||||
Array<XmlElement> createExtraAudioUnitV3TargetPlistOptions() const;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,275 +1,319 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
//==============================================================================
|
||||
class ProjectType
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
virtual ~ProjectType() { getAllTypes().removeFirstMatchingValue (this); }
|
||||
|
||||
const String& getType() const noexcept { return type; }
|
||||
const String& getDescription() const noexcept { return desc; }
|
||||
|
||||
//==============================================================================
|
||||
static Array<ProjectType*> getAllTypes();
|
||||
static const ProjectType* findType (const String& typeCode)
|
||||
{
|
||||
const auto& types = getAllTypes();
|
||||
|
||||
for (auto i = types.size(); --i >= 0;)
|
||||
if (types.getUnchecked(i)->getType() == typeCode)
|
||||
return types.getUnchecked(i);
|
||||
|
||||
jassertfalse;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
virtual bool isStaticLibrary() const { return false; }
|
||||
virtual bool isDynamicLibrary() const { return false; }
|
||||
virtual bool isGUIApplication() const { return false; }
|
||||
virtual bool isCommandLineApp() const { return false; }
|
||||
virtual bool isAudioPlugin() const { return false; }
|
||||
|
||||
//==============================================================================
|
||||
struct Target
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
GUIApp = 0,
|
||||
ConsoleApp = 1,
|
||||
StaticLibrary = 2,
|
||||
DynamicLibrary = 3,
|
||||
|
||||
VSTPlugIn = 10,
|
||||
VST3PlugIn = 11,
|
||||
AAXPlugIn = 12,
|
||||
RTASPlugIn = 13,
|
||||
AudioUnitPlugIn = 14,
|
||||
AudioUnitv3PlugIn = 15,
|
||||
StandalonePlugIn = 16,
|
||||
UnityPlugIn = 17,
|
||||
|
||||
SharedCodeTarget = 20, // internal
|
||||
AggregateTarget = 21,
|
||||
|
||||
unspecified = 30
|
||||
};
|
||||
|
||||
enum TargetFileType
|
||||
{
|
||||
executable = 0,
|
||||
staticLibrary = 1,
|
||||
sharedLibraryOrDLL = 2,
|
||||
pluginBundle = 3,
|
||||
macOSAppex = 4,
|
||||
unknown = 5
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
explicit Target (Type targetType) : type (targetType) {}
|
||||
|
||||
const char* getName() const noexcept
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GUIApp: return "App";
|
||||
case ConsoleApp: return "ConsoleApp";
|
||||
case StaticLibrary: return "Static Library";
|
||||
case DynamicLibrary: return "Dynamic Library";
|
||||
case VSTPlugIn: return "VST";
|
||||
case VST3PlugIn: return "VST3";
|
||||
case AudioUnitPlugIn: return "AU";
|
||||
case StandalonePlugIn: return "Standalone Plugin";
|
||||
case AudioUnitv3PlugIn: return "AUv3 AppExtension";
|
||||
case AAXPlugIn: return "AAX";
|
||||
case RTASPlugIn: return "RTAS";
|
||||
case UnityPlugIn: return "Unity Plugin";
|
||||
case SharedCodeTarget: return "Shared Code";
|
||||
case AggregateTarget: return "All";
|
||||
case unspecified:
|
||||
default: break;
|
||||
}
|
||||
|
||||
return "undefined";
|
||||
}
|
||||
|
||||
static Type typeFromName (const String& name)
|
||||
{
|
||||
if (name == "App") return Type::GUIApp;
|
||||
if (name == "ConsoleApp") return Type::ConsoleApp;
|
||||
if (name == "Static Library") return Type::StaticLibrary;
|
||||
if (name == "Dynamic Library") return Type::DynamicLibrary;
|
||||
if (name == "VST") return Type::VSTPlugIn;
|
||||
if (name == "VST3") return Type::VST3PlugIn;
|
||||
if (name == "AU") return Type::AudioUnitPlugIn;
|
||||
if (name == "Standalone Plugin") return Type::StandalonePlugIn;
|
||||
if (name == "AUv3 AppExtension") return Type::AudioUnitv3PlugIn;
|
||||
if (name == "AAX") return Type::AAXPlugIn;
|
||||
if (name == "RTAS") return Type::RTASPlugIn;
|
||||
if (name == "Unity Plugin") return Type::UnityPlugIn;
|
||||
if (name == "Shared Code") return Type::SharedCodeTarget;
|
||||
if (name == "All") return Type::AggregateTarget;
|
||||
|
||||
jassertfalse;
|
||||
return Type::ConsoleApp;
|
||||
}
|
||||
|
||||
TargetFileType getTargetFileType() const noexcept
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GUIApp: return executable;
|
||||
case ConsoleApp: return executable;
|
||||
case StaticLibrary: return staticLibrary;
|
||||
case DynamicLibrary: return sharedLibraryOrDLL;
|
||||
case VSTPlugIn: return pluginBundle;
|
||||
case VST3PlugIn: return pluginBundle;
|
||||
case AudioUnitPlugIn: return pluginBundle;
|
||||
case StandalonePlugIn: return executable;
|
||||
case AudioUnitv3PlugIn: return macOSAppex;
|
||||
case AAXPlugIn: return pluginBundle;
|
||||
case RTASPlugIn: return pluginBundle;
|
||||
case UnityPlugIn: return pluginBundle;
|
||||
case SharedCodeTarget: return staticLibrary;
|
||||
case AggregateTarget:
|
||||
case unspecified:
|
||||
default: break;
|
||||
}
|
||||
|
||||
return unknown;
|
||||
}
|
||||
|
||||
const Type type;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
Target& operator= (const Target&) = delete;
|
||||
};
|
||||
|
||||
virtual bool supportsTargetType (Target::Type /*targetType*/) const { return false; }
|
||||
|
||||
protected:
|
||||
ProjectType (const String& t, const String& d)
|
||||
: type (t), desc (d)
|
||||
{}
|
||||
|
||||
private:
|
||||
const String type, desc;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjectType)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
struct ProjectType_GUIApp : public ProjectType
|
||||
{
|
||||
ProjectType_GUIApp() : ProjectType (getTypeName(), "GUI Application") {}
|
||||
|
||||
static const char* getTypeName() noexcept { return "guiapp"; }
|
||||
bool isGUIApplication() const override { return true; }
|
||||
bool supportsTargetType (Target::Type targetType) const override { return (targetType == Target::GUIApp); }
|
||||
};
|
||||
|
||||
struct ProjectType_ConsoleApp : public ProjectType
|
||||
{
|
||||
ProjectType_ConsoleApp() : ProjectType (getTypeName(), "Console Application") {}
|
||||
|
||||
static const char* getTypeName() noexcept { return "consoleapp"; }
|
||||
bool isCommandLineApp() const override { return true; }
|
||||
bool supportsTargetType (Target::Type targetType) const override { return (targetType == Target::ConsoleApp); }
|
||||
};
|
||||
|
||||
struct ProjectType_StaticLibrary : public ProjectType
|
||||
{
|
||||
ProjectType_StaticLibrary() : ProjectType (getTypeName(), "Static Library") {}
|
||||
|
||||
static const char* getTypeName() noexcept { return "library"; }
|
||||
bool isStaticLibrary() const override { return true; }
|
||||
bool supportsTargetType (Target::Type targetType) const override { return (targetType == Target::StaticLibrary); }
|
||||
};
|
||||
|
||||
struct ProjectType_DLL : public ProjectType
|
||||
{
|
||||
ProjectType_DLL() : ProjectType (getTypeName(), "Dynamic Library") {}
|
||||
|
||||
static const char* getTypeName() noexcept { return "dll"; }
|
||||
bool isDynamicLibrary() const override { return true; }
|
||||
bool supportsTargetType (Target::Type targetType) const override { return (targetType == Target::DynamicLibrary); }
|
||||
};
|
||||
|
||||
struct ProjectType_AudioPlugin : public ProjectType
|
||||
{
|
||||
ProjectType_AudioPlugin() : ProjectType (getTypeName(), "Audio Plug-in") {}
|
||||
|
||||
static const char* getTypeName() noexcept { return "audioplug"; }
|
||||
bool isAudioPlugin() const override { return true; }
|
||||
|
||||
bool supportsTargetType (Target::Type targetType) const override
|
||||
{
|
||||
switch (targetType)
|
||||
{
|
||||
case Target::VSTPlugIn:
|
||||
case Target::VST3PlugIn:
|
||||
case Target::AAXPlugIn:
|
||||
case Target::RTASPlugIn:
|
||||
case Target::AudioUnitPlugIn:
|
||||
case Target::AudioUnitv3PlugIn:
|
||||
case Target::StandalonePlugIn:
|
||||
case Target::UnityPlugIn:
|
||||
case Target::SharedCodeTarget:
|
||||
case Target::AggregateTarget:
|
||||
return true;
|
||||
|
||||
case Target::GUIApp:
|
||||
case Target::ConsoleApp:
|
||||
case Target::StaticLibrary:
|
||||
case Target::DynamicLibrary:
|
||||
case Target::unspecified:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
inline Array<ProjectType*> ProjectType::getAllTypes()
|
||||
{
|
||||
static ProjectType_GUIApp guiApp;
|
||||
static ProjectType_ConsoleApp consoleApp;
|
||||
static ProjectType_StaticLibrary staticLib;
|
||||
static ProjectType_DLL dll;
|
||||
static ProjectType_AudioPlugin plugin;
|
||||
|
||||
return Array<ProjectType*>(&guiApp, &consoleApp, &staticLib, &dll, &plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
//==============================================================================
|
||||
class ProjectType
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
virtual ~ProjectType() { getAllTypes().removeFirstMatchingValue (this); }
|
||||
|
||||
const String& getType() const noexcept { return type; }
|
||||
const String& getDescription() const noexcept { return desc; }
|
||||
|
||||
//==============================================================================
|
||||
static Array<ProjectType*> getAllTypes();
|
||||
static const ProjectType* findType (const String& typeCode)
|
||||
{
|
||||
const auto& types = getAllTypes();
|
||||
|
||||
for (auto i = types.size(); --i >= 0;)
|
||||
if (types.getUnchecked(i)->getType() == typeCode)
|
||||
return types.getUnchecked(i);
|
||||
|
||||
jassertfalse;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
virtual bool isStaticLibrary() const { return false; }
|
||||
virtual bool isDynamicLibrary() const { return false; }
|
||||
virtual bool isGUIApplication() const { return false; }
|
||||
virtual bool isCommandLineApp() const { return false; }
|
||||
virtual bool isAudioPlugin() const { return false; }
|
||||
virtual bool isARAAudioPlugin() const { return false; }
|
||||
|
||||
//==============================================================================
|
||||
struct Target
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
GUIApp = 0,
|
||||
ConsoleApp = 1,
|
||||
StaticLibrary = 2,
|
||||
DynamicLibrary = 3,
|
||||
|
||||
VSTPlugIn = 10,
|
||||
VST3PlugIn = 11,
|
||||
AAXPlugIn = 12,
|
||||
|
||||
AudioUnitPlugIn = 14,
|
||||
AudioUnitv3PlugIn = 15,
|
||||
StandalonePlugIn = 16,
|
||||
UnityPlugIn = 17,
|
||||
LV2PlugIn = 18,
|
||||
|
||||
SharedCodeTarget = 20, // internal
|
||||
AggregateTarget = 21,
|
||||
|
||||
LV2TurtleProgram = 25, // internal
|
||||
|
||||
unspecified = 30
|
||||
};
|
||||
|
||||
enum TargetFileType
|
||||
{
|
||||
executable = 0,
|
||||
staticLibrary = 1,
|
||||
sharedLibraryOrDLL = 2,
|
||||
pluginBundle = 3,
|
||||
macOSAppex = 4,
|
||||
unknown = 5
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
explicit Target (Type targetType) : type (targetType) {}
|
||||
|
||||
const char* getName() const noexcept
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GUIApp: return "App";
|
||||
case ConsoleApp: return "ConsoleApp";
|
||||
case StaticLibrary: return "Static Library";
|
||||
case DynamicLibrary: return "Dynamic Library";
|
||||
case VSTPlugIn: return "VST";
|
||||
case VST3PlugIn: return "VST3";
|
||||
case AudioUnitPlugIn: return "AU";
|
||||
case StandalonePlugIn: return "Standalone Plugin";
|
||||
case AudioUnitv3PlugIn: return "AUv3 AppExtension";
|
||||
case AAXPlugIn: return "AAX";
|
||||
case UnityPlugIn: return "Unity Plugin";
|
||||
case LV2PlugIn: return "LV2 Plugin";
|
||||
case SharedCodeTarget: return "Shared Code";
|
||||
case AggregateTarget: return "All";
|
||||
case LV2TurtleProgram: return "LV2 Manifest Helper";
|
||||
case unspecified: break;
|
||||
}
|
||||
|
||||
return "undefined";
|
||||
}
|
||||
|
||||
static Type typeFromName (const String& name)
|
||||
{
|
||||
if (name == "App") return Type::GUIApp;
|
||||
if (name == "ConsoleApp") return Type::ConsoleApp;
|
||||
if (name == "Static Library") return Type::StaticLibrary;
|
||||
if (name == "Dynamic Library") return Type::DynamicLibrary;
|
||||
if (name == "VST") return Type::VSTPlugIn;
|
||||
if (name == "VST3") return Type::VST3PlugIn;
|
||||
if (name == "AU") return Type::AudioUnitPlugIn;
|
||||
if (name == "Standalone Plugin") return Type::StandalonePlugIn;
|
||||
if (name == "AUv3 AppExtension") return Type::AudioUnitv3PlugIn;
|
||||
if (name == "AAX") return Type::AAXPlugIn;
|
||||
if (name == "Unity Plugin") return Type::UnityPlugIn;
|
||||
if (name == "LV2 Plugin") return Type::LV2PlugIn;
|
||||
if (name == "Shared Code") return Type::SharedCodeTarget;
|
||||
if (name == "All") return Type::AggregateTarget;
|
||||
if (name == "LV2 Manifest Helper") return Type::LV2TurtleProgram;
|
||||
|
||||
jassertfalse;
|
||||
return Type::ConsoleApp;
|
||||
}
|
||||
|
||||
TargetFileType getTargetFileType() const noexcept
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GUIApp: return executable;
|
||||
case ConsoleApp: return executable;
|
||||
case StaticLibrary: return staticLibrary;
|
||||
case DynamicLibrary: return sharedLibraryOrDLL;
|
||||
case VSTPlugIn: return pluginBundle;
|
||||
case VST3PlugIn: return pluginBundle;
|
||||
case AudioUnitPlugIn: return pluginBundle;
|
||||
case StandalonePlugIn: return executable;
|
||||
case AudioUnitv3PlugIn: return macOSAppex;
|
||||
case AAXPlugIn: return pluginBundle;
|
||||
case UnityPlugIn: return pluginBundle;
|
||||
case LV2PlugIn: return pluginBundle;
|
||||
case SharedCodeTarget: return staticLibrary;
|
||||
case LV2TurtleProgram: return executable;
|
||||
case AggregateTarget:
|
||||
case unspecified:
|
||||
break;
|
||||
}
|
||||
|
||||
return unknown;
|
||||
}
|
||||
|
||||
const Type type;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
Target& operator= (const Target&) = delete;
|
||||
};
|
||||
|
||||
virtual bool supportsTargetType (Target::Type /*targetType*/) const { return false; }
|
||||
|
||||
protected:
|
||||
ProjectType (const String& t, const String& d)
|
||||
: type (t), desc (d)
|
||||
{}
|
||||
|
||||
private:
|
||||
const String type, desc;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjectType)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
struct ProjectType_GUIApp : public ProjectType
|
||||
{
|
||||
ProjectType_GUIApp() : ProjectType (getTypeName(), "GUI Application") {}
|
||||
|
||||
static const char* getTypeName() noexcept { return "guiapp"; }
|
||||
bool isGUIApplication() const override { return true; }
|
||||
bool supportsTargetType (Target::Type targetType) const override { return (targetType == Target::GUIApp); }
|
||||
};
|
||||
|
||||
struct ProjectType_ConsoleApp : public ProjectType
|
||||
{
|
||||
ProjectType_ConsoleApp() : ProjectType (getTypeName(), "Console Application") {}
|
||||
|
||||
static const char* getTypeName() noexcept { return "consoleapp"; }
|
||||
bool isCommandLineApp() const override { return true; }
|
||||
bool supportsTargetType (Target::Type targetType) const override { return (targetType == Target::ConsoleApp); }
|
||||
};
|
||||
|
||||
struct ProjectType_StaticLibrary : public ProjectType
|
||||
{
|
||||
ProjectType_StaticLibrary() : ProjectType (getTypeName(), "Static Library") {}
|
||||
|
||||
static const char* getTypeName() noexcept { return "library"; }
|
||||
bool isStaticLibrary() const override { return true; }
|
||||
bool supportsTargetType (Target::Type targetType) const override { return (targetType == Target::StaticLibrary); }
|
||||
};
|
||||
|
||||
struct ProjectType_DLL : public ProjectType
|
||||
{
|
||||
ProjectType_DLL() : ProjectType (getTypeName(), "Dynamic Library") {}
|
||||
|
||||
static const char* getTypeName() noexcept { return "dll"; }
|
||||
bool isDynamicLibrary() const override { return true; }
|
||||
bool supportsTargetType (Target::Type targetType) const override { return (targetType == Target::DynamicLibrary); }
|
||||
};
|
||||
|
||||
struct ProjectType_AudioPlugin : public ProjectType
|
||||
{
|
||||
ProjectType_AudioPlugin() : ProjectType (getTypeName(), "Audio Plug-in") {}
|
||||
|
||||
static const char* getTypeName() noexcept { return "audioplug"; }
|
||||
bool isAudioPlugin() const override { return true; }
|
||||
|
||||
bool supportsTargetType (Target::Type targetType) const override
|
||||
{
|
||||
switch (targetType)
|
||||
{
|
||||
case Target::VSTPlugIn:
|
||||
case Target::VST3PlugIn:
|
||||
case Target::AAXPlugIn:
|
||||
case Target::AudioUnitPlugIn:
|
||||
case Target::AudioUnitv3PlugIn:
|
||||
case Target::StandalonePlugIn:
|
||||
case Target::UnityPlugIn:
|
||||
case Target::LV2PlugIn:
|
||||
case Target::LV2TurtleProgram:
|
||||
case Target::SharedCodeTarget:
|
||||
case Target::AggregateTarget:
|
||||
return true;
|
||||
|
||||
case Target::GUIApp:
|
||||
case Target::ConsoleApp:
|
||||
case Target::StaticLibrary:
|
||||
case Target::DynamicLibrary:
|
||||
case Target::unspecified:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct ProjectType_ARAAudioPlugin : public ProjectType
|
||||
{
|
||||
ProjectType_ARAAudioPlugin() : ProjectType (getTypeName(), "ARA Audio Plug-in") {}
|
||||
|
||||
static const char* getTypeName() noexcept { return "araaudioplug"; }
|
||||
bool isAudioPlugin() const override { return true; }
|
||||
bool isARAAudioPlugin() const override { return true; }
|
||||
|
||||
bool supportsTargetType (Target::Type targetType) const override
|
||||
{
|
||||
switch (targetType)
|
||||
{
|
||||
case Target::VSTPlugIn:
|
||||
case Target::VST3PlugIn:
|
||||
case Target::AAXPlugIn:
|
||||
case Target::AudioUnitPlugIn:
|
||||
case Target::AudioUnitv3PlugIn:
|
||||
case Target::StandalonePlugIn:
|
||||
case Target::UnityPlugIn:
|
||||
case Target::SharedCodeTarget:
|
||||
case Target::AggregateTarget:
|
||||
return true;
|
||||
|
||||
case Target::GUIApp:
|
||||
case Target::ConsoleApp:
|
||||
case Target::StaticLibrary:
|
||||
case Target::DynamicLibrary:
|
||||
case Target::unspecified:
|
||||
case Target::LV2PlugIn:
|
||||
case Target::LV2TurtleProgram:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
inline Array<ProjectType*> ProjectType::getAllTypes()
|
||||
{
|
||||
static ProjectType_GUIApp guiApp;
|
||||
static ProjectType_ConsoleApp consoleApp;
|
||||
static ProjectType_StaticLibrary staticLib;
|
||||
static ProjectType_DLL dll;
|
||||
static ProjectType_AudioPlugin plugin;
|
||||
static ProjectType_ARAAudioPlugin araplugin;
|
||||
|
||||
return Array<ProjectType*>(&guiApp, &consoleApp, &staticLib, &dll, &plugin, &araplugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,129 +1,129 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
//==============================================================================
|
||||
/** Manipulates a cross-platform partial file path. (Needed because File is designed
|
||||
for absolute paths on the active OS)
|
||||
*/
|
||||
class RelativePath
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
enum RootFolder
|
||||
{
|
||||
unknown,
|
||||
projectFolder,
|
||||
buildTargetFolder
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
RelativePath()
|
||||
: root (unknown)
|
||||
{}
|
||||
|
||||
RelativePath (const String& relPath, const RootFolder rootType)
|
||||
: path (unixStylePath (relPath)), root (rootType)
|
||||
{}
|
||||
|
||||
RelativePath (const File& file, const File& rootFolder, const RootFolder rootType)
|
||||
: path (unixStylePath (getRelativePathFrom (file, rootFolder))), root (rootType)
|
||||
{}
|
||||
|
||||
RootFolder getRoot() const { return root; }
|
||||
|
||||
String toUnixStyle() const { return unixStylePath (path); }
|
||||
String toWindowsStyle() const { return windowsStylePath (path); }
|
||||
|
||||
String getFileName() const { return getFakeFile().getFileName(); }
|
||||
String getFileNameWithoutExtension() const { return getFakeFile().getFileNameWithoutExtension(); }
|
||||
|
||||
String getFileExtension() const { return getFakeFile().getFileExtension(); }
|
||||
bool hasFileExtension (StringRef extension) const { return getFakeFile().hasFileExtension (extension); }
|
||||
bool isAbsolute() const { return isAbsolutePath (path); }
|
||||
|
||||
RelativePath withFileExtension (const String& extension) const
|
||||
{
|
||||
return RelativePath (path.upToLastOccurrenceOf (".", ! extension.startsWithChar ('.'), false) + extension, root);
|
||||
}
|
||||
|
||||
RelativePath getParentDirectory() const
|
||||
{
|
||||
String p (path);
|
||||
if (path.endsWithChar ('/'))
|
||||
p = p.dropLastCharacters (1);
|
||||
|
||||
return RelativePath (p.upToLastOccurrenceOf ("/", false, false), root);
|
||||
}
|
||||
|
||||
RelativePath getChildFile (const String& subpath) const
|
||||
{
|
||||
if (isAbsolutePath (subpath))
|
||||
return RelativePath (subpath, root);
|
||||
|
||||
String p (toUnixStyle());
|
||||
if (! p.endsWithChar ('/'))
|
||||
p << '/';
|
||||
|
||||
return RelativePath (p + subpath, root);
|
||||
}
|
||||
|
||||
RelativePath rebased (const File& originalRoot, const File& newRoot, const RootFolder newRootType) const
|
||||
{
|
||||
if (isAbsolute())
|
||||
return RelativePath (path, newRootType);
|
||||
|
||||
return RelativePath (getRelativePathFrom (originalRoot.getChildFile (toUnixStyle()), newRoot), newRootType);
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
String path;
|
||||
RootFolder root;
|
||||
|
||||
File getFakeFile() const
|
||||
{
|
||||
#if JUCE_WINDOWS
|
||||
if (isAbsolutePath (path))
|
||||
{
|
||||
// This is a hack to convert unix-style absolute paths into valid absolute Windows paths to avoid hitting
|
||||
// an assertion in File::parseAbsolutePath().
|
||||
if (path.startsWithChar (L'/') || path.startsWithChar (L'$') || path.startsWithChar (L'~'))
|
||||
return File (String ("C:\\") + windowsStylePath (path.substring (1)));
|
||||
|
||||
return File (path);
|
||||
}
|
||||
#endif
|
||||
|
||||
// This method gets called very often, so we'll cache this directory.
|
||||
static const File currentWorkingDirectory (File::getCurrentWorkingDirectory());
|
||||
return currentWorkingDirectory.getChildFile (path);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
//==============================================================================
|
||||
/** Manipulates a cross-platform partial file path. (Needed because File is designed
|
||||
for absolute paths on the active OS)
|
||||
*/
|
||||
class RelativePath
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
enum RootFolder
|
||||
{
|
||||
unknown,
|
||||
projectFolder,
|
||||
buildTargetFolder
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
RelativePath()
|
||||
: root (unknown)
|
||||
{}
|
||||
|
||||
RelativePath (const String& relPath, const RootFolder rootType)
|
||||
: path (unixStylePath (relPath)), root (rootType)
|
||||
{}
|
||||
|
||||
RelativePath (const File& file, const File& rootFolder, const RootFolder rootType)
|
||||
: path (unixStylePath (getRelativePathFrom (file, rootFolder))), root (rootType)
|
||||
{}
|
||||
|
||||
RootFolder getRoot() const { return root; }
|
||||
|
||||
String toUnixStyle() const { return unixStylePath (path); }
|
||||
String toWindowsStyle() const { return windowsStylePath (path); }
|
||||
|
||||
String getFileName() const { return getFakeFile().getFileName(); }
|
||||
String getFileNameWithoutExtension() const { return getFakeFile().getFileNameWithoutExtension(); }
|
||||
|
||||
String getFileExtension() const { return getFakeFile().getFileExtension(); }
|
||||
bool hasFileExtension (StringRef extension) const { return getFakeFile().hasFileExtension (extension); }
|
||||
bool isAbsolute() const { return isAbsolutePath (path); }
|
||||
|
||||
RelativePath withFileExtension (const String& extension) const
|
||||
{
|
||||
return RelativePath (path.upToLastOccurrenceOf (".", ! extension.startsWithChar ('.'), false) + extension, root);
|
||||
}
|
||||
|
||||
RelativePath getParentDirectory() const
|
||||
{
|
||||
String p (path);
|
||||
if (path.endsWithChar ('/'))
|
||||
p = p.dropLastCharacters (1);
|
||||
|
||||
return RelativePath (p.upToLastOccurrenceOf ("/", false, false), root);
|
||||
}
|
||||
|
||||
RelativePath getChildFile (const String& subpath) const
|
||||
{
|
||||
if (isAbsolutePath (subpath))
|
||||
return RelativePath (subpath, root);
|
||||
|
||||
String p (toUnixStyle());
|
||||
if (! p.endsWithChar ('/'))
|
||||
p << '/';
|
||||
|
||||
return RelativePath (p + subpath, root);
|
||||
}
|
||||
|
||||
RelativePath rebased (const File& originalRoot, const File& newRoot, const RootFolder newRootType) const
|
||||
{
|
||||
if (isAbsolute())
|
||||
return RelativePath (path, newRootType);
|
||||
|
||||
return RelativePath (getRelativePathFrom (originalRoot.getChildFile (toUnixStyle()), newRoot), newRootType);
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
String path;
|
||||
RootFolder root;
|
||||
|
||||
File getFakeFile() const
|
||||
{
|
||||
#if JUCE_WINDOWS
|
||||
if (isAbsolutePath (path))
|
||||
{
|
||||
// This is a hack to convert unix-style absolute paths into valid absolute Windows paths to avoid hitting
|
||||
// an assertion in File::parseAbsolutePath().
|
||||
if (path.startsWithChar (L'/') || path.startsWithChar (L'$') || path.startsWithChar (L'~'))
|
||||
return File (String ("C:\\") + windowsStylePath (path.substring (1)));
|
||||
|
||||
return File (path);
|
||||
}
|
||||
#endif
|
||||
|
||||
// This method gets called very often, so we'll cache this directory.
|
||||
static const File currentWorkingDirectory (File::getCurrentWorkingDirectory());
|
||||
return currentWorkingDirectory.getChildFile (path);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,91 +1,91 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
uint64 calculateStreamHashCode (InputStream& in)
|
||||
{
|
||||
uint64 t = 0;
|
||||
|
||||
const int bufferSize = 4096;
|
||||
HeapBlock<uint8> buffer;
|
||||
buffer.malloc (bufferSize);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
auto num = in.read (buffer, bufferSize);
|
||||
|
||||
if (num <= 0)
|
||||
break;
|
||||
|
||||
for (int i = 0; i < num; ++i)
|
||||
t = t * 65599 + buffer[i];
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
uint64 calculateFileHashCode (const File& file)
|
||||
{
|
||||
std::unique_ptr<FileInputStream> stream (file.createInputStream());
|
||||
return stream != nullptr ? calculateStreamHashCode (*stream) : 0;
|
||||
}
|
||||
|
||||
uint64 calculateMemoryHashCode (const void* data, size_t numBytes)
|
||||
{
|
||||
uint64 t = 0;
|
||||
|
||||
for (size_t i = 0; i < numBytes; ++i)
|
||||
t = t * 65599 + static_cast<const uint8*> (data)[i];
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
bool overwriteFileWithNewDataIfDifferent (const File& file, const void* data, size_t numBytes)
|
||||
{
|
||||
if (file.getSize() == (int64) numBytes
|
||||
&& calculateMemoryHashCode (data, numBytes) == calculateFileHashCode (file))
|
||||
return true;
|
||||
|
||||
if (file.exists())
|
||||
return file.replaceWithData (data, numBytes);
|
||||
|
||||
return file.getParentDirectory().createDirectory() && file.appendData (data, numBytes);
|
||||
}
|
||||
|
||||
bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData)
|
||||
{
|
||||
return overwriteFileWithNewDataIfDifferent (file, newData.getData(), newData.getDataSize());
|
||||
}
|
||||
|
||||
bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData)
|
||||
{
|
||||
const char* const utf8 = newData.toUTF8();
|
||||
return overwriteFileWithNewDataIfDifferent (file, utf8, strlen (utf8));
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
uint64 calculateStreamHashCode (InputStream& in)
|
||||
{
|
||||
uint64 t = 0;
|
||||
|
||||
const int bufferSize = 4096;
|
||||
HeapBlock<uint8> buffer;
|
||||
buffer.malloc (bufferSize);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
auto num = in.read (buffer, bufferSize);
|
||||
|
||||
if (num <= 0)
|
||||
break;
|
||||
|
||||
for (int i = 0; i < num; ++i)
|
||||
t = t * 65599 + buffer[i];
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
uint64 calculateFileHashCode (const File& file)
|
||||
{
|
||||
std::unique_ptr<FileInputStream> stream (file.createInputStream());
|
||||
return stream != nullptr ? calculateStreamHashCode (*stream) : 0;
|
||||
}
|
||||
|
||||
uint64 calculateMemoryHashCode (const void* data, size_t numBytes)
|
||||
{
|
||||
uint64 t = 0;
|
||||
|
||||
for (size_t i = 0; i < numBytes; ++i)
|
||||
t = t * 65599 + static_cast<const uint8*> (data)[i];
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
bool overwriteFileWithNewDataIfDifferent (const File& file, const void* data, size_t numBytes)
|
||||
{
|
||||
if (file.getSize() == (int64) numBytes
|
||||
&& calculateMemoryHashCode (data, numBytes) == calculateFileHashCode (file))
|
||||
return true;
|
||||
|
||||
if (file.exists())
|
||||
return file.replaceWithData (data, numBytes);
|
||||
|
||||
return file.getParentDirectory().createDirectory() && file.appendData (data, numBytes);
|
||||
}
|
||||
|
||||
bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData)
|
||||
{
|
||||
return overwriteFileWithNewDataIfDifferent (file, newData.getData(), newData.getDataSize());
|
||||
}
|
||||
|
||||
bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData)
|
||||
{
|
||||
const char* const utf8 = newData.toUTF8();
|
||||
return overwriteFileWithNewDataIfDifferent (file, utf8, strlen (utf8));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,38 +1,38 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
uint64 calculateStreamHashCode (InputStream& in);
|
||||
uint64 calculateFileHashCode (const File& file);
|
||||
uint64 calculateMemoryHashCode (const void* data, size_t numBytes);
|
||||
|
||||
bool overwriteFileWithNewDataIfDifferent (const File& file, const void* data, size_t numBytes);
|
||||
bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData);
|
||||
bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData);
|
||||
}
|
||||
}
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
uint64 calculateStreamHashCode (InputStream& in);
|
||||
uint64 calculateFileHashCode (const File& file);
|
||||
uint64 calculateMemoryHashCode (const void* data, size_t numBytes);
|
||||
|
||||
bool overwriteFileWithNewDataIfDifferent (const File& file, const void* data, size_t numBytes);
|
||||
bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData);
|
||||
bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData);
|
||||
}
|
||||
}
|
||||
|
@ -1,97 +1,97 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
static String getCommaSeparatedVersionNumber (const String& version)
|
||||
{
|
||||
auto versionParts = StringArray::fromTokens (version, ",.", "");
|
||||
versionParts.trim();
|
||||
versionParts.removeEmptyStrings();
|
||||
while (versionParts.size() < 4)
|
||||
versionParts.add ("0");
|
||||
|
||||
return versionParts.joinIntoString (",");
|
||||
}
|
||||
|
||||
void ResourceRcOptions::write (const File& resourceRcFile) const
|
||||
{
|
||||
MemoryOutputStream mo;
|
||||
|
||||
mo << "#pragma code_page(65001)" << newLine
|
||||
<< newLine
|
||||
<< "#ifdef JUCE_USER_DEFINED_RC_FILE" << newLine
|
||||
<< " #include JUCE_USER_DEFINED_RC_FILE" << newLine
|
||||
<< "#else" << newLine
|
||||
<< newLine
|
||||
<< "#undef WIN32_LEAN_AND_MEAN" << newLine
|
||||
<< "#define WIN32_LEAN_AND_MEAN" << newLine
|
||||
<< "#include <windows.h>" << newLine
|
||||
<< newLine
|
||||
<< "VS_VERSION_INFO VERSIONINFO" << newLine
|
||||
<< "FILEVERSION " << getCommaSeparatedVersionNumber (version) << newLine
|
||||
<< "BEGIN" << newLine
|
||||
<< " BLOCK \"StringFileInfo\"" << newLine
|
||||
<< " BEGIN" << newLine
|
||||
<< " BLOCK \"040904E4\"" << newLine
|
||||
<< " BEGIN" << newLine;
|
||||
|
||||
const auto writeRCValue = [&] (const String& n, const String& value)
|
||||
{
|
||||
if (value.isNotEmpty())
|
||||
mo << " VALUE \"" << n << "\", \""
|
||||
<< value.replace ("\"", "\"\"") << "\\0\"" << newLine;
|
||||
};
|
||||
|
||||
writeRCValue ("CompanyName", companyName);
|
||||
writeRCValue ("LegalCopyright", companyCopyright);
|
||||
writeRCValue ("FileDescription", projectName);
|
||||
writeRCValue ("FileVersion", version);
|
||||
writeRCValue ("ProductName", projectName);
|
||||
writeRCValue ("ProductVersion", version);
|
||||
|
||||
mo << " END" << newLine
|
||||
<< " END" << newLine
|
||||
<< newLine
|
||||
<< " BLOCK \"VarFileInfo\"" << newLine
|
||||
<< " BEGIN" << newLine
|
||||
<< " VALUE \"Translation\", 0x409, 1252" << newLine
|
||||
<< " END" << newLine
|
||||
<< "END" << newLine
|
||||
<< newLine
|
||||
<< "#endif" << newLine;
|
||||
|
||||
if (icon.existsAsFile())
|
||||
mo << newLine
|
||||
<< "IDI_ICON1 ICON DISCARDABLE " << icon.getFileName().quoted()
|
||||
<< newLine
|
||||
<< "IDI_ICON2 ICON DISCARDABLE " << icon.getFileName().quoted();
|
||||
|
||||
overwriteFileIfDifferentOrThrow (resourceRcFile, mo);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
static String getCommaSeparatedVersionNumber (const String& version)
|
||||
{
|
||||
auto versionParts = StringArray::fromTokens (version, ",.", "");
|
||||
versionParts.trim();
|
||||
versionParts.removeEmptyStrings();
|
||||
while (versionParts.size() < 4)
|
||||
versionParts.add ("0");
|
||||
|
||||
return versionParts.joinIntoString (",");
|
||||
}
|
||||
|
||||
void ResourceRcOptions::write (const File& resourceRcFile) const
|
||||
{
|
||||
MemoryOutputStream mo;
|
||||
|
||||
mo << "#pragma code_page(65001)" << newLine
|
||||
<< newLine
|
||||
<< "#ifdef JUCE_USER_DEFINED_RC_FILE" << newLine
|
||||
<< " #include JUCE_USER_DEFINED_RC_FILE" << newLine
|
||||
<< "#else" << newLine
|
||||
<< newLine
|
||||
<< "#undef WIN32_LEAN_AND_MEAN" << newLine
|
||||
<< "#define WIN32_LEAN_AND_MEAN" << newLine
|
||||
<< "#include <windows.h>" << newLine
|
||||
<< newLine
|
||||
<< "VS_VERSION_INFO VERSIONINFO" << newLine
|
||||
<< "FILEVERSION " << getCommaSeparatedVersionNumber (version) << newLine
|
||||
<< "BEGIN" << newLine
|
||||
<< " BLOCK \"StringFileInfo\"" << newLine
|
||||
<< " BEGIN" << newLine
|
||||
<< " BLOCK \"040904E4\"" << newLine
|
||||
<< " BEGIN" << newLine;
|
||||
|
||||
const auto writeRCValue = [&] (const String& n, const String& value)
|
||||
{
|
||||
if (value.isNotEmpty())
|
||||
mo << " VALUE \"" << n << "\", \""
|
||||
<< value.replace ("\"", "\"\"") << "\\0\"" << newLine;
|
||||
};
|
||||
|
||||
writeRCValue ("CompanyName", companyName);
|
||||
writeRCValue ("LegalCopyright", companyCopyright);
|
||||
writeRCValue ("FileDescription", projectName);
|
||||
writeRCValue ("FileVersion", version);
|
||||
writeRCValue ("ProductName", projectName);
|
||||
writeRCValue ("ProductVersion", version);
|
||||
|
||||
mo << " END" << newLine
|
||||
<< " END" << newLine
|
||||
<< newLine
|
||||
<< " BLOCK \"VarFileInfo\"" << newLine
|
||||
<< " BEGIN" << newLine
|
||||
<< " VALUE \"Translation\", 0x409, 1252" << newLine
|
||||
<< " END" << newLine
|
||||
<< "END" << newLine
|
||||
<< newLine
|
||||
<< "#endif" << newLine;
|
||||
|
||||
if (icon.existsAsFile())
|
||||
mo << newLine
|
||||
<< "IDI_ICON1 ICON DISCARDABLE " << icon.getFileName().quoted()
|
||||
<< newLine
|
||||
<< "IDI_ICON2 ICON DISCARDABLE " << icon.getFileName().quoted();
|
||||
|
||||
overwriteFileIfDifferentOrThrow (resourceRcFile, mo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,43 +1,43 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
class ResourceRcOptions final
|
||||
{
|
||||
public:
|
||||
void write (const File& resourceRcFile) const;
|
||||
|
||||
//==============================================================================
|
||||
String version;
|
||||
String companyName;
|
||||
String companyCopyright;
|
||||
String projectName;
|
||||
File icon;
|
||||
};
|
||||
}
|
||||
}
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
class ResourceRcOptions final
|
||||
{
|
||||
public:
|
||||
void write (const File& resourceRcFile) const;
|
||||
|
||||
//==============================================================================
|
||||
String version;
|
||||
String companyName;
|
||||
String companyCopyright;
|
||||
String projectName;
|
||||
File icon;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,60 +1,60 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
StringArray getVersionSegments (StringRef p)
|
||||
{
|
||||
auto segments = StringArray::fromTokens (p, ",.", "");
|
||||
segments.trim();
|
||||
segments.removeEmptyStrings();
|
||||
return segments;
|
||||
}
|
||||
|
||||
int getVersionAsHexIntegerFromParts (const StringArray& segments)
|
||||
{
|
||||
auto value = (segments[0].getIntValue() << 16)
|
||||
+ (segments[1].getIntValue() << 8)
|
||||
+ segments[2].getIntValue();
|
||||
|
||||
if (segments.size() > 3)
|
||||
value = (value << 8) + segments[3].getIntValue();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
int getVersionAsHexInteger (StringRef versionString)
|
||||
{
|
||||
return getVersionAsHexIntegerFromParts (getVersionSegments (versionString));
|
||||
}
|
||||
|
||||
String getVersionAsHex (StringRef versionString)
|
||||
{
|
||||
return "0x" + String::toHexString (getVersionAsHexInteger (versionString));
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
StringArray getVersionSegments (StringRef p)
|
||||
{
|
||||
auto segments = StringArray::fromTokens (p, ",.", "");
|
||||
segments.trim();
|
||||
segments.removeEmptyStrings();
|
||||
return segments;
|
||||
}
|
||||
|
||||
int getVersionAsHexIntegerFromParts (const StringArray& segments)
|
||||
{
|
||||
auto value = (segments[0].getIntValue() << 16)
|
||||
+ (segments[1].getIntValue() << 8)
|
||||
+ segments[2].getIntValue();
|
||||
|
||||
if (segments.size() > 3)
|
||||
value = (value << 8) + segments[3].getIntValue();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
int getVersionAsHexInteger (StringRef versionString)
|
||||
{
|
||||
return getVersionAsHexIntegerFromParts (getVersionSegments (versionString));
|
||||
}
|
||||
|
||||
String getVersionAsHex (StringRef versionString)
|
||||
{
|
||||
return "0x" + String::toHexString (getVersionAsHexInteger (versionString));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,37 +1,37 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
StringArray getVersionSegments (StringRef p);
|
||||
|
||||
int getVersionAsHexIntegerFromParts (const StringArray& versionString);
|
||||
int getVersionAsHexInteger (StringRef versionString);
|
||||
|
||||
String getVersionAsHex (StringRef versionString);
|
||||
}
|
||||
}
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
namespace build_tools
|
||||
{
|
||||
StringArray getVersionSegments (StringRef p);
|
||||
|
||||
int getVersionAsHexIntegerFromParts (const StringArray& versionString);
|
||||
int getVersionAsHexInteger (StringRef versionString);
|
||||
|
||||
String getVersionAsHex (StringRef versionString);
|
||||
}
|
||||
}
|
||||
|
28
deps/juce/extras/Build/juceaide/CMakeLists.txt
vendored
28
deps/juce/extras/Build/juceaide/CMakeLists.txt
vendored
@ -1,15 +1,15 @@
|
||||
# ==============================================================================
|
||||
#
|
||||
# This file is part of the JUCE library.
|
||||
# Copyright (c) 2020 - Raw Material Software Limited
|
||||
# Copyright (c) 2022 - Raw Material Software Limited
|
||||
#
|
||||
# JUCE is an open source library subject to commercial or open-source
|
||||
# licensing.
|
||||
#
|
||||
# By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
# Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
# By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
# Agreement and JUCE Privacy Policy.
|
||||
#
|
||||
# End User License Agreement: www.juce.com/juce-6-licence
|
||||
# End User License Agreement: www.juce.com/juce-7-licence
|
||||
# Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
#
|
||||
# Or: You may also use this code under the terms of the GPL v3 (see
|
||||
@ -53,20 +53,32 @@ else()
|
||||
# environment variables, which is unfortunate because we really don't want to cross-compile
|
||||
# juceaide. If you really want to set the compilers for juceaide, pass the appropriate
|
||||
# CMAKE_<lang>_COMPILER flags when configuring CMake.
|
||||
unset(ENV{ASM})
|
||||
unset(ENV{CC})
|
||||
unset(ENV{CXX})
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
unset(ENV{ASM})
|
||||
unset(ENV{CC})
|
||||
unset(ENV{CXX})
|
||||
else()
|
||||
# When building with clang-cl in Clion on Windows for an x64 target, the ABI detection phase
|
||||
# of the inner build can fail unless we pass through these flags too
|
||||
set(extra_configure_flags
|
||||
"-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}"
|
||||
"-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}"
|
||||
"-DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS}"
|
||||
"-DCMAKE_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM}")
|
||||
endif()
|
||||
|
||||
message(STATUS "Configuring juceaide")
|
||||
|
||||
# Looks like we're boostrapping, reinvoke CMake
|
||||
# Looks like we're bootstrapping, reinvoke CMake
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}"
|
||||
"."
|
||||
"-B${JUCE_BINARY_DIR}/tools"
|
||||
"-G${CMAKE_GENERATOR}"
|
||||
"-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}"
|
||||
"-DCMAKE_BUILD_TYPE=Debug"
|
||||
"-DJUCE_BUILD_HELPER_TOOLS=ON"
|
||||
"-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}"
|
||||
${extra_configure_flags}
|
||||
WORKING_DIRECTORY "${JUCE_SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE command_output
|
||||
ERROR_VARIABLE command_output
|
||||
|
1092
deps/juce/extras/Build/juceaide/Main.cpp
vendored
1092
deps/juce/extras/Build/juceaide/Main.cpp
vendored
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user