diff --git a/extras/Projucer/Source/Project/UI/Sidebar/jucer_LiveBuildTab.h b/extras/Projucer/Source/Project/UI/Sidebar/jucer_LiveBuildTab.h index 30eacc29ee..6ce902beeb 100644 --- a/extras/Projucer/Source/Project/UI/Sidebar/jucer_LiveBuildTab.h +++ b/extras/Projucer/Source/Project/UI/Sidebar/jucer_LiveBuildTab.h @@ -192,7 +192,7 @@ private: if (isMac) if (osType < SystemStats::MacOSX_10_9) - return "Live-build features are available only on MacOSX 10.9 or higher."; + return "Live-build features are available only on macOS 10.9 or higher."; if (isWin) if (! SystemStats::isOperatingSystem64Bit() || osType < SystemStats::Windows8_0) diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h index 8afa48e418..92c3a07c3e 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h @@ -34,44 +34,62 @@ namespace static const StringArray iOSVersions { "9.0", "9.1", "9.2", "9.3", "10.0", "10.1", "10.2", "10.3", "11.0", "12.0", "13.0" }; - static const char* const macOSVersions[] { "10.7", "10.8", "10.9", "10.10", "10.11", "10.12", "10.13", - "10.14", "10.15", "10.16", "11.0" }; - - class MacOSVersion + enum class MacOSVersion { - public: - MacOSVersion() = default; - explicit MacOSVersion (int i) : index (i) {} - - bool operator< (const MacOSVersion& other) const { return index < other.index; } - bool operator== (const MacOSVersion& other) const { return index == other.index; } - bool operator!= (const MacOSVersion& other) const { return index != other.index; } - - MacOSVersion& operator++() - { - ++index; - return *this; - } - - String getName() const { return macOSVersions[index]; } - String getDisplayName() const { return getName() + " SDK"; } - String getRootName() const { return "macosx" + getName(); } - - private: - int index{}; + v10_7, + v10_8, + v10_9, + v10_10, + v10_11, + v10_12, + v10_13, + v10_14, + v10_15, + v10_16, + v11_0, }; - static const MacOSVersion nextMacOSVersion { numElementsInArray (macOSVersions) }; - static const MacOSVersion oldestDeploymentTarget { 0 }; - static const MacOSVersion macOSDefaultVersion { 4 }; - static const MacOSVersion oldestSDKVersion { 4 }; - static const MacOSVersion minimumAUv3SDKVersion { 4 }; + static const char* const getName (MacOSVersion m) + { + switch (m) + { + case MacOSVersion::v10_7: return "10.7"; + case MacOSVersion::v10_8: return "10.8"; + case MacOSVersion::v10_9: return "10.9"; + case MacOSVersion::v10_10: return "10.10"; + case MacOSVersion::v10_11: return "10.11"; + case MacOSVersion::v10_12: return "10.12"; + case MacOSVersion::v10_13: return "10.13"; + case MacOSVersion::v10_14: return "10.14"; + case MacOSVersion::v10_15: return "10.15"; + case MacOSVersion::v10_16: return "10.16"; + case MacOSVersion::v11_0: return "11.0"; + default: break; + } + + jassertfalse; + return ""; + } + + static String getDisplayName (MacOSVersion m) { return getName (m) + String (" SDK"); } + static String getRootName (MacOSVersion m) { return String ("macosx") + getName (m); } + + constexpr auto nextMacOSVersion = (MacOSVersion) ((int) MacOSVersion::v11_0 + 1); + constexpr auto oldestDeploymentTarget = MacOSVersion::v10_7; + constexpr auto macOSDefaultVersion = MacOSVersion::v10_11; + constexpr auto oldestSDKVersion = MacOSVersion::v10_11; + constexpr auto minimumAUv3SDKVersion = MacOSVersion::v10_11; + + static MacOSVersion& operator++ (MacOSVersion& m) + { + return m = (MacOSVersion) ((int) m + 1); + } static String getOSXSDKVersion (const String& sdkVersion) { - for (auto v = oldestSDKVersion; v < nextMacOSVersion; ++v) - if (sdkVersion == v.getDisplayName()) - return v.getRootName(); + for (auto v = oldestSDKVersion; v != nextMacOSVersion; ++v) + if (sdkVersion == getDisplayName (v)) + return getRootName (v); return "macosx"; } @@ -81,8 +99,8 @@ namespace { ContainerType container; - for (auto v = oldestVersion; v < nextMacOSVersion; ++v) - container.add (displayName ? v.getDisplayName() : v.getName()); + for (auto v = oldestVersion; v != nextMacOSVersion; ++v) + container.add (displayName ? getDisplayName (v) : getName (v)); return container; } @@ -99,7 +117,7 @@ class XcodeProjectExporter : public ProjectExporter { public: //============================================================================== - static String getDisplayNameMac() { return "Xcode (MacOSX)"; } + static String getDisplayNameMac() { return "Xcode (macOS)"; } static String getDisplayNameiOS() { return "Xcode (iOS)"; } static String getTargetFolderNameMac() { return "MacOSX"; } @@ -117,6 +135,7 @@ public: pListPrefixHeaderValue (settings, Ids::pListPrefixHeader, getUndoManager()), pListPreprocessValue (settings, Ids::pListPreprocess, getUndoManager()), subprojectsValue (settings, Ids::xcodeSubprojects, getUndoManager()), + validArchsValue (settings, Ids::xcodeValidArchs, getUndoManager(), getAllArchs(), ","), extraFrameworksValue (settings, Ids::extraFrameworks, getUndoManager()), frameworkSearchPathsValue (settings, Ids::frameworkSearchPaths, getUndoManager()), extraCustomFrameworksValue (settings, Ids::extraCustomFrameworks, getUndoManager()), @@ -207,6 +226,8 @@ public: "UIInterfaceOrientationLandscapeLeft", "UIInterfaceOrientationLandscapeRight" }; } + Array getAllArchs() const { return { "i386", "x86_64", "arm64", "arm64e"}; } + Array getiPhoneScreenOrientations() const { return *iPhoneScreenOrientationValue.get().getArray(); } Array getiPadScreenOrientations() const { return *iPadScreenOrientationValue.get().getArray(); } @@ -222,6 +243,8 @@ public: bool isAppSandboxInhertianceEnabled() const { return appSandboxInheritanceValue.get(); } Array getAppSandboxOptions() const { return *appSandboxOptionsValue.get().getArray(); } + Array getValidArchs() const { return *validArchsValue.get().getArray(); } + bool isMicrophonePermissionEnabled() const { return microphonePermissionNeededValue.get(); } String getMicrophonePermissionsTextString() const { return microphonePermissionsTextValue.get(); } @@ -364,6 +387,10 @@ public: if (isOSX()) { + props.add (new MultiChoicePropertyComponent (validArchsValue, "Valid Architectures", getAllArchs(), getAllArchs()), + "The full set of architectures which this project may target. " + "Each configuration will build for the intersection of this property, and the per-configuration macOS Architecture property"); + props.add (new ChoicePropertyComponent (appSandboxValue, "Use App Sandbox"), "Enable this to use the app sandbox."); @@ -664,7 +691,7 @@ public: if (hasInvalidPostBuildScript()) { String alertWindowText = iOS ? "Your Xcode (iOS) Exporter settings use an invalid post-build script. Click 'Update' to remove it." - : "Your Xcode (OSX) Exporter settings use a pre-JUCE 4.2 post-build script to move the plug-in binaries to their plug-in install folders.\n\n" + : "Your Xcode (macOS) Exporter settings use a pre-JUCE 4.2 post-build script to move the plug-in binaries to their plug-in install folders.\n\n" "Since JUCE 4.2, this is instead done using \"AU/VST/VST2/AAX/RTAS Binary Location\" in the Xcode (OS X) configuration settings.\n\n" "Click 'Update' to remove the script (otherwise your plug-in may not compile correctly)."; @@ -703,7 +730,7 @@ protected: : BuildConfiguration (p, t, e), iOS (isIOS), osxSDKVersion (config, Ids::osxSDK, getUndoManager()), - osxDeploymentTarget (config, Ids::osxCompatibility, getUndoManager(), macOSDefaultVersion.getDisplayName()), + osxDeploymentTarget (config, Ids::osxCompatibility, getUndoManager(), getDisplayName (macOSDefaultVersion)), iosDeploymentTarget (config, Ids::iosCompatibility, getUndoManager(), iOSDefaultVersion), osxArchitecture (config, Ids::osxArchitecture, getUndoManager(), osxArch_Default), customXcodeFlags (config, Ids::customXcodeFlags, getUndoManager()), @@ -746,23 +773,23 @@ protected: } else { - props.add (new ChoicePropertyComponent (osxSDKVersion, "OSX Base SDK Version", getSDKChoiceList (oldestSDKVersion, true), - getSDKChoiceList> (oldestSDKVersion, true)), + props.add (new ChoicePropertyComponent (osxSDKVersion, "macOS Base SDK Version", getSDKChoiceList (oldestSDKVersion, true), + getSDKChoiceList> (oldestSDKVersion, true)), "The version of the macOS SDK to link against. If \"Default\" is selected then the Xcode default will be used."); - props.add (new ChoicePropertyComponent (osxDeploymentTarget, "OSX Deployment Target", getSDKChoiceList (oldestDeploymentTarget, false), - getSDKChoiceList> (oldestDeploymentTarget, true)), - "The minimum version of OSX that the target binary will be compatible with."); + props.add (new ChoicePropertyComponent (osxDeploymentTarget, "macOS Deployment Target", getSDKChoiceList (oldestDeploymentTarget, false), + getSDKChoiceList> (oldestDeploymentTarget, true)), + "The minimum version of macOS that the target binary will be compatible with."); - props.add (new ChoicePropertyComponent (osxArchitecture, "OSX Architecture", - { "Native architecture of build machine", "Universal Binary (32-bit)", "Universal Binary (32/64-bit)", "Universal Binary (64-bit)" }, - { osxArch_Native, osxArch_32BitUniversal, osxArch_64BitUniversal, osxArch_64Bit }), - "The type of OSX binary that will be produced."); + props.add (new ChoicePropertyComponent (osxArchitecture, "macOS Architecture", + { "Native architecture of build machine", "Standard 32-bit", "Standard 32/64-bit", "Standard 64-bit" }, + { osxArch_Native, osxArch_32BitUniversal, osxArch_64BitUniversal, osxArch_64Bit }), + "The type of macOS binary that will be produced."); } props.add (new TextPropertyComponent (customXcodeFlags, "Custom Xcode Flags", 8192, true), "A comma-separated list of custom Xcode setting flags which will be appended to the list of generated flags, " - "e.g. MACOSX_DEPLOYMENT_TARGET_i386 = 10.5, VALID_ARCHS = \"ppc i386 x86_64\""); + "e.g. MACOSX_DEPLOYMENT_TARGET_i386 = 10.5"); props.add (new TextPropertyComponent (plistPreprocessorDefinitions, "PList Preprocessor Definitions", 2048, true), "Preprocessor definitions used during PList preprocessing (see PList Preprocess)."); @@ -1332,6 +1359,21 @@ public: else if (arch == osxArch_64BitUniversal) s.set ("ARCHS", "\"$(ARCHS_STANDARD_32_64_BIT)\""); else if (arch == osxArch_64Bit) s.set ("ARCHS", "\"$(ARCHS_STANDARD_64_BIT)\""); + if (! owner.isiOS()) + { + auto validArchs = owner.getValidArchs(); + + if (! validArchs.isEmpty()) + { + const auto joined = std::accumulate (validArchs.begin(), + validArchs.end(), + String(), + [] (String str, const var& v) { return str + v.toString() + " "; }); + + s.set ("VALID_ARCHS", joined.trim().quoted()); + } + } + StringArray headerPaths (getHeaderSearchPaths (config)); headerPaths.add ("\"$(inherited)\""); s.set ("HEADER_SEARCH_PATHS", indentParenthesisedList (headerPaths, 1)); @@ -1839,11 +1881,11 @@ public: auto minVersion = (type == Target::AudioUnitv3PlugIn ? minimumAUv3SDKVersion : oldestDeploymentTarget); - for (auto v = minVersion; v < nextMacOSVersion; ++v) - if (deploymentTarget == v.getDisplayName()) - return v.getName(); + for (auto v = minVersion; v != nextMacOSVersion; ++v) + if (deploymentTarget == getDisplayName (v)) + return ::getName (v); - return minVersion.getName(); + return ::getName (minVersion); } //============================================================================== @@ -1873,6 +1915,7 @@ private: ValueWithDefault customPListValue, pListPrefixHeaderValue, pListPreprocessValue, subprojectsValue, + validArchsValue, extraFrameworksValue, frameworkSearchPathsValue, extraCustomFrameworksValue, embeddedFrameworksValue, postbuildCommandValue, prebuildCommandValue, duplicateAppExResourcesFolderValue, iosDeviceFamilyValue, iPhoneScreenOrientationValue, diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h b/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h index edd3b091fe..578ce1cd07 100644 --- a/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h +++ b/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h @@ -162,6 +162,7 @@ namespace Ids DECLARE_ID (noWarnings); DECLARE_ID (resource); DECLARE_ID (xcodeResource); + DECLARE_ID (xcodeValidArchs); DECLARE_ID (className); DECLARE_ID (classDesc); DECLARE_ID (controlPoint);