Add remaining files
[juce-lv2.git] / juce / source / extras / Introjucer / Source / Project / jucer_ProjectExport_XCode.h
blobc2fd313c60e493a8609699d44f755573bb2566f9
1 /*
2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-10 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #ifndef __JUCER_PROJECTEXPORT_XCODE_JUCEHEADER__
27 #define __JUCER_PROJECTEXPORT_XCODE_JUCEHEADER__
29 #include "jucer_ProjectExporter.h"
32 //==============================================================================
33 class XCodeProjectExporter : public ProjectExporter
35 public:
36 //==============================================================================
37 static const char* getNameMac() { return "XCode (MacOSX)"; }
38 static const char* getNameiOS() { return "XCode (iOS)"; }
39 static const char* getValueTreeTypeName (bool iPhone) { return iPhone ? "XCODE_IPHONE" : "XCODE_MAC"; }
41 //==============================================================================
42 XCodeProjectExporter (Project& project_, const ValueTree& settings_, const bool iPhone_)
43 : ProjectExporter (project_, settings_),
44 iPhone (iPhone_)
46 name = iPhone ? getNameiOS() : getNameMac();
48 projectIDSalt = hashCode64 (project.getProjectUID());
50 if (getTargetLocation().toString().isEmpty())
51 getTargetLocation() = getDefaultBuildsRootFolder() + (iPhone ? "iOS" : "MacOSX");
53 if (getVSTFolder().toString().isEmpty())
54 getVSTFolder() = "~/SDKs/vstsdk2.4";
56 if (getRTASFolder().toString().isEmpty())
57 getRTASFolder() = "~/SDKs/PT_80_SDK";
59 if (getSettings() ["objCExtraSuffix"].isVoid())
60 getObjCSuffix() = createAlphaNumericUID();
63 static XCodeProjectExporter* createForSettings (Project& project, const ValueTree& settings)
65 if (settings.hasType (getValueTreeTypeName (false)))
66 return new XCodeProjectExporter (project, settings, false);
67 else if (settings.hasType (getValueTreeTypeName (true)))
68 return new XCodeProjectExporter (project, settings, true);
70 return 0;
73 //==============================================================================
74 Value getObjCSuffix() { return getSetting ("objCExtraSuffix"); }
76 bool isDefaultFormatForCurrentOS()
78 #if JUCE_MAC
79 return ! iPhone;
80 #else
81 return false;
82 #endif
85 bool isPossibleForCurrentProject() { return project.isGUIApplication() || ! iPhone; }
86 bool usesMMFiles() const { return true; }
88 void createPropertyEditors (Array <PropertyComponent*>& props)
90 ProjectExporter::createPropertyEditors (props);
92 props.add (new TextPropertyComponent (getObjCSuffix(), "Objective-C class name suffix", 64, false));
93 props.getLast()->setTooltip ("Because objective-C linkage is done by string-matching, you can get horrible linkage mix-ups when different modules containing the "
94 "same class-names are loaded simultaneously. This setting lets you provide a unique string that will be used in naming the obj-C classes in your executable to avoid this.");
96 if (project.isGUIApplication() && ! iPhone)
98 props.add (new TextPropertyComponent (getSetting ("documentExtensions"), "Document file extensions", 128, false));
99 props.getLast()->setTooltip ("A comma-separated list of file extensions for documents that your app can open.");
101 else if (iPhone)
103 props.add (new BooleanPropertyComponent (getSetting ("UIFileSharingEnabled"), "File Sharing Enabled", "Enabled"));
104 props.getLast()->setTooltip ("Enable this to expose your app's files to iTunes.");
106 props.add (new BooleanPropertyComponent (getSetting ("UIStatusBarHidden"), "Status Bar Hidden", "Enabled"));
107 props.getLast()->setTooltip ("Enable this to disable the status bar in your app.");
111 void launchProject()
113 getProjectBundle().startAsProcess();
116 //==============================================================================
117 void create()
119 infoPlistFile = getTargetFolder().getChildFile ("Info.plist");
121 createIconFile();
123 File projectBundle (getProjectBundle());
124 createDirectoryOrThrow (projectBundle);
126 createObjects();
128 File projectFile (projectBundle.getChildFile ("project.pbxproj"));
131 MemoryOutputStream mo;
132 writeProjectFile (mo);
133 overwriteFileIfDifferentOrThrow (projectFile, mo);
136 writeInfoPlistFile();
139 private:
140 OwnedArray<ValueTree> pbxBuildFiles, pbxFileReferences, groups, misc, projectConfigs, targetConfigs;
141 StringArray buildPhaseIDs, resourceIDs, sourceIDs, frameworkIDs;
142 StringArray frameworkFileIDs, rezFileIDs, resourceFileRefs;
143 File infoPlistFile, iconFile;
144 int64 projectIDSalt;
145 const bool iPhone;
147 static const String sanitisePath (const String& path)
149 if (path.startsWithChar ('~'))
150 return "$(HOME)" + path.substring (1);
152 return path;
155 const File getProjectBundle() const { return getTargetFolder().getChildFile (project.getProjectFilenameRoot()).withFileExtension (".xcodeproj"); }
157 bool hasPList() const { return ! (project.isLibrary() || project.isCommandLineApp()); }
158 const String getAudioPluginBundleExtension() const { return "component"; }
160 //==============================================================================
161 void createObjects()
163 if (! project.isLibrary())
164 addFrameworks();
166 const String productName (project.getConfiguration (0).getTargetBinaryName().toString());
168 if (project.isGUIApplication()) addBuildProduct ("wrapper.application", productName + ".app");
169 else if (project.isCommandLineApp()) addBuildProduct ("compiled.mach-o.executable", productName);
170 else if (project.isLibrary()) addBuildProduct ("archive.ar", getLibbedFilename (productName));
171 else if (project.isAudioPlugin()) addBuildProduct ("wrapper.cfbundle", productName + "." + getAudioPluginBundleExtension());
172 else if (project.isBrowserPlugin()) addBuildProduct ("wrapper.cfbundle", productName + ".plugin");
173 else jassert (productName.isEmpty());
175 if (hasPList())
177 RelativePath plistPath (infoPlistFile, getTargetFolder(), RelativePath::buildTargetFolder);
178 addFileReference (plistPath);
179 resourceFileRefs.add (createID (plistPath));
182 if (iconFile.exists())
184 RelativePath iconPath (iconFile, getTargetFolder(), RelativePath::buildTargetFolder);
185 addFileReference (iconPath);
186 resourceIDs.add (addBuildFile (iconPath, false, false));
187 resourceFileRefs.add (createID (iconPath));
190 addProjectItem (project.getMainGroup());
192 for (int i = 0; i < project.getNumConfigurations(); ++i)
194 Project::BuildConfiguration config (project.getConfiguration (i));
196 addProjectConfig (config.getName().getValue(), getProjectSettings (config));
197 addTargetConfig (config.getName().getValue(), getTargetSettings (config));
200 addConfigList (projectConfigs, createID ("__projList"));
201 addConfigList (targetConfigs, createID ("__configList"));
203 if (! project.isLibrary())
204 addBuildPhase ("PBXResourcesBuildPhase", resourceIDs);
206 if (rezFileIDs.size() > 0)
207 addBuildPhase ("PBXRezBuildPhase", rezFileIDs);
209 addBuildPhase ("PBXSourcesBuildPhase", sourceIDs);
211 if (! project.isLibrary())
212 addBuildPhase ("PBXFrameworksBuildPhase", frameworkIDs);
214 if (project.isAudioPlugin())
215 addPluginShellScriptPhase();
217 addTargetObject();
218 addProjectObject();
221 static const Image fixMacIconImageSize (Image& image)
223 const int w = image.getWidth();
224 const int h = image.getHeight();
226 if (w != h || (w != 16 && w != 32 && w != 48 && w != 64))
228 const int newSize = w >= 128 ? 128 : (w >= 64 ? 64 : (w >= 32 ? 32 : 16));
229 Image newIm (Image::ARGB, newSize, newSize, true);
230 Graphics g (newIm);
231 g.drawImageWithin (image, 0, 0, newSize, newSize,
232 RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, false);
233 return newIm;
236 return image;
239 void writeIcnsFile (const Array<Image>& images, OutputStream& out)
241 MemoryOutputStream data;
243 for (int i = 0; i < images.size(); ++i)
245 Image image (fixMacIconImageSize (images.getReference (i)));
247 const int w = image.getWidth();
248 const int h = image.getHeight();
250 const char* type = nullptr;
251 const char* maskType = nullptr;
253 if (w == h)
255 if (w == 16) { type = "is32"; maskType = "s8mk"; }
256 if (w == 32) { type = "il32"; maskType = "l8mk"; }
257 if (w == 48) { type = "ih32"; maskType = "h8mk"; }
258 if (w == 128) { type = "it32"; maskType = "t8mk"; }
261 if (type != nullptr)
263 data.write (type, 4);
264 data.writeIntBigEndian (8 + 4 * w * h);
266 const Image::BitmapData bitmap (image, Image::BitmapData::readOnly);
268 int y;
269 for (y = 0; y < h; ++y)
271 for (int x = 0; x < w; ++x)
273 const Colour pixel (bitmap.getPixelColour (x, y));
274 data.writeByte ((char) pixel.getAlpha());
275 data.writeByte ((char) pixel.getRed());
276 data.writeByte ((char) pixel.getGreen());
277 data.writeByte ((char) pixel.getBlue());
281 data.write (maskType, 4);
282 data.writeIntBigEndian (8 + w * h);
284 for (y = 0; y < h; ++y)
286 for (int x = 0; x < w; ++x)
288 const Colour pixel (bitmap.getPixelColour (x, y));
289 data.writeByte ((char) pixel.getAlpha());
295 jassert (data.getDataSize() > 0); // no suitable sized images?
297 out.write ("icns", 4);
298 out.writeIntBigEndian (data.getDataSize() + 8);
299 out << data;
302 void createIconFile()
304 Array<Image> images;
306 Image bigIcon (project.getBigIcon());
307 if (bigIcon.isValid())
308 images.add (bigIcon);
310 Image smallIcon (project.getSmallIcon());
311 if (smallIcon.isValid())
312 images.add (smallIcon);
314 if (images.size() > 0)
316 MemoryOutputStream mo;
317 writeIcnsFile (images, mo);
319 iconFile = getTargetFolder().getChildFile ("Icon.icns");
320 overwriteFileIfDifferentOrThrow (iconFile, mo);
324 void writeInfoPlistFile()
326 if (! hasPList())
327 return;
329 XmlElement plist ("plist");
330 XmlElement* dict = plist.createNewChildElement ("dict");
332 if (iPhone)
333 addPlistDictionaryKeyBool (dict, "LSRequiresIPhoneOS", true);
335 addPlistDictionaryKey (dict, "CFBundleExecutable", "${EXECUTABLE_NAME}");
336 addPlistDictionaryKey (dict, "CFBundleIconFile", iconFile.exists() ? iconFile.getFileName() : String::empty);
337 addPlistDictionaryKey (dict, "CFBundleIdentifier", project.getBundleIdentifier().toString());
338 addPlistDictionaryKey (dict, "CFBundleName", project.getProjectName().toString());
340 if (project.isAudioPlugin())
342 addPlistDictionaryKey (dict, "CFBundlePackageType", "TDMw");
343 addPlistDictionaryKey (dict, "CFBundleSignature", "PTul");
345 else
347 addPlistDictionaryKey (dict, "CFBundlePackageType", "APPL");
348 addPlistDictionaryKey (dict, "CFBundleSignature", "????");
351 addPlistDictionaryKey (dict, "CFBundleShortVersionString", project.getVersion().toString());
352 addPlistDictionaryKey (dict, "CFBundleVersion", project.getVersion().toString());
354 StringArray documentExtensions;
355 documentExtensions.addTokens (replacePreprocessorDefs (getAllPreprocessorDefs(), getSetting ("documentExtensions").toString()),
356 ",", String::empty);
357 documentExtensions.trim();
358 documentExtensions.removeEmptyStrings (true);
360 if (documentExtensions.size() > 0)
362 dict->createNewChildElement ("key")->addTextElement ("CFBundleDocumentTypes");
363 XmlElement* dict2 = dict->createNewChildElement ("array")->createNewChildElement ("dict");
365 for (int i = 0; i < documentExtensions.size(); ++i)
367 String ex (documentExtensions[i]);
368 if (ex.startsWithChar ('.'))
369 ex = ex.substring (1);
371 dict2->createNewChildElement ("key")->addTextElement ("CFBundleTypeExtensions");
372 dict2->createNewChildElement ("array")->createNewChildElement ("string")->addTextElement (ex);
373 addPlistDictionaryKey (dict2, "CFBundleTypeName", ex);
374 addPlistDictionaryKey (dict2, "CFBundleTypeRole", "Editor");
375 addPlistDictionaryKey (dict2, "NSPersistentStoreTypeKey", "XML");
379 if (getSetting ("UIFileSharingEnabled").getValue())
380 addPlistDictionaryKeyBool (dict, "UIFileSharingEnabled", true);
382 if (getSetting ("UIStatusBarHidden").getValue())
383 addPlistDictionaryKeyBool (dict, "UIStatusBarHidden", true);
385 MemoryOutputStream mo;
386 plist.writeToStream (mo, "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">");
388 overwriteFileIfDifferentOrThrow (infoPlistFile, mo);
391 const StringArray getHeaderSearchPaths (const Project::BuildConfiguration& config)
393 StringArray searchPaths (config.getHeaderSearchPaths());
395 if (project.shouldAddVSTFolderToPath() && getVSTFolder().toString().isNotEmpty())
396 searchPaths.add (rebaseFromProjectFolderToBuildTarget (RelativePath (getVSTFolder().toString(), RelativePath::projectFolder)).toUnixStyle());
398 if (project.isAudioPlugin())
400 if (isAU())
402 searchPaths.add ("$(DEVELOPER_DIR)/Extras/CoreAudio/PublicUtility");
403 searchPaths.add ("$(DEVELOPER_DIR)/Extras/CoreAudio/AudioUnits/AUPublic/Utility");
406 if (isRTAS())
408 searchPaths.add ("/Developer/Headers/FlatCarbon");
410 static const char* rtasIncludePaths[] = { "AlturaPorts/TDMPlugIns/PlugInLibrary/Controls",
411 "AlturaPorts/TDMPlugIns/PlugInLibrary/CoreClasses",
412 "AlturaPorts/TDMPlugIns/PlugInLibrary/DSPClasses",
413 "AlturaPorts/TDMPlugIns/PlugInLibrary/EffectClasses",
414 "AlturaPorts/TDMPlugIns/PlugInLibrary/MacBuild",
415 "AlturaPorts/TDMPlugIns/PlugInLibrary/Meters",
416 "AlturaPorts/TDMPlugIns/PlugInLibrary/ProcessClasses",
417 "AlturaPorts/TDMPlugIns/PlugInLibrary/ProcessClasses/Interfaces",
418 "AlturaPorts/TDMPlugIns/PlugInLibrary/RTASP_Adapt",
419 "AlturaPorts/TDMPlugIns/PlugInLibrary/Utilities",
420 "AlturaPorts/TDMPlugIns/PlugInLibrary/ViewClasses",
421 "AlturaPorts/TDMPlugIns/DSPManager/**",
422 "AlturaPorts/TDMPlugIns/SupplementalPlugInLib/Encryption",
423 "AlturaPorts/TDMPlugIns/SupplementalPlugInLib/GraphicsExtensions",
424 "AlturaPorts/TDMPlugIns/common",
425 "AlturaPorts/TDMPlugIns/common/PI_LibInterface",
426 "AlturaPorts/TDMPlugIns/PACEProtection/**",
427 "AlturaPorts/TDMPlugIns/SignalProcessing/**",
428 "AlturaPorts/OMS/Headers",
429 "AlturaPorts/Fic/Interfaces/**",
430 "AlturaPorts/Fic/Source/SignalNets",
431 "AlturaPorts/DSIPublicInterface/PublicHeaders",
432 "DAEWin/Include",
433 "AlturaPorts/DigiPublic/Interfaces",
434 "AlturaPorts/DigiPublic",
435 "AlturaPorts/NewFileLibs/DOA",
436 "AlturaPorts/NewFileLibs/Cmn",
437 "xplat/AVX/avx2/avx2sdk/inc",
438 "xplat/AVX/avx2/avx2sdk/utils" };
440 RelativePath sdkFolder (getRTASFolder().toString(), RelativePath::projectFolder);
442 for (int i = 0; i < numElementsInArray (rtasIncludePaths); ++i)
443 searchPaths.add (rebaseFromProjectFolderToBuildTarget (sdkFolder.getChildFile (rtasIncludePaths[i])).toUnixStyle());
447 return searchPaths;
450 void getLinkerFlagsForStaticLibrary (const RelativePath& library, StringArray& flags, StringArray& librarySearchPaths)
452 jassert (library.getFileNameWithoutExtension().substring (0, 3) == "lib");
454 flags.add ("-l" + library.getFileNameWithoutExtension().substring (3));
456 String searchPath (library.toUnixStyle().upToLastOccurrenceOf ("/", false, false));
457 if (! library.isAbsolute())
458 searchPath = "$(SRCROOT)/" + searchPath;
460 librarySearchPaths.add (sanitisePath (searchPath));
463 void getLinkerFlags (const Project::BuildConfiguration& config, StringArray& flags, StringArray& librarySearchPaths)
465 if (project.isAudioPlugin())
467 flags.add ("-bundle");
469 if (isRTAS() && getRTASFolder().toString().isNotEmpty())
471 getLinkerFlagsForStaticLibrary (RelativePath (getRTASFolder().toString(), RelativePath::buildTargetFolder)
472 .getChildFile (config.isDebug().getValue() ? "MacBag/Libs/Debug/libPluginLibrary.a"
473 : "MacBag/Libs/Release/libPluginLibrary.a"),
474 flags, librarySearchPaths);
478 if (project.getJuceLinkageMode() == Project::useLinkedJuce)
480 RelativePath juceLib (getJucePathFromTargetFolder().getChildFile (config.isDebug().getValue() ? "bin/libjucedebug.a"
481 : "bin/libjuce.a"));
482 getLinkerFlagsForStaticLibrary (juceLib, flags, librarySearchPaths);
485 flags.add (replacePreprocessorTokens (config, getExtraLinkerFlags().toString()));
486 flags.removeEmptyStrings (true);
489 const StringArray getProjectSettings (const Project::BuildConfiguration& config)
491 StringArray s;
492 s.add ("ALWAYS_SEARCH_USER_PATHS = NO");
493 s.add ("GCC_C_LANGUAGE_STANDARD = c99");
494 s.add ("GCC_WARN_ABOUT_RETURN_TYPE = YES");
495 s.add ("GCC_WARN_CHECK_SWITCH_STATEMENTS = YES");
496 s.add ("GCC_WARN_UNUSED_VARIABLE = YES");
497 s.add ("GCC_WARN_MISSING_PARENTHESES = YES");
498 s.add ("GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES");
499 s.add ("GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES");
500 s.add ("WARNING_CFLAGS = -Wreorder");
501 s.add ("GCC_MODEL_TUNING = G5");
503 if (project.isLibrary() || project.getJuceLinkageMode() == Project::useLinkedJuce)
505 s.add ("GCC_INLINES_ARE_PRIVATE_EXTERN = NO");
506 s.add ("GCC_SYMBOLS_PRIVATE_EXTERN = NO");
508 else
510 s.add ("GCC_INLINES_ARE_PRIVATE_EXTERN = YES");
513 if (iPhone)
515 s.add ("\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\"");
516 s.add ("SDKROOT = iphoneos");
517 s.add ("TARGETED_DEVICE_FAMILY = \"1,2\"");
520 s.add ("ZERO_LINK = NO");
522 if (! isRTAS()) // (dwarf seems to be incompatible with the RTAS libs)
523 s.add ("DEBUG_INFORMATION_FORMAT = \"dwarf\"");
525 s.add ("PRODUCT_NAME = \"" + config.getTargetBinaryName().toString() + "\"");
526 return s;
529 const StringArray getTargetSettings (const Project::BuildConfiguration& config)
531 StringArray s;
533 const String arch (config.getMacArchitecture().toString());
534 if (arch == Project::BuildConfiguration::osxArch_Native) s.add ("ARCHS = \"$(ARCHS_NATIVE)\"");
535 else if (arch == Project::BuildConfiguration::osxArch_32BitUniversal) s.add ("ARCHS = \"$(ARCHS_STANDARD_32_BIT)\"");
536 else if (arch == Project::BuildConfiguration::osxArch_64BitUniversal) s.add ("ARCHS = \"$(ARCHS_STANDARD_32_64_BIT)\"");
537 else if (arch == Project::BuildConfiguration::osxArch_64Bit) s.add ("ARCHS = \"$(ARCHS_STANDARD_64_BIT)\"");
539 s.add ("PREBINDING = NO");
540 s.add ("HEADER_SEARCH_PATHS = \"" + replacePreprocessorTokens (config, getHeaderSearchPaths (config).joinIntoString (" ")) + " $(inherited)\"");
541 s.add ("GCC_OPTIMIZATION_LEVEL = " + config.getGCCOptimisationFlag());
542 s.add ("INFOPLIST_FILE = " + infoPlistFile.getFileName());
544 const String extraFlags (replacePreprocessorTokens (config, getExtraCompilerFlags().toString()).trim());
545 if (extraFlags.isNotEmpty())
546 s.add ("OTHER_CPLUSPLUSFLAGS = " + extraFlags);
548 if (project.isGUIApplication())
550 s.add ("INSTALL_PATH = \"$(HOME)/Applications\"");
552 else if (project.isAudioPlugin())
554 s.add ("LIBRARY_STYLE = Bundle");
555 s.add ("INSTALL_PATH = \"$(HOME)/Library/Audio/Plug-Ins/Components/\"");
556 s.add ("WRAPPER_EXTENSION = " + getAudioPluginBundleExtension());
557 s.add ("GENERATE_PKGINFO_FILE = YES");
558 s.add ("OTHER_REZFLAGS = \"-d ppc_$ppc -d i386_$i386 -d ppc64_$ppc64 -d x86_64_$x86_64"
559 " -I /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Versions/A/Headers"
560 " -I \\\"$(DEVELOPER_DIR)/Extras/CoreAudio/AudioUnits/AUPublic/AUBase\\\"\"");
562 else if (project.isBrowserPlugin())
564 s.add ("LIBRARY_STYLE = Bundle");
565 s.add ("INSTALL_PATH = \"/Library/Internet Plug-Ins/\"");
567 else if (project.isLibrary())
569 if (config.getTargetBinaryRelativePath().toString().isNotEmpty())
571 RelativePath binaryPath (config.getTargetBinaryRelativePath().toString(), RelativePath::projectFolder);
572 binaryPath = binaryPath.rebased (project.getFile().getParentDirectory(), getTargetFolder(), RelativePath::buildTargetFolder);
574 s.add ("DSTROOT = " + sanitisePath (binaryPath.toUnixStyle()));
575 s.add ("SYMROOT = " + sanitisePath (binaryPath.toUnixStyle()));
578 s.add ("CONFIGURATION_BUILD_DIR = \"$(BUILD_DIR)\"");
579 s.add ("DEPLOYMENT_LOCATION = YES");
581 else if (project.isCommandLineApp())
584 else
586 jassertfalse;
589 if (! iPhone)
591 const String sdk (config.getMacSDKVersion().toString());
592 const String sdkCompat (config.getMacCompatibilityVersion().toString());
594 if (sdk == Project::BuildConfiguration::osxVersion10_4)
596 s.add ("SDKROOT = macosx10.4");
597 s.add ("GCC_VERSION = 4.0");
599 else if (sdk == Project::BuildConfiguration::osxVersion10_5)
601 s.add ("SDKROOT = macosx10.5");
603 else if (sdk == Project::BuildConfiguration::osxVersion10_6)
605 s.add ("SDKROOT = macosx10.6");
608 if (sdkCompat == Project::BuildConfiguration::osxVersion10_4) s.add ("MACOSX_DEPLOYMENT_TARGET = 10.4");
609 else if (sdkCompat == Project::BuildConfiguration::osxVersion10_5) s.add ("MACOSX_DEPLOYMENT_TARGET = 10.5");
610 else if (sdkCompat == Project::BuildConfiguration::osxVersion10_6) s.add ("MACOSX_DEPLOYMENT_TARGET = 10.6");
612 s.add ("MACOSX_DEPLOYMENT_TARGET_ppc = 10.4");
616 StringArray linkerFlags, librarySearchPaths;
617 getLinkerFlags (config, linkerFlags, librarySearchPaths);
619 if (linkerFlags.size() > 0)
620 s.add ("OTHER_LDFLAGS = \"" + linkerFlags.joinIntoString (" ") + "\"");
622 if (librarySearchPaths.size() > 0)
624 String libPaths ("LIBRARY_SEARCH_PATHS = (\"$(inherited)\"");
626 for (int i = 0; i < librarySearchPaths.size(); ++i)
627 libPaths += ", \"\\\"" + librarySearchPaths[i] + "\\\"\"";
629 s.add (libPaths + ")");
633 StringPairArray defines;
635 if (config.isDebug().getValue())
637 defines.set ("_DEBUG", "1");
638 defines.set ("DEBUG", "1");
639 s.add ("ONLY_ACTIVE_ARCH = YES");
640 s.add ("COPY_PHASE_STRIP = NO");
641 s.add ("GCC_DYNAMIC_NO_PIC = NO");
642 s.add ("GCC_ENABLE_FIX_AND_CONTINUE = NO");
644 else
646 defines.set ("_NDEBUG", "1");
647 defines.set ("NDEBUG", "1");
648 s.add ("GCC_GENERATE_DEBUGGING_SYMBOLS = NO");
649 s.add ("GCC_SYMBOLS_PRIVATE_EXTERN = YES");
653 const String objCSuffix (getObjCSuffix().toString().trim());
654 if (objCSuffix.isNotEmpty())
655 defines.set ("JUCE_ObjCExtraSuffix", replacePreprocessorTokens (config, objCSuffix));
659 defines = mergePreprocessorDefs (defines, getAllPreprocessorDefs (config));
661 StringArray defsList;
663 for (int i = 0; i < defines.size(); ++i)
665 String def (defines.getAllKeys()[i]);
666 const String value (defines.getAllValues()[i]);
667 if (value.isNotEmpty())
668 def << "=" << value;
670 defsList.add (def.quoted());
673 s.add ("GCC_PREPROCESSOR_DEFINITIONS = (" + indentList (defsList, ",") + ")");
676 return s;
679 void addFrameworks()
681 StringArray s;
683 if (iPhone)
685 s.addTokens ("UIKit Foundation CoreGraphics CoreText AudioToolbox QuartzCore OpenGLES", false);
687 else
689 s.addTokens ("Cocoa Carbon IOKit CoreAudio CoreMIDI WebKit DiscRecording OpenGL QuartzCore QTKit QuickTime", false);
691 if (isAU())
692 s.addTokens ("AudioUnit CoreAudioKit AudioToolbox", false);
693 else if (project.getJuceConfigFlag ("JUCE_PLUGINHOST_AU").toString() == Project::configFlagEnabled)
694 s.addTokens ("AudioUnit CoreAudioKit", false);
697 for (int i = 0; i < s.size(); ++i)
698 addFramework (s[i]);
701 //==============================================================================
702 void writeProjectFile (OutputStream& output)
704 output << "// !$*UTF8*$!\n{\n"
705 "\tarchiveVersion = 1;\n"
706 "\tclasses = {\n\t};\n"
707 "\tobjectVersion = 45;\n"
708 "\tobjects = {\n\n";
710 Array <ValueTree*> objects;
711 objects.addArray (pbxBuildFiles);
712 objects.addArray (pbxFileReferences);
713 objects.addArray (groups);
714 objects.addArray (targetConfigs);
715 objects.addArray (projectConfigs);
716 objects.addArray (misc);
718 for (int i = 0; i < objects.size(); ++i)
720 ValueTree& o = *objects.getUnchecked(i);
721 output << "\t\t" << o.getType().toString() << " = { ";
723 for (int j = 0; j < o.getNumProperties(); ++j)
725 const Identifier propertyName (o.getPropertyName(j));
726 String val (o.getProperty (propertyName).toString());
728 if (val.isEmpty() || (val.containsAnyOf (" \t;<>()=,&+-_\r\n")
729 && ! (val.trimStart().startsWithChar ('(')
730 || val.trimStart().startsWithChar ('{'))))
731 val = val.quoted();
733 output << propertyName.toString() << " = " << val << "; ";
736 output << "};\n";
739 output << "\t};\n\trootObject = " << createID ("__root") << ";\n}\n";
742 static void addPlistDictionaryKey (XmlElement* xml, const String& key, const String& value)
744 xml->createNewChildElement ("key")->addTextElement (key);
745 xml->createNewChildElement ("string")->addTextElement (value);
748 static void addPlistDictionaryKeyBool (XmlElement* xml, const String& key, const bool value)
750 xml->createNewChildElement ("key")->addTextElement (key);
751 xml->createNewChildElement (value ? "true" : "false");
754 const String addBuildFile (const RelativePath& path, const String& fileRefID, bool addToSourceBuildPhase, bool inhibitWarnings)
756 String fileID (createID (path.toUnixStyle() + "buildref"));
758 if (addToSourceBuildPhase)
759 sourceIDs.add (fileID);
761 ValueTree* v = new ValueTree (fileID);
762 v->setProperty ("isa", "PBXBuildFile", 0);
763 v->setProperty ("fileRef", fileRefID, 0);
765 if (inhibitWarnings)
766 v->setProperty ("settings", "{COMPILER_FLAGS = \"-w\"; }", 0);
768 pbxBuildFiles.add (v);
769 return fileID;
772 const String addBuildFile (const RelativePath& path, bool addToSourceBuildPhase, bool inhibitWarnings)
774 return addBuildFile (path, createID (path), addToSourceBuildPhase, inhibitWarnings);
777 void addFileReference (const RelativePath& path, const String& sourceTree, const String& lastKnownFileType, const String& fileRefID)
779 ValueTree* v = new ValueTree (fileRefID);
780 v->setProperty ("isa", "PBXFileReference", 0);
781 v->setProperty ("lastKnownFileType", lastKnownFileType, 0);
782 v->setProperty (Ids::name, path.getFileName(), 0);
783 v->setProperty ("path", sanitisePath (path.toUnixStyle()), 0);
784 v->setProperty ("sourceTree", sourceTree, 0);
785 pbxFileReferences.add (v);
788 const String addFileReference (const RelativePath& path)
790 const String fileRefID (createID (path));
792 jassert (path.isAbsolute() || path.getRoot() == RelativePath::buildTargetFolder);
793 addFileReference (path, path.isAbsolute() ? "<absolute>" : "SOURCE_ROOT",
794 getFileType (path), fileRefID);
796 return fileRefID;
799 static const String getFileType (const RelativePath& file)
801 if (file.hasFileExtension ("cpp;cc;cxx")) return "sourcecode.cpp.cpp";
802 else if (file.hasFileExtension (".mm")) return "sourcecode.cpp.objcpp";
803 else if (file.hasFileExtension (".m")) return "sourcecode.c.objc";
804 else if (file.hasFileExtension (headerFileExtensions)) return "sourcecode.c.h";
805 else if (file.hasFileExtension (".framework")) return "wrapper.framework";
806 else if (file.hasFileExtension (".jpeg;.jpg")) return "image.jpeg";
807 else if (file.hasFileExtension ("png;gif")) return "image" + file.getFileExtension();
808 else if (file.hasFileExtension ("html;htm")) return "text.html";
809 else if (file.hasFileExtension ("txt;rtf")) return "text" + file.getFileExtension();
810 else if (file.hasFileExtension ("plist")) return "text.plist.xml";
811 else if (file.hasFileExtension ("app")) return "wrapper.application";
812 else if (file.hasFileExtension ("component;vst;plugin")) return "wrapper.cfbundle";
813 else if (file.hasFileExtension ("xcodeproj")) return "wrapper.pb-project";
814 else if (file.hasFileExtension ("a")) return "archive.ar";
816 return "file" + file.getFileExtension();
819 const String addFile (const RelativePath& path, bool shouldBeCompiled, bool inhibitWarnings)
821 if (shouldBeCompiled)
822 addBuildFile (path, true, inhibitWarnings);
823 else if (path.hasFileExtension (".r"))
824 rezFileIDs.add (addBuildFile (path, false, inhibitWarnings));
826 return addFileReference (path);
829 const String addProjectItem (const Project::Item& projectItem)
831 if (projectItem.isGroup())
833 StringArray childIDs;
834 for (int i = 0; i < projectItem.getNumChildren(); ++i)
836 const String childID (addProjectItem (projectItem.getChild(i)));
838 if (childID.isNotEmpty())
839 childIDs.add (childID);
842 return addGroup (projectItem, childIDs);
844 else
846 if (projectItem.shouldBeAddedToTargetProject())
848 const RelativePath path (projectItem.getFile(), getTargetFolder(), RelativePath::buildTargetFolder);
849 return addFile (path, projectItem.shouldBeCompiled(), false);
853 return String::empty;
856 void addFramework (const String& frameworkName)
858 const RelativePath path ("System/Library/Frameworks/" + frameworkName + ".framework", RelativePath::unknown);
859 const String fileRefID (createID (path));
860 addFileReference (path, "SDKROOT", getFileType (path), fileRefID);
861 frameworkIDs.add (addBuildFile (path, fileRefID, false, false));
862 frameworkFileIDs.add (fileRefID);
865 void addGroup (const String& groupID, const String& groupName, const StringArray& childIDs)
867 ValueTree* v = new ValueTree (groupID);
868 v->setProperty ("isa", "PBXGroup", 0);
869 v->setProperty ("children", "(" + indentList (childIDs, ",") + " )", 0);
870 v->setProperty (Ids::name, groupName, 0);
871 v->setProperty ("sourceTree", "<group>", 0);
872 groups.add (v);
875 const String createGroup (const Array<RelativePath>& files, const String& groupName, const String& groupIDName, bool inhibitWarnings)
877 StringArray fileIDs;
879 for (int i = 0; i < files.size(); ++i)
881 addFile (files.getReference(i), shouldFileBeCompiledByDefault (files.getReference(i)), inhibitWarnings);
882 fileIDs.add (createID (files.getReference(i)));
885 const String groupID (createID (groupIDName));
886 addGroup (groupID, groupName, fileIDs);
887 return groupID;
890 const String addGroup (const Project::Item& item, StringArray& childIDs)
892 String groupName (item.getName().toString());
894 if (item.isMainGroup())
896 groupName = "Source";
898 // Add 'Juce Library Code' group
899 if (juceWrapperFiles.size() > 0)
900 childIDs.add (createGroup (juceWrapperFiles, project.getJuceCodeGroupName(), "__jucelibfiles", false));
902 if (isVST())
903 childIDs.add (createGroup (getVSTFilesRequired(), "Juce VST Wrapper", "__jucevstfiles", false));
905 if (isAU())
906 childIDs.add (createAUWrappersGroup());
908 if (isRTAS())
909 childIDs.add (createGroup (getRTASFilesRequired(), "Juce RTAS Wrapper", "__jucertasfiles", true));
911 { // Add 'resources' group
912 String resourcesGroupID (createID ("__resources"));
913 addGroup (resourcesGroupID, "Resources", resourceFileRefs);
914 childIDs.add (resourcesGroupID);
917 { // Add 'frameworks' group
918 String frameworksGroupID (createID ("__frameworks"));
919 addGroup (frameworksGroupID, "Frameworks", frameworkFileIDs);
920 childIDs.add (frameworksGroupID);
923 { // Add 'products' group
924 String productsGroupID (createID ("__products"));
925 StringArray products;
926 products.add (createID ("__productFileID"));
927 addGroup (productsGroupID, "Products", products);
928 childIDs.add (productsGroupID);
932 String groupID (getIDForGroup (item));
933 addGroup (groupID, groupName, childIDs);
934 return groupID;
937 void addBuildProduct (const String& fileType, const String& binaryName)
939 ValueTree* v = new ValueTree (createID ("__productFileID"));
940 v->setProperty ("isa", "PBXFileReference", 0);
941 v->setProperty ("explicitFileType", fileType, 0);
942 v->setProperty ("includeInIndex", (int) 0, 0);
943 v->setProperty ("path", sanitisePath (binaryName), 0);
944 v->setProperty ("sourceTree", "BUILT_PRODUCTS_DIR", 0);
945 pbxFileReferences.add (v);
948 void addTargetConfig (const String& configName, const StringArray& buildSettings)
950 ValueTree* v = new ValueTree (createID ("targetconfigid_" + configName));
951 v->setProperty ("isa", "XCBuildConfiguration", 0);
952 v->setProperty ("buildSettings", "{" + indentList (buildSettings, ";") + " }", 0);
953 v->setProperty (Ids::name, configName, 0);
954 targetConfigs.add (v);
957 void addProjectConfig (const String& configName, const StringArray& buildSettings)
959 ValueTree* v = new ValueTree (createID ("projectconfigid_" + configName));
960 v->setProperty ("isa", "XCBuildConfiguration", 0);
961 v->setProperty ("buildSettings", "{" + indentList (buildSettings, ";") + " }", 0);
962 v->setProperty (Ids::name, configName, 0);
963 projectConfigs.add (v);
966 void addConfigList (const OwnedArray <ValueTree>& configsToUse, const String& listID)
968 StringArray configIDs;
970 for (int i = 0; i < configsToUse.size(); ++i)
971 configIDs.add (configsToUse[i]->getType().toString());
973 ValueTree* v = new ValueTree (listID);
974 v->setProperty ("isa", "XCConfigurationList", 0);
975 v->setProperty ("buildConfigurations", "(" + indentList (configIDs, ",") + " )", 0);
976 v->setProperty ("defaultConfigurationIsVisible", (int) 0, 0);
978 if (configsToUse[0] != nullptr)
979 v->setProperty ("defaultConfigurationName", configsToUse[0]->getProperty (Ids::name), 0);
981 misc.add (v);
984 ValueTree* addBuildPhase (const String& phaseType, const StringArray& fileIds)
986 String phaseId (createID (phaseType + "resbuildphase"));
987 buildPhaseIDs.add (phaseId);
989 ValueTree* v = new ValueTree (phaseId);
990 v->setProperty ("isa", phaseType, 0);
991 v->setProperty ("buildActionMask", "2147483647", 0);
992 v->setProperty ("files", "(" + indentList (fileIds, ",") + " )", 0);
993 v->setProperty ("runOnlyForDeploymentPostprocessing", (int) 0, 0);
994 misc.add (v);
995 return v;
998 void addTargetObject()
1000 ValueTree* v = new ValueTree (createID ("__target"));
1001 v->setProperty ("isa", "PBXNativeTarget", 0);
1002 v->setProperty ("buildConfigurationList", createID ("__configList"), 0);
1003 v->setProperty ("buildPhases", "(" + indentList (buildPhaseIDs, ",") + " )", 0);
1004 v->setProperty ("buildRules", "( )", 0);
1005 v->setProperty ("dependencies", "( )", 0);
1006 v->setProperty (Ids::name, project.getDocumentTitle(), 0);
1007 v->setProperty ("productName", project.getDocumentTitle(), 0);
1008 v->setProperty ("productReference", createID ("__productFileID"), 0);
1010 if (project.isGUIApplication())
1012 v->setProperty ("productInstallPath", "$(HOME)/Applications", 0);
1013 v->setProperty ("productType", "com.apple.product-type.application", 0);
1015 else if (project.isCommandLineApp())
1017 v->setProperty ("productInstallPath", "/usr/bin", 0);
1018 v->setProperty ("productType", "com.apple.product-type.tool", 0);
1020 else if (project.isAudioPlugin() || project.isBrowserPlugin())
1022 v->setProperty ("productInstallPath", "$(HOME)/Library/Audio/Plug-Ins/Components/", 0);
1023 v->setProperty ("productType", "com.apple.product-type.bundle", 0);
1025 else if (project.isLibrary())
1027 v->setProperty ("productType", "com.apple.product-type.library.static", 0);
1029 else
1030 jassertfalse; //xxx
1032 misc.add (v);
1035 void addProjectObject()
1037 ValueTree* v = new ValueTree (createID ("__root"));
1038 v->setProperty ("isa", "PBXProject", 0);
1039 v->setProperty ("buildConfigurationList", createID ("__projList"), 0);
1040 v->setProperty ("compatibilityVersion", "Xcode 3.1", 0);
1041 v->setProperty ("hasScannedForEncodings", (int) 0, 0);
1042 v->setProperty ("mainGroup", getIDForGroup (project.getMainGroup()), 0);
1043 v->setProperty ("projectDirPath", "\"\"", 0);
1044 v->setProperty ("projectRoot", "\"\"", 0);
1045 v->setProperty ("targets", "( " + createID ("__target") + " )", 0);
1046 misc.add (v);
1049 void addPluginShellScriptPhase()
1051 ValueTree* v = addBuildPhase ("PBXShellScriptBuildPhase", StringArray());
1052 v->setProperty (Ids::name, "Copy to the different plugin folders", 0);
1053 v->setProperty ("shellPath", "/bin/sh", 0);
1054 v->setProperty ("shellScript", String::fromUTF8 (BinaryData::AudioPluginXCodeScript_txt, BinaryData::AudioPluginXCodeScript_txtSize)
1055 .replace ("\\", "\\\\")
1056 .replace ("\"", "\\\"")
1057 .replace ("\r\n", "\\n")
1058 .replace ("\n", "\\n"), 0);
1061 //==============================================================================
1062 static const String indentList (const StringArray& list, const String& separator)
1064 if (list.size() == 0)
1065 return " ";
1067 return "\n\t\t\t\t" + list.joinIntoString (separator + "\n\t\t\t\t")
1068 + (separator == ";" ? separator : String::empty);
1071 const String createID (const RelativePath& path) const
1073 return createID (path.toUnixStyle());
1076 const String createID (const String& rootString) const
1078 static const char digits[] = "0123456789ABCDEF";
1079 char n[24];
1080 Random ran (projectIDSalt + hashCode64 (rootString));
1082 for (int i = 0; i < numElementsInArray (n); ++i)
1083 n[i] = digits [ran.nextInt (16)];
1085 return String (n, numElementsInArray (n));
1088 const String getIDForGroup (const Project::Item& item) const
1090 return createID (item.getID());
1093 bool shouldFileBeCompiledByDefault (const RelativePath& file) const
1095 return file.hasFileExtension (sourceFileExtensions);
1098 //==============================================================================
1099 const Array<RelativePath> getRTASFilesRequired() const
1101 Array<RelativePath> s;
1102 if (isRTAS())
1104 const char* files[] = { JUCE_PLUGINS_PATH_RTAS "juce_RTAS_DigiCode1.cpp",
1105 JUCE_PLUGINS_PATH_RTAS "juce_RTAS_DigiCode2.cpp",
1106 JUCE_PLUGINS_PATH_RTAS "juce_RTAS_DigiCode3.cpp",
1107 JUCE_PLUGINS_PATH_RTAS "juce_RTAS_DigiCode_Header.h",
1108 JUCE_PLUGINS_PATH_RTAS "juce_RTAS_MacResources.r",
1109 JUCE_PLUGINS_PATH_RTAS "juce_RTAS_MacUtilities.mm",
1110 JUCE_PLUGINS_PATH_RTAS "juce_RTAS_Wrapper.cpp" };
1112 for (int i = 0; i < numElementsInArray (files); ++i)
1113 s.add (getJucePathFromTargetFolder().getChildFile (files[i]));
1116 return s;
1119 const String createAUWrappersGroup()
1121 Array<RelativePath> auWrappers;
1123 const char* files[] = { JUCE_PLUGINS_PATH_AU "juce_AU_Resources.r",
1124 JUCE_PLUGINS_PATH_AU "juce_AU_Wrapper.mm" };
1125 int i;
1126 for (i = 0; i < numElementsInArray (files); ++i)
1127 auWrappers.add (getJucePathFromTargetFolder().getChildFile (files[i]));
1129 const char* appleAUFiles[] = { "Extras/CoreAudio/PublicUtility/CADebugMacros.h",
1130 "Extras/CoreAudio/PublicUtility/CAAUParameter.cpp",
1131 "Extras/CoreAudio/PublicUtility/CAAUParameter.h",
1132 "Extras/CoreAudio/PublicUtility/CAAudioChannelLayout.cpp",
1133 "Extras/CoreAudio/PublicUtility/CAAudioChannelLayout.h",
1134 "Extras/CoreAudio/PublicUtility/CAMutex.cpp",
1135 "Extras/CoreAudio/PublicUtility/CAMutex.h",
1136 "Extras/CoreAudio/PublicUtility/CAStreamBasicDescription.cpp",
1137 "Extras/CoreAudio/PublicUtility/CAStreamBasicDescription.h",
1138 "Extras/CoreAudio/PublicUtility/CAVectorUnitTypes.h",
1139 "Extras/CoreAudio/PublicUtility/CAVectorUnit.cpp",
1140 "Extras/CoreAudio/PublicUtility/CAVectorUnit.h",
1141 "Extras/CoreAudio/AudioUnits/AUPublic/AUViewBase/AUViewLocalizedStringKeys.h",
1142 "Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/AUCarbonViewDispatch.cpp",
1143 "Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/AUCarbonViewControl.cpp",
1144 "Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/AUCarbonViewControl.h",
1145 "Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/CarbonEventHandler.cpp",
1146 "Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/CarbonEventHandler.h",
1147 "Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/AUCarbonViewBase.cpp",
1148 "Extras/CoreAudio/AudioUnits/AUPublic/AUCarbonViewBase/AUCarbonViewBase.h",
1149 "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUBase.cpp",
1150 "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUBase.h",
1151 "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUDispatch.cpp",
1152 "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUDispatch.h",
1153 "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUInputElement.cpp",
1154 "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUInputElement.h",
1155 "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUOutputElement.cpp",
1156 "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUOutputElement.h",
1157 "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUResources.r",
1158 "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUScopeElement.cpp",
1159 "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/AUScopeElement.h",
1160 "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/ComponentBase.cpp",
1161 "Extras/CoreAudio/AudioUnits/AUPublic/AUBase/ComponentBase.h",
1162 "Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUMIDIBase.cpp",
1163 "Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUMIDIBase.h",
1164 "Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUMIDIEffectBase.cpp",
1165 "Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUMIDIEffectBase.h",
1166 "Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUOutputBase.cpp",
1167 "Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUOutputBase.h",
1168 "Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/MusicDeviceBase.cpp",
1169 "Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/MusicDeviceBase.h",
1170 "Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUEffectBase.cpp",
1171 "Extras/CoreAudio/AudioUnits/AUPublic/OtherBases/AUEffectBase.h",
1172 "Extras/CoreAudio/AudioUnits/AUPublic/Utility/AUBuffer.cpp",
1173 "Extras/CoreAudio/AudioUnits/AUPublic/Utility/AUBuffer.h",
1174 "Extras/CoreAudio/AudioUnits/AUPublic/Utility/AUDebugDispatcher.cpp",
1175 "Extras/CoreAudio/AudioUnits/AUPublic/Utility/AUDebugDispatcher.h",
1176 "Extras/CoreAudio/AudioUnits/AUPublic/Utility/AUInputFormatConverter.h",
1177 "Extras/CoreAudio/AudioUnits/AUPublic/Utility/AUSilentTimeout.h",
1178 "Extras/CoreAudio/AudioUnits/AUPublic/Utility/AUTimestampGenerator.h" };
1180 StringArray fileIDs, appleFileIDs;
1182 for (i = 0; i < auWrappers.size(); ++i)
1184 addFile (auWrappers.getReference(i), shouldFileBeCompiledByDefault (auWrappers.getReference(i)), false);
1185 fileIDs.add (createID (auWrappers.getReference(i)));
1188 for (i = 0; i < numElementsInArray (appleAUFiles); ++i)
1190 RelativePath file (appleAUFiles[i], RelativePath::unknown);
1191 const String fileRefID (createID (file));
1193 addFileReference (file, "DEVELOPER_DIR", getFileType (file), fileRefID);
1195 if (shouldFileBeCompiledByDefault (file))
1196 addBuildFile (file, fileRefID, true, true);
1198 appleFileIDs.add (fileRefID);
1201 const String appleGroupID (createID ("__juceappleaufiles"));
1202 addGroup (appleGroupID, "Apple AU Files", appleFileIDs);
1203 fileIDs.add (appleGroupID);
1205 const String groupID (createID ("__juceaufiles"));
1206 addGroup (groupID, "Juce AU Wrapper", fileIDs);
1207 return groupID;
1212 #endif // __JUCER_PROJECTEXPORT_XCODE_JUCEHEADER__