git subrepo clone --branch=sono6good https://github.com/essej/JUCE.git deps/juce
subrepo: subdir: "deps/juce" merged: "b13f9084e" upstream: origin: "https://github.com/essej/JUCE.git" branch: "sono6good" commit: "b13f9084e" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596"
This commit is contained in:
86
deps/juce/extras/Build/CMake/JUCECheckAtomic.cmake
vendored
Normal file
86
deps/juce/extras/Build/CMake/JUCECheckAtomic.cmake
vendored
Normal file
@ -0,0 +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.
|
||||
#
|
||||
# ==============================================================================
|
||||
|
||||
function(_juce_create_atomic_target target_name)
|
||||
add_library("${target_name}" INTERFACE)
|
||||
add_library("juce::${target_name}" ALIAS "${target_name}")
|
||||
|
||||
if(NOT ((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD")))
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(test_file_contents
|
||||
[[
|
||||
#include <atomic>
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
std::atomic<long long> ll { static_cast<long long> (argc) };
|
||||
ll ^= 1;
|
||||
return static_cast<int> (ll);
|
||||
}
|
||||
]])
|
||||
|
||||
string(RANDOM LENGTH 16 random_file_string)
|
||||
set(test_file_name "${CMAKE_CURRENT_BINARY_DIR}/check_atomic_${random_file_string}.cpp")
|
||||
|
||||
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}")
|
||||
|
||||
try_compile(compile_result "${test_bindir}" "${test_file_name}"
|
||||
OUTPUT_VARIABLE test_build_output_0
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD_REQUIRED TRUE
|
||||
CXX_EXTENSIONS FALSE)
|
||||
|
||||
if(NOT compile_result)
|
||||
try_compile(compile_result "${test_bindir}" "${test_file_name}"
|
||||
OUTPUT_VARIABLE test_build_output_1
|
||||
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\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.")
|
||||
endif()
|
||||
|
||||
target_link_libraries("${target_name}" INTERFACE atomic)
|
||||
endif()
|
||||
|
||||
file(REMOVE "${test_file_name}")
|
||||
file(REMOVE_RECURSE "${test_bindir}")
|
||||
endfunction()
|
||||
|
||||
_juce_create_atomic_target(juce_atomic_wrapper)
|
||||
|
90
deps/juce/extras/Build/CMake/JUCEConfig.cmake.in
vendored
Normal file
90
deps/juce/extras/Build/CMake/JUCEConfig.cmake.in
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
# ==============================================================================
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# The code included in this file is provided under the terms of the ISC license
|
||||
# http://www.isc.org/downloads/software-support-policy/isc-license. Permission
|
||||
# To use, copy, modify, and/or distribute this software for any purpose with or
|
||||
# without fee is hereby granted provided that the above copyright notice and
|
||||
# this permission notice appear in all copies.
|
||||
#
|
||||
# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
# DISCLAIMED.
|
||||
#
|
||||
# ==============================================================================
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
if(NOT TARGET juce::juceaide)
|
||||
add_executable(juce::juceaide IMPORTED)
|
||||
set_target_properties(juce::juceaide PROPERTIES
|
||||
IMPORTED_LOCATION "@PACKAGE_JUCEAIDE_PATH@")
|
||||
endif()
|
||||
|
||||
check_required_components("@PROJECT_NAME@")
|
||||
|
||||
set(JUCE_MODULES_DIR "@PACKAGE_JUCE_MODULE_PATH@" CACHE INTERNAL
|
||||
"The path to JUCE modules")
|
||||
|
||||
include("@PACKAGE_UTILS_INSTALL_DIR@/JUCEModuleSupport.cmake")
|
||||
include("@PACKAGE_UTILS_INSTALL_DIR@/JUCEUtils.cmake")
|
||||
|
||||
set(_juce_modules
|
||||
juce_analytics
|
||||
juce_audio_basics
|
||||
juce_audio_devices
|
||||
juce_audio_formats
|
||||
juce_audio_plugin_client
|
||||
juce_audio_processors
|
||||
juce_audio_utils
|
||||
juce_box2d
|
||||
juce_core
|
||||
juce_cryptography
|
||||
juce_data_structures
|
||||
juce_dsp
|
||||
juce_events
|
||||
juce_graphics
|
||||
juce_gui_basics
|
||||
juce_gui_extra
|
||||
juce_opengl
|
||||
juce_osc
|
||||
juce_product_unlocking
|
||||
juce_video)
|
||||
|
||||
set(_targets_defined)
|
||||
set(_targets_expected)
|
||||
|
||||
foreach(_juce_module IN LISTS _juce_modules)
|
||||
list(APPEND _targets_expected ${_juce_module} juce::${_juce_modules})
|
||||
if(TARGET ${_juce_module})
|
||||
list(APPEND _targets_defined ${_juce_module})
|
||||
endif()
|
||||
|
||||
if(TARGET juce::${_juce_module})
|
||||
list(APPEND _targets_defined juce::${_juce_module})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if("${_targets_defined}" STREQUAL "${_targets_expected}")
|
||||
unset(_targets_defined)
|
||||
unset(_targets_expected)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(NOT "${_targets_defined}" STREQUAL "")
|
||||
message(FATAL_ERROR "Some targets in this export set were already defined.")
|
||||
endif()
|
||||
|
||||
unset(_targets_defined)
|
||||
unset(_targets_expected)
|
||||
|
||||
foreach(_juce_module IN LISTS _juce_modules)
|
||||
juce_add_module("@PACKAGE_JUCE_MODULE_PATH@/${_juce_module}" ALIAS_NAMESPACE juce)
|
||||
endforeach()
|
||||
|
||||
unset(_juce_modules)
|
61
deps/juce/extras/Build/CMake/JUCEHelperTargets.cmake
vendored
Normal file
61
deps/juce/extras/Build/CMake/JUCEHelperTargets.cmake
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
add_library(juce_recommended_warning_flags INTERFACE)
|
||||
add_library(juce::juce_recommended_warning_flags ALIAS juce_recommended_warning_flags)
|
||||
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC"))
|
||||
target_compile_options(juce_recommended_warning_flags INTERFACE "/W4")
|
||||
elseif((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") OR (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang"))
|
||||
target_compile_options(juce_recommended_warning_flags INTERFACE
|
||||
-Wall -Wshadow-all -Wshorten-64-to-32 -Wstrict-aliasing
|
||||
-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
|
||||
-Wnullable-to-nonnull-conversion -Wno-ignored-qualifiers -Wswitch-enum
|
||||
-Wpedantic
|
||||
$<$<OR:$<COMPILE_LANGUAGE:CXX>,$<COMPILE_LANGUAGE:OBJCXX>>:
|
||||
-Wzero-as-null-pointer-constant -Wunused-private-field
|
||||
-Woverloaded-virtual -Wreorder
|
||||
-Winconsistent-missing-destructor-override>)
|
||||
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
|
||||
-Wredundant-decls -Wno-strict-overflow -Wshadow
|
||||
$<$<COMPILE_LANGUAGE:CXX>:
|
||||
-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant>)
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
|
||||
add_library(juce_recommended_config_flags INTERFACE)
|
||||
add_library(juce::juce_recommended_config_flags ALIAS juce_recommended_config_flags)
|
||||
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC"))
|
||||
target_compile_options(juce_recommended_config_flags INTERFACE
|
||||
$<IF:$<CONFIG:Debug>,/Od /Zi,/Ox> $<$<STREQUAL:"${CMAKE_CXX_COMPILER_ID}","MSVC">:/MP> /EHsc)
|
||||
elseif((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_config_flags INTERFACE
|
||||
$<$<CONFIG:Debug>:-g -O0>
|
||||
$<$<CONFIG:Release>:-O3>)
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
|
||||
add_library(juce_recommended_lto_flags INTERFACE)
|
||||
add_library(juce::juce_recommended_lto_flags ALIAS juce_recommended_lto_flags)
|
||||
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC"))
|
||||
target_compile_options(juce_recommended_lto_flags INTERFACE
|
||||
$<$<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"))
|
||||
target_compile_options(juce_recommended_lto_flags INTERFACE $<$<CONFIG:Release>:-flto>)
|
||||
target_link_libraries(juce_recommended_lto_flags INTERFACE $<$<CONFIG:Release>:-flto>)
|
||||
endif()
|
592
deps/juce/extras/Build/CMake/JUCEModuleSupport.cmake
vendored
Normal file
592
deps/juce/extras/Build/CMake/JUCEModuleSupport.cmake
vendored
Normal file
@ -0,0 +1,592 @@
|
||||
# ==============================================================================
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# ==============================================================================
|
||||
|
||||
# ==================================================================================================
|
||||
# JUCE Modules Support Helper Functions
|
||||
#
|
||||
# In this file, functions intended for use by end-users have the prefix `juce_`.
|
||||
# Functions beginning with an underscore should be considered private and susceptible to
|
||||
# change, so don't call them directly.
|
||||
#
|
||||
# See the readme at `docs/CMake API.md` for more information about CMake usage,
|
||||
# including documentation of the public functions in this file.
|
||||
# ==================================================================================================
|
||||
|
||||
include_guard(GLOBAL)
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
# ==================================================================================================
|
||||
|
||||
set(JUCE_CMAKE_UTILS_DIR ${CMAKE_CURRENT_LIST_DIR}
|
||||
CACHE INTERNAL "The path to the folder holding this file and other resources")
|
||||
|
||||
include("${JUCE_CMAKE_UTILS_DIR}/JUCEHelperTargets.cmake")
|
||||
include("${JUCE_CMAKE_UTILS_DIR}/JUCECheckAtomic.cmake")
|
||||
|
||||
# Tries to discover the target platform architecture, which is necessary for
|
||||
# naming VST3 bundle folders and including bundled libraries from modules
|
||||
function(_juce_find_target_architecture result)
|
||||
set(test_file "${JUCE_CMAKE_UTILS_DIR}/juce_runtime_arch_detection.cpp")
|
||||
try_compile(compile_result "${CMAKE_CURRENT_BINARY_DIR}" "${test_file}"
|
||||
OUTPUT_VARIABLE compile_output)
|
||||
string(REGEX REPLACE ".*JUCE_ARCH ([a-zA-Z0-9_-]*).*" "\\1" match_result "${compile_output}")
|
||||
set("${result}" "${match_result}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
if((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD") OR MSYS OR MINGW)
|
||||
# If you really need to override the detected arch for some reason,
|
||||
# you can configure the build with -DJUCE_TARGET_ARCHITECTURE=<custom arch>
|
||||
if(NOT DEFINED JUCE_TARGET_ARCHITECTURE)
|
||||
_juce_find_target_architecture(target_arch)
|
||||
set(JUCE_TARGET_ARCHITECTURE "${target_arch}"
|
||||
CACHE INTERNAL "The target architecture, used to name internal folders in VST3 bundles, and to locate bundled libraries in modules")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
|
||||
function(_juce_add_interface_library target)
|
||||
add_library(${target} INTERFACE)
|
||||
target_sources(${target} INTERFACE ${ARGN})
|
||||
endfunction()
|
||||
|
||||
# ==================================================================================================
|
||||
|
||||
function(_juce_add_standard_defs juce_target)
|
||||
target_compile_definitions(${juce_target} INTERFACE
|
||||
JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1
|
||||
$<IF:$<CONFIG:DEBUG>,DEBUG=1 _DEBUG=1,NDEBUG=1 _NDEBUG=1>
|
||||
$<$<PLATFORM_ID:Android>:JUCE_ANDROID=1>)
|
||||
endfunction()
|
||||
|
||||
# ==================================================================================================
|
||||
|
||||
macro(_juce_make_absolute path)
|
||||
if(NOT IS_ABSOLUTE "${${path}}")
|
||||
get_filename_component("${path}" "${${path}}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(_juce_make_absolute_and_check path)
|
||||
_juce_make_absolute("${path}")
|
||||
|
||||
if(NOT EXISTS "${${path}}")
|
||||
message(FATAL_ERROR "No file at path ${${path}}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# ==================================================================================================
|
||||
|
||||
# This creates an imported interface library with a random name, and then adds
|
||||
# the fields from a JUCE module header to the target as INTERFACE_ properties.
|
||||
# We can extract properties later using `_juce_get_metadata`.
|
||||
# This way, the interface library ends up behaving a bit like a dictionary,
|
||||
# and we don't have to parse the module header from scratch every time we
|
||||
# want to find a specific key.
|
||||
function(_juce_extract_metadata_block delim_str file_with_block out_dict)
|
||||
string(RANDOM LENGTH 16 random_string)
|
||||
set(target_name "${random_string}_dict")
|
||||
set(${out_dict} "${target_name}" PARENT_SCOPE)
|
||||
add_library(${target_name} INTERFACE IMPORTED)
|
||||
|
||||
if(NOT EXISTS ${file_with_block})
|
||||
message(FATAL_ERROR "Unable to find file ${file_with_block}")
|
||||
endif()
|
||||
|
||||
file(STRINGS ${file_with_block} module_header_contents)
|
||||
|
||||
set(last_written_key)
|
||||
set(append NO)
|
||||
|
||||
foreach(line IN LISTS module_header_contents)
|
||||
if(NOT append)
|
||||
if(line MATCHES " *BEGIN_${delim_str} *")
|
||||
set(append YES)
|
||||
endif()
|
||||
|
||||
continue()
|
||||
endif()
|
||||
|
||||
if(append AND (line MATCHES " *END_${delim_str} *"))
|
||||
break()
|
||||
endif()
|
||||
|
||||
if(line MATCHES "^ *([a-zA-Z]+):")
|
||||
set(last_written_key "${CMAKE_MATCH_1}")
|
||||
endif()
|
||||
|
||||
string(REGEX REPLACE "^ *${last_written_key}: *" "" line "${line}")
|
||||
string(REGEX REPLACE "[ ,]+" ";" line "${line}")
|
||||
|
||||
set_property(TARGET ${target_name} APPEND PROPERTY
|
||||
"INTERFACE_JUCE_${last_written_key}" "${line}")
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# Fetches properties attached to a metadata target.
|
||||
function(_juce_get_metadata target key out_var)
|
||||
get_target_property(content "${target}" "INTERFACE_JUCE_${key}")
|
||||
|
||||
if(NOT "${content}" STREQUAL "content-NOTFOUND")
|
||||
set(${out_var} "${content}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# ==================================================================================================
|
||||
|
||||
function(_juce_should_build_module_source filename output_var)
|
||||
get_filename_component(trimmed_name "${filename}" NAME_WE)
|
||||
|
||||
set(result TRUE)
|
||||
|
||||
set(pairs
|
||||
"OSX\;Darwin"
|
||||
"Windows\;Windows"
|
||||
"Linux\;Linux"
|
||||
"Android\;Android"
|
||||
"iOS\;iOS")
|
||||
|
||||
foreach(pair IN LISTS pairs)
|
||||
list(GET pair 0 suffix)
|
||||
list(GET pair 1 system_name)
|
||||
|
||||
if((trimmed_name MATCHES "_${suffix}$") AND NOT (CMAKE_SYSTEM_NAME STREQUAL "${system_name}"))
|
||||
set(result FALSE)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set("${output_var}" "${result}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(_juce_module_sources module_path output_path built_sources other_sources)
|
||||
get_filename_component(module_parent_path ${module_path} DIRECTORY)
|
||||
get_filename_component(module_glob ${module_path} NAME)
|
||||
|
||||
file(GLOB_RECURSE all_module_files
|
||||
CONFIGURE_DEPENDS LIST_DIRECTORIES FALSE
|
||||
RELATIVE "${module_parent_path}"
|
||||
"${module_path}/*")
|
||||
|
||||
set(base_path "${module_glob}/${module_glob}")
|
||||
|
||||
set(module_cpp ${all_module_files})
|
||||
list(FILTER module_cpp INCLUDE REGEX "^${base_path}[^/]*\\.(c|cc|cpp|cxx|s|asm)$")
|
||||
|
||||
if(APPLE)
|
||||
set(module_mm ${all_module_files})
|
||||
list(FILTER module_mm INCLUDE REGEX "^${base_path}[^/]*\\.mm$")
|
||||
|
||||
if(module_mm)
|
||||
set(module_mm_replaced ${module_mm})
|
||||
list(TRANSFORM module_mm_replaced REPLACE "\\.mm$" ".cpp")
|
||||
list(REMOVE_ITEM module_cpp ${module_mm_replaced})
|
||||
endif()
|
||||
|
||||
set(module_apple_files ${all_module_files})
|
||||
list(FILTER module_apple_files INCLUDE REGEX "${base_path}[^/]*\\.(m|mm|metal|r|swift)$")
|
||||
list(APPEND module_cpp ${module_apple_files})
|
||||
endif()
|
||||
|
||||
set(headers ${all_module_files})
|
||||
|
||||
set(module_files_to_build)
|
||||
|
||||
foreach(filename IN LISTS module_cpp)
|
||||
_juce_should_build_module_source("${filename}" should_build_file)
|
||||
|
||||
if(should_build_file)
|
||||
list(APPEND module_files_to_build "${filename}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(NOT "${module_files_to_build}" STREQUAL "")
|
||||
list(REMOVE_ITEM headers ${module_files_to_build})
|
||||
endif()
|
||||
|
||||
foreach(source_list IN ITEMS module_files_to_build headers)
|
||||
list(TRANSFORM ${source_list} PREPEND "${output_path}/")
|
||||
endforeach()
|
||||
|
||||
set(${built_sources} ${module_files_to_build} PARENT_SCOPE)
|
||||
set(${other_sources} ${headers} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# ==================================================================================================
|
||||
|
||||
function(_juce_get_all_plugin_kinds out)
|
||||
set(${out} AU AUv3 AAX Standalone Unity VST VST3 PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(_juce_get_platform_plugin_kinds out)
|
||||
set(result Standalone)
|
||||
|
||||
if(APPLE AND (CMAKE_GENERATOR STREQUAL "Xcode"))
|
||||
list(APPEND result AUv3)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
list(APPEND result AU)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_SYSTEM_NAME STREQUAL "iOS" AND NOT CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
list(APPEND result AAX Unity VST VST3)
|
||||
endif()
|
||||
|
||||
set(${out} ${result} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(_juce_add_plugin_definitions target visibility)
|
||||
_juce_get_all_plugin_kinds(options)
|
||||
cmake_parse_arguments(JUCE_ARG "${options}" "" "" ${ARGN})
|
||||
|
||||
foreach(opt IN LISTS options)
|
||||
set(flag_value 0)
|
||||
|
||||
if(JUCE_ARG_${opt})
|
||||
set(flag_value 1)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(${target} ${visibility} "JucePlugin_Build_${opt}=${flag_value}")
|
||||
endforeach()
|
||||
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`.
|
||||
function(_juce_link_frameworks target visibility)
|
||||
foreach(framework IN LISTS ARGN)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
find_library("juce_found_${framework}" "${framework}" REQUIRED)
|
||||
target_link_libraries("${target}" "${visibility}" "${juce_found_${framework}}")
|
||||
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))
|
||||
set(framework_flags "-weak_framework ${framework}")
|
||||
else()
|
||||
set(framework_flags "-framework ${framework}")
|
||||
endif()
|
||||
|
||||
target_link_libraries("${target}" "${visibility}" "${framework_flags}")
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# ==================================================================================================
|
||||
|
||||
function(_juce_add_plugin_wrapper_target format path out_path)
|
||||
_juce_module_sources("${path}" "${out_path}" out_var headers)
|
||||
list(FILTER out_var EXCLUDE REGEX "/juce_audio_plugin_client_utils.cpp$")
|
||||
set(target_name juce_audio_plugin_client_${format})
|
||||
|
||||
_juce_add_interface_library("${target_name}" ${out_var})
|
||||
_juce_add_plugin_definitions("${target_name}" INTERFACE ${format})
|
||||
_juce_add_standard_defs("${target_name}")
|
||||
|
||||
target_compile_features("${target_name}" INTERFACE cxx_std_14)
|
||||
add_library("juce::${target_name}" ALIAS "${target_name}")
|
||||
|
||||
if(format STREQUAL "AUv3")
|
||||
_juce_link_frameworks("${target_name}" INTERFACE AVFoundation)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
_juce_link_frameworks("${target_name}" INTERFACE AudioUnit)
|
||||
endif()
|
||||
elseif(format STREQUAL "AU")
|
||||
_juce_link_frameworks("${target_name}" INTERFACE AudioUnit CoreAudioKit)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# ==================================================================================================
|
||||
|
||||
function(_juce_link_libs_from_metadata module_name dict key)
|
||||
_juce_get_metadata("${dict}" "${key}" libs)
|
||||
|
||||
if(libs)
|
||||
target_link_libraries(${module_name} INTERFACE ${libs})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# ==================================================================================================
|
||||
|
||||
function(_juce_create_pkgconfig_target name)
|
||||
if(TARGET juce::pkgconfig_${name})
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(${name} ${ARGN})
|
||||
|
||||
add_library(pkgconfig_${name} INTERFACE)
|
||||
add_library(juce::pkgconfig_${name} ALIAS pkgconfig_${name})
|
||||
install(TARGETS pkgconfig_${name} EXPORT JUCE)
|
||||
|
||||
set(pairs
|
||||
"INCLUDE_DIRECTORIES\;INCLUDE_DIRS"
|
||||
"LINK_LIBRARIES\;LINK_LIBRARIES"
|
||||
"LINK_OPTIONS\;LDFLAGS_OTHER"
|
||||
"COMPILE_OPTIONS\;CFLAGS_OTHER")
|
||||
|
||||
foreach(pair IN LISTS pairs)
|
||||
list(GET pair 0 key)
|
||||
list(GET pair 1 value)
|
||||
|
||||
if(${name}_${value})
|
||||
set_target_properties(pkgconfig_${name} PROPERTIES INTERFACE_${key} "${${name}_${value}}")
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# ==================================================================================================
|
||||
|
||||
function(_juce_add_library_path target path)
|
||||
if(EXISTS "${path}")
|
||||
target_link_directories(${target} INTERFACE ${path})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(_juce_add_module_staticlib_paths module_target module_path)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
_juce_add_library_path(${module_target} "${module_path}/libs/MacOSX")
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||
_juce_add_library_path(${module_target} "${module_path}/libs/iOS")
|
||||
elseif((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD"))
|
||||
_juce_add_library_path(${module_target} "${module_path}/libs/Linux/${JUCE_TARGET_ARCHITECTURE}")
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
if(CMAKE_GENERATOR MATCHES "Visual Studio [0-9]+ (20[0-9]+)")
|
||||
set(arch "$<IF:$<EQUAL:${CMAKE_SIZEOF_VOID_P},8>,x64,Win32>")
|
||||
|
||||
if(NOT CMAKE_GENERATOR_PLATFORM STREQUAL "")
|
||||
set(arch ${CMAKE_GENERATOR_PLATFORM})
|
||||
endif()
|
||||
|
||||
set(runtime_lib "$<GENEX_EVAL:$<TARGET_PROPERTY:MSVC_RUNTIME_LIBRARY>>")
|
||||
set(subfolder "MDd")
|
||||
set(subfolder "$<IF:$<STREQUAL:${runtime_lib},MultiThreadedDebug>,MTd,${subfolder}>")
|
||||
set(subfolder "$<IF:$<STREQUAL:${runtime_lib},MultiThreadedDLL>,MD,${subfolder}>")
|
||||
set(subfolder "$<IF:$<STREQUAL:${runtime_lib},MultiThreaded>,MT,${subfolder}>")
|
||||
target_link_directories(${module_target} INTERFACE
|
||||
"${module_path}/libs/VisualStudio${CMAKE_MATCH_1}/${arch}/${subfolder}")
|
||||
elseif(MSYS OR MINGW)
|
||||
_juce_add_library_path(${module_target} "${module_path}/libs/MinGW/${JUCE_TARGET_ARCHITECTURE}")
|
||||
endif()
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
_juce_add_library_path(${module_target} "${module_path}/libs/Android/${CMAKE_ANDROID_ARCH_ABI}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# ==================================================================================================
|
||||
|
||||
function(juce_add_module module_path)
|
||||
set(one_value_args INSTALL_PATH ALIAS_NAMESPACE)
|
||||
cmake_parse_arguments(JUCE_ARG "" "${one_value_args}" "" ${ARGN})
|
||||
|
||||
_juce_make_absolute(module_path)
|
||||
|
||||
get_filename_component(module_name ${module_path} NAME)
|
||||
get_filename_component(module_parent_path ${module_path} DIRECTORY)
|
||||
|
||||
set(module_header_name "${module_name}.h")
|
||||
|
||||
if(NOT EXISTS "${module_path}/${module_header_name}")
|
||||
set(module_header_name "${module_header_name}pp")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${module_path}/${module_header_name}")
|
||||
message(FATAL_ERROR "Could not locate module header for module '${module_path}'")
|
||||
endif()
|
||||
|
||||
set(base_path "${module_parent_path}")
|
||||
|
||||
_juce_module_sources("${module_path}" "${base_path}" globbed_sources headers)
|
||||
|
||||
if(${module_name} STREQUAL "juce_audio_plugin_client")
|
||||
_juce_get_platform_plugin_kinds(plugin_kinds)
|
||||
|
||||
foreach(kind IN LISTS plugin_kinds)
|
||||
_juce_add_plugin_wrapper_target(${kind} "${module_path}" "${base_path}")
|
||||
endforeach()
|
||||
|
||||
set(utils_source
|
||||
"${base_path}/${module_name}/juce_audio_plugin_client_utils.cpp")
|
||||
add_library(juce_audio_plugin_client_utils INTERFACE)
|
||||
target_sources(juce_audio_plugin_client_utils INTERFACE "${utils_source}")
|
||||
|
||||
if(JUCE_ARG_ALIAS_NAMESPACE)
|
||||
add_library(${JUCE_ARG_ALIAS_NAMESPACE}::juce_audio_plugin_client_utils
|
||||
ALIAS juce_audio_plugin_client_utils)
|
||||
endif()
|
||||
|
||||
file(GLOB_RECURSE all_module_files
|
||||
CONFIGURE_DEPENDS LIST_DIRECTORIES FALSE
|
||||
RELATIVE "${module_parent_path}"
|
||||
"${module_path}/*")
|
||||
else()
|
||||
list(APPEND all_module_sources ${globbed_sources})
|
||||
endif()
|
||||
|
||||
_juce_add_interface_library(${module_name} ${all_module_sources})
|
||||
|
||||
set_property(GLOBAL APPEND PROPERTY _juce_module_names ${module_name})
|
||||
|
||||
set_target_properties(${module_name} PROPERTIES
|
||||
INTERFACE_JUCE_MODULE_SOURCES "${globbed_sources}"
|
||||
INTERFACE_JUCE_MODULE_HEADERS "${headers}"
|
||||
INTERFACE_JUCE_MODULE_PATH "${base_path}")
|
||||
|
||||
if(JUCE_ENABLE_MODULE_SOURCE_GROUPS)
|
||||
target_sources(${module_name} INTERFACE ${headers})
|
||||
endif()
|
||||
|
||||
if(${module_name} STREQUAL "juce_core")
|
||||
_juce_add_standard_defs(${module_name})
|
||||
|
||||
target_link_libraries(juce_core INTERFACE juce::juce_atomic_wrapper)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES ".*BSD")
|
||||
target_link_libraries(juce_core INTERFACE execinfo)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
target_sources(juce_core INTERFACE "${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c")
|
||||
target_include_directories(juce_core INTERFACE "${ANDROID_NDK}/sources/android/cpufeatures")
|
||||
target_link_libraries(juce_core INTERFACE android log)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(${module_name} STREQUAL "juce_audio_processors")
|
||||
add_library(juce_vst3_headers INTERFACE)
|
||||
|
||||
target_compile_definitions(juce_vst3_headers INTERFACE "$<$<TARGET_EXISTS:juce_vst3_sdk>:JUCE_CUSTOM_VST3_SDK=1>")
|
||||
|
||||
target_include_directories(juce_vst3_headers INTERFACE
|
||||
"$<$<TARGET_EXISTS:juce_vst3_sdk>:$<TARGET_PROPERTY:juce_vst3_sdk,INTERFACE_INCLUDE_DIRECTORIES>>"
|
||||
"$<$<NOT:$<TARGET_EXISTS:juce_vst3_sdk>>:${base_path}/juce_audio_processors/format_types/VST3_SDK>")
|
||||
|
||||
target_link_libraries(juce_audio_processors INTERFACE juce_vst3_headers)
|
||||
|
||||
if(JUCE_ARG_ALIAS_NAMESPACE)
|
||||
add_library(${JUCE_ARG_ALIAS_NAMESPACE}::juce_vst3_headers ALIAS juce_vst3_headers)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_include_directories(${module_name} INTERFACE ${base_path})
|
||||
|
||||
target_compile_definitions(${module_name} INTERFACE JUCE_MODULE_AVAILABLE_${module_name}=1)
|
||||
|
||||
if((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD"))
|
||||
target_compile_definitions(${module_name} INTERFACE LINUX=1)
|
||||
endif()
|
||||
|
||||
_juce_extract_metadata_block(JUCE_MODULE_DECLARATION "${module_path}/${module_header_name}" metadata_dict)
|
||||
|
||||
_juce_get_metadata("${metadata_dict}" minimumCppStandard module_cpp_standard)
|
||||
|
||||
if(module_cpp_standard)
|
||||
target_compile_features(${module_name} INTERFACE cxx_std_${module_cpp_standard})
|
||||
else()
|
||||
target_compile_features(${module_name} INTERFACE cxx_std_11)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
_juce_get_metadata("${metadata_dict}" OSXFrameworks 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_link_libs_from_metadata("${module_name}" "${metadata_dict}" OSXLibs)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||
_juce_get_metadata("${metadata_dict}" iOSFrameworks 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_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)
|
||||
|
||||
if(module_linuxpackages)
|
||||
_juce_create_pkgconfig_target(${module_name}_LINUX_DEPS ${module_linuxpackages})
|
||||
target_link_libraries(${module_name} INTERFACE juce::pkgconfig_${module_name}_LINUX_DEPS)
|
||||
endif()
|
||||
|
||||
_juce_link_libs_from_metadata("${module_name}" "${metadata_dict}" linuxLibs)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC"))
|
||||
if(module_name STREQUAL "juce_gui_basics")
|
||||
target_compile_options(${module_name} INTERFACE /bigobj)
|
||||
endif()
|
||||
|
||||
_juce_link_libs_from_metadata("${module_name}" "${metadata_dict}" windowsLibs)
|
||||
elseif(MSYS OR MINGW)
|
||||
if(module_name STREQUAL "juce_gui_basics")
|
||||
target_compile_options(${module_name} INTERFACE "-Wa,-mbig-obj")
|
||||
endif()
|
||||
|
||||
_juce_link_libs_from_metadata("${module_name}" "${metadata_dict}" mingwLibs)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
_juce_get_metadata("${metadata_dict}" dependencies module_dependencies)
|
||||
target_link_libraries(${module_name} INTERFACE ${module_dependencies})
|
||||
|
||||
_juce_get_metadata("${metadata_dict}" searchpaths module_searchpaths)
|
||||
|
||||
if(NOT module_searchpaths STREQUAL "")
|
||||
foreach(module_searchpath IN LISTS module_searchpaths)
|
||||
target_include_directories(${module_name}
|
||||
INTERFACE "${module_path}/${module_searchpath}")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
_juce_add_module_staticlib_paths("${module_name}" "${module_path}")
|
||||
|
||||
if(JUCE_ARG_INSTALL_PATH)
|
||||
install(DIRECTORY "${module_path}" DESTINATION "${JUCE_ARG_INSTALL_PATH}")
|
||||
endif()
|
||||
|
||||
if(JUCE_ARG_ALIAS_NAMESPACE)
|
||||
add_library(${JUCE_ARG_ALIAS_NAMESPACE}::${module_name} ALIAS ${module_name})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(juce_add_modules)
|
||||
set(one_value_args INSTALL_PATH ALIAS_NAMESPACE)
|
||||
cmake_parse_arguments(JUCE_ARG "" "${one_value_args}" "" ${ARGN})
|
||||
|
||||
foreach(path IN LISTS JUCE_ARG_UNPARSED_ARGUMENTS)
|
||||
juce_add_module(${path}
|
||||
INSTALL_PATH "${JUCE_ARG_INSTALL_PATH}"
|
||||
ALIAS_NAMESPACE "${JUCE_ARG_ALIAS_NAMESPACE}")
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
1933
deps/juce/extras/Build/CMake/JUCEUtils.cmake
vendored
Normal file
1933
deps/juce/extras/Build/CMake/JUCEUtils.cmake
vendored
Normal file
File diff suppressed because it is too large
Load Diff
16
deps/juce/extras/Build/CMake/LaunchScreen.storyboard
vendored
Normal file
16
deps/juce/extras/Build/CMake/LaunchScreen.storyboard
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<scenes>
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="" sceneMemberID="firstResponder"/>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<color key="backgroundColor" red="0" green="0" blue="0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
</viewController>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
16
deps/juce/extras/Build/CMake/PIPAudioProcessor.cpp.in
vendored
Normal file
16
deps/juce/extras/Build/CMake/PIPAudioProcessor.cpp.in
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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}();
|
||||
}
|
68
deps/juce/extras/Build/CMake/PIPComponent.cpp.in
vendored
Normal file
68
deps/juce/extras/Build/CMake/PIPComponent.cpp.in
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file contains the startup code for a PIP.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include <JuceHeader.h>
|
||||
#include "${JUCE_PIP_HEADER}"
|
||||
|
||||
class Application : public juce::JUCEApplication
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
Application() = default;
|
||||
|
||||
const juce::String getApplicationName() override { return "${JUCE_PIP_NAME}"; }
|
||||
const juce::String getApplicationVersion() override { return "${PROJECT_VERSION}"; }
|
||||
|
||||
void initialise (const juce::String&) override
|
||||
{
|
||||
mainWindow.reset (new MainWindow ("${JUCE_PIP_NAME}", new ${JUCE_PIP_MAIN_CLASS}, *this));
|
||||
}
|
||||
|
||||
void shutdown() override { mainWindow = nullptr; }
|
||||
|
||||
private:
|
||||
class MainWindow : public juce::DocumentWindow
|
||||
{
|
||||
public:
|
||||
MainWindow (const juce::String& name, juce::Component* c, JUCEApplication& a)
|
||||
: DocumentWindow (name, juce::Desktop::getInstance().getDefaultLookAndFeel()
|
||||
.findColour (ResizableWindow::backgroundColourId),
|
||||
juce::DocumentWindow::allButtons),
|
||||
app (a)
|
||||
{
|
||||
setUsingNativeTitleBar (true);
|
||||
setContentOwned (c, true);
|
||||
|
||||
#if JUCE_ANDROID || JUCE_IOS
|
||||
setFullScreen (true);
|
||||
#else
|
||||
setResizable (true, false);
|
||||
setResizeLimits (300, 250, 10000, 10000);
|
||||
centreWithSize (getWidth(), getHeight());
|
||||
#endif
|
||||
|
||||
setVisible (true);
|
||||
}
|
||||
|
||||
void closeButtonPressed() override
|
||||
{
|
||||
app.systemRequestedQuit();
|
||||
}
|
||||
|
||||
private:
|
||||
JUCEApplication& app;
|
||||
|
||||
//==============================================================================
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow)
|
||||
};
|
||||
|
||||
std::unique_ptr<MainWindow> mainWindow;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
START_JUCE_APPLICATION (Application)
|
10
deps/juce/extras/Build/CMake/PIPConsole.cpp.in
vendored
Normal file
10
deps/juce/extras/Build/CMake/PIPConsole.cpp.in
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file was auto-generated and contains the startup code for a PIP.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include <JuceHeader.h>
|
||||
#include "${JUCE_PIP_HEADER}"
|
BIN
deps/juce/extras/Build/CMake/RecentFilesMenuTemplate.nib
generated
vendored
Normal file
BIN
deps/juce/extras/Build/CMake/RecentFilesMenuTemplate.nib
generated
vendored
Normal file
Binary file not shown.
181
deps/juce/extras/Build/CMake/UnityPluginGUIScript.cs.in
vendored
Normal file
181
deps/juce/extras/Build/CMake/UnityPluginGUIScript.cs.in
vendored
Normal file
@ -0,0 +1,181 @@
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public class ${plugin_class_name}GUI : IAudioEffectPluginGUI
|
||||
{
|
||||
public override string Name { get { return "${plugin_name}"; } }
|
||||
public override string Description { get { return "${plugin_description}"; } }
|
||||
public override string Vendor { get { return "${plugin_vendor}"; } }
|
||||
|
||||
//==============================================================================
|
||||
[DllImport("${plugin_name}")] static extern System.IntPtr getRenderCallback();
|
||||
|
||||
[DllImport("${plugin_name}")] static extern void unityInitialiseTexture (int id, System.IntPtr texture, int width, int height);
|
||||
|
||||
[DllImport("${plugin_name}")] static extern void unityMouseDown (int id, float x, float y, EventModifiers mods, int button);
|
||||
[DllImport("${plugin_name}")] static extern void unityMouseDrag (int id, float x, float y, EventModifiers mods, int button);
|
||||
[DllImport("${plugin_name}")] static extern void unityMouseUp (int id, float x, float y, EventModifiers mods);
|
||||
|
||||
[DllImport("${plugin_name}")] static extern void unityKeyEvent (int id, KeyCode code, EventModifiers mods, string name);
|
||||
|
||||
[DllImport("${plugin_name}")] static extern void unitySetScreenBounds (int id, float x, float y, float w, float h);
|
||||
|
||||
//==============================================================================
|
||||
private class PluginGUIInstance
|
||||
{
|
||||
public PluginGUIInstance (ref IAudioEffectPlugin plugin, int id)
|
||||
{
|
||||
instanceID = id;
|
||||
|
||||
float[] arr;
|
||||
plugin.GetFloatBuffer ("Editor", out arr, 1);
|
||||
hasEditor = (arr[0] > 0.0f);
|
||||
}
|
||||
|
||||
public void repaint (Rect r)
|
||||
{
|
||||
Vector2 newScreenPosition = GUIUtility.GUIToScreenPoint (r.position);
|
||||
|
||||
if (bounds != r
|
||||
|| screenPosition != newScreenPosition)
|
||||
{
|
||||
screenPosition = newScreenPosition;
|
||||
bounds = r;
|
||||
|
||||
unitySetScreenBounds (instanceID, screenPosition.x, screenPosition.y, bounds.width, bounds.height);
|
||||
setupTexture();
|
||||
}
|
||||
|
||||
GL.IssuePluginEvent (getRenderCallback(), instanceID);
|
||||
|
||||
texture.SetPixels32 (pixels);
|
||||
texture.Apply();
|
||||
|
||||
EditorGUI.DrawPreviewTexture (bounds, texture);
|
||||
}
|
||||
|
||||
public bool handleMouseEvent (EventType eventType)
|
||||
{
|
||||
Vector2 mousePos = Event.current.mousePosition;
|
||||
EventModifiers mods = Event.current.modifiers;
|
||||
|
||||
if (! bounds.Contains (mousePos))
|
||||
return false;
|
||||
|
||||
Vector2 relativePos = new Vector2 (mousePos.x - bounds.x, mousePos.y - bounds.y);
|
||||
|
||||
if (eventType == EventType.MouseDown)
|
||||
{
|
||||
unityMouseDown (instanceID, relativePos.x, relativePos.y, mods, Event.current.button);
|
||||
GUIUtility.hotControl = GUIUtility.GetControlID (FocusType.Passive);
|
||||
}
|
||||
else if (eventType == EventType.MouseUp)
|
||||
{
|
||||
unityMouseUp (instanceID, relativePos.x, relativePos.y, mods);
|
||||
GUIUtility.hotControl = 0;
|
||||
}
|
||||
else if (eventType == EventType.MouseDrag)
|
||||
{
|
||||
unityMouseDrag (instanceID, relativePos.x, relativePos.y, mods, Event.current.button);
|
||||
}
|
||||
|
||||
Event.current.Use();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void handleKeyEvent (EventType eventType)
|
||||
{
|
||||
if (eventType == EventType.KeyDown)
|
||||
{
|
||||
KeyCode code = Event.current.keyCode;
|
||||
|
||||
if (code == KeyCode.None)
|
||||
return;
|
||||
|
||||
EventModifiers mods = Event.current.modifiers;
|
||||
|
||||
unityKeyEvent (instanceID, code, mods, code.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private void setupTexture()
|
||||
{
|
||||
if (pixelHandle.IsAllocated)
|
||||
pixelHandle.Free();
|
||||
|
||||
texture = new Texture2D ((int) bounds.width, (int) bounds.height, TextureFormat.ARGB32, false);
|
||||
|
||||
pixels = texture.GetPixels32();
|
||||
pixelHandle = GCHandle.Alloc (pixels, GCHandleType.Pinned);
|
||||
|
||||
unityInitialiseTexture (instanceID, pixelHandle.AddrOfPinnedObject(), texture.width, texture.height);
|
||||
}
|
||||
|
||||
public int instanceID = -1;
|
||||
public bool hasEditor;
|
||||
|
||||
private Vector2 screenPosition;
|
||||
private Rect bounds;
|
||||
|
||||
private Texture2D texture;
|
||||
private Color32[] pixels;
|
||||
private GCHandle pixelHandle;
|
||||
}
|
||||
List<PluginGUIInstance> guis = new List<PluginGUIInstance>();
|
||||
|
||||
private PluginGUIInstance getGUIInstanceForPlugin (ref IAudioEffectPlugin plugin)
|
||||
{
|
||||
float[] idArray;
|
||||
plugin.GetFloatBuffer ("ID", out idArray, 1);
|
||||
|
||||
int id = (int) idArray[0];
|
||||
|
||||
for (int i = 0; i < guis.Count; ++i)
|
||||
{
|
||||
if (guis[i].instanceID == id)
|
||||
return guis[i];
|
||||
}
|
||||
|
||||
PluginGUIInstance newInstance = new PluginGUIInstance (ref plugin, id);
|
||||
guis.Add (newInstance);
|
||||
|
||||
return guis[guis.Count - 1];
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
public override bool OnGUI (IAudioEffectPlugin plugin)
|
||||
{
|
||||
PluginGUIInstance guiInstance = getGUIInstanceForPlugin (ref plugin);
|
||||
|
||||
if (! guiInstance.hasEditor)
|
||||
return true;
|
||||
|
||||
float[] arr;
|
||||
plugin.GetFloatBuffer ("Size", out arr, 6);
|
||||
|
||||
Rect r = GUILayoutUtility.GetRect (arr[0], arr[1],
|
||||
new GUILayoutOption[] { GUILayout.MinWidth (arr[2]), GUILayout.MinHeight (arr[3]),
|
||||
GUILayout.MaxWidth (arr[4]), GUILayout.MaxHeight (arr[5]) });
|
||||
|
||||
int controlID = GUIUtility.GetControlID (FocusType.Passive);
|
||||
Event currentEvent = Event.current;
|
||||
EventType currentEventType = currentEvent.GetTypeForControl (controlID);
|
||||
|
||||
if (currentEventType == EventType.Repaint)
|
||||
guiInstance.repaint (r);
|
||||
else if (currentEvent.isMouse)
|
||||
guiInstance.handleMouseEvent (currentEventType);
|
||||
else if (currentEvent.isKey)
|
||||
guiInstance.handleKeyEvent (currentEventType);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
24
deps/juce/extras/Build/CMake/copyDir.cmake
vendored
Normal file
24
deps/juce/extras/Build/CMake/copyDir.cmake
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
# ==============================================================================
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# ==============================================================================
|
||||
|
||||
file(INSTALL ${src} DESTINATION ${dest} USE_SOURCE_PERMISSIONS)
|
57
deps/juce/extras/Build/CMake/juce_runtime_arch_detection.cpp
vendored
Normal file
57
deps/juce/extras/Build/CMake/juce_runtime_arch_detection.cpp
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
#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
|
27
deps/juce/extras/Build/CMakeLists.txt
vendored
Normal file
27
deps/juce/extras/Build/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
# ==============================================================================
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# ==============================================================================
|
||||
|
||||
juce_add_module(juce_build_tools ALIAS_NAMESPACE juce)
|
||||
|
||||
add_subdirectory(juceaide)
|
||||
|
47
deps/juce/extras/Build/juce_build_tools/juce_build_tools.cpp
vendored
Normal file
47
deps/juce/extras/Build/juce_build_tools/juce_build_tools.cpp
vendored
Normal file
@ -0,0 +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"
|
67
deps/juce/extras/Build/juce_build_tools/juce_build_tools.h
vendored
Normal file
67
deps/juce/extras/Build/juce_build_tools/juce_build_tools.h
vendored
Normal file
@ -0,0 +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"
|
289
deps/juce/extras/Build/juce_build_tools/utils/juce_BinaryResourceFile.cpp
vendored
Normal file
289
deps/juce/extras/Build/juce_build_tools/utils/juce_BinaryResourceFile.cpp
vendored
Normal file
@ -0,0 +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) };
|
||||
}
|
||||
}
|
||||
}
|
74
deps/juce/extras/Build/juce_build_tools/utils/juce_BinaryResourceFile.h
vendored
Normal file
74
deps/juce/extras/Build/juce_build_tools/utils/juce_BinaryResourceFile.h
vendored
Normal file
@ -0,0 +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)
|
||||
};
|
||||
}
|
||||
}
|
355
deps/juce/extras/Build/juce_build_tools/utils/juce_BuildHelperFunctions.cpp
vendored
Normal file
355
deps/juce/extras/Build/juce_build_tools/utils/juce_BuildHelperFunctions.cpp
vendored
Normal file
@ -0,0 +1,355 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
86
deps/juce/extras/Build/juce_build_tools/utils/juce_BuildHelperFunctions.h
vendored
Normal file
86
deps/juce/extras/Build/juce_build_tools/utils/juce_BuildHelperFunctions.h
vendored
Normal file
@ -0,0 +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);
|
||||
}
|
||||
}
|
206
deps/juce/extras/Build/juce_build_tools/utils/juce_CppTokeniserFunctions.cpp
vendored
Normal file
206
deps/juce/extras/Build/juce_build_tools/utils/juce_CppTokeniserFunctions.cpp
vendored
Normal file
@ -0,0 +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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
119
deps/juce/extras/Build/juce_build_tools/utils/juce_Entitlements.cpp
vendored
Normal file
119
deps/juce/extras/Build/juce_build_tools/utils/juce_Entitlements.cpp
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
56
deps/juce/extras/Build/juce_build_tools/utils/juce_Entitlements.h
vendored
Normal file
56
deps/juce/extras/Build/juce_build_tools/utils/juce_Entitlements.h
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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;
|
||||
};
|
||||
}
|
||||
}
|
505
deps/juce/extras/Build/juce_build_tools/utils/juce_Icons.cpp
vendored
Normal file
505
deps/juce/extras/Build/juce_build_tools/utils/juce_Icons.cpp
vendored
Normal file
@ -0,0 +1,505 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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
|
||||
{
|
||||
Array<Drawable*> asArray (const Icons& icons)
|
||||
{
|
||||
Array<Drawable*> result;
|
||||
|
||||
if (icons.small != nullptr)
|
||||
result.add (icons.small.get());
|
||||
|
||||
if (icons.big != nullptr)
|
||||
result.add (icons.big.get());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
namespace mac
|
||||
{
|
||||
static Image fixIconImageSize (Drawable& image)
|
||||
{
|
||||
const int validSizes[] = { 16, 32, 64, 128, 256, 512, 1024 };
|
||||
|
||||
auto w = image.getWidth();
|
||||
auto h = image.getHeight();
|
||||
|
||||
int bestSize = 16;
|
||||
|
||||
for (int size : validSizes)
|
||||
{
|
||||
if (w == h && w == size)
|
||||
{
|
||||
bestSize = w;
|
||||
break;
|
||||
}
|
||||
|
||||
if (jmax (w, h) > size)
|
||||
bestSize = size;
|
||||
}
|
||||
|
||||
return rescaleImageForIcon (image, bestSize);
|
||||
}
|
||||
|
||||
static void writeIconData (MemoryOutputStream& out, const Image& image, const char* type)
|
||||
{
|
||||
MemoryOutputStream pngData;
|
||||
PNGImageFormat pngFormat;
|
||||
pngFormat.writeImageToStream (image, pngData);
|
||||
|
||||
out.write (type, 4);
|
||||
out.writeIntBigEndian (8 + (int) pngData.getDataSize());
|
||||
out << pngData;
|
||||
}
|
||||
} // namespace mac
|
||||
|
||||
static void writeMacIcon (const Icons& icons, OutputStream& out)
|
||||
{
|
||||
MemoryOutputStream data;
|
||||
auto smallest = std::numeric_limits<int>::max();
|
||||
Drawable* smallestImage = nullptr;
|
||||
|
||||
const auto images = asArray (icons);
|
||||
|
||||
for (int i = 0; i < images.size(); ++i)
|
||||
{
|
||||
auto image = mac::fixIconImageSize (*images[i]);
|
||||
jassert (image.getWidth() == image.getHeight());
|
||||
|
||||
if (image.getWidth() < smallest)
|
||||
{
|
||||
smallest = image.getWidth();
|
||||
smallestImage = images[i];
|
||||
}
|
||||
|
||||
switch (image.getWidth())
|
||||
{
|
||||
case 16: mac::writeIconData (data, image, "icp4"); break;
|
||||
case 32: mac::writeIconData (data, image, "icp5"); break;
|
||||
case 64: mac::writeIconData (data, image, "icp6"); break;
|
||||
case 128: mac::writeIconData (data, image, "ic07"); break;
|
||||
case 256: mac::writeIconData (data, image, "ic08"); break;
|
||||
case 512: mac::writeIconData (data, image, "ic09"); break;
|
||||
case 1024: mac::writeIconData (data, image, "ic10"); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
jassert (data.getDataSize() > 0); // no suitable sized images?
|
||||
|
||||
// If you only supply a 1024 image, the file doesn't work on 10.8, so we need
|
||||
// to force a smaller one in there too..
|
||||
if (smallest > 512 && smallestImage != nullptr)
|
||||
mac::writeIconData (data, rescaleImageForIcon (*smallestImage, 512), "ic09");
|
||||
|
||||
out.write ("icns", 4);
|
||||
out.writeIntBigEndian ((int) data.getDataSize() + 8);
|
||||
out << data;
|
||||
}
|
||||
|
||||
Image getBestIconForSize (const Icons& icons,
|
||||
int size,
|
||||
bool returnNullIfNothingBigEnough)
|
||||
{
|
||||
auto* const im = [&]() -> Drawable*
|
||||
{
|
||||
if ((icons.small != nullptr) != (icons.big != nullptr))
|
||||
return icons.small != nullptr ? icons.small.get() : icons.big.get();
|
||||
|
||||
if (icons.small != nullptr && icons.big != nullptr)
|
||||
{
|
||||
if (icons.small->getWidth() >= size && icons.big->getWidth() >= size)
|
||||
return icons.small->getWidth() < icons.big->getWidth() ? icons.small.get() : icons.big.get();
|
||||
|
||||
if (icons.small->getWidth() >= size)
|
||||
return icons.small.get();
|
||||
|
||||
if (icons.big->getWidth() >= size)
|
||||
return icons.big.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}();
|
||||
|
||||
if (im == nullptr)
|
||||
return {};
|
||||
|
||||
if (returnNullIfNothingBigEnough && im->getWidth() < size && im->getHeight() < size)
|
||||
return {};
|
||||
|
||||
return rescaleImageForIcon (*im, size);
|
||||
}
|
||||
|
||||
namespace win
|
||||
{
|
||||
static void writeBMPImage (const Image& image, const int w, const int h, MemoryOutputStream& out)
|
||||
{
|
||||
int maskStride = (w / 8 + 3) & ~3;
|
||||
|
||||
out.writeInt (40); // bitmapinfoheader size
|
||||
out.writeInt (w);
|
||||
out.writeInt (h * 2);
|
||||
out.writeShort (1); // planes
|
||||
out.writeShort (32); // bits
|
||||
out.writeInt (0); // compression
|
||||
out.writeInt ((h * w * 4) + (h * maskStride)); // size image
|
||||
out.writeInt (0); // x pixels per meter
|
||||
out.writeInt (0); // y pixels per meter
|
||||
out.writeInt (0); // clr used
|
||||
out.writeInt (0); // clr important
|
||||
|
||||
Image::BitmapData bitmap (image, Image::BitmapData::readOnly);
|
||||
int alphaThreshold = 5;
|
||||
|
||||
int y;
|
||||
for (y = h; --y >= 0;)
|
||||
{
|
||||
for (int x = 0; x < w; ++x)
|
||||
{
|
||||
auto pixel = bitmap.getPixelColour (x, y);
|
||||
|
||||
if (pixel.getAlpha() <= alphaThreshold)
|
||||
{
|
||||
out.writeInt (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
out.writeByte ((char) pixel.getBlue());
|
||||
out.writeByte ((char) pixel.getGreen());
|
||||
out.writeByte ((char) pixel.getRed());
|
||||
out.writeByte ((char) pixel.getAlpha());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (y = h; --y >= 0;)
|
||||
{
|
||||
int mask = 0, count = 0;
|
||||
|
||||
for (int x = 0; x < w; ++x)
|
||||
{
|
||||
auto pixel = bitmap.getPixelColour (x, y);
|
||||
|
||||
mask <<= 1;
|
||||
if (pixel.getAlpha() <= alphaThreshold)
|
||||
mask |= 1;
|
||||
|
||||
if (++count == 8)
|
||||
{
|
||||
out.writeByte ((char) mask);
|
||||
count = 0;
|
||||
mask = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (mask != 0)
|
||||
out.writeByte ((char) mask);
|
||||
|
||||
for (int i = maskStride - w / 8; --i >= 0;)
|
||||
out.writeByte (0);
|
||||
}
|
||||
}
|
||||
|
||||
static void writeIcon (const Array<Image>& images, OutputStream& out)
|
||||
{
|
||||
out.writeShort (0); // reserved
|
||||
out.writeShort (1); // .ico tag
|
||||
out.writeShort ((short) images.size());
|
||||
|
||||
MemoryOutputStream dataBlock;
|
||||
|
||||
int imageDirEntrySize = 16;
|
||||
int dataBlockStart = 6 + images.size() * imageDirEntrySize;
|
||||
|
||||
for (int i = 0; i < images.size(); ++i)
|
||||
{
|
||||
auto oldDataSize = dataBlock.getDataSize();
|
||||
|
||||
auto& image = images.getReference (i);
|
||||
auto w = image.getWidth();
|
||||
auto h = image.getHeight();
|
||||
|
||||
if (w >= 256 || h >= 256)
|
||||
{
|
||||
PNGImageFormat pngFormat;
|
||||
pngFormat.writeImageToStream (image, dataBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeBMPImage (image, w, h, dataBlock);
|
||||
}
|
||||
|
||||
out.writeByte ((char) w);
|
||||
out.writeByte ((char) h);
|
||||
out.writeByte (0);
|
||||
out.writeByte (0);
|
||||
out.writeShort (1); // colour planes
|
||||
out.writeShort (32); // bits per pixel
|
||||
out.writeInt ((int) (dataBlock.getDataSize() - oldDataSize));
|
||||
out.writeInt (dataBlockStart + (int) oldDataSize);
|
||||
}
|
||||
|
||||
jassert (out.getPosition() == dataBlockStart);
|
||||
out << dataBlock;
|
||||
}
|
||||
} // namespace win
|
||||
|
||||
static void writeWinIcon (const Icons& icons, OutputStream& os)
|
||||
{
|
||||
Array<Image> images;
|
||||
int sizes[] = { 16, 32, 48, 256 };
|
||||
|
||||
for (int size : sizes)
|
||||
{
|
||||
auto im = getBestIconForSize (icons, size, true);
|
||||
|
||||
if (im.isValid())
|
||||
images.add (im);
|
||||
}
|
||||
|
||||
if (images.size() > 0)
|
||||
win::writeIcon (images, os);
|
||||
}
|
||||
|
||||
void writeMacIcon (const Icons& icons, const File& file)
|
||||
{
|
||||
writeStreamToFile (file, [&] (MemoryOutputStream& mo) { writeMacIcon (icons, mo); });
|
||||
}
|
||||
|
||||
void writeWinIcon (const Icons& icons, const File& file)
|
||||
{
|
||||
writeStreamToFile (file, [&] (MemoryOutputStream& mo) { writeWinIcon (icons, mo); });
|
||||
}
|
||||
|
||||
Image rescaleImageForIcon (Drawable& d, const int size)
|
||||
{
|
||||
if (auto* drawableImage = dynamic_cast<DrawableImage*> (&d))
|
||||
{
|
||||
auto im = SoftwareImageType().convert (drawableImage->getImage());
|
||||
|
||||
if (im.getWidth() == size && im.getHeight() == size)
|
||||
return im;
|
||||
|
||||
// (scale it down in stages for better resampling)
|
||||
while (im.getWidth() > 2 * size && im.getHeight() > 2 * size)
|
||||
im = im.rescaled (im.getWidth() / 2,
|
||||
im.getHeight() / 2);
|
||||
|
||||
Image newIm (Image::ARGB, size, size, true, SoftwareImageType());
|
||||
Graphics g (newIm);
|
||||
g.drawImageWithin (im, 0, 0, size, size,
|
||||
RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, false);
|
||||
return newIm;
|
||||
}
|
||||
|
||||
Image im (Image::ARGB, size, size, true, SoftwareImageType());
|
||||
Graphics g (im);
|
||||
d.drawWithin (g, im.getBounds().toFloat(), RectanglePlacement::centred, 1.0f);
|
||||
return im;
|
||||
}
|
||||
|
||||
struct AppIconType
|
||||
{
|
||||
const char* idiom;
|
||||
const char* sizeString;
|
||||
const char* filename;
|
||||
const char* scale;
|
||||
int size;
|
||||
};
|
||||
|
||||
static const AppIconType iOSAppIconTypes[]
|
||||
{
|
||||
{ "iphone", "20x20", "Icon-Notification-20@2x.png", "2x", 40 },
|
||||
{ "iphone", "20x20", "Icon-Notification-20@3x.png", "3x", 60 },
|
||||
{ "iphone", "29x29", "Icon-29.png", "1x", 29 },
|
||||
{ "iphone", "29x29", "Icon-29@2x.png", "2x", 58 },
|
||||
{ "iphone", "29x29", "Icon-29@3x.png", "3x", 87 },
|
||||
{ "iphone", "40x40", "Icon-Spotlight-40@2x.png", "2x", 80 },
|
||||
{ "iphone", "40x40", "Icon-Spotlight-40@3x.png", "3x", 120 },
|
||||
{ "iphone", "57x57", "Icon.png", "1x", 57 },
|
||||
{ "iphone", "57x57", "Icon@2x.png", "2x", 114 },
|
||||
{ "iphone", "60x60", "Icon-60@2x.png", "2x", 120 },
|
||||
{ "iphone", "60x60", "Icon-@3x.png", "3x", 180 },
|
||||
{ "ipad", "20x20", "Icon-Notifications-20.png", "1x", 20 },
|
||||
{ "ipad", "20x20", "Icon-Notifications-20@2x.png", "2x", 40 },
|
||||
{ "ipad", "29x29", "Icon-Small-1.png", "1x", 29 },
|
||||
{ "ipad", "29x29", "Icon-Small@2x-1.png", "2x", 58 },
|
||||
{ "ipad", "40x40", "Icon-Spotlight-40.png", "1x", 40 },
|
||||
{ "ipad", "40x40", "Icon-Spotlight-40@2x-1.png", "2x", 80 },
|
||||
{ "ipad", "50x50", "Icon-Small-50.png", "1x", 50 },
|
||||
{ "ipad", "50x50", "Icon-Small-50@2x.png", "2x", 100 },
|
||||
{ "ipad", "72x72", "Icon-72.png", "1x", 72 },
|
||||
{ "ipad", "72x72", "Icon-72@2x.png", "2x", 144 },
|
||||
{ "ipad", "76x76", "Icon-76.png", "1x", 76 },
|
||||
{ "ipad", "76x76", "Icon-76@2x.png", "2x", 152 },
|
||||
{ "ipad", "83.5x83.5", "Icon-83.5@2x.png", "2x", 167 },
|
||||
{ "ios-marketing", "1024x1024", "Icon-AppStore-1024.png", "1x", 1024 }
|
||||
};
|
||||
|
||||
static void createiOSIconFiles (const Icons& icons, File appIconSet)
|
||||
{
|
||||
auto* imageToUse = icons.big != nullptr ? icons.big.get()
|
||||
: icons.small.get();
|
||||
|
||||
if (imageToUse != nullptr)
|
||||
{
|
||||
for (auto& type : iOSAppIconTypes)
|
||||
{
|
||||
auto image = rescaleImageForIcon (*imageToUse, type.size);
|
||||
|
||||
if (image.hasAlphaChannel())
|
||||
{
|
||||
Image background (Image::RGB, image.getWidth(), image.getHeight(), false);
|
||||
Graphics g (background);
|
||||
g.fillAll (Colours::white);
|
||||
|
||||
g.drawImageWithin (image, 0, 0, image.getWidth(), image.getHeight(),
|
||||
RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize);
|
||||
|
||||
image = background;
|
||||
}
|
||||
|
||||
MemoryOutputStream pngData;
|
||||
PNGImageFormat pngFormat;
|
||||
pngFormat.writeImageToStream (image, pngData);
|
||||
|
||||
overwriteFileIfDifferentOrThrow (appIconSet.getChildFile (type.filename), pngData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static String getiOSAssetContents (var images)
|
||||
{
|
||||
DynamicObject::Ptr v (new DynamicObject());
|
||||
|
||||
var info (new DynamicObject());
|
||||
info.getDynamicObject()->setProperty ("version", 1);
|
||||
info.getDynamicObject()->setProperty ("author", "xcode");
|
||||
|
||||
v->setProperty ("images", images);
|
||||
v->setProperty ("info", info);
|
||||
|
||||
return JSON::toString (var (v.get()));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static String getiOSAppIconContents()
|
||||
{
|
||||
var images;
|
||||
|
||||
for (auto& type : iOSAppIconTypes)
|
||||
{
|
||||
DynamicObject::Ptr d (new DynamicObject());
|
||||
d->setProperty ("idiom", type.idiom);
|
||||
d->setProperty ("size", type.sizeString);
|
||||
d->setProperty ("filename", type.filename);
|
||||
d->setProperty ("scale", type.scale);
|
||||
images.append (var (d.get()));
|
||||
}
|
||||
|
||||
return getiOSAssetContents (images);
|
||||
}
|
||||
|
||||
struct ImageType
|
||||
{
|
||||
const char* orientation;
|
||||
const char* idiom;
|
||||
const char* subtype;
|
||||
const char* extent;
|
||||
const char* scale;
|
||||
const char* filename;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
static const ImageType iOSLaunchImageTypes[]
|
||||
{
|
||||
{ "portrait", "iphone", nullptr, "full-screen", "2x", "LaunchImage-iphone-2x.png", 640, 960 },
|
||||
{ "portrait", "iphone", "retina4", "full-screen", "2x", "LaunchImage-iphone-retina4.png", 640, 1136 },
|
||||
{ "portrait", "ipad", nullptr, "full-screen", "1x", "LaunchImage-ipad-portrait-1x.png", 768, 1024 },
|
||||
{ "landscape","ipad", nullptr, "full-screen", "1x", "LaunchImage-ipad-landscape-1x.png", 1024, 768 },
|
||||
{ "portrait", "ipad", nullptr, "full-screen", "2x", "LaunchImage-ipad-portrait-2x.png", 1536, 2048 },
|
||||
{ "landscape","ipad", nullptr, "full-screen", "2x", "LaunchImage-ipad-landscape-2x.png", 2048, 1536 }
|
||||
};
|
||||
|
||||
static void createiOSLaunchImageFiles (const File& launchImageSet)
|
||||
{
|
||||
for (auto& type : iOSLaunchImageTypes)
|
||||
{
|
||||
Image image (Image::ARGB, type.width, type.height, true); // (empty black image)
|
||||
image.clear (image.getBounds(), Colours::black);
|
||||
|
||||
MemoryOutputStream pngData;
|
||||
PNGImageFormat pngFormat;
|
||||
pngFormat.writeImageToStream (image, pngData);
|
||||
build_tools::overwriteFileIfDifferentOrThrow (launchImageSet.getChildFile (type.filename), pngData);
|
||||
}
|
||||
}
|
||||
|
||||
static String getiOSLaunchImageContents()
|
||||
{
|
||||
var images;
|
||||
|
||||
for (auto& type : iOSLaunchImageTypes)
|
||||
{
|
||||
DynamicObject::Ptr d (new DynamicObject());
|
||||
d->setProperty ("orientation", type.orientation);
|
||||
d->setProperty ("idiom", type.idiom);
|
||||
d->setProperty ("extent", type.extent);
|
||||
d->setProperty ("minimum-system-version", "7.0");
|
||||
d->setProperty ("scale", type.scale);
|
||||
d->setProperty ("filename", type.filename);
|
||||
|
||||
if (type.subtype != nullptr)
|
||||
d->setProperty ("subtype", type.subtype);
|
||||
|
||||
images.append (var (d.get()));
|
||||
}
|
||||
|
||||
return getiOSAssetContents (images);
|
||||
}
|
||||
|
||||
RelativePath createXcassetsFolderFromIcons (const Icons& icons,
|
||||
const File& targetFolder,
|
||||
String projectFilenameRootString)
|
||||
{
|
||||
const auto assets = targetFolder.getChildFile (projectFilenameRootString)
|
||||
.getChildFile ("Images.xcassets");
|
||||
const auto iconSet = assets.getChildFile ("AppIcon.appiconset");
|
||||
const auto launchImage = assets.getChildFile ("LaunchImage.launchimage");
|
||||
|
||||
overwriteFileIfDifferentOrThrow (iconSet.getChildFile ("Contents.json"), getiOSAppIconContents());
|
||||
createiOSIconFiles (icons, iconSet);
|
||||
|
||||
overwriteFileIfDifferentOrThrow (launchImage.getChildFile ("Contents.json"), getiOSLaunchImageContents());
|
||||
createiOSLaunchImageFiles (launchImage);
|
||||
|
||||
return { assets, targetFolder, RelativePath::buildTargetFolder };
|
||||
}
|
||||
}
|
||||
}
|
49
deps/juce/extras/Build/juce_build_tools/utils/juce_Icons.h
vendored
Normal file
49
deps/juce/extras/Build/juce_build_tools/utils/juce_Icons.h
vendored
Normal file
@ -0,0 +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);
|
||||
}
|
||||
}
|
370
deps/juce/extras/Build/juce_build_tools/utils/juce_PlistOptions.cpp
vendored
Normal file
370
deps/juce/extras/Build/juce_build_tools/utils/juce_PlistOptions.cpp
vendored
Normal file
@ -0,0 +1,370 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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 };
|
||||
}
|
||||
}
|
||||
}
|
106
deps/juce/extras/Build/juce_build_tools/utils/juce_PlistOptions.h
vendored
Normal file
106
deps/juce/extras/Build/juce_build_tools/utils/juce_PlistOptions.h
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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;
|
||||
};
|
||||
}
|
||||
}
|
275
deps/juce/extras/Build/juce_build_tools/utils/juce_ProjectType.h
vendored
Normal file
275
deps/juce/extras/Build/juce_build_tools/utils/juce_ProjectType.h
vendored
Normal file
@ -0,0 +1,275 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
129
deps/juce/extras/Build/juce_build_tools/utils/juce_RelativePath.h
vendored
Normal file
129
deps/juce/extras/Build/juce_build_tools/utils/juce_RelativePath.h
vendored
Normal file
@ -0,0 +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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
91
deps/juce/extras/Build/juce_build_tools/utils/juce_ResourceFileHelpers.cpp
vendored
Normal file
91
deps/juce/extras/Build/juce_build_tools/utils/juce_ResourceFileHelpers.cpp
vendored
Normal file
@ -0,0 +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));
|
||||
}
|
||||
}
|
||||
}
|
38
deps/juce/extras/Build/juce_build_tools/utils/juce_ResourceFileHelpers.h
vendored
Normal file
38
deps/juce/extras/Build/juce_build_tools/utils/juce_ResourceFileHelpers.h
vendored
Normal file
@ -0,0 +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);
|
||||
}
|
||||
}
|
97
deps/juce/extras/Build/juce_build_tools/utils/juce_ResourceRc.cpp
vendored
Normal file
97
deps/juce/extras/Build/juce_build_tools/utils/juce_ResourceRc.cpp
vendored
Normal file
@ -0,0 +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);
|
||||
}
|
||||
}
|
||||
}
|
43
deps/juce/extras/Build/juce_build_tools/utils/juce_ResourceRc.h
vendored
Normal file
43
deps/juce/extras/Build/juce_build_tools/utils/juce_ResourceRc.h
vendored
Normal file
@ -0,0 +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;
|
||||
};
|
||||
}
|
||||
}
|
60
deps/juce/extras/Build/juce_build_tools/utils/juce_VersionNumbers.cpp
vendored
Normal file
60
deps/juce/extras/Build/juce_build_tools/utils/juce_VersionNumbers.cpp
vendored
Normal file
@ -0,0 +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));
|
||||
}
|
||||
}
|
||||
}
|
37
deps/juce/extras/Build/juce_build_tools/utils/juce_VersionNumbers.h
vendored
Normal file
37
deps/juce/extras/Build/juce_build_tools/utils/juce_VersionNumbers.h
vendored
Normal file
@ -0,0 +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);
|
||||
}
|
||||
}
|
110
deps/juce/extras/Build/juceaide/CMakeLists.txt
vendored
Normal file
110
deps/juce/extras/Build/juceaide/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
# ==============================================================================
|
||||
#
|
||||
# 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 juceaide program generates intermediate build files including BinaryData sources, icons, and
|
||||
# plists. To ensure that we always build it for the host system, and not for, say, a device or
|
||||
# simulator if we're targeting iOS or Android, we reinvoke cmake here and build juceaide during the
|
||||
# configuration stage of the outer project.
|
||||
|
||||
if(JUCE_BUILD_HELPER_TOOLS)
|
||||
# Build the tool for the current system
|
||||
juce_add_console_app(juceaide)
|
||||
|
||||
target_sources(juceaide PRIVATE Main.cpp)
|
||||
|
||||
target_compile_definitions(juceaide PRIVATE
|
||||
JUCE_DISABLE_JUCE_VERSION_PRINTING=1
|
||||
JUCE_USE_CURL=0)
|
||||
|
||||
target_link_libraries(juceaide PRIVATE
|
||||
juce::juce_build_tools
|
||||
juce::juce_recommended_config_flags
|
||||
juce::juce_recommended_lto_flags
|
||||
juce::juce_recommended_warning_flags)
|
||||
|
||||
set_target_properties(juceaide PROPERTIES
|
||||
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
|
||||
export(TARGETS juceaide
|
||||
NAMESPACE juce_tools::
|
||||
FILE "${JUCE_BINARY_DIR}/JUCEToolsExport.cmake")
|
||||
else()
|
||||
# If we're building using the NDK, the gradle wrapper will try to inject its own compiler using
|
||||
# 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})
|
||||
|
||||
message(STATUS "Configuring juceaide")
|
||||
|
||||
# Looks like we're boostrapping, reinvoke CMake
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}"
|
||||
"."
|
||||
"-B${JUCE_BINARY_DIR}/tools"
|
||||
"-G${CMAKE_GENERATOR}"
|
||||
"-DCMAKE_BUILD_TYPE=Debug"
|
||||
"-DJUCE_BUILD_HELPER_TOOLS=ON"
|
||||
"-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}"
|
||||
WORKING_DIRECTORY "${JUCE_SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE command_output
|
||||
ERROR_VARIABLE command_output
|
||||
RESULT_VARIABLE result_variable)
|
||||
|
||||
if(result_variable)
|
||||
message(FATAL_ERROR "Failed to configure juceaide\n${command_output}")
|
||||
endif()
|
||||
|
||||
message(STATUS "Building juceaide")
|
||||
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}"
|
||||
--build "${JUCE_BINARY_DIR}/tools"
|
||||
--config Debug
|
||||
OUTPUT_VARIABLE command_output
|
||||
ERROR_VARIABLE command_output
|
||||
RESULT_VARIABLE result_variable)
|
||||
|
||||
if(result_variable)
|
||||
message(FATAL_ERROR "Failed to build juceaide\n${command_output}")
|
||||
endif()
|
||||
|
||||
message(STATUS "Exporting juceaide")
|
||||
|
||||
# This will be generated by the recursive invocation of CMake (above)
|
||||
include("${JUCE_BINARY_DIR}/tools/JUCEToolsExport.cmake")
|
||||
|
||||
add_executable(juceaide IMPORTED GLOBAL)
|
||||
get_target_property(imported_location juce_tools::juceaide IMPORTED_LOCATION_DEBUG)
|
||||
set_target_properties(juceaide PROPERTIES IMPORTED_LOCATION "${imported_location}")
|
||||
|
||||
add_executable(juce::juceaide ALIAS juceaide)
|
||||
|
||||
set(JUCE_TOOL_INSTALL_DIR "bin/JUCE-${JUCE_VERSION}" CACHE STRING
|
||||
"The location, relative to the install prefix, where juceaide will be installed")
|
||||
|
||||
install(PROGRAMS "${imported_location}" DESTINATION "${JUCE_TOOL_INSTALL_DIR}")
|
||||
|
||||
get_filename_component(binary_name "${imported_location}" NAME)
|
||||
set(JUCE_JUCEAIDE_NAME "${binary_name}" CACHE INTERNAL "The name of the juceaide program")
|
||||
endif()
|
534
deps/juce/extras/Build/juceaide/Main.cpp
vendored
Normal file
534
deps/juce/extras/Build/juceaide/Main.cpp
vendored
Normal file
@ -0,0 +1,534 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include <juce_build_tools/juce_build_tools.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
constexpr auto headerTemplate = R"(/*
|
||||
IMPORTANT! This file is auto-generated.
|
||||
If you alter its contents, your changes may be overwritten!
|
||||
|
||||
This is the header file that your files should include in order to get all the
|
||||
JUCE library headers. You should avoid including the JUCE headers directly in
|
||||
your own source files, because that wouldn't pick up the correct configuration
|
||||
options for your app.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
${JUCE_INCLUDES}
|
||||
|
||||
#if JUCE_TARGET_HAS_BINARY_DATA
|
||||
#include "BinaryData.h"
|
||||
#endif
|
||||
|
||||
#if ! DONT_SET_USING_JUCE_NAMESPACE
|
||||
// If your code uses a lot of JUCE classes, then this will obviously save you
|
||||
// a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE.
|
||||
using namespace juce;
|
||||
#endif
|
||||
|
||||
#if ! JUCE_DONT_DECLARE_PROJECTINFO
|
||||
namespace ProjectInfo
|
||||
{
|
||||
const char* const projectName = "${JUCE_EXECUTABLE_NAME}";
|
||||
const char* const companyName = "${JUCE_COMPANY_NAME}";
|
||||
const char* const versionString = "${JUCE_PROJECT_VERSION}";
|
||||
const int versionNumber = ${JUCE_PROJECT_VERSION_HEX};
|
||||
}
|
||||
#endif
|
||||
)";
|
||||
|
||||
int writeBinaryData (juce::ArgumentList&& args)
|
||||
{
|
||||
args.checkMinNumArguments (4);
|
||||
const auto namespaceName = args.arguments.removeAndReturn (0);
|
||||
const auto headerName = args.arguments.removeAndReturn (0);
|
||||
const auto outFolder = args.arguments.removeAndReturn (0).resolveAsExistingFolder();
|
||||
const auto inputFileList = args.arguments.removeAndReturn (0).resolveAsExistingFile();
|
||||
|
||||
juce::build_tools::ResourceFile resourceFile;
|
||||
|
||||
resourceFile.setClassName (namespaceName.text);
|
||||
const auto lineEndings = args.removeOptionIfFound ("--windows") ? "\r\n" : "\n";
|
||||
|
||||
const auto allLines = [&]
|
||||
{
|
||||
auto lines = juce::StringArray::fromLines (inputFileList.loadFileAsString());
|
||||
lines.removeEmptyStrings();
|
||||
return lines;
|
||||
}();
|
||||
|
||||
for (const auto& arg : allLines)
|
||||
resourceFile.addFile (juce::File (arg));
|
||||
|
||||
const auto result = resourceFile.write (0,
|
||||
lineEndings,
|
||||
outFolder.getChildFile (headerName.text),
|
||||
[&outFolder] (int index)
|
||||
{
|
||||
return outFolder.getChildFile ("./BinaryData" + juce::String { index + 1 } + ".cpp");
|
||||
});
|
||||
|
||||
if (result.result.failed())
|
||||
juce::ConsoleApplication::fail (result.result.getErrorMessage(), 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct IconParseResults final
|
||||
{
|
||||
juce::build_tools::Icons icons;
|
||||
juce::File output;
|
||||
};
|
||||
|
||||
IconParseResults parseIconArguments (juce::ArgumentList&& args)
|
||||
{
|
||||
args.checkMinNumArguments (2);
|
||||
const auto output = args.arguments.removeAndReturn (0);
|
||||
|
||||
const auto popDrawable = [&args]() -> std::unique_ptr<juce::Drawable>
|
||||
{
|
||||
if (args.size() == 0)
|
||||
return {};
|
||||
|
||||
const auto firstArgText = args.arguments.removeAndReturn (0).text;
|
||||
return juce::Drawable::createFromImageFile (firstArgText);
|
||||
};
|
||||
|
||||
auto smallIcon = popDrawable();
|
||||
auto bigIcon = popDrawable();
|
||||
|
||||
return { { std::move (smallIcon), std::move (bigIcon) }, output.text };
|
||||
}
|
||||
|
||||
int writeMacIcon (juce::ArgumentList&& argumentList)
|
||||
{
|
||||
const auto parsed = parseIconArguments (std::move (argumentList));
|
||||
juce::build_tools::writeMacIcon (parsed.icons, parsed.output);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int writeiOSAssets (juce::ArgumentList&& argumentList)
|
||||
{
|
||||
const auto parsed = parseIconArguments (std::move (argumentList));
|
||||
juce::build_tools::createXcassetsFolderFromIcons (parsed.icons,
|
||||
parsed.output.getParentDirectory(),
|
||||
parsed.output.getFileName());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int writeWinIcon (juce::ArgumentList&& argumentList)
|
||||
{
|
||||
const auto parsed = parseIconArguments (std::move (argumentList));
|
||||
juce::build_tools::writeWinIcon (parsed.icons, parsed.output);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::unordered_map<juce::String, juce::String> parseProjectData (const juce::File& file)
|
||||
{
|
||||
constexpr auto recordSeparator = "\x1e";
|
||||
const auto contents = file.loadFileAsString();
|
||||
const auto lines = juce::StringArray::fromTokens (contents, recordSeparator, {});
|
||||
|
||||
std::unordered_map<juce::String, juce::String> result;
|
||||
|
||||
constexpr auto unitSeparator = "\x1f";
|
||||
|
||||
for (const auto& line : lines)
|
||||
{
|
||||
if (line.isEmpty())
|
||||
continue;
|
||||
|
||||
result.emplace (line.upToFirstOccurrenceOf (unitSeparator, false, false),
|
||||
line.fromFirstOccurrenceOf (unitSeparator, false, false));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
juce::String getStringValue (const std::unordered_map<juce::String, juce::String>& dict,
|
||||
juce::StringRef key)
|
||||
{
|
||||
const auto it = dict.find (key);
|
||||
return it != dict.cend() ? it->second : juce::String{};
|
||||
}
|
||||
|
||||
bool getBoolValue (const std::unordered_map<juce::String, juce::String>& dict, juce::StringRef key)
|
||||
{
|
||||
const auto str = getStringValue (dict, key);
|
||||
return str.equalsIgnoreCase ("yes")
|
||||
|| str.equalsIgnoreCase ("true")
|
||||
|| str.equalsIgnoreCase ("1")
|
||||
|| str.equalsIgnoreCase ("on");
|
||||
}
|
||||
|
||||
struct UpdateField final
|
||||
{
|
||||
const std::unordered_map<juce::String, juce::String>& dict;
|
||||
|
||||
void operator() (juce::StringRef key, juce::String& value) const
|
||||
{
|
||||
value = getStringValue (dict, key);
|
||||
}
|
||||
|
||||
void operator() (juce::StringRef key, juce::File& value) const
|
||||
{
|
||||
value = getStringValue (dict, key);
|
||||
}
|
||||
|
||||
void operator() (juce::StringRef key, bool& value) const
|
||||
{
|
||||
value = getBoolValue (dict, key);
|
||||
}
|
||||
|
||||
void operator() (juce::StringRef key, juce::StringArray& value) const
|
||||
{
|
||||
value = juce::StringArray::fromTokens (getStringValue (dict, key), ";", {});
|
||||
}
|
||||
};
|
||||
|
||||
void setIfEmpty (juce::String& field, juce::StringRef fallback)
|
||||
{
|
||||
if (field.isEmpty())
|
||||
field = fallback;
|
||||
}
|
||||
|
||||
juce::build_tools::PlistOptions parsePlistOptions (const juce::File& file,
|
||||
juce::build_tools::ProjectType::Target::Type type)
|
||||
{
|
||||
if (type == juce::build_tools::ProjectType::Target::ConsoleApp)
|
||||
juce::ConsoleApplication::fail ("Deduced project type does not require a plist", 1);
|
||||
|
||||
const auto dict = parseProjectData (file);
|
||||
|
||||
UpdateField updateField { dict };
|
||||
|
||||
juce::build_tools::PlistOptions result;
|
||||
|
||||
updateField ("EXECUTABLE_NAME", result.executableName);
|
||||
updateField ("PLIST_TO_MERGE", result.plistToMerge);
|
||||
updateField ("IS_IOS", result.iOS);
|
||||
updateField ("MICROPHONE_PERMISSION_ENABLED", result.microphonePermissionEnabled);
|
||||
updateField ("MICROPHONE_PERMISSION_TEXT", result.microphonePermissionText);
|
||||
updateField ("CAMERA_PERMISSION_ENABLED", result.cameraPermissionEnabled);
|
||||
updateField ("CAMERA_PERMISSION_TEXT", result.cameraPermissionText);
|
||||
updateField ("BLUETOOTH_PERMISSION_ENABLED", result.bluetoothPermissionEnabled);
|
||||
updateField ("BLUETOOTH_PERMISSION_TEXT", result.bluetoothPermissionText);
|
||||
updateField ("SEND_APPLE_EVENTS_PERMISSION_ENABLED", result.sendAppleEventsPermissionEnabled);
|
||||
updateField ("SEND_APPLE_EVENTS_PERMISSION_TEXT", result.sendAppleEventsPermissionText);
|
||||
updateField ("SHOULD_ADD_STORYBOARD", result.shouldAddStoryboardToProject);
|
||||
updateField ("LAUNCH_STORYBOARD_FILE", result.storyboardName);
|
||||
updateField ("PROJECT_NAME", result.projectName);
|
||||
updateField ("VERSION", result.marketingVersion);
|
||||
updateField ("BUILD_VERSION", result.currentProjectVersion);
|
||||
updateField ("COMPANY_COPYRIGHT", result.companyCopyright);
|
||||
updateField ("DOCUMENT_EXTENSIONS", result.documentExtensions);
|
||||
updateField ("FILE_SHARING_ENABLED", result.fileSharingEnabled);
|
||||
updateField ("DOCUMENT_BROWSER_ENABLED", result.documentBrowserEnabled);
|
||||
updateField ("STATUS_BAR_HIDDEN", result.statusBarHidden);
|
||||
updateField ("REQUIRES_FULL_SCREEN", result.requiresFullScreen);
|
||||
updateField ("BACKGROUND_AUDIO_ENABLED", result.backgroundAudioEnabled);
|
||||
updateField ("BACKGROUND_BLE_ENABLED", result.backgroundBleEnabled);
|
||||
updateField ("PUSH_NOTIFICATIONS_ENABLED", result.pushNotificationsEnabled);
|
||||
updateField ("PLUGIN_MANUFACTURER_CODE", result.pluginManufacturerCode);
|
||||
updateField ("PLUGIN_CODE", result.pluginCode);
|
||||
updateField ("IPHONE_SCREEN_ORIENTATIONS", result.iPhoneScreenOrientations);
|
||||
updateField ("IPAD_SCREEN_ORIENTATIONS", result.iPadScreenOrientations);
|
||||
updateField ("PLUGIN_NAME", result.pluginName);
|
||||
updateField ("PLUGIN_MANUFACTURER", result.pluginManufacturer);
|
||||
updateField ("PLUGIN_DESCRIPTION", result.pluginDescription);
|
||||
updateField ("PLUGIN_AU_EXPORT_PREFIX", result.pluginAUExportPrefix);
|
||||
updateField ("PLUGIN_AU_MAIN_TYPE", result.auMainType);
|
||||
updateField ("IS_AU_SANDBOX_SAFE", result.isAuSandboxSafe);
|
||||
updateField ("IS_PLUGIN_SYNTH", result.isPluginSynth);
|
||||
updateField ("SUPPRESS_AU_PLIST_RESOURCE_USAGE", result.suppressResourceUsage);
|
||||
updateField ("BUNDLE_ID", result.bundleIdentifier);
|
||||
updateField ("ICON_FILE", result.iconFile);
|
||||
|
||||
result.type = type;
|
||||
|
||||
if (result.storyboardName.isNotEmpty())
|
||||
result.storyboardName = result.storyboardName.fromLastOccurrenceOf ("/", false, false)
|
||||
.upToLastOccurrenceOf (".storyboard", false, false);
|
||||
|
||||
setIfEmpty (result.microphonePermissionText,
|
||||
"This app requires audio input. If you do not have an audio interface connected it will use the built-in microphone.");
|
||||
setIfEmpty (result.cameraPermissionText,
|
||||
"This app requires access to the camera to function correctly.");
|
||||
setIfEmpty (result.bluetoothPermissionText,
|
||||
"This app requires access to Bluetooth to function correctly.");
|
||||
setIfEmpty (result.sendAppleEventsPermissionText,
|
||||
"This app requires the ability to send Apple events to function correctly.");
|
||||
|
||||
result.documentExtensions = result.documentExtensions.replace (";", ",");
|
||||
|
||||
// AUv3 needs a slightly different bundle ID
|
||||
if (type == juce::build_tools::ProjectType::Target::Type::AudioUnitv3PlugIn)
|
||||
{
|
||||
const auto bundleIdSegments = juce::StringArray::fromTokens (result.bundleIdentifier, ".", {});
|
||||
jassert (! bundleIdSegments.isEmpty());
|
||||
|
||||
const auto last = bundleIdSegments.isEmpty() ? ""
|
||||
: bundleIdSegments[bundleIdSegments.size() - 1];
|
||||
|
||||
result.bundleIdentifier += "." + last + "AUv3";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int writePlist (juce::ArgumentList&& args)
|
||||
{
|
||||
args.checkMinNumArguments (3);
|
||||
const auto kind = args.arguments.removeAndReturn (0);
|
||||
const auto input = args.arguments.removeAndReturn (0);
|
||||
const auto output = args.arguments.removeAndReturn (0);
|
||||
parsePlistOptions (input.resolveAsExistingFile(),
|
||||
juce::build_tools::ProjectType::Target::typeFromName (kind.text))
|
||||
.write (output.resolveAsFile());
|
||||
return 0;
|
||||
}
|
||||
|
||||
juce::build_tools::EntitlementOptions parseEntitlementsOptions (const juce::File& file,
|
||||
juce::build_tools::ProjectType::Target::Type type)
|
||||
{
|
||||
if (type == juce::build_tools::ProjectType::Target::ConsoleApp)
|
||||
juce::ConsoleApplication::fail ("Deduced project type does not require entitlements", 1);
|
||||
|
||||
const auto dict = parseProjectData (file);
|
||||
|
||||
UpdateField updateField { dict };
|
||||
|
||||
juce::build_tools::EntitlementOptions result;
|
||||
|
||||
updateField ("IS_IOS", result.isiOS);
|
||||
updateField ("IS_PLUGIN", result.isAudioPluginProject);
|
||||
updateField ("ICLOUD_PERMISSIONS_ENABLED", result.isiCloudPermissionsEnabled);
|
||||
updateField ("PUSH_NOTIFICATIONS_ENABLED", result.isPushNotificationsEnabled);
|
||||
updateField ("APP_GROUPS_ENABLED", result.isAppGroupsEnabled);
|
||||
updateField ("APP_GROUP_IDS", result.appGroupIdString);
|
||||
updateField ("HARDENED_RUNTIME_ENABLED", result.isHardenedRuntimeEnabled);
|
||||
updateField ("HARDENED_RUNTIME_OPTIONS", result.hardenedRuntimeOptions);
|
||||
updateField ("APP_SANDBOX_ENABLED", result.isAppSandboxEnabled);
|
||||
updateField ("APP_SANDBOX_INHERIT", result.isAppSandboxInhertianceEnabled);
|
||||
updateField ("APP_SANDBOX_OPTIONS", result.appSandboxOptions);
|
||||
updateField ("NETWORK_MULTICAST_ENABLED", result.isNetworkingMulticastEnabled);
|
||||
|
||||
result.type = type;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int writeEntitlements (juce::ArgumentList&& args)
|
||||
{
|
||||
args.checkMinNumArguments (3);
|
||||
const auto kind = args.arguments.removeAndReturn (0);
|
||||
const auto input = args.arguments.removeAndReturn (0);
|
||||
const auto output = args.arguments.removeAndReturn (0);
|
||||
|
||||
const auto options = parseEntitlementsOptions (input.resolveAsExistingFile(),
|
||||
juce::build_tools::ProjectType::Target::typeFromName (kind.text));
|
||||
juce::build_tools::overwriteFileIfDifferentOrThrow (output.resolveAsFile(), options.getEntitlementsFileContent());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int createAndWrite (const juce::File& file, juce::StringRef text)
|
||||
{
|
||||
if (file.create())
|
||||
return file.replaceWithText (text) ? 0 : 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int writePkgInfo (juce::ArgumentList&& args)
|
||||
{
|
||||
args.checkMinNumArguments (2);
|
||||
const auto kind = args.arguments.removeAndReturn (0);
|
||||
const auto output = args.arguments.removeAndReturn (0);
|
||||
|
||||
const auto projectType = juce::build_tools::ProjectType::Target::typeFromName (kind.text);
|
||||
return createAndWrite (output.resolveAsFile(),
|
||||
juce::build_tools::getXcodePackageType (projectType)
|
||||
+ juce::build_tools::getXcodeBundleSignature (projectType));
|
||||
}
|
||||
|
||||
juce::build_tools::ResourceRcOptions parseRcFileOptions (const juce::File& file)
|
||||
{
|
||||
const auto dict = parseProjectData (file);
|
||||
UpdateField updateField { dict };
|
||||
|
||||
juce::build_tools::ResourceRcOptions result;
|
||||
|
||||
updateField ("VERSION", result.version);
|
||||
updateField ("COMPANY_NAME", result.companyName);
|
||||
updateField ("COMPANY_COPYRIGHT", result.companyCopyright);
|
||||
updateField ("PROJECT_NAME", result.projectName);
|
||||
updateField ("ICON_FILE", result.icon);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int writeRcFile (juce::ArgumentList&& args)
|
||||
{
|
||||
args.checkMinNumArguments (2);
|
||||
const auto input = args.arguments.removeAndReturn (0);
|
||||
const auto output = args.arguments.removeAndReturn (0);
|
||||
parseRcFileOptions (input.resolveAsExistingFile()).write (output.resolveAsFile());
|
||||
return 0;
|
||||
}
|
||||
|
||||
juce::String createDefineStatements (juce::StringRef definitions)
|
||||
{
|
||||
const auto split = juce::StringArray::fromTokens (definitions, ";", "\"");
|
||||
|
||||
juce::String defineStatements;
|
||||
|
||||
for (const auto& def : split)
|
||||
{
|
||||
if (! def.startsWith ("JucePlugin_"))
|
||||
continue;
|
||||
|
||||
const auto defineName = def.upToFirstOccurrenceOf ("=", false, false);
|
||||
const auto defineValue = def.fromFirstOccurrenceOf ("=", false, false);
|
||||
defineStatements += "#define " + defineName + " " + defineValue + '\n';
|
||||
}
|
||||
|
||||
return defineStatements;
|
||||
}
|
||||
|
||||
int writeAuPluginDefines (juce::ArgumentList&& args)
|
||||
{
|
||||
args.checkMinNumArguments (2);
|
||||
const auto input = args.arguments.removeAndReturn (0);
|
||||
const auto output = args.arguments.removeAndReturn (0);
|
||||
|
||||
const auto dict = parseProjectData (input.resolveAsExistingFile());
|
||||
const auto getString = [&] (juce::StringRef key) { return getStringValue (dict, key); };
|
||||
|
||||
const auto defines = "#pragma once\n" + createDefineStatements (getString ("MODULE_DEFINITIONS"));
|
||||
return createAndWrite (output.resolveAsFile(), defines);
|
||||
}
|
||||
|
||||
juce::String createIncludeStatements (juce::StringRef definitions)
|
||||
{
|
||||
const auto split = juce::StringArray::fromTokens (definitions, ";", "\"");
|
||||
|
||||
juce::String includeStatements;
|
||||
|
||||
for (const auto& def : split)
|
||||
{
|
||||
constexpr auto moduleToken = "JUCE_MODULE_AVAILABLE_";
|
||||
|
||||
if (def.startsWith (moduleToken))
|
||||
{
|
||||
const auto moduleName = def.fromFirstOccurrenceOf (moduleToken, false, false)
|
||||
.upToFirstOccurrenceOf ("=", false, false);
|
||||
includeStatements += "#include <" + moduleName + "/" + moduleName + ".h>\n";
|
||||
}
|
||||
}
|
||||
|
||||
return includeStatements;
|
||||
}
|
||||
|
||||
int writeHeader (juce::ArgumentList&& args)
|
||||
{
|
||||
args.checkMinNumArguments (2);
|
||||
const auto input = args.arguments.removeAndReturn (0);
|
||||
const auto output = args.arguments.removeAndReturn (0);
|
||||
|
||||
const auto dict = parseProjectData (input.resolveAsExistingFile());
|
||||
|
||||
const auto getString = [&] (juce::StringRef key) { return getStringValue (dict, key); };
|
||||
|
||||
const auto includes = createIncludeStatements (getString ("MODULE_DEFINITIONS"));
|
||||
const auto projectName = getString ("PROJECT_NAME");
|
||||
const auto name = projectName.isEmpty() ? getString ("EXECUTABLE_NAME") : projectName;
|
||||
const auto versionString = getString ("VERSION");
|
||||
|
||||
const auto headerText = juce::String (headerTemplate)
|
||||
.replace ("${JUCE_INCLUDES}", includes)
|
||||
.replace ("${JUCE_EXECUTABLE_NAME}", name)
|
||||
.replace ("${JUCE_COMPANY_NAME}", getString ("COMPANY_NAME"))
|
||||
.replace ("${JUCE_PROJECT_VERSION}", versionString)
|
||||
.replace ("${JUCE_PROJECT_VERSION_HEX}", juce::build_tools::getVersionAsHex (versionString));
|
||||
|
||||
return createAndWrite (output.resolveAsFile(), headerText);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
juce::ScopedJuceInitialiser_GUI libraryInitialiser;
|
||||
|
||||
return juce::ConsoleApplication::invokeCatchingFailures ([argc, argv]
|
||||
{
|
||||
if (argc < 1)
|
||||
juce::ConsoleApplication::fail ("No arguments passed", 1);
|
||||
|
||||
const auto getString = [&] (const char* text)
|
||||
{
|
||||
return juce::String (juce::CharPointer_UTF8 (text));
|
||||
};
|
||||
|
||||
std::vector<juce::String> arguments;
|
||||
std::transform (argv, argv + argc, std::back_inserter (arguments), getString);
|
||||
|
||||
juce::ArgumentList argumentList { arguments.front(),
|
||||
juce::StringArray (arguments.data() + 1, (int) arguments.size() - 1) };
|
||||
|
||||
using Fn = std::add_lvalue_reference<decltype (writeBinaryData)>::type;
|
||||
|
||||
const std::unordered_map<juce::String, Fn> commands
|
||||
{
|
||||
{ "auplugindefines", writeAuPluginDefines },
|
||||
{ "binarydata", writeBinaryData },
|
||||
{ "entitlements", writeEntitlements },
|
||||
{ "header", writeHeader },
|
||||
{ "iosassets", writeiOSAssets },
|
||||
{ "macicon", writeMacIcon },
|
||||
{ "pkginfo", writePkgInfo },
|
||||
{ "plist", writePlist },
|
||||
{ "rcfile", writeRcFile },
|
||||
{ "winicon", writeWinIcon }
|
||||
};
|
||||
|
||||
argumentList.checkMinNumArguments (1);
|
||||
const auto mode = argumentList.arguments.removeAndReturn (0);
|
||||
const auto it = commands.find (mode.text);
|
||||
|
||||
if (it == commands.cend())
|
||||
juce::ConsoleApplication::fail ("No matching mode", 1);
|
||||
|
||||
return it->second (std::move (argumentList));
|
||||
});
|
||||
}
|
Reference in New Issue
Block a user