The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

576 lines
31KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2015 - ROLI Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. #ifndef JUCER_AUDIOPLUGINMODULE_H_INCLUDED
  18. #define JUCER_AUDIOPLUGINMODULE_H_INCLUDED
  19. #include "../Application/jucer_GlobalPreferences.h"
  20. //==============================================================================
  21. namespace
  22. {
  23. inline Value shouldBuildVST (Project& project) { return project.getProjectValue ("buildVST"); }
  24. inline Value shouldBuildVST3 (Project& project) { return project.getProjectValue ("buildVST3"); }
  25. inline Value shouldBuildAU (Project& project) { return project.getProjectValue ("buildAU"); }
  26. inline Value shouldBuildRTAS (Project& project) { return project.getProjectValue ("buildRTAS"); }
  27. inline Value shouldBuildAAX (Project& project) { return project.getProjectValue ("buildAAX"); }
  28. inline Value getPluginName (Project& project) { return project.getProjectValue ("pluginName"); }
  29. inline Value getPluginDesc (Project& project) { return project.getProjectValue ("pluginDesc"); }
  30. inline Value getPluginManufacturer (Project& project) { return project.getProjectValue ("pluginManufacturer"); }
  31. inline Value getPluginManufacturerCode (Project& project) { return project.getProjectValue ("pluginManufacturerCode"); }
  32. inline Value getPluginCode (Project& project) { return project.getProjectValue ("pluginCode"); }
  33. inline Value getPluginChannelConfigs (Project& project) { return project.getProjectValue ("pluginChannelConfigs"); }
  34. inline Value getPluginIsSynth (Project& project) { return project.getProjectValue ("pluginIsSynth"); }
  35. inline Value getPluginWantsMidiInput (Project& project) { return project.getProjectValue ("pluginWantsMidiIn"); }
  36. inline Value getPluginProducesMidiOut (Project& project) { return project.getProjectValue ("pluginProducesMidiOut"); }
  37. inline Value getPluginIsMidiEffectPlugin (Project& project) { return project.getProjectValue ("pluginIsMidiEffectPlugin"); }
  38. inline Value getPluginSilenceInProducesSilenceOut (Project& project) { return project.getProjectValue ("pluginSilenceInIsSilenceOut"); }
  39. inline Value getPluginEditorNeedsKeyFocus (Project& project) { return project.getProjectValue ("pluginEditorRequiresKeys"); }
  40. inline Value getPluginVSTCategory (Project& project) { return project.getProjectValue ("pluginVSTCategory"); }
  41. inline Value getPluginAUExportPrefix (Project& project) { return project.getProjectValue ("pluginAUExportPrefix"); }
  42. inline Value getPluginAUMainType (Project& project) { return project.getProjectValue ("pluginAUMainType"); }
  43. inline Value getPluginRTASCategory (Project& project) { return project.getProjectValue ("pluginRTASCategory"); }
  44. inline Value getPluginRTASBypassDisabled (Project& project) { return project.getProjectValue ("pluginRTASDisableBypass"); }
  45. inline Value getPluginRTASMultiMonoDisabled (Project& project) { return project.getProjectValue ("pluginRTASDisableMultiMono"); }
  46. inline Value getPluginAAXCategory (Project& project) { return project.getProjectValue ("pluginAAXCategory"); }
  47. inline Value getPluginAAXBypassDisabled (Project& project) { return project.getProjectValue ("pluginAAXDisableBypass"); }
  48. inline Value getPluginAAXMultiMonoDisabled (Project& project) { return project.getProjectValue ("pluginAAXDisableMultiMono"); }
  49. inline String getPluginRTASCategoryCode (Project& project)
  50. {
  51. if (static_cast<bool> (getPluginIsSynth (project).getValue()))
  52. return "ePlugInCategory_SWGenerators";
  53. String s (getPluginRTASCategory (project).toString());
  54. if (s.isEmpty())
  55. s = "ePlugInCategory_None";
  56. return s;
  57. }
  58. inline String getAUMainTypeString (Project& project)
  59. {
  60. String s (getPluginAUMainType (project).toString());
  61. if (s.isEmpty())
  62. {
  63. if (getPluginIsSynth (project).getValue()) s = "kAudioUnitType_MusicDevice";
  64. else if (getPluginWantsMidiInput (project).getValue()) s = "kAudioUnitType_MusicEffect";
  65. else s = "kAudioUnitType_Effect";
  66. }
  67. return s;
  68. }
  69. inline String getAUMainTypeCode (Project& project)
  70. {
  71. String s (getPluginAUMainType (project).toString());
  72. if (s.isEmpty())
  73. {
  74. if (getPluginIsMidiEffectPlugin (project).getValue()) s = "aumi";
  75. else if (getPluginIsSynth (project).getValue()) s = "aumu";
  76. else if (getPluginWantsMidiInput (project).getValue()) s = "aumf";
  77. else s = "aufx";
  78. }
  79. return s;
  80. }
  81. inline String getPluginVSTCategoryString (Project& project)
  82. {
  83. String s (getPluginVSTCategory (project).toString().trim());
  84. if (s.isEmpty())
  85. s = static_cast<bool> (getPluginIsSynth (project).getValue()) ? "kPlugCategSynth"
  86. : "kPlugCategEffect";
  87. return s;
  88. }
  89. inline int countMaxPluginChannels (const String& configString, bool isInput)
  90. {
  91. StringArray configs;
  92. configs.addTokens (configString, ", {}", StringRef());
  93. configs.trim();
  94. configs.removeEmptyStrings();
  95. jassert ((configs.size() & 1) == 0); // looks like a syntax error in the configs?
  96. int maxVal = 0;
  97. for (int i = (isInput ? 0 : 1); i < configs.size(); i += 2)
  98. maxVal = jmax (maxVal, configs[i].getIntValue());
  99. return maxVal;
  100. }
  101. inline String valueToBool (const Value& v)
  102. {
  103. return static_cast<bool> (v.getValue()) ? "1" : "0";
  104. }
  105. inline String valueToStringLiteral (const var& v)
  106. {
  107. return CppTokeniserFunctions::addEscapeChars (v.toString()).quoted();
  108. }
  109. inline String valueToCharLiteral (const var& v)
  110. {
  111. return CppTokeniserFunctions::addEscapeChars (v.toString().trim().substring (0, 4)).quoted ('\'');
  112. }
  113. inline void writePluginCharacteristicsFile (ProjectSaver& projectSaver)
  114. {
  115. Project& project = projectSaver.project;
  116. StringPairArray flags;
  117. flags.set ("JucePlugin_Build_VST", valueToBool (shouldBuildVST (project)));
  118. flags.set ("JucePlugin_Build_VST3", valueToBool (shouldBuildVST3 (project)));
  119. flags.set ("JucePlugin_Build_AU", valueToBool (shouldBuildAU (project)));
  120. flags.set ("JucePlugin_Build_RTAS", valueToBool (shouldBuildRTAS (project)));
  121. flags.set ("JucePlugin_Build_AAX", valueToBool (shouldBuildAAX (project)));
  122. flags.set ("JucePlugin_Name", valueToStringLiteral (getPluginName (project)));
  123. flags.set ("JucePlugin_Desc", valueToStringLiteral (getPluginDesc (project)));
  124. flags.set ("JucePlugin_Manufacturer", valueToStringLiteral (getPluginManufacturer (project)));
  125. flags.set ("JucePlugin_ManufacturerWebsite", valueToStringLiteral (project.getCompanyWebsite()));
  126. flags.set ("JucePlugin_ManufacturerEmail", valueToStringLiteral (project.getCompanyEmail()));
  127. flags.set ("JucePlugin_ManufacturerCode", valueToCharLiteral (getPluginManufacturerCode (project)));
  128. flags.set ("JucePlugin_PluginCode", valueToCharLiteral (getPluginCode (project)));
  129. flags.set ("JucePlugin_IsSynth", valueToBool (getPluginIsSynth (project)));
  130. flags.set ("JucePlugin_WantsMidiInput", valueToBool (getPluginWantsMidiInput (project)));
  131. flags.set ("JucePlugin_ProducesMidiOutput", valueToBool (getPluginProducesMidiOut (project)));
  132. flags.set ("JucePlugin_IsMidiEffect", valueToBool (getPluginIsMidiEffectPlugin (project)));
  133. flags.set ("JucePlugin_SilenceInProducesSilenceOut", valueToBool (getPluginSilenceInProducesSilenceOut (project)));
  134. flags.set ("JucePlugin_EditorRequiresKeyboardFocus", valueToBool (getPluginEditorNeedsKeyFocus (project)));
  135. flags.set ("JucePlugin_Version", project.getVersionString());
  136. flags.set ("JucePlugin_VersionCode", project.getVersionAsHex());
  137. flags.set ("JucePlugin_VersionString", valueToStringLiteral (project.getVersionString()));
  138. flags.set ("JucePlugin_VSTUniqueID", "JucePlugin_PluginCode");
  139. flags.set ("JucePlugin_VSTCategory", getPluginVSTCategoryString (project));
  140. flags.set ("JucePlugin_AUMainType", getAUMainTypeString (project));
  141. flags.set ("JucePlugin_AUSubType", "JucePlugin_PluginCode");
  142. flags.set ("JucePlugin_AUExportPrefix", getPluginAUExportPrefix (project).toString());
  143. flags.set ("JucePlugin_AUExportPrefixQuoted", valueToStringLiteral (getPluginAUExportPrefix (project)));
  144. flags.set ("JucePlugin_AUManufacturerCode", "JucePlugin_ManufacturerCode");
  145. flags.set ("JucePlugin_CFBundleIdentifier", project.getBundleIdentifier().toString());
  146. flags.set ("JucePlugin_RTASCategory", getPluginRTASCategoryCode (project));
  147. flags.set ("JucePlugin_RTASManufacturerCode", "JucePlugin_ManufacturerCode");
  148. flags.set ("JucePlugin_RTASProductId", "JucePlugin_PluginCode");
  149. flags.set ("JucePlugin_RTASDisableBypass", valueToBool (getPluginRTASBypassDisabled (project)));
  150. flags.set ("JucePlugin_RTASDisableMultiMono", valueToBool (getPluginRTASMultiMonoDisabled (project)));
  151. flags.set ("JucePlugin_AAXIdentifier", project.getAAXIdentifier().toString());
  152. flags.set ("JucePlugin_AAXManufacturerCode", "JucePlugin_ManufacturerCode");
  153. flags.set ("JucePlugin_AAXProductId", "JucePlugin_PluginCode");
  154. flags.set ("JucePlugin_AAXCategory", getPluginAAXCategory (project).toString());
  155. flags.set ("JucePlugin_AAXDisableBypass", valueToBool (getPluginAAXBypassDisabled (project)));
  156. flags.set ("JucePlugin_AAXDisableMultiMono", valueToBool (getPluginAAXMultiMonoDisabled (project)));
  157. {
  158. String plugInChannelConfig = getPluginChannelConfigs (project).toString();
  159. if (plugInChannelConfig.isNotEmpty())
  160. {
  161. flags.set ("JucePlugin_MaxNumInputChannels", String (countMaxPluginChannels (plugInChannelConfig, true)));
  162. flags.set ("JucePlugin_MaxNumOutputChannels", String (countMaxPluginChannels (plugInChannelConfig, false)));
  163. flags.set ("JucePlugin_PreferredChannelConfigurations", plugInChannelConfig);
  164. }
  165. }
  166. MemoryOutputStream mem;
  167. mem << "//==============================================================================" << newLine
  168. << "// Audio plugin settings.." << newLine
  169. << newLine;
  170. for (int i = 0; i < flags.size(); ++i)
  171. {
  172. mem << "#ifndef " << flags.getAllKeys()[i] << newLine
  173. << " #define " << flags.getAllKeys()[i].paddedRight (' ', 32) << " "
  174. << flags.getAllValues()[i] << newLine
  175. << "#endif" << newLine;
  176. }
  177. projectSaver.setExtraAppConfigFileContent (mem.toString());
  178. }
  179. inline static void fixMissingXcodePostBuildScript (ProjectExporter& exporter)
  180. {
  181. if (exporter.isXcode() && exporter.settings [Ids::postbuildCommand].toString().isEmpty())
  182. exporter.getSetting (Ids::postbuildCommand) = String::fromUTF8 (BinaryData::AudioPluginXCodeScript_txt,
  183. BinaryData::AudioPluginXCodeScript_txtSize);
  184. }
  185. inline String createEscapedStringForVersion (ProjectExporter& exporter, const String& text)
  186. {
  187. // (VS10 automatically adds escape characters to the quotes for this definition)
  188. return exporter.getVisualStudioVersion() < 10 ? CppTokeniserFunctions::addEscapeChars (text.quoted())
  189. : CppTokeniserFunctions::addEscapeChars (text).quoted();
  190. }
  191. inline String createRebasedPath (ProjectExporter& exporter, const RelativePath& path)
  192. {
  193. return createEscapedStringForVersion (exporter,
  194. exporter.rebaseFromProjectFolderToBuildTarget (path)
  195. .toWindowsStyle());
  196. }
  197. }
  198. //==============================================================================
  199. namespace VSTHelpers
  200. {
  201. inline bool isExporterSupported (ProjectExporter& exporter)
  202. {
  203. return ! exporter.isAndroid();
  204. }
  205. inline void addVSTFolderToPath (ProjectExporter& exporter, bool isVST3)
  206. {
  207. const String vstFolder (exporter.getVSTPathValue (isVST3).toString());
  208. if (vstFolder.isNotEmpty())
  209. exporter.addToExtraSearchPaths (RelativePath (vstFolder, RelativePath::projectFolder), 0);
  210. }
  211. inline void createVSTPathEditor (ProjectExporter& exporter, PropertyListBuilder& props, bool isVST3)
  212. {
  213. const String vstFormat (isVST3 ? "VST3" : "VST");
  214. props.add (new DependencyPathPropertyComponent (exporter.getVSTPathValue (isVST3),
  215. vstFormat + " Folder"),
  216. "If you're building a " + vstFormat + ", this must be the folder containing the " + vstFormat + " SDK. This should be an absolute path.");
  217. }
  218. inline void prepareExporter (ProjectExporter& exporter, ProjectSaver& projectSaver, bool isVST3)
  219. {
  220. if (isExporterSupported (exporter))
  221. {
  222. fixMissingXcodePostBuildScript (exporter);
  223. writePluginCharacteristicsFile (projectSaver);
  224. exporter.makefileTargetSuffix = ".so";
  225. Project::Item group (Project::Item::createGroup (const_cast<ProjectExporter&> (exporter).getProject(),
  226. "Juce VST Wrapper", "__jucevstfiles"));
  227. addVSTFolderToPath (exporter, isVST3);
  228. if (exporter.isVisualStudio())
  229. {
  230. if (! exporter.getExtraLinkerFlagsString().contains ("/FORCE:multiple"))
  231. exporter.getExtraLinkerFlags() = exporter.getExtraLinkerFlags().toString() + " /FORCE:multiple";
  232. RelativePath modulePath (exporter.rebaseFromProjectFolderToBuildTarget (RelativePath (exporter.getPathForModuleString ("juce_audio_plugin_client"),
  233. RelativePath::projectFolder)
  234. .getChildFile ("juce_audio_plugin_client")
  235. .getChildFile ("VST3")));
  236. for (ProjectExporter::ConfigIterator config (exporter); config.next();)
  237. {
  238. if (config->getValue (Ids::useRuntimeLibDLL).getValue().isVoid())
  239. config->getValue (Ids::useRuntimeLibDLL) = true;
  240. if (isVST3)
  241. if (config->getValue (Ids::postbuildCommand).toString().isEmpty())
  242. config->getValue (Ids::postbuildCommand) = "copy /Y \"$(OutDir)\\$(TargetFileName)\" \"$(OutDir)\\$(TargetName).vst3\"";
  243. }
  244. }
  245. if (exporter.isLinux())
  246. exporter.makefileExtraLinkerFlags.add ("-Wl,--no-undefined");
  247. }
  248. }
  249. inline void createPropertyEditors (ProjectExporter& exporter, PropertyListBuilder& props, bool isVST3)
  250. {
  251. if (isExporterSupported (exporter))
  252. {
  253. fixMissingXcodePostBuildScript (exporter);
  254. createVSTPathEditor (exporter, props, isVST3);
  255. }
  256. }
  257. }
  258. //==============================================================================
  259. namespace RTASHelpers
  260. {
  261. inline RelativePath getRTASRelativeFolderPath (ProjectExporter& exporter)
  262. {
  263. return RelativePath (exporter.getRTASPathValue().toString(), RelativePath::projectFolder);
  264. }
  265. inline bool isExporterSupported (ProjectExporter& exporter)
  266. {
  267. return exporter.isVisualStudio() || exporter.isXcode();
  268. }
  269. inline void addExtraSearchPaths (ProjectExporter& exporter)
  270. {
  271. RelativePath rtasFolder (getRTASRelativeFolderPath (exporter));
  272. if (exporter.isVisualStudio())
  273. {
  274. RelativePath juceWrapperFolder (exporter.getProject().getGeneratedCodeFolder(),
  275. exporter.getTargetFolder(), RelativePath::buildTargetFolder);
  276. exporter.extraSearchPaths.add (juceWrapperFolder.toWindowsStyle());
  277. static const char* p[] = { "AlturaPorts/TDMPlugins/PluginLibrary/EffectClasses",
  278. "AlturaPorts/TDMPlugins/PluginLibrary/ProcessClasses",
  279. "AlturaPorts/TDMPlugins/PluginLibrary/ProcessClasses/Interfaces",
  280. "AlturaPorts/TDMPlugins/PluginLibrary/Utilities",
  281. "AlturaPorts/TDMPlugins/PluginLibrary/RTASP_Adapt",
  282. "AlturaPorts/TDMPlugins/PluginLibrary/CoreClasses",
  283. "AlturaPorts/TDMPlugins/PluginLibrary/Controls",
  284. "AlturaPorts/TDMPlugins/PluginLibrary/Meters",
  285. "AlturaPorts/TDMPlugins/PluginLibrary/ViewClasses",
  286. "AlturaPorts/TDMPlugins/PluginLibrary/DSPClasses",
  287. "AlturaPorts/TDMPlugins/PluginLibrary/Interfaces",
  288. "AlturaPorts/TDMPlugins/common",
  289. "AlturaPorts/TDMPlugins/common/Platform",
  290. "AlturaPorts/TDMPlugins/common/Macros",
  291. "AlturaPorts/TDMPlugins/SignalProcessing/Public",
  292. "AlturaPorts/TDMPlugIns/DSPManager/Interfaces",
  293. "AlturaPorts/SADriver/Interfaces",
  294. "AlturaPorts/DigiPublic/Interfaces",
  295. "AlturaPorts/DigiPublic",
  296. "AlturaPorts/Fic/Interfaces/DAEClient",
  297. "AlturaPorts/NewFileLibs/Cmn",
  298. "AlturaPorts/NewFileLibs/DOA",
  299. "AlturaPorts/AlturaSource/PPC_H",
  300. "AlturaPorts/AlturaSource/AppSupport",
  301. "AvidCode/AVX2sdk/AVX/avx2/avx2sdk/inc",
  302. "xplat/AVX/avx2/avx2sdk/inc" };
  303. for (int i = 0; i < numElementsInArray (p); ++i)
  304. exporter.addToExtraSearchPaths (rtasFolder.getChildFile (p[i]));
  305. }
  306. else if (exporter.isXcode())
  307. {
  308. exporter.extraSearchPaths.add ("$(DEVELOPER_DIR)/Headers/FlatCarbon");
  309. exporter.extraSearchPaths.add ("$(SDKROOT)/Developer/Headers/FlatCarbon");
  310. static const char* p[] = { "AlturaPorts/TDMPlugIns/PlugInLibrary/Controls",
  311. "AlturaPorts/TDMPlugIns/PlugInLibrary/CoreClasses",
  312. "AlturaPorts/TDMPlugIns/PlugInLibrary/DSPClasses",
  313. "AlturaPorts/TDMPlugIns/PlugInLibrary/EffectClasses",
  314. "AlturaPorts/TDMPlugIns/PlugInLibrary/MacBuild",
  315. "AlturaPorts/TDMPlugIns/PlugInLibrary/Meters",
  316. "AlturaPorts/TDMPlugIns/PlugInLibrary/ProcessClasses",
  317. "AlturaPorts/TDMPlugIns/PlugInLibrary/ProcessClasses/Interfaces",
  318. "AlturaPorts/TDMPlugIns/PlugInLibrary/RTASP_Adapt",
  319. "AlturaPorts/TDMPlugIns/PlugInLibrary/Utilities",
  320. "AlturaPorts/TDMPlugIns/PlugInLibrary/ViewClasses",
  321. "AlturaPorts/TDMPlugIns/DSPManager/**",
  322. "AlturaPorts/TDMPlugIns/SupplementalPlugInLib/Encryption",
  323. "AlturaPorts/TDMPlugIns/SupplementalPlugInLib/GraphicsExtensions",
  324. "AlturaPorts/TDMPlugIns/common/**",
  325. "AlturaPorts/TDMPlugIns/common/PI_LibInterface",
  326. "AlturaPorts/TDMPlugIns/PACEProtection/**",
  327. "AlturaPorts/TDMPlugIns/SignalProcessing/**",
  328. "AlturaPorts/OMS/Headers",
  329. "AlturaPorts/Fic/Interfaces/**",
  330. "AlturaPorts/Fic/Source/SignalNets",
  331. "AlturaPorts/DSIPublicInterface/PublicHeaders",
  332. "DAEWin/Include",
  333. "AlturaPorts/DigiPublic/Interfaces",
  334. "AlturaPorts/DigiPublic",
  335. "AlturaPorts/NewFileLibs/DOA",
  336. "AlturaPorts/NewFileLibs/Cmn",
  337. "xplat/AVX/avx2/avx2sdk/inc",
  338. "xplat/AVX/avx2/avx2sdk/utils" };
  339. for (int i = 0; i < numElementsInArray (p); ++i)
  340. exporter.addToExtraSearchPaths (rtasFolder.getChildFile (p[i]));
  341. }
  342. }
  343. inline void prepareExporter (ProjectExporter& exporter, ProjectSaver& projectSaver)
  344. {
  345. if (isExporterSupported (exporter))
  346. {
  347. fixMissingXcodePostBuildScript (exporter);
  348. const RelativePath rtasFolder (getRTASRelativeFolderPath (exporter));
  349. if (exporter.isVisualStudio())
  350. {
  351. exporter.msvcTargetSuffix = ".dpm";
  352. exporter.msvcExtraPreprocessorDefs.set ("JucePlugin_WinBag_path",
  353. createRebasedPath (exporter,
  354. rtasFolder.getChildFile ("WinBag")));
  355. exporter.msvcDelayLoadedDLLs = "DAE.dll; DigiExt.dll; DSI.dll; PluginLib.dll; "
  356. "DSPManager.dll; DSPManager.dll; DSPManagerClientLib.dll; RTASClientLib.dll";
  357. if (! exporter.getExtraLinkerFlagsString().contains ("/FORCE:multiple"))
  358. exporter.getExtraLinkerFlags() = exporter.getExtraLinkerFlags().toString() + " /FORCE:multiple";
  359. RelativePath modulePath (exporter.rebaseFromProjectFolderToBuildTarget (RelativePath (exporter.getPathForModuleString ("juce_audio_plugin_client"),
  360. RelativePath::projectFolder)
  361. .getChildFile ("juce_audio_plugin_client")
  362. .getChildFile ("RTAS")));
  363. for (ProjectExporter::ConfigIterator config (exporter); config.next();)
  364. {
  365. config->getValue (Ids::msvcModuleDefinitionFile) = modulePath.getChildFile ("juce_RTAS_WinExports.def").toWindowsStyle();
  366. if (config->getValue (Ids::useRuntimeLibDLL).getValue().isVoid())
  367. config->getValue (Ids::useRuntimeLibDLL) = true;
  368. if (config->getValue (Ids::postbuildCommand).toString().isEmpty())
  369. config->getValue (Ids::postbuildCommand)
  370. = "copy /Y "
  371. + modulePath.getChildFile ("juce_RTAS_WinResources.rsr").toWindowsStyle().quoted()
  372. + " \"$(TargetPath)\".rsr";
  373. }
  374. }
  375. else
  376. {
  377. exporter.xcodeCanUseDwarf = false;
  378. exporter.xcodeExtraLibrariesDebug.add (rtasFolder.getChildFile ("MacBag/Libs/Debug/libPluginLibrary.a"));
  379. exporter.xcodeExtraLibrariesRelease.add (rtasFolder.getChildFile ("MacBag/Libs/Release/libPluginLibrary.a"));
  380. }
  381. writePluginCharacteristicsFile (projectSaver);
  382. addExtraSearchPaths (exporter);
  383. }
  384. }
  385. inline void createPropertyEditors (ProjectExporter& exporter, PropertyListBuilder& props)
  386. {
  387. if (isExporterSupported (exporter))
  388. {
  389. fixMissingXcodePostBuildScript (exporter);
  390. props.add (new DependencyPathPropertyComponent (exporter.getRTASPathValue(),
  391. "RTAS Folder"),
  392. "If you're building an RTAS, this must be the folder containing the RTAS SDK. This should be an absolute path.");
  393. }
  394. }
  395. }
  396. //==============================================================================
  397. namespace AUHelpers
  398. {
  399. inline void prepareExporter (ProjectExporter& exporter, ProjectSaver& projectSaver)
  400. {
  401. writePluginCharacteristicsFile (projectSaver);
  402. if (exporter.isXcode())
  403. {
  404. exporter.xcodeFrameworks.addTokens ("AudioUnit CoreAudioKit", false);
  405. XmlElement plistKey ("key");
  406. plistKey.addTextElement ("AudioComponents");
  407. XmlElement plistEntry ("array");
  408. XmlElement* dict = plistEntry.createNewChildElement ("dict");
  409. Project& project = exporter.getProject();
  410. addPlistDictionaryKey (dict, "name", getPluginManufacturer (project).toString()
  411. + ": " + getPluginName (project).toString());
  412. addPlistDictionaryKey (dict, "description", getPluginDesc (project).toString());
  413. addPlistDictionaryKey (dict, "factoryFunction", getPluginAUExportPrefix (project).toString() + "Factory");
  414. addPlistDictionaryKey (dict, "manufacturer", getPluginManufacturerCode (project).toString().trim().substring (0, 4));
  415. addPlistDictionaryKey (dict, "type", getAUMainTypeCode (project));
  416. addPlistDictionaryKey (dict, "subtype", getPluginCode (project).toString().trim().substring (0, 4));
  417. addPlistDictionaryKeyInt (dict, "version", project.getVersionAsHexInteger());
  418. exporter.xcodeExtraPListEntries.add (plistKey);
  419. exporter.xcodeExtraPListEntries.add (plistEntry);
  420. fixMissingXcodePostBuildScript (exporter);
  421. }
  422. }
  423. }
  424. //==============================================================================
  425. namespace AAXHelpers
  426. {
  427. inline RelativePath getAAXRelativeFolderPath (ProjectExporter& exporter)
  428. {
  429. return RelativePath (exporter.getAAXPathValue().toString(), RelativePath::projectFolder);
  430. }
  431. inline bool isExporterSupported (ProjectExporter& exporter)
  432. {
  433. return exporter.isVisualStudio() || exporter.isXcode();
  434. }
  435. inline void addExtraSearchPaths (ProjectExporter& exporter)
  436. {
  437. const RelativePath aaxFolder (getAAXRelativeFolderPath (exporter));
  438. exporter.addToExtraSearchPaths (aaxFolder);
  439. exporter.addToExtraSearchPaths (aaxFolder.getChildFile ("Interfaces"));
  440. exporter.addToExtraSearchPaths (aaxFolder.getChildFile ("Interfaces").getChildFile ("ACF"));
  441. }
  442. inline void prepareExporter (ProjectExporter& exporter, ProjectSaver& projectSaver)
  443. {
  444. if (isExporterSupported (exporter))
  445. {
  446. fixMissingXcodePostBuildScript (exporter);
  447. const RelativePath aaxLibsFolder (getAAXRelativeFolderPath (exporter).getChildFile ("Libs"));
  448. if (exporter.isVisualStudio())
  449. {
  450. for (ProjectExporter::ConfigIterator config (exporter); config.next();)
  451. if (config->getValue (Ids::useRuntimeLibDLL).getValue().isVoid())
  452. config->getValue (Ids::useRuntimeLibDLL) = true;
  453. exporter.msvcExtraPreprocessorDefs.set ("JucePlugin_AAXLibs_path",
  454. createRebasedPath (exporter, aaxLibsFolder));
  455. }
  456. else
  457. {
  458. exporter.xcodeExtraLibrariesDebug.add (aaxLibsFolder.getChildFile ("Debug/libAAXLibrary.a"));
  459. exporter.xcodeExtraLibrariesRelease.add (aaxLibsFolder.getChildFile ("Release/libAAXLibrary.a"));
  460. }
  461. writePluginCharacteristicsFile (projectSaver);
  462. addExtraSearchPaths (exporter);
  463. }
  464. }
  465. inline void createPropertyEditors (ProjectExporter& exporter, PropertyListBuilder& props)
  466. {
  467. if (isExporterSupported (exporter))
  468. {
  469. fixMissingXcodePostBuildScript (exporter);
  470. props.add (new DependencyPathPropertyComponent (exporter.getAAXPathValue(),
  471. "AAX SDK Folder"),
  472. "If you're building an AAX, this must be the folder containing the AAX SDK. This should be an absolute path.");
  473. }
  474. }
  475. }
  476. #endif // JUCER_AUDIOPLUGINMODULE_H_INCLUDED