/* ============================================================================== This file is part of the JUCE library. Copyright (c) 2015 - ROLI Ltd. Permission is granted to use this software under the terms of either: a) the GPL v2 (or any later version) b) the Affero GPL v3 Details of these licenses can be found at: www.gnu.org/licenses JUCE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. ------------------------------------------------------------------------------ To release a closed-source product which uses JUCE, commercial licenses are available: visit www.juce.com for more information. ============================================================================== */ #ifndef JUCER_AUDIOPLUGINMODULE_H_INCLUDED #define JUCER_AUDIOPLUGINMODULE_H_INCLUDED #include "../Application/jucer_GlobalPreferences.h" //============================================================================== namespace { inline Value shouldBuildVST (Project& project) { return project.getProjectValue ("buildVST"); } inline Value shouldBuildVST3 (Project& project) { return project.getProjectValue ("buildVST3"); } inline Value shouldBuildAU (Project& project) { return project.getProjectValue ("buildAU"); } inline Value shouldBuildRTAS (Project& project) { return project.getProjectValue ("buildRTAS"); } inline Value shouldBuildAAX (Project& project) { return project.getProjectValue ("buildAAX"); } inline Value getPluginName (Project& project) { return project.getProjectValue ("pluginName"); } inline Value getPluginDesc (Project& project) { return project.getProjectValue ("pluginDesc"); } inline Value getPluginManufacturer (Project& project) { return project.getProjectValue ("pluginManufacturer"); } inline Value getPluginManufacturerCode (Project& project) { return project.getProjectValue ("pluginManufacturerCode"); } inline Value getPluginCode (Project& project) { return project.getProjectValue ("pluginCode"); } inline Value getPluginChannelConfigs (Project& project) { return project.getProjectValue ("pluginChannelConfigs"); } inline Value getPluginIsSynth (Project& project) { return project.getProjectValue ("pluginIsSynth"); } inline Value getPluginWantsMidiInput (Project& project) { return project.getProjectValue ("pluginWantsMidiIn"); } inline Value getPluginProducesMidiOut (Project& project) { return project.getProjectValue ("pluginProducesMidiOut"); } inline Value getPluginSilenceInProducesSilenceOut (Project& project) { return project.getProjectValue ("pluginSilenceInIsSilenceOut"); } inline Value getPluginEditorNeedsKeyFocus (Project& project) { return project.getProjectValue ("pluginEditorRequiresKeys"); } inline Value getPluginVSTCategory (Project& project) { return project.getProjectValue ("pluginVSTCategory"); } inline Value getPluginAUExportPrefix (Project& project) { return project.getProjectValue ("pluginAUExportPrefix"); } inline Value getPluginAUMainType (Project& project) { return project.getProjectValue ("pluginAUMainType"); } inline Value getPluginRTASCategory (Project& project) { return project.getProjectValue ("pluginRTASCategory"); } inline Value getPluginRTASBypassDisabled (Project& project) { return project.getProjectValue ("pluginRTASDisableBypass"); } inline Value getPluginRTASMultiMonoDisabled (Project& project) { return project.getProjectValue ("pluginRTASDisableMultiMono"); } inline Value getPluginAAXCategory (Project& project) { return project.getProjectValue ("pluginAAXCategory"); } inline Value getPluginAAXBypassDisabled (Project& project) { return project.getProjectValue ("pluginAAXDisableBypass"); } inline Value getPluginAAXMultiMonoDisabled (Project& project) { return project.getProjectValue ("pluginAAXDisableMultiMono"); } inline String getPluginRTASCategoryCode (Project& project) { if (static_cast (getPluginIsSynth (project).getValue())) return "ePlugInCategory_SWGenerators"; String s (getPluginRTASCategory (project).toString()); if (s.isEmpty()) s = "ePlugInCategory_None"; return s; } inline String getAUMainTypeString (Project& project) { String s (getPluginAUMainType (project).toString()); if (s.isEmpty()) { if (getPluginIsSynth (project).getValue()) s = "kAudioUnitType_MusicDevice"; else if (getPluginWantsMidiInput (project).getValue()) s = "kAudioUnitType_MusicEffect"; else s = "kAudioUnitType_Effect"; } return s; } inline String getAUMainTypeCode (Project& project) { String s (getPluginAUMainType (project).toString()); if (s.isEmpty()) { if (getPluginIsSynth (project).getValue()) s = "aumu"; else if (getPluginWantsMidiInput (project).getValue()) s = "aumf"; else s = "aufx"; } return s; } inline String getPluginVSTCategoryString (Project& project) { String s (getPluginVSTCategory (project).toString().trim()); if (s.isEmpty()) s = static_cast (getPluginIsSynth (project).getValue()) ? "kPlugCategSynth" : "kPlugCategEffect"; return s; } inline int countMaxPluginChannels (const String& configString, bool isInput) { StringArray configs; configs.addTokens (configString, ", {}", StringRef()); configs.trim(); configs.removeEmptyStrings(); jassert ((configs.size() & 1) == 0); // looks like a syntax error in the configs? int maxVal = 0; for (int i = (isInput ? 0 : 1); i < configs.size(); i += 2) maxVal = jmax (maxVal, configs[i].getIntValue()); return maxVal; } inline String valueToBool (const Value& v) { return static_cast (v.getValue()) ? "1" : "0"; } inline String valueToStringLiteral (const var& v) { return CppTokeniserFunctions::addEscapeChars (v.toString()).quoted(); } inline String valueToCharLiteral (const var& v) { return CppTokeniserFunctions::addEscapeChars (v.toString().trim().substring (0, 4)).quoted ('\''); } inline void writePluginCharacteristicsFile (ProjectSaver& projectSaver) { Project& project = projectSaver.project; StringPairArray flags; flags.set ("JucePlugin_Build_VST", valueToBool (shouldBuildVST (project))); flags.set ("JucePlugin_Build_VST3", valueToBool (shouldBuildVST3 (project))); flags.set ("JucePlugin_Build_AU", valueToBool (shouldBuildAU (project))); flags.set ("JucePlugin_Build_RTAS", valueToBool (shouldBuildRTAS (project))); flags.set ("JucePlugin_Build_AAX", valueToBool (shouldBuildAAX (project))); flags.set ("JucePlugin_Name", valueToStringLiteral (getPluginName (project))); flags.set ("JucePlugin_Desc", valueToStringLiteral (getPluginDesc (project))); flags.set ("JucePlugin_Manufacturer", valueToStringLiteral (getPluginManufacturer (project))); flags.set ("JucePlugin_ManufacturerWebsite", valueToStringLiteral (project.getCompanyWebsite())); flags.set ("JucePlugin_ManufacturerEmail", valueToStringLiteral (project.getCompanyEmail())); flags.set ("JucePlugin_ManufacturerCode", valueToCharLiteral (getPluginManufacturerCode (project))); flags.set ("JucePlugin_PluginCode", valueToCharLiteral (getPluginCode (project))); flags.set ("JucePlugin_MaxNumInputChannels", String (countMaxPluginChannels (getPluginChannelConfigs (project).toString(), true))); flags.set ("JucePlugin_MaxNumOutputChannels", String (countMaxPluginChannels (getPluginChannelConfigs (project).toString(), false))); flags.set ("JucePlugin_PreferredChannelConfigurations", getPluginChannelConfigs (project).toString()); flags.set ("JucePlugin_IsSynth", valueToBool (getPluginIsSynth (project))); flags.set ("JucePlugin_WantsMidiInput", valueToBool (getPluginWantsMidiInput (project))); flags.set ("JucePlugin_ProducesMidiOutput", valueToBool (getPluginProducesMidiOut (project))); flags.set ("JucePlugin_SilenceInProducesSilenceOut", valueToBool (getPluginSilenceInProducesSilenceOut (project))); flags.set ("JucePlugin_EditorRequiresKeyboardFocus", valueToBool (getPluginEditorNeedsKeyFocus (project))); flags.set ("JucePlugin_Version", project.getVersionString()); flags.set ("JucePlugin_VersionCode", project.getVersionAsHex()); flags.set ("JucePlugin_VersionString", valueToStringLiteral (project.getVersionString())); flags.set ("JucePlugin_VSTUniqueID", "JucePlugin_PluginCode"); flags.set ("JucePlugin_VSTCategory", getPluginVSTCategoryString (project)); flags.set ("JucePlugin_AUMainType", getAUMainTypeString (project)); flags.set ("JucePlugin_AUSubType", "JucePlugin_PluginCode"); flags.set ("JucePlugin_AUExportPrefix", getPluginAUExportPrefix (project).toString()); flags.set ("JucePlugin_AUExportPrefixQuoted", valueToStringLiteral (getPluginAUExportPrefix (project))); flags.set ("JucePlugin_AUManufacturerCode", "JucePlugin_ManufacturerCode"); flags.set ("JucePlugin_CFBundleIdentifier", project.getBundleIdentifier().toString()); flags.set ("JucePlugin_RTASCategory", getPluginRTASCategoryCode (project)); flags.set ("JucePlugin_RTASManufacturerCode", "JucePlugin_ManufacturerCode"); flags.set ("JucePlugin_RTASProductId", "JucePlugin_PluginCode"); flags.set ("JucePlugin_RTASDisableBypass", valueToBool (getPluginRTASBypassDisabled (project))); flags.set ("JucePlugin_RTASDisableMultiMono", valueToBool (getPluginRTASMultiMonoDisabled (project))); flags.set ("JucePlugin_AAXIdentifier", project.getAAXIdentifier().toString()); flags.set ("JucePlugin_AAXManufacturerCode", "JucePlugin_ManufacturerCode"); flags.set ("JucePlugin_AAXProductId", "JucePlugin_PluginCode"); flags.set ("JucePlugin_AAXCategory", getPluginAAXCategory (project).toString()); flags.set ("JucePlugin_AAXDisableBypass", valueToBool (getPluginAAXBypassDisabled (project))); flags.set ("JucePlugin_AAXDisableMultiMono", valueToBool (getPluginAAXMultiMonoDisabled (project))); MemoryOutputStream mem; mem << "//==============================================================================" << newLine << "// Audio plugin settings.." << newLine << newLine; for (int i = 0; i < flags.size(); ++i) { mem << "#ifndef " << flags.getAllKeys()[i] << newLine << " #define " << flags.getAllKeys()[i].paddedRight (' ', 32) << " " << flags.getAllValues()[i] << newLine << "#endif" << newLine; } projectSaver.setExtraAppConfigFileContent (mem.toString()); } inline static void fixMissingXcodePostBuildScript (ProjectExporter& exporter) { if (exporter.isXcode() && exporter.settings [Ids::postbuildCommand].toString().isEmpty()) exporter.getSetting (Ids::postbuildCommand) = String::fromUTF8 (BinaryData::AudioPluginXCodeScript_txt, BinaryData::AudioPluginXCodeScript_txtSize); } inline String createEscapedStringForVersion (ProjectExporter& exporter, const String& text) { // (VS10 automatically adds escape characters to the quotes for this definition) return exporter.getVisualStudioVersion() < 10 ? CppTokeniserFunctions::addEscapeChars (text.quoted()) : CppTokeniserFunctions::addEscapeChars (text).quoted(); } inline String createRebasedPath (ProjectExporter& exporter, const RelativePath& path) { return createEscapedStringForVersion (exporter, exporter.rebaseFromProjectFolderToBuildTarget (path) .toWindowsStyle()); } } //============================================================================== namespace VSTHelpers { static void addVSTFolderToPath (ProjectExporter& exporter, bool isVST3) { const String vstFolder (exporter.getVSTPathValue (isVST3).toString()); if (vstFolder.isNotEmpty()) { RelativePath path (exporter.rebaseFromProjectFolderToBuildTarget (RelativePath (vstFolder, RelativePath::projectFolder))); if (exporter.isVisualStudio()) exporter.extraSearchPaths.add (path.toWindowsStyle()); else if (exporter.isLinux() || exporter.isXcode()) exporter.extraSearchPaths.insert (0, path.toUnixStyle()); } } static void createVSTPathEditor (ProjectExporter& exporter, PropertyListBuilder& props, bool isVST3) { const String vstFormat (isVST3 ? "VST3" : "VST"); props.add (new DependencyPathPropertyComponent (exporter.getVSTPathValue (isVST3), vstFormat + " Folder"), "If you're building a " + vstFormat + ", this must be the folder containing the " + vstFormat + " SDK. This should be an absolute path."); } static inline void prepareExporter (ProjectExporter& exporter, ProjectSaver& projectSaver, bool isVST3) { fixMissingXcodePostBuildScript (exporter); writePluginCharacteristicsFile (projectSaver); exporter.makefileTargetSuffix = ".so"; Project::Item group (Project::Item::createGroup (const_cast (exporter).getProject(), "Juce VST Wrapper", "__jucevstfiles")); RelativePath juceWrapperFolder (exporter.getProject().getGeneratedCodeFolder(), exporter.getTargetFolder(), RelativePath::buildTargetFolder); addVSTFolderToPath (exporter, isVST3); if (exporter.isWindows()) exporter.extraSearchPaths.add (juceWrapperFolder.toWindowsStyle()); else if (exporter.isLinux()) exporter.extraSearchPaths.add (juceWrapperFolder.toUnixStyle()); if (exporter.isVisualStudio()) { if (! exporter.getExtraLinkerFlagsString().contains ("/FORCE:multiple")) exporter.getExtraLinkerFlags() = exporter.getExtraLinkerFlags().toString() + " /FORCE:multiple"; RelativePath modulePath (exporter.rebaseFromProjectFolderToBuildTarget (RelativePath (exporter.getPathForModuleString ("juce_audio_plugin_client"), RelativePath::projectFolder) .getChildFile ("juce_audio_plugin_client") .getChildFile ("VST3"))); for (ProjectExporter::ConfigIterator config (exporter); config.next();) { if (config->getValue (Ids::useRuntimeLibDLL).getValue().isVoid()) config->getValue (Ids::useRuntimeLibDLL) = true; if (isVST3) if (config->getValue (Ids::postbuildCommand).toString().isEmpty()) config->getValue (Ids::postbuildCommand) = "copy /Y \"$(OutDir)\\$(TargetFileName)\" \"$(OutDir)\\$(TargetName).vst3\""; } } if (exporter.isLinux()) exporter.makefileExtraLinkerFlags.add ("-Wl,--no-undefined"); } static inline void createPropertyEditors (ProjectExporter& exporter, PropertyListBuilder& props, bool isVST3) { fixMissingXcodePostBuildScript (exporter); createVSTPathEditor (exporter, props, isVST3); } } //============================================================================== namespace RTASHelpers { static RelativePath getRTASRelativeFolderPath (ProjectExporter& exporter) { return RelativePath (exporter.getRTASPathValue().toString(), RelativePath::projectFolder); } static bool isExporterSupported (ProjectExporter& exporter) { return exporter.isVisualStudio() || exporter.isXcode(); } static void addExtraSearchPaths (ProjectExporter& exporter) { RelativePath rtasFolder (getRTASRelativeFolderPath (exporter)); if (exporter.isVisualStudio()) { RelativePath juceWrapperFolder (exporter.getProject().getGeneratedCodeFolder(), exporter.getTargetFolder(), RelativePath::buildTargetFolder); exporter.extraSearchPaths.add (juceWrapperFolder.toWindowsStyle()); static const char* p[] = { "AlturaPorts/TDMPlugins/PluginLibrary/EffectClasses", "AlturaPorts/TDMPlugins/PluginLibrary/ProcessClasses", "AlturaPorts/TDMPlugins/PluginLibrary/ProcessClasses/Interfaces", "AlturaPorts/TDMPlugins/PluginLibrary/Utilities", "AlturaPorts/TDMPlugins/PluginLibrary/RTASP_Adapt", "AlturaPorts/TDMPlugins/PluginLibrary/CoreClasses", "AlturaPorts/TDMPlugins/PluginLibrary/Controls", "AlturaPorts/TDMPlugins/PluginLibrary/Meters", "AlturaPorts/TDMPlugins/PluginLibrary/ViewClasses", "AlturaPorts/TDMPlugins/PluginLibrary/DSPClasses", "AlturaPorts/TDMPlugins/PluginLibrary/Interfaces", "AlturaPorts/TDMPlugins/common", "AlturaPorts/TDMPlugins/common/Platform", "AlturaPorts/TDMPlugins/common/Macros", "AlturaPorts/TDMPlugins/SignalProcessing/Public", "AlturaPorts/TDMPlugIns/DSPManager/Interfaces", "AlturaPorts/SADriver/Interfaces", "AlturaPorts/DigiPublic/Interfaces", "AlturaPorts/DigiPublic", "AlturaPorts/Fic/Interfaces/DAEClient", "AlturaPorts/NewFileLibs/Cmn", "AlturaPorts/NewFileLibs/DOA", "AlturaPorts/AlturaSource/PPC_H", "AlturaPorts/AlturaSource/AppSupport", "AvidCode/AVX2sdk/AVX/avx2/avx2sdk/inc", "xplat/AVX/avx2/avx2sdk/inc" }; for (int i = 0; i < numElementsInArray (p); ++i) exporter.addToExtraSearchPaths (rtasFolder.getChildFile (p[i])); } else if (exporter.isXcode()) { exporter.extraSearchPaths.add ("$(DEVELOPER_DIR)/Headers/FlatCarbon"); exporter.extraSearchPaths.add ("$(SDKROOT)/Developer/Headers/FlatCarbon"); static const char* p[] = { "AlturaPorts/TDMPlugIns/PlugInLibrary/Controls", "AlturaPorts/TDMPlugIns/PlugInLibrary/CoreClasses", "AlturaPorts/TDMPlugIns/PlugInLibrary/DSPClasses", "AlturaPorts/TDMPlugIns/PlugInLibrary/EffectClasses", "AlturaPorts/TDMPlugIns/PlugInLibrary/MacBuild", "AlturaPorts/TDMPlugIns/PlugInLibrary/Meters", "AlturaPorts/TDMPlugIns/PlugInLibrary/ProcessClasses", "AlturaPorts/TDMPlugIns/PlugInLibrary/ProcessClasses/Interfaces", "AlturaPorts/TDMPlugIns/PlugInLibrary/RTASP_Adapt", "AlturaPorts/TDMPlugIns/PlugInLibrary/Utilities", "AlturaPorts/TDMPlugIns/PlugInLibrary/ViewClasses", "AlturaPorts/TDMPlugIns/DSPManager/**", "AlturaPorts/TDMPlugIns/SupplementalPlugInLib/Encryption", "AlturaPorts/TDMPlugIns/SupplementalPlugInLib/GraphicsExtensions", "AlturaPorts/TDMPlugIns/common/**", "AlturaPorts/TDMPlugIns/common/PI_LibInterface", "AlturaPorts/TDMPlugIns/PACEProtection/**", "AlturaPorts/TDMPlugIns/SignalProcessing/**", "AlturaPorts/OMS/Headers", "AlturaPorts/Fic/Interfaces/**", "AlturaPorts/Fic/Source/SignalNets", "AlturaPorts/DSIPublicInterface/PublicHeaders", "DAEWin/Include", "AlturaPorts/DigiPublic/Interfaces", "AlturaPorts/DigiPublic", "AlturaPorts/NewFileLibs/DOA", "AlturaPorts/NewFileLibs/Cmn", "xplat/AVX/avx2/avx2sdk/inc", "xplat/AVX/avx2/avx2sdk/utils" }; for (int i = 0; i < numElementsInArray (p); ++i) exporter.addToExtraSearchPaths (rtasFolder.getChildFile (p[i])); } } static inline void prepareExporter (ProjectExporter& exporter, ProjectSaver& projectSaver) { if (isExporterSupported (exporter)) { fixMissingXcodePostBuildScript (exporter); const RelativePath rtasFolder (getRTASRelativeFolderPath (exporter)); if (exporter.isVisualStudio()) { exporter.msvcTargetSuffix = ".dpm"; exporter.msvcExtraPreprocessorDefs.set ("JucePlugin_WinBag_path", createRebasedPath (exporter, rtasFolder.getChildFile ("WinBag"))); exporter.msvcDelayLoadedDLLs = "DAE.dll; DigiExt.dll; DSI.dll; PluginLib.dll; " "DSPManager.dll; DSPManager.dll; DSPManagerClientLib.dll; RTASClientLib.dll"; if (! exporter.getExtraLinkerFlagsString().contains ("/FORCE:multiple")) exporter.getExtraLinkerFlags() = exporter.getExtraLinkerFlags().toString() + " /FORCE:multiple"; RelativePath modulePath (exporter.rebaseFromProjectFolderToBuildTarget (RelativePath (exporter.getPathForModuleString ("juce_audio_plugin_client"), RelativePath::projectFolder) .getChildFile ("juce_audio_plugin_client") .getChildFile ("RTAS"))); for (ProjectExporter::ConfigIterator config (exporter); config.next();) { config->getValue (Ids::msvcModuleDefinitionFile) = modulePath.getChildFile ("juce_RTAS_WinExports.def").toWindowsStyle(); if (config->getValue (Ids::useRuntimeLibDLL).getValue().isVoid()) config->getValue (Ids::useRuntimeLibDLL) = true; if (config->getValue (Ids::postbuildCommand).toString().isEmpty()) config->getValue (Ids::postbuildCommand) = "copy /Y " + modulePath.getChildFile ("juce_RTAS_WinResources.rsr").toWindowsStyle().quoted() + " \"$(TargetPath)\".rsr"; } } else { exporter.xcodeCanUseDwarf = false; exporter.xcodeExtraLibrariesDebug.add (rtasFolder.getChildFile ("MacBag/Libs/Debug/libPluginLibrary.a")); exporter.xcodeExtraLibrariesRelease.add (rtasFolder.getChildFile ("MacBag/Libs/Release/libPluginLibrary.a")); } writePluginCharacteristicsFile (projectSaver); addExtraSearchPaths (exporter); } } static inline void createPropertyEditors (ProjectExporter& exporter, PropertyListBuilder& props) { if (isExporterSupported (exporter)) { fixMissingXcodePostBuildScript (exporter); props.add (new DependencyPathPropertyComponent (exporter.getRTASPathValue(), "RTAS Folder"), "If you're building an RTAS, this must be the folder containing the RTAS SDK. This should be an absolute path."); } } } //============================================================================== namespace AUHelpers { static inline void prepareExporter (ProjectExporter& exporter, ProjectSaver& projectSaver) { writePluginCharacteristicsFile (projectSaver); if (exporter.isXcode()) { exporter.xcodeFrameworks.addTokens ("AudioUnit CoreAudioKit", false); XmlElement plistKey ("key"); plistKey.addTextElement ("AudioComponents"); XmlElement plistEntry ("array"); XmlElement* dict = plistEntry.createNewChildElement ("dict"); Project& project = exporter.getProject(); addPlistDictionaryKey (dict, "name", getPluginManufacturer (project).toString() + ": " + getPluginName (project).toString()); addPlistDictionaryKey (dict, "description", getPluginDesc (project).toString()); addPlistDictionaryKey (dict, "factoryFunction", getPluginAUExportPrefix (project).toString() + "Factory"); addPlistDictionaryKey (dict, "manufacturer", getPluginManufacturerCode (project).toString().trim().substring (0, 4)); addPlistDictionaryKey (dict, "type", getAUMainTypeCode (project)); addPlistDictionaryKey (dict, "subtype", getPluginCode (project).toString().trim().substring (0, 4)); addPlistDictionaryKeyInt (dict, "version", project.getVersionAsHexInteger()); exporter.xcodeExtraPListEntries.add (plistKey); exporter.xcodeExtraPListEntries.add (plistEntry); fixMissingXcodePostBuildScript (exporter); } } } //============================================================================== namespace AAXHelpers { static RelativePath getAAXRelativeFolderPath (ProjectExporter& exporter) { return RelativePath (exporter.getAAXPathValue().toString(), RelativePath::projectFolder); } static bool isExporterSupported (ProjectExporter& exporter) { return exporter.isVisualStudio() || exporter.isXcode(); } static void addExtraSearchPaths (ProjectExporter& exporter) { const RelativePath aaxFolder (getAAXRelativeFolderPath (exporter)); exporter.addToExtraSearchPaths (aaxFolder); exporter.addToExtraSearchPaths (aaxFolder.getChildFile ("Interfaces")); exporter.addToExtraSearchPaths (aaxFolder.getChildFile ("Interfaces").getChildFile ("ACF")); } static inline void prepareExporter (ProjectExporter& exporter, ProjectSaver& projectSaver) { if (isExporterSupported (exporter)) { fixMissingXcodePostBuildScript (exporter); const RelativePath aaxLibsFolder (getAAXRelativeFolderPath (exporter).getChildFile ("Libs")); if (exporter.isVisualStudio()) { for (ProjectExporter::ConfigIterator config (exporter); config.next();) if (config->getValue (Ids::useRuntimeLibDLL).getValue().isVoid()) config->getValue (Ids::useRuntimeLibDLL) = true; exporter.msvcExtraPreprocessorDefs.set ("JucePlugin_AAXLibs_path", createRebasedPath (exporter, aaxLibsFolder)); } else { exporter.xcodeExtraLibrariesDebug.add (aaxLibsFolder.getChildFile ("Debug/libAAXLibrary.a")); exporter.xcodeExtraLibrariesRelease.add (aaxLibsFolder.getChildFile ("Release/libAAXLibrary.a")); } writePluginCharacteristicsFile (projectSaver); addExtraSearchPaths (exporter); } } static inline void createPropertyEditors (ProjectExporter& exporter, PropertyListBuilder& props) { if (isExporterSupported (exporter)) { fixMissingXcodePostBuildScript (exporter); props.add (new DependencyPathPropertyComponent (exporter.getAAXPathValue(), "AAX SDK Folder"), "If you're building an AAX, this must be the folder containing the AAX SDK. This should be an absolute path."); } } } #endif // JUCER_AUDIOPLUGINMODULE_H_INCLUDED