Browse Source

Added support for multi-target exporters and standalone plug-in format

tags/2021-05-28
hogliux 8 years ago
parent
commit
0117aace01
15 changed files with 2499 additions and 1680 deletions
  1. +14
    -6
      extras/Projucer/Source/Project Saving/jucer_ProjectExport_AndroidAnt.h
  2. +13
    -7
      extras/Projucer/Source/Project Saving/jucer_ProjectExport_AndroidBase.h
  3. +1
    -1
      extras/Projucer/Source/Project Saving/jucer_ProjectExport_AndroidStudio.h
  4. +314
    -57
      extras/Projucer/Source/Project Saving/jucer_ProjectExport_CodeBlocks.h
  5. +1361
    -1139
      extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h
  6. +340
    -130
      extras/Projucer/Source/Project Saving/jucer_ProjectExport_Make.h
  7. +101
    -226
      extras/Projucer/Source/Project Saving/jucer_ProjectExport_XCode.h
  8. +68
    -34
      extras/Projucer/Source/Project Saving/jucer_ProjectExporter.cpp
  9. +24
    -14
      extras/Projucer/Source/Project Saving/jucer_ProjectExporter.h
  10. +7
    -7
      extras/Projucer/Source/Project Saving/jucer_ProjectSaver.cpp
  11. +28
    -17
      extras/Projucer/Source/Project/jucer_Module.cpp
  12. +118
    -23
      extras/Projucer/Source/Project/jucer_Project.cpp
  13. +25
    -9
      extras/Projucer/Source/Project/jucer_Project.h
  14. +82
    -8
      extras/Projucer/Source/Project/jucer_ProjectType.h
  15. +3
    -2
      extras/Projucer/Source/Utility/jucer_PresetIDs.h

+ 14
- 6
extras/Projucer/Source/Project Saving/jucer_ProjectExport_AndroidAnt.h View File

@@ -36,11 +36,19 @@ public:
bool isAndroidStudio() const override { return false; }
bool isAndroidAnt() const override { return true; }
bool supportsVST() const override { return false; }
bool supportsVST3() const override { return false; }
bool supportsAAX() const override { return false; }
bool supportsRTAS() const override { return false; }
bool supportsStandalone() const override { return false; }
bool supportsTargetType (ProjectType::Target::Type type) const override
{
switch (type)
{
case ProjectType::Target::GUIApp:
case ProjectType::Target::StaticLibrary:
return true;
default:
break;
}
return false;
}
//==============================================================================
static const char* getName() { return "Android Ant Project"; }
@@ -340,7 +348,7 @@ private:
flags << " -std=gnu++11";
defines = mergePreprocessorDefs (defines, getAllPreprocessorDefs (config));
defines = mergePreprocessorDefs (defines, getAllPreprocessorDefs ());
return flags + createGCCPreprocessorFlags (defines);
}


+ 13
- 7
extras/Projucer/Source/Project Saving/jucer_ProjectExport_AndroidBase.h View File

@@ -58,13 +58,19 @@ public:
bool isOSX() const override { return false; }
bool isiOS() const override { return false; }
bool supportsVST() const override { return false; }
bool supportsVST3() const override { return false; }
bool supportsAAX() const override { return false; }
bool supportsRTAS() const override { return false; }
bool supportsAU() const override { return false; }
bool supportsAUv3() const override { return false; }
bool supportsStandalone() const override { return false; }
bool supportsTargetType (ProjectType::Target::Type type) const override
{
switch (type)
{
case ProjectType::Target::GUIApp:
case ProjectType::Target::StaticLibrary:
return true;
default:
break;
}
return false;
}
//==============================================================================
void create (const OwnedArray<LibraryModule>& modules) const override


+ 1
- 1
extras/Projucer/Source/Project Saving/jucer_ProjectExport_AndroidStudio.h View File

@@ -51,7 +51,7 @@ public:
AndroidStudioProjectExporter (Project& p, const ValueTree& t)
: AndroidProjectExporterBase (p, t),
gradleVersion (settings, Ids::gradleVersion, nullptr, "2.14.1"),
gradleWrapperVersion (settings, Ids::gradleWrapperVersion, nullptr, "0.8.1"),
gradleWrapperVersion (settings, Ids::androidPluginVersion, nullptr, "0.8.1"),
gradleToolchain (settings, Ids::gradleToolchain, nullptr, "clang"),
buildToolsVersion (settings, Ids::buildToolsVersion, nullptr, "23.0.2"),
androidStudioExecutable (findAndroidStudioExecutable())


+ 314
- 57
extras/Projucer/Source/Project Saving/jucer_ProjectExport_CodeBlocks.h View File

@@ -113,13 +113,25 @@ public:
bool isOSX() const override { return false; }
bool isiOS() const override { return false; }
bool supportsVST() const override { return false; }
bool supportsVST3() const override { return false; }
bool supportsAAX() const override { return false; }
bool supportsRTAS() const override { return false; }
bool supportsAU() const override { return false; }
bool supportsAUv3() const override { return false; }
bool supportsStandalone() const override { return false; }
bool supportsTargetType (ProjectType::Target::Type type) const override
{
switch (type)
{
case ProjectType::Target::StandalonePlugIn:
case ProjectType::Target::GUIApp:
case ProjectType::Target::ConsoleApp:
case ProjectType::Target::StaticLibrary:
case ProjectType::Target::SharedCodeTarget:
case ProjectType::Target::AggregateTarget:
case ProjectType::Target::VSTPlugIn:
case ProjectType::Target::DynamicLibrary:
return true;
default:
break;
}
return false;
}
void createExporterProperties (PropertyListBuilder&) override
{
@@ -138,9 +150,30 @@ public:
}
//==============================================================================
void addPlatformSpecificSettingsForProjectType (const ProjectType& type) override
void addPlatformSpecificSettingsForProjectType (const ProjectType&) override
{
createDynamicLibrary = type.isAudioPlugin() || type.isDynamicLibrary();
// add shared code target first as order matters for Codeblocks
if (shouldBuildTargetType (ProjectType::Target::SharedCodeTarget))
targets.add (new CodeBlocksTarget (*this, ProjectType::Target::SharedCodeTarget));
//ProjectType::Target::SharedCodeTarget
callForAllSupportedTargets ([this] (ProjectType::Target::Type targetType)
{
if (targetType == ProjectType::Target::SharedCodeTarget)
return;
if (auto* target = new CodeBlocksTarget (*this, targetType))
{
if (targetType == ProjectType::Target::AggregateTarget)
targets.insert (0, target);
else
targets.add (target);
}
});
// If you hit this assert, you tried to generate a project for an exporter
// that does not support any of your targets!
jassert (targets.size() > 0);
}
private:
@@ -151,14 +184,52 @@ private:
CodeBlocksBuildConfiguration (Project& p, const ValueTree& settings, const ProjectExporter& e)
: BuildConfiguration (p, settings, e)
{
if (getArchitectureType().toString().isEmpty())
getArchitectureType() = static_cast<const char* const> ("-m64");
}
Value getArchitectureType()
{
const auto archID = exporter.isWindows() ? Ids::windowsCodeBlocksArchitecture
: Ids::linuxCodeBlocksArchitecture;
return getValue (archID);
}
var getArchitectureTypeVar() const
{
const auto archID = exporter.isWindows() ? Ids::windowsCodeBlocksArchitecture
: Ids::linuxCodeBlocksArchitecture;
return config [archID];
}
var getDefaultOptimisationLevel() const override { return var ((int) (isDebug() ? gccO0 : gccO3)); }
void createConfigProperties (PropertyListBuilder& props) override
{
addGCCOptimisationProperty (props);
static const char* const archNames[] = { "32-bit (-m32)", "64-bit (-m64)", "ARM v6", "ARM v7" };
const var archFlags[] = { "-m32", "-m64", "-march=armv6", "-march=armv7" };
props.add (new ChoicePropertyComponent (getArchitectureType(), "Architecture",
StringArray (archNames, numElementsInArray (archNames)),
Array<var> (archFlags, numElementsInArray (archFlags))));
}
var getDefaultOptimisationLevel() const override { return var ((int) (isDebug() ? gccO0 : gccO3)); }
String getLibrarySubdirPath () const override
{
const String archFlag = getArchitectureTypeVar();
const auto prefix = String ("-march=");
if (archFlag.startsWith (prefix))
return String ("/") + archFlag.substring (prefix.length());
else if (archFlag == "-m64")
return "/x86_64";
else if (archFlag == "-m32")
return "/i386";
jassertfalse;
return String();
}
};
BuildConfiguration::Ptr createBuildConfig (const ValueTree& tree) const override
@@ -166,6 +237,59 @@ private:
return new CodeBlocksBuildConfiguration (project, tree, *this);
}
//==============================================================================
class CodeBlocksTarget : public ProjectType::Target
{
public:
CodeBlocksTarget (CodeBlocksProjectExporter&, ProjectType::Target::Type typeToUse)
: ProjectType::Target (typeToUse)
{}
String getTargetNameForConfiguration (const BuildConfiguration& config) const
{
if (type == ProjectType::Target::AggregateTarget)
return config.getName();
return getName() + String (" | ") + config.getName();
}
String getTargetSuffix() const
{
const ProjectType::Target::TargetFileType fileType = getTargetFileType();
switch (fileType)
{
case executable:
return "";
case staticLibrary:
return ".a";
case sharedLibraryOrDLL:
return ".so";
case pluginBundle:
switch (type)
{
case VST3PlugIn:
return ".vst3";
case VSTPlugIn:
return ".so";
default:
break;
}
return ".so";
default:
break;
}
return String();
}
bool isDynamicLibrary() const
{
return (type == DynamicLibrary || type == VST3PlugIn || type == VSTPlugIn || type == AAXPlugIn);
}
};
//==============================================================================
void addVersion (XmlElement& xml) const
{
@@ -181,7 +305,7 @@ private:
xml.createNewChildElement ("Option")->setAttribute ("compiler", "gcc");
}
StringArray getDefines (const BuildConfiguration& config) const
StringArray getDefines (const BuildConfiguration& config, CodeBlocksTarget& target) const
{
StringPairArray defines;
@@ -205,7 +329,7 @@ private:
defines.set ("NDEBUG", "1");
}
defines = mergePreprocessorDefs (defines, getAllPreprocessorDefs (config));
defines = mergePreprocessorDefs (defines, getAllPreprocessorDefs (config, target.type));
StringArray defs;
for (int i = 0; i < defines.size(); ++i)
@@ -214,9 +338,12 @@ private:
return getCleanedStringArray (defs);
}
StringArray getCompilerFlags (const BuildConfiguration& config) const
StringArray getCompilerFlags (const BuildConfiguration& config, CodeBlocksTarget& target) const
{
StringArray flags;
if (const auto codeBlocksConfig = dynamic_cast<const CodeBlocksBuildConfiguration*> (&config))
flags.add (codeBlocksConfig->getArchitectureTypeVar());
flags.add ("-O" + config.getGCCOptimisationFlag());
flags.add ("-std=c++11");
flags.add ("-mstackrealign");
@@ -228,7 +355,7 @@ private:
" \n", "\"'");
{
const StringArray defines (getDefines (config));
const StringArray defines (getDefines (config, target));
for (int i = 0; i < defines.size(); ++i)
{
@@ -243,7 +370,7 @@ private:
if (config.exporter.isLinux())
{
if (createDynamicLibrary)
if (target.isDynamicLibrary() || getProject().getProjectType().isAudioPlugin())
flags.add ("-fPIC");
if (linuxPackages.size() > 0)
@@ -263,19 +390,25 @@ private:
return getCleanedStringArray (flags);
}
StringArray getLinkerFlags (const BuildConfiguration& config) const
StringArray getLinkerFlags (const BuildConfiguration& config, CodeBlocksTarget& target) const
{
StringArray flags (makefileExtraLinkerFlags);
if (const auto codeBlocksConfig = dynamic_cast<const CodeBlocksBuildConfiguration*> (&config))
flags.add (codeBlocksConfig->getArchitectureTypeVar());
if (! config.isDebug())
flags.add ("-s");
flags.addTokens (replacePreprocessorTokens (config, getExtraLinkerFlagsString()).trim(),
" \n", "\"'");
if (getProject().getProjectType().isAudioPlugin() && target.type != ProjectType::Target::SharedCodeTarget)
flags.add ("-l" + config.getTargetBinaryNameString());
if (config.exporter.isLinux() && linuxPackages.size() > 0)
{
if (createDynamicLibrary)
if (target.isDynamicLibrary())
flags.add ("-shared");
auto pkgconfigLibs = String ("`pkg-config --libs");
@@ -303,80 +436,119 @@ private:
return getCleanedStringArray (paths);
}
static int getTypeIndex (const ProjectType& type)
static int getTypeIndex (const ProjectType::Target::Type& type)
{
if (type.isGUIApplication()) return 0;
if (type.isCommandLineApp()) return 1;
if (type.isStaticLibrary()) return 2;
if (type.isDynamicLibrary()) return 3;
if (type.isAudioPlugin()) return 3;
switch (type)
{
case ProjectType::Target::GUIApp:
case ProjectType::Target::StandalonePlugIn:
return 0;
case ProjectType::Target::ConsoleApp:
return 1;
case ProjectType::Target::StaticLibrary:
case ProjectType::Target::SharedCodeTarget:
return 2;
case ProjectType::Target::DynamicLibrary:
case ProjectType::Target::VSTPlugIn:
case ProjectType::Target::VST3PlugIn:
return 3;
default:
break;
}
return 0;
}
void createBuildTarget (XmlElement& xml, const BuildConfiguration& config) const
String getOutputPathForTarget (CodeBlocksTarget& target, const BuildConfiguration& config) const
{
String outputPath;
if (config.getTargetBinaryRelativePathString().isNotEmpty())
{
RelativePath binaryPath (config.getTargetBinaryRelativePathString(), RelativePath::projectFolder);
binaryPath = binaryPath.rebased (projectFolder, getTargetFolder(), RelativePath::buildTargetFolder);
outputPath = config.getTargetBinaryRelativePathString();
}
else
{
outputPath ="bin/" + File::createLegalFileName (config.getName().trim());
}
return outputPath + "/" + replacePreprocessorTokens (config, config.getTargetBinaryNameString() + target.getTargetSuffix());
}
String getSharedCodePath (const BuildConfiguration& config) const
{
const String outputPath = getOutputPathForTarget (getTargetWithType (ProjectType::Target::SharedCodeTarget), config);
RelativePath path (outputPath, RelativePath::buildTargetFolder);
const String autoPrefixedFilename = "lib" + path.getFileName();
return path.getParentDirectory().getChildFile (autoPrefixedFilename).toUnixStyle();
}
void createBuildTarget (XmlElement& xml, CodeBlocksTarget& target, const BuildConfiguration& config) const
{
xml.setAttribute ("title", config.getName());
xml.setAttribute ("title", target.getTargetNameForConfiguration (config));
{
XmlElement* output = xml.createNewChildElement ("Option");
String outputPath;
if (config.getTargetBinaryRelativePathString().isNotEmpty())
{
RelativePath binaryPath (config.getTargetBinaryRelativePathString(), RelativePath::projectFolder);
binaryPath = binaryPath.rebased (projectFolder, getTargetFolder(), RelativePath::buildTargetFolder);
outputPath = config.getTargetBinaryRelativePathString();
}
else
{
outputPath ="bin/" + File::createLegalFileName (config.getName().trim());
}
output->setAttribute ("output", getOutputPathForTarget (target, config));
output->setAttribute ("output", outputPath + "/" + replacePreprocessorTokens (config, config.getTargetBinaryNameString()));
const bool keepPrefix = (target.type == ProjectType::Target::VSTPlugIn || target.type == ProjectType::Target::VST3PlugIn
|| target.type == ProjectType::Target::AAXPlugIn || target.type == ProjectType::Target::RTASPlugIn);
output->setAttribute ("prefix_auto", 1);
output->setAttribute ("extension_auto", 1);
output->setAttribute ("prefix_auto", keepPrefix ? 0 : 1);
output->setAttribute ("extension_auto", 0);
}
xml.createNewChildElement ("Option")
->setAttribute ("object_output", "obj/" + File::createLegalFileName (config.getName().trim()));
xml.createNewChildElement ("Option")->setAttribute ("type", getTypeIndex (project.getProjectType()));
xml.createNewChildElement ("Option")->setAttribute ("type", getTypeIndex (target.type));
xml.createNewChildElement ("Option")->setAttribute ("compiler", "gcc");
if (getProject().getProjectType().isAudioPlugin() && target.type != ProjectType::Target::SharedCodeTarget)
xml.createNewChildElement ("Option")->setAttribute ("external_deps", getSharedCodePath (config));
{
XmlElement* const compiler = xml.createNewChildElement ("Compiler");
{
const StringArray compilerFlags (getCompilerFlags (config));
const StringArray compilerFlags (getCompilerFlags (config, target));
for (int i = 0; i < compilerFlags.size(); ++i)
setAddOption (*compiler, "option", compilerFlags[i]);
for (auto flag : compilerFlags)
setAddOption (*compiler, "option", flag);
}
{
const StringArray includePaths (getIncludePaths (config));
for (int i = 0; i < includePaths.size(); ++i)
setAddOption (*compiler, "directory", includePaths[i]);
for (auto path : includePaths)
setAddOption (*compiler, "directory", path);
}
}
{
XmlElement* const linker = xml.createNewChildElement ("Linker");
const StringArray linkerFlags (getLinkerFlags (config));
for (int i = 0; i < linkerFlags.size(); ++i)
setAddOption (*linker, "option", linkerFlags[i]);
const StringArray linkerFlags (getLinkerFlags (config, target));
for (auto flag : linkerFlags)
setAddOption (*linker, "option", flag);
const StringArray& libs = isWindows() ? mingwLibs : linuxLibs;
for (int i = 0; i < libs.size(); ++i)
setAddOption (*linker, "library", libs[i]);
for (auto lib : libs)
setAddOption (*linker, "library", lib);
const StringArray librarySearchPaths (config.getLibrarySearchPaths());
for (int i = 0; i < librarySearchPaths.size(); ++i)
setAddOption (*linker, "directory", replacePreprocessorDefs (getAllPreprocessorDefs(), librarySearchPaths[i]));
StringArray librarySearchPaths (config.getLibrarySearchPaths());
if (getProject().getProjectType().isAudioPlugin() && target.type != ProjectType::Target::SharedCodeTarget)
librarySearchPaths.add (RelativePath (getSharedCodePath (config), RelativePath::buildTargetFolder).getParentDirectory().toUnixStyle());
for (auto path : librarySearchPaths)
{
setAddOption (*linker, "directory", replacePreprocessorDefs (getAllPreprocessorDefs(), path));
}
}
}
@@ -385,7 +557,36 @@ private:
XmlElement* const build = xml.createNewChildElement ("Build");
for (ConstConfigIterator config (*this); config.next();)
createBuildTarget (*build->createNewChildElement ("Target"), *config);
{
for (auto target : targets)
if (target->type != ProjectType::Target::AggregateTarget)
createBuildTarget (*build->createNewChildElement ("Target"), *target, *config);
}
}
void addVirtualTargets (XmlElement& xml) const
{
XmlElement* const virtualTargets = xml.createNewChildElement ("VirtualTargets");
for (ConstConfigIterator config (*this); config.next();)
{
StringArray allTargets;
for (auto target : targets)
if (target->type != ProjectType::Target::AggregateTarget)
allTargets.add (target->getTargetNameForConfiguration (*config));
for (auto target : targets)
{
if (target->type == ProjectType::Target::AggregateTarget)
{
auto* configTarget = virtualTargets->createNewChildElement ("Add");
configTarget->setAttribute ("alias", config->getName());
configTarget->setAttribute ("targets", allTargets.joinIntoString (";"));
}
}
}
}
void addProjectCompilerOptions (XmlElement& xml) const
@@ -416,6 +617,54 @@ private:
setAddOption (*linker, "library", replacePreprocessorDefs (getAllPreprocessorDefs(), libs[i]));
}
CodeBlocksTarget& getTargetWithType (ProjectType::Target::Type type) const
{
CodeBlocksTarget* nonAggregrateTarget = nullptr;
for (auto* target : targets)
{
if (target->type == type)
return *target;
if (target->type != ProjectType::Target::AggregateTarget)
nonAggregrateTarget = target;
}
// this project has no valid targets
jassert (nonAggregrateTarget != nullptr);
return *nonAggregrateTarget;
}
// Returns SharedCode target for multi-target projects, otherwise it returns
// the single target
CodeBlocksTarget& getMainTarget() const
{
if (getProject().getProjectType().isAudioPlugin())
return getTargetWithType (ProjectType::Target::SharedCodeTarget);
for (auto* target : targets)
if (target->type != ProjectType::Target::AggregateTarget)
return *target;
jassertfalse;
return *targets[0];
}
CodeBlocksTarget& getTargetForProjectItem (const Project::Item& projectItem) const
{
if (getProject().getProjectType().isAudioPlugin())
{
if (! projectItem.shouldBeCompiled())
return getTargetWithType (ProjectType::Target::SharedCodeTarget);
return getTargetWithType (getProject().getTargetTypeFromFilePath (projectItem.getFile(), true));
}
return getMainTarget();
}
void addCompileUnits (const Project::Item& projectItem, XmlElement& xml) const
{
if (projectItem.isGroup())
@@ -430,10 +679,16 @@ private:
XmlElement* unit = xml.createNewChildElement ("Unit");
unit->setAttribute ("filename", file.toUnixStyle());
for (ConstConfigIterator config (*this); config.next();)
{
const String& targetName = getTargetForProjectItem (projectItem).getTargetNameForConfiguration (*config);
unit->createNewChildElement ("Option")->setAttribute ("target", targetName);
}
if (! projectItem.shouldBeCompiled())
{
unit->createNewChildElement("Option")->setAttribute ("compile", 0);
unit->createNewChildElement("Option")->setAttribute ("link", 0);
unit->createNewChildElement ("Option")->setAttribute ("compile", 0);
unit->createNewChildElement ("Option")->setAttribute ("link", 0);
}
}
}
@@ -448,6 +703,7 @@ private:
{
addOptions (xml);
addBuild (xml);
addVirtualTargets (xml);
addProjectCompilerOptions (xml);
addProjectLinkerOptions (xml);
addCompileUnits (xml);
@@ -473,7 +729,8 @@ private:
}
CodeBlocksOS os;
bool createDynamicLibrary = false;
OwnedArray<CodeBlocksTarget> targets;
JUCE_DECLARE_NON_COPYABLE (CodeBlocksProjectExporter)
};

+ 1361
- 1139
extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h
File diff suppressed because it is too large
View File


+ 340
- 130
extras/Projucer/Source/Project Saving/jucer_ProjectExport_Make.h View File

@@ -24,7 +24,243 @@
class MakefileProjectExporter : public ProjectExporter
{
protected:
//==============================================================================
class MakeBuildConfiguration : public BuildConfiguration
{
public:
MakeBuildConfiguration (Project& p, const ValueTree& settings, const ProjectExporter& e)
: BuildConfiguration (p, settings, e)
{
}
Value getArchitectureType() { return getValue (Ids::linuxArchitecture); }
var getArchitectureTypeVar() const { return config [Ids::linuxArchitecture]; }
var getDefaultOptimisationLevel() const override { return var ((int) (isDebug() ? gccO0 : gccO3)); }
void createConfigProperties (PropertyListBuilder& props) override
{
addGCCOptimisationProperty (props);
static const char* const archNames[] = { "(Default)", "<None>", "32-bit (-m32)", "64-bit (-m64)", "ARM v6", "ARM v7" };
const var archFlags[] = { var(), var (String()), "-m32", "-m64", "-march=armv6", "-march=armv7" };
props.add (new ChoicePropertyComponent (getArchitectureType(), "Architecture",
StringArray (archNames, numElementsInArray (archNames)),
Array<var> (archFlags, numElementsInArray (archFlags))));
}
String getLibrarySubdirPath () const override
{
const String archFlag = getArchitectureTypeVar();
const auto prefix = String ("-march=");
if (archFlag.startsWith (prefix))
return archFlag.substring (prefix.length());
else if (archFlag == "-m64")
return "x86_64";
else if (archFlag == "-m32")
return "i386";
else
return "$(shell uname -m)";
}
};
BuildConfiguration::Ptr createBuildConfig (const ValueTree& tree) const override
{
return new MakeBuildConfiguration (project, tree, *this);
}
public:
//==============================================================================
class MakefileTarget : public ProjectType::Target
{
public:
MakefileTarget (ProjectType::Target::Type targetType, const MakefileProjectExporter& exporter)
: ProjectType::Target (targetType), owner (exporter)
{}
StringArray getTargetSettings (const BuildConfiguration& config) const
{
if (type == AggregateTarget)
// the aggregate target should not specify any settings at all!
// it just defines dependencies on the other targets.
return StringArray();
StringPairArray commonOptions = owner.getAllPreprocessorDefs (config, ProjectType::Target::unspecified);
StringPairArray targetSpecific = owner.getAllPreprocessorDefs (config, type);
StringArray defs;
// remove any defines that have already been added by the configuration
const int n = targetSpecific.size();
for (int i = 0 ; i < n; ++i)
{
const String& key = targetSpecific.getAllKeys()[i];
if (! commonOptions.getAllKeys().contains (key))
defs.add (String ("-D") + key + String ("=") + targetSpecific.getAllValues()[i]);
}
StringArray s;
const String cppflagsVarName = String ("JUCE_CPPFLAGS_") + getTargetVarName();
s.add (cppflagsVarName + String (" := ") + defs.joinIntoString (" "));
if (getTargetFileType() == sharedLibraryOrDLL || getTargetFileType() == pluginBundle)
{
s.add (String ("JUCE_CFLAGS_") + getTargetVarName() + String (" := -fPIC"));
const String ldflagsVarName = String ("JUCE_LDFLAGS_") + getTargetVarName();
String targetLinkOptions = ldflagsVarName + String (" := -shared");
if (getTargetFileType() == pluginBundle)
targetLinkOptions += " -Wl,--no-undefined";
s.add (targetLinkOptions);
}
String targetName (owner.replacePreprocessorTokens (config, config.getTargetBinaryNameString()));
if (owner.projectType.isStaticLibrary() || owner.projectType.isDynamicLibrary())
targetName = getLibbedFilename (targetName);
else
targetName = targetName.upToLastOccurrenceOf (".", false, false) + getTargetFileSuffix();
s.add (String ("JUCE_TARGET_") + getTargetVarName() + String (" := ") + escapeSpaces (targetName));
return s;
}
String getTargetFileSuffix() const
{
switch (type)
{
case VSTPlugIn:
return ".so";
case VST3PlugIn:
return ".vst3";
case SharedCodeTarget:
return ".a";
default:
break;
}
return String();
}
String getTargetVarName() const
{
return String (getName()).toUpperCase().replaceCharacter (L' ', L'_');
}
void writeObjects (OutputStream& out) const
{
Array<RelativePath> targetFiles;
for (int i = 0; i < owner.getAllGroups().size(); ++i)
findAllFilesToCompile (owner.getAllGroups().getReference(i), targetFiles);
out << "OBJECTS_" + getTargetVarName() + String (" := \\") << newLine;
for (int i = 0; i < targetFiles.size(); ++i)
out << " $(JUCE_OBJDIR)/" << escapeSpaces (owner.getObjectFileFor (targetFiles.getReference(i))) << " \\" << newLine;
out << newLine;
}
void findAllFilesToCompile (const Project::Item& projectItem, Array<RelativePath>& results) const
{
if (projectItem.isGroup())
{
for (int i = 0; i < projectItem.getNumChildren(); ++i)
findAllFilesToCompile (projectItem.getChild(i), results);
}
else
{
if (projectItem.shouldBeCompiled())
{
const Type targetType = (owner.getProject().getProjectType().isAudioPlugin() ? type : SharedCodeTarget);
const File f = projectItem.getFile();
RelativePath relativePath (f, owner.getTargetFolder(), RelativePath::buildTargetFolder);
if (owner.shouldFileBeCompiledByDefault (relativePath)
&& owner.getProject().getTargetTypeFromFilePath (f, true) == targetType)
results.add (relativePath);
}
}
}
void addFiles (OutputStream& out)
{
Array<RelativePath> targetFiles;
for (int i = 0; i < owner.getAllGroups().size(); ++i)
findAllFilesToCompile (owner.getAllGroups().getReference(i), targetFiles);
const String cppflagsVarName = String ("JUCE_CPPFLAGS_") + getTargetVarName();
const String cflagsVarName = String ("JUCE_CFLAGS_") + getTargetVarName();
for (int i = 0; i < targetFiles.size(); ++i)
{
jassert (targetFiles.getReference(i).getRoot() == RelativePath::buildTargetFolder);
out << "$(JUCE_OBJDIR)/" << escapeSpaces (owner.getObjectFileFor (targetFiles.getReference(i)))
<< ": " << escapeSpaces (targetFiles.getReference(i).toUnixStyle()) << newLine
<< "\t-$(V_AT)mkdir -p $(JUCE_OBJDIR)" << newLine
<< "\t@echo \"Compiling " << targetFiles.getReference(i).getFileName() << "\"" << newLine
<< (targetFiles.getReference(i).hasFileExtension ("c;s;S") ? "\t$(V_AT)$(CC) $(JUCE_CFLAGS)" : "\t$(V_AT)$(CXX) $(JUCE_CXXFLAGS) ")
<< "$(" << cppflagsVarName << ") $(" << cflagsVarName << ") -o \"$@\" -c \"$<\""
<< newLine << newLine;
}
}
String getBuildProduct() const
{
return String ("$(JUCE_OUTDIR)/$(JUCE_TARGET_") + getTargetVarName() + String (")");
}
void writeTargetLine (OutputStream& out, const bool useLinuxPackages)
{
jassert (type != AggregateTarget);
out << getBuildProduct() << " : "
<< ((useLinuxPackages) ? "check-pkg-config " : "")
<< "$(OBJECTS_" << getTargetVarName() << ") $(RESOURCES)";
if (type != SharedCodeTarget && owner.shouldBuildTargetType (SharedCodeTarget))
out << " $(JUCE_OUTDIR)/$(JUCE_TARGET_SHARED_CODE)";
out << newLine << "\t@echo Linking \"" << owner.projectName << " (" << getName() << ")\"" << newLine
<< "\t-$(V_AT)mkdir -p $(JUCE_BINDIR)" << newLine
<< "\t-$(V_AT)mkdir -p $(JUCE_LIBDIR)" << newLine
<< "\t-$(V_AT)mkdir -p $(JUCE_OUTDIR)" << newLine;
if (owner.projectType.isStaticLibrary() || type == SharedCodeTarget)
out << "\t$(V_AT)$(AR) -rcs " << getBuildProduct()
<< " $(OBJECTS_" << getTargetVarName() << ")" << newLine;
else
{
out << "\t$(V_AT)$(CXX) -o " << getBuildProduct()
<< " $(OBJECTS_" << getTargetVarName() << ") ";
if (owner.shouldBuildTargetType (SharedCodeTarget))
out << "$(JUCE_OUTDIR)/$(JUCE_TARGET_SHARED_CODE) ";
out << "$(JUCE_LDFLAGS) ";
if (getTargetFileType() == sharedLibraryOrDLL || getTargetFileType() == pluginBundle)
out << "$(JUCE_LDFLAGS_" << getTargetVarName() << ") ";
out << "$(RESOURCES) $(TARGET_ARCH)" << newLine;
}
out << newLine;
}
const MakefileProjectExporter& owner;
};
//==============================================================================
static const char* getNameLinux() { return "Linux Makefile"; }
static const char* getValueTreeTypeName() { return "LINUX_MAKE"; }
@@ -72,13 +308,25 @@ public:
bool isOSX() const override { return false; }
bool isiOS() const override { return false; }
bool supportsVST() const override { return true; }
bool supportsVST3() const override { return false; }
bool supportsAAX() const override { return false; }
bool supportsRTAS() const override { return false; }
bool supportsAU() const override { return false; }
bool supportsAUv3() const override { return false; }
bool supportsStandalone() const override { return false; }
bool supportsTargetType (ProjectType::Target::Type type) const override
{
switch (type)
{
case ProjectType::Target::GUIApp:
case ProjectType::Target::ConsoleApp:
case ProjectType::Target::StaticLibrary:
case ProjectType::Target::SharedCodeTarget:
case ProjectType::Target::AggregateTarget:
case ProjectType::Target::VSTPlugIn:
case ProjectType::Target::StandalonePlugIn:
case ProjectType::Target::DynamicLibrary:
return true;
default:
break;
}
return false;
}
Value getCppStandardValue() { return getSetting (Ids::cppLanguageStandard); }
String getCppStandardString() const { return settings[Ids::cppLanguageStandard]; }
@@ -99,81 +347,49 @@ public:
}
//==============================================================================
void create (const OwnedArray<LibraryModule>&) const override
bool anyTargetIsSharedLibrary() const
{
Array<RelativePath> files;
for (int i = 0; i < getAllGroups().size(); ++i)
findAllFilesToCompile (getAllGroups().getReference(i), files);
MemoryOutputStream mo;
writeMakefile (mo, files);
const int n = targets.size();
for (int i = 0; i < n; ++i)
{
const ProjectType::Target::TargetFileType fileType = targets.getUnchecked (i)->getTargetFileType();
if (fileType == ProjectType::Target::sharedLibraryOrDLL || fileType == ProjectType::Target::pluginBundle)
return true;
}
overwriteFileIfDifferentOrThrow (getTargetFolder().getChildFile ("Makefile"), mo);
return false;
}
//==============================================================================
void addPlatformSpecificSettingsForProjectType (const ProjectType& type) override
void create (const OwnedArray<LibraryModule>&) const override
{
if (type.isStaticLibrary())
makefileTargetSuffix = ".a";
MemoryOutputStream mo;
writeMakefile (mo);
else if (type.isAudioPlugin() || type.isDynamicLibrary())
{
makefileIsDLL = true;
if (type.isDynamicLibrary())
makefileTargetSuffix = ".so";
}
overwriteFileIfDifferentOrThrow (getTargetFolder().getChildFile ("Makefile"), mo);
}
protected:
//==============================================================================
class MakeBuildConfiguration : public BuildConfiguration
void addPlatformSpecificSettingsForProjectType (const ProjectType&) override
{
public:
MakeBuildConfiguration (Project& p, const ValueTree& settings, const ProjectExporter& e)
: BuildConfiguration (p, settings, e)
{
}
Value getArchitectureType() { return getValue (Ids::linuxArchitecture); }
var getArchitectureTypeVar() const { return config [Ids::linuxArchitecture]; }
var getDefaultOptimisationLevel() const override { return var ((int) (isDebug() ? gccO0 : gccO3)); }
void createConfigProperties (PropertyListBuilder& props) override
{
addGCCOptimisationProperty (props);
static const char* const archNames[] = { "(Default)", "<None>", "32-bit (-m32)", "64-bit (-m64)", "ARM v6", "ARM v7" };
const var archFlags[] = { var(), var (String()), "-m32", "-m64", "-march=armv6", "-march=armv7" };
props.add (new ChoicePropertyComponent (getArchitectureType(), "Architecture",
StringArray (archNames, numElementsInArray (archNames)),
Array<var> (archFlags, numElementsInArray (archFlags))));
}
};
BuildConfiguration::Ptr createBuildConfig (const ValueTree& tree) const override
{
return new MakeBuildConfiguration (project, tree, *this);
callForAllSupportedTargets ([this] (ProjectType::Target::Type targetType)
{
if (MakefileTarget* target = new MakefileTarget (targetType, *this))
{
if (targetType == ProjectType::Target::AggregateTarget)
targets.insert (0, target);
else
targets.add (target);
}
});
// If you hit this assert, you tried to generate a project for an exporter
// that does not support any of your targets!
jassert (targets.size() > 0);
}
private:
//==============================================================================
void findAllFilesToCompile (const Project::Item& projectItem, Array<RelativePath>& results) const
{
if (projectItem.isGroup())
{
for (int i = 0; i < projectItem.getNumChildren(); ++i)
findAllFilesToCompile (projectItem.getChild(i), results);
}
else
{
if (projectItem.shouldBeCompiled())
results.add (RelativePath (projectItem.getFile(), getTargetFolder(), RelativePath::buildTargetFolder));
}
}
void writeDefineFlags (OutputStream& out, const BuildConfiguration& config) const
{
StringPairArray defines;
@@ -189,7 +405,7 @@ private:
defines.set ("NDEBUG", "1");
}
out << createGCCPreprocessorFlags (mergePreprocessorDefs (defines, getAllPreprocessorDefs (config)));
out << createGCCPreprocessorFlags (mergePreprocessorDefs (defines, getAllPreprocessorDefs (config, ProjectType::Target::unspecified)));
}
void writeHeaderPathFlags (OutputStream& out, const BuildConfiguration& config) const
@@ -239,9 +455,6 @@ private:
{
StringArray flags (makefileExtraLinkerFlags);
if (makefileIsDLL)
flags.add ("-shared");
if (! config.isDebug())
flags.add ("-fvisibility=hidden");
@@ -282,6 +495,36 @@ private:
<< " $(LDFLAGS)" << newLine;
}
void writeTargetLines (OutputStream& out, const bool useLinuxPackages) const
{
const int n = targets.size();
for (int i = 0; i < n; ++i)
{
if (MakefileTarget* target = targets.getUnchecked (i))
{
if (target->type == ProjectType::Target::AggregateTarget)
{
StringArray dependencies;
for (int j = 0; j < n; ++j)
{
if (i == j) continue;
if (MakefileTarget* dependency = targets.getUnchecked (j))
{
if (dependency->type != ProjectType::Target::SharedCodeTarget)
dependencies.add (dependency->getBuildProduct());
}
}
out << "all : " << dependencies.joinIntoString (" ") << newLine << newLine;
}
else
target->writeTargetLine (out, useLinuxPackages);
}
}
}
void writeConfig (OutputStream& out, const BuildConfiguration& config) const
{
const String buildDirName ("build");
@@ -307,14 +550,24 @@ private:
writeCppFlags (out, config);
for (auto target : targets)
{
StringArray lines = target->getTargetSettings (config);
if (lines.size() > 0)
out << " " << lines.joinIntoString ("\n ") << newLine;
out << newLine;
}
out << " JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH)";
if (anyTargetIsSharedLibrary())
out << " -fPIC";
if (config.isDebug())
out << " -g -ggdb";
if (makefileIsDLL)
out << " -fPIC";
out << " -O" << config.getGCCOptimisationFlag()
<< (" " + replacePreprocessorTokens (config, getExtraCompilerFlagsString())).trimEnd()
<< " $(CFLAGS)" << newLine;
@@ -324,44 +577,19 @@ private:
if (cppStandardToUse.isEmpty())
cppStandardToUse = "-std=c++11";
out << " JUCE_CXXFLAGS += $(JUCE_CFLAGS) "
out << " JUCE_CXXFLAGS += $(CXXFLAGS) $(JUCE_CFLAGS) "
<< cppStandardToUse << " $(CXXFLAGS)" << newLine;
writeLinkerFlags (out, config);
out << newLine;
String targetName (replacePreprocessorTokens (config, config.getTargetBinaryNameString()));
if (projectType.isStaticLibrary() || projectType.isDynamicLibrary())
targetName = getLibbedFilename (targetName);
else
targetName = targetName.upToLastOccurrenceOf (".", false, false) + makefileTargetSuffix;
out << " TARGET := " << escapeSpaces (targetName) << newLine;
if (projectType.isStaticLibrary())
out << " BLDCMD = $(AR) -rcs $(JUCE_OUTDIR)/$(TARGET) $(OBJECTS)" << newLine;
else
out << " BLDCMD = $(CXX) -o $(JUCE_OUTDIR)/$(TARGET) $(OBJECTS) $(JUCE_LDFLAGS) $(RESOURCES) $(TARGET_ARCH)" << newLine;
out << " CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR)" << newLine
<< "endif" << newLine
<< newLine;
}
void writeObjects (OutputStream& out, const Array<RelativePath>& files) const
{
out << "OBJECTS := \\" << newLine;
for (int i = 0; i < files.size(); ++i)
if (shouldFileBeCompiledByDefault (files.getReference(i)))
out << " $(JUCE_OBJDIR)/" << escapeSpaces (getObjectFileFor (files.getReference(i))) << " \\" << newLine;
out << newLine;
}
void writeMakefile (OutputStream& out, const Array<RelativePath>& files) const
void writeMakefile (OutputStream& out) const
{
out << "# Automatically generated makefile, created by the Projucer" << newLine
<< "# Don't edit this file! Your changes will be overwritten when you re-save the Projucer project!" << newLine
@@ -397,26 +625,22 @@ private:
for (ConstConfigIterator config (*this); config.next();)
writeConfig (out, *config);
writeObjects (out, files);
for (auto target : targets)
target->writeObjects (out);
out << ".PHONY: clean" << newLine
out << ".PHONY: clean all" << newLine
<< newLine;
StringArray packages;
packages.addTokens (getExtraPkgConfigString(), " ", "\"'");
packages.removeEmptyStrings();
bool useLinuxPackages = (linuxPackages.size() > 0 || packages.size() > 0);
const bool useLinuxPackages = (linuxPackages.size() > 0 || packages.size() > 0);
out << "$(JUCE_OUTDIR)/$(TARGET): "
<< ((useLinuxPackages) ? "check-pkg-config " : "")
<< "$(OBJECTS) $(RESOURCES)" << newLine
<< "\t@echo Linking " << projectName << newLine
<< "\t-@mkdir -p $(JUCE_BINDIR)" << newLine
<< "\t-@mkdir -p $(JUCE_LIBDIR)" << newLine
<< "\t-@mkdir -p $(JUCE_OUTDIR)" << newLine
<< "\t$(V_AT)$(BLDCMD)" << newLine
<< newLine;
writeTargetLines (out, useLinuxPackages);
for (auto target : targets)
target->addFiles (out);
if (useLinuxPackages)
{
@@ -442,25 +666,9 @@ private:
out << "strip:" << newLine
<< "\t@echo Stripping " << projectName << newLine
<< "\t-@$(STRIP) --strip-unneeded $(JUCE_OUTDIR)/$(TARGET)" << newLine
<< "\t-$(V_AT)$(STRIP) --strip-unneeded $(JUCE_OUTDIR)/$(TARGET)" << newLine
<< newLine;
for (int i = 0; i < files.size(); ++i)
{
if (shouldFileBeCompiledByDefault (files.getReference(i)))
{
jassert (files.getReference(i).getRoot() == RelativePath::buildTargetFolder);
out << "$(JUCE_OBJDIR)/" << escapeSpaces (getObjectFileFor (files.getReference(i)))
<< ": " << escapeSpaces (files.getReference(i).toUnixStyle()) << newLine
<< "\t-@mkdir -p $(JUCE_OBJDIR)" << newLine
<< "\t@echo \"Compiling " << files.getReference(i).getFileName() << "\"" << newLine
<< (files.getReference(i).hasFileExtension ("c;s;S") ? "\t$(V_AT)$(CC) $(JUCE_CFLAGS) -o \"$@\" -c \"$<\""
: "\t$(V_AT)$(CXX) $(JUCE_CXXFLAGS) -o \"$@\" -c \"$<\"")
<< newLine << newLine;
}
}
out << "-include $(OBJECTS:%.o=%.d)" << newLine;
}
@@ -486,5 +694,7 @@ private:
TargetOS::linux)));
}
OwnedArray<MakefileTarget> targets;
JUCE_DECLARE_NON_COPYABLE (MakefileProjectExporter)
};

+ 101
- 226
extras/Projucer/Source/Project Saving/jucer_ProjectExport_XCode.h View File

@@ -127,13 +127,31 @@ public:
bool isOSX() const override { return ! iOS; }
bool isiOS() const override { return iOS; }
bool supportsVST() const override { return ! iOS; }
bool supportsVST3() const override { return ! iOS; }
bool supportsAAX() const override { return ! iOS; }
bool supportsRTAS() const override { return ! iOS; }
bool supportsAU() const override { return ! iOS; }
bool supportsAUv3() const override { return true; }
bool supportsStandalone() const override { return true; }
bool supportsTargetType (ProjectType::Target::Type type) const override
{
switch (type)
{
case ProjectType::Target::AudioUnitv3PlugIn:
case ProjectType::Target::StandalonePlugIn:
case ProjectType::Target::GUIApp:
case ProjectType::Target::StaticLibrary:
case ProjectType::Target::SharedCodeTarget:
case ProjectType::Target::AggregateTarget:
return true;
case ProjectType::Target::ConsoleApp:
case ProjectType::Target::VSTPlugIn:
case ProjectType::Target::VST3PlugIn:
case ProjectType::Target::AAXPlugIn:
case ProjectType::Target::RTASPlugIn:
case ProjectType::Target::AudioUnitPlugIn:
case ProjectType::Target::DynamicLibrary:
return ! iOS;
default:
break;
}
return false;
}
void createExporterProperties (PropertyListBuilder& props) override
{
@@ -206,7 +224,8 @@ public:
"You can find this string in the OS X app Keychain Access under \"Certificates\".");
props.add (new BooleanPropertyComponent (getSetting ("keepCustomXcodeSchemes"), "Keep custom Xcode schemes", "Enabled"),
"Enable this to keep any Xcode schemes you have created for debugging or running, e.g. to launch a plug-in in various hosts. If disabled, all schemes are replaced by a default set.");
"Enable this to keep any Xcode schemes you have created for debugging or running, e.g. to launch a plug-in in"
"various hosts. If disabled, all schemes are replaced by a default set.");
}
bool launchProject() override
@@ -231,7 +250,7 @@ public:
void create (const OwnedArray<LibraryModule>&) const override
{
for (auto& target : targets)
if (target->xcodeCreatePList)
if (target->shouldCreatePList())
target->infoPlistFile = getTargetFolder().getChildFile (target->getInfoPlistName());
menuNibFile = getTargetFolder().getChildFile ("RecentFilesMenuTemplate.nib");
@@ -265,52 +284,18 @@ public:
}
//==============================================================================
void addPlatformSpecificSettingsForProjectType (const ProjectType& type) override
{
if (type.isGUIApplication())
targets.add (new Target (Target::GUIApp, *this));
else if (type.isCommandLineApp())
targets.add (new Target (Target::ConsoleApp, *this));
else if (type.isStaticLibrary())
targets.add (new Target (Target::StaticLibrary, *this));
else if (type.isDynamicLibrary())
targets.add (new Target (Target::DynamicLibrary, *this));
else if (type.isAudioPlugin())
{
if (project.shouldBuildVST().getValue() && supportsVST())
targets.add (new Target (Target::VSTPlugIn, *this));
if (project.shouldBuildVST3().getValue() && supportsVST3())
targets.add (new Target (Target::VST3PlugIn, *this));
if (project.shouldBuildAU().getValue() && supportsAU())
targets.add (new Target (Target::AudioUnitPlugIn, *this));
if (project.shouldBuildAUv3().getValue())
targets.add (new Target (Target::AudioUnitv3PlugIn, *this));
if (project.shouldBuildAAX().getValue() && supportsAAX())
targets.add (new Target (Target::AAXPlugIn, *this));
if (project.shouldBuildStandalone().getValue())
targets.add (new Target (Target::StandalonePlugIn, *this));
if (project.shouldBuildRTAS().getValue() && supportsRTAS())
{
targets.add (new Target (Target::RTASPlugIn, *this));
addRTASPluginSettings();
}
if (targets.size() > 0)
targets.add (new Target (Target::SharedCodeTarget, *this));
}
if (targets.size() > 1)
targets.insert (0, new Target (Target::AggregateTarget, *this));
void addPlatformSpecificSettingsForProjectType (const ProjectType&) override
{
callForAllSupportedTargets ([this] (ProjectType::Target::Type targetType)
{
if (XCodeTarget* target = new XCodeTarget (targetType, *this))
{
if (targetType == ProjectType::Target::AggregateTarget)
targets.insert (0, target);
else
targets.add (target);
}
});
// If you hit this assert, you tried to generate a project for an exporter
// that does not support any of your targets!
@@ -400,7 +385,9 @@ protected:
osxVersionNames.add ("Use Default");
versionValues.add (osxVersionDefault);
for (int ver = oldestSDKVersion; ver <= currentSDKVersion; ++ver)
int oldestAllowedSDKVersion = project.shouldBuildAUv3() ? minimumAUv3SDKVersion : oldestSDKVersion;
for (int ver = oldestAllowedSDKVersion; ver <= currentSDKVersion; ++ver)
{
sdkVersionNames.add (getSDKName (ver));
osxVersionNames.add (getOSXVersionName (ver));
@@ -463,27 +450,32 @@ protected:
"Enable this to strip any locally defined symbols resulting in a smaller binary size. Enabling this will also remove any function names from crash logs. Must be disabled for static library projects.");
}
String getLibrarySubdirPath () const override
{
return "${CURRENT_ARCH}";
}
private:
//==========================================================================
void addXcodePluginInstallPathProperties (PropertyListBuilder& props)
{
if (project.shouldBuildVST().getValue())
if (project.shouldBuildVST())
props.add (new TextWithDefaultPropertyComponent<String> (vstBinaryLocation, "VST Binary location", 1024),
"The folder in which the compiled VST binary should be placed.");
if (project.shouldBuildVST3().getValue())
if (project.shouldBuildVST3())
props.add (new TextWithDefaultPropertyComponent<String> (vst3BinaryLocation, "VST3 Binary location", 1024),
"The folder in which the compiled VST3 binary should be placed.");
if (project.shouldBuildAU().getValue())
if (project.shouldBuildAU())
props.add (new TextWithDefaultPropertyComponent<String> (auBinaryLocation, "AU Binary location", 1024),
"The folder in which the compiled AU binary should be placed.");
if (project.shouldBuildRTAS().getValue())
if (project.shouldBuildRTAS())
props.add (new TextWithDefaultPropertyComponent<String> (rtasBinaryLocation, "RTAS Binary location", 1024),
"The folder in which the compiled RTAS binary should be placed.");
if (project.shouldBuildAAX().getValue())
if (project.shouldBuildAAX())
props.add (new TextWithDefaultPropertyComponent<String> (aaxBinaryLocation, "AAX Binary location", 1024),
"The folder in which the compiled AAX binary should be placed.");
}
@@ -513,40 +505,16 @@ public:
};
//==============================================================================
struct Target
struct XCodeTarget : ProjectType::Target
{
enum Type
{
GUIApp = 0,
ConsoleApp = 1,
StaticLibrary = 2,
DynamicLibrary = 3,
VSTPlugIn = 10,
VST3PlugIn = 11,
AAXPlugIn = 12,
RTASPlugIn = 13,
AudioUnitPlugIn = 14,
AudioUnitv3PlugIn = 15,
StandalonePlugIn = 16,
SharedCodeTarget = 20, // internal
AggregateTarget = 21,
unspecified = 30
};
//==============================================================================
Target (Type targetType, const XCodeProjectExporter& exporter)
: type (targetType),
XCodeTarget (ProjectType::Target::Type targetType, const XCodeProjectExporter& exporter)
: ProjectType::Target (targetType),
owner (exporter)
{
switch (type)
{
case GUIApp:
xcodeIsBundle = false;
xcodeIsExecutable = true;
xcodeCreatePList = true;
xcodePackageType = "APPL";
xcodeBundleSignature = "????";
xcodeFileType = "wrapper.application";
@@ -556,9 +524,6 @@ public:
break;
case ConsoleApp:
xcodeIsBundle = false;
xcodeIsExecutable = true;
xcodeCreatePList = false;
xcodeFileType = "compiled.mach-o.executable";
xcodeBundleExtension = String();
xcodeProductType = "com.apple.product-type.tool";
@@ -566,55 +531,37 @@ public:
break;
case StaticLibrary:
xcodeIsBundle = false;
xcodeIsExecutable = false;
xcodeCreatePList = false;
xcodeFileType = "archive.ar";
xcodeProductType = "com.apple.product-type.library.static";
xcodeCopyToProductInstallPathAfterBuild = false;
break;
case DynamicLibrary:
xcodeIsBundle = false;
xcodeIsExecutable = false;
xcodeCreatePList = false;
xcodeFileType = "compiled.mach-o.dylib";
xcodeProductType = "com.apple.product-type.library.dynamic";
xcodeBundleExtension = ".dylib";
xcodeCopyToProductInstallPathAfterBuild = false;
break;
case VSTPlugIn:
xcodeIsBundle = true;
xcodeIsExecutable = false;
xcodeCreatePList = true;
xcodePackageType = "BNDL";
xcodeBundleSignature = "????";
xcodeFileType = "wrapper.cfbundle";
xcodeBundleExtension = ".vst";
xcodeProductType = "com.apple.product-type.bundle";
xcodeCopyToProductInstallPathAfterBuild = true;
break;
case VST3PlugIn:
xcodeIsBundle = true;
xcodeIsExecutable = false;
xcodeCreatePList = true;
xcodePackageType = "BNDL";
xcodeBundleSignature = "????";
xcodeFileType = "wrapper.cfbundle";
xcodeBundleExtension = ".vst3";
xcodeProductType = "com.apple.product-type.bundle";
xcodeCopyToProductInstallPathAfterBuild = true;
break;
case AudioUnitPlugIn:
xcodeIsBundle = true;
xcodeIsExecutable = false;
xcodeCreatePList = true;
xcodePackageType = "BNDL";
xcodeBundleSignature = "????";
xcodeFileType = "wrapper.cfbundle";
@@ -626,12 +573,8 @@ public:
break;
case StandalonePlugIn:
xcodeIsBundle = false;
xcodeIsExecutable = true;
xcodeCreatePList = true;
xcodePackageType = "APPL";
xcodeBundleSignature = "????";
xcodeCreatePList = true;
xcodeFileType = "wrapper.application";
xcodeBundleExtension = ".app";
xcodeProductType = "com.apple.product-type.application";
@@ -639,9 +582,6 @@ public:
break;
case AudioUnitv3PlugIn:
xcodeIsBundle = false;
xcodeIsExecutable = false;
xcodeCreatePList = true;
xcodePackageType = "XPC!";
xcodeBundleSignature = "????";
xcodeFileType = "wrapper.app-extension";
@@ -654,9 +594,6 @@ public:
break;
case AAXPlugIn:
xcodeIsBundle = true;
xcodeIsExecutable = false;
xcodeCreatePList = true;
xcodePackageType = "TDMw";
xcodeBundleSignature = "PTul";
xcodeFileType = "wrapper.cfbundle";
@@ -668,9 +605,6 @@ public:
break;
case RTASPlugIn:
xcodeIsBundle = true;
xcodeIsExecutable = false;
xcodeCreatePList = true;
xcodePackageType = "TDMw";
xcodeBundleSignature = "PTul";
xcodeFileType = "wrapper.cfbundle";
@@ -682,18 +616,12 @@ public:
break;
case SharedCodeTarget:
xcodeIsBundle = false;
xcodeIsExecutable = false;
xcodeCreatePList = false;
xcodeFileType = "archive.ar";
xcodeProductType = "com.apple.product-type.library.static";
xcodeCopyToProductInstallPathAfterBuild = false;
break;
case AggregateTarget:
xcodeIsBundle = false;
xcodeIsExecutable = false;
xcodeCreatePList = false;
xcodeCopyToProductInstallPathAfterBuild = false;
break;
@@ -704,40 +632,11 @@ public:
}
}
const char* getName() const noexcept
{
switch (type)
{
case GUIApp: return "App";
case ConsoleApp: return "ConsoleApp";
case StaticLibrary: return "Static Library";
case DynamicLibrary: return "Dynamic Library";
case VSTPlugIn: return "VST";
case VST3PlugIn: return "VST3";
case AudioUnitPlugIn: return "AU";
case StandalonePlugIn: return "AUv3 Standalone";
case AudioUnitv3PlugIn: return "AUv3 AppExtension";
case AAXPlugIn: return "AAX";
case RTASPlugIn: return "RTAS";
case SharedCodeTarget: return "Shared Code";
case AggregateTarget: return "All";
default: return "undefined";
}
}
String getXCodeSchemeName() const
{
return owner.projectName + " (" + getName() + ")";
}
bool shouldBuildVST() const { return owner.supportsVST() && owner.project.shouldBuildVST().getValue() && (type == SharedCodeTarget || type == VSTPlugIn); }
bool shouldBuildVST3() const { return owner.supportsVST3() && owner.project.shouldBuildVST3().getValue() && (type == SharedCodeTarget || type == VST3PlugIn); }
bool shouldBuildAAX() const { return owner.supportsAAX() && owner.project.shouldBuildAAX().getValue() && (type == SharedCodeTarget || type == AAXPlugIn); }
bool shouldBuildRTAS() const { return owner.supportsRTAS() && owner.project.shouldBuildRTAS().getValue() && (type == SharedCodeTarget || type == RTASPlugIn); }
bool shouldBuildAU() const { return owner.supportsAU() && owner.project.shouldBuildAU().getValue() && (type == SharedCodeTarget || type == AudioUnitPlugIn); }
bool shouldBuildAUv3() const { return owner.supportsAUv3() && owner.project.shouldBuildAUv3().getValue() && (type == SharedCodeTarget || type == AudioUnitv3PlugIn); }
bool shouldBuildStandalone() const { return owner.project.shouldBuildStandalone().getValue() && (type == SharedCodeTarget || type == StandalonePlugIn); }
String getID() const
{
return owner.createID (String ("__target") + getName());
@@ -751,9 +650,8 @@ public:
String xcodePackageType, xcodeBundleSignature, xcodeBundleExtension;
String xcodeProductType, xcodeFileType;
String xcodeOtherRezFlags, xcodeExcludedFiles64Bit, xcodeBundleIDSubPath;
bool xcodeIsBundle, xcodeCreatePList, xcodeIsExecutable, xcodeCopyToProductInstallPathAfterBuild;
bool xcodeCopyToProductInstallPathAfterBuild;
StringArray xcodeFrameworks, xcodeLibs;
Type type;
Array<XmlElement> xcodeExtraPListEntries;
Array<RelativePath> xcodeExtraLibrariesDebug, xcodeExtraLibrariesRelease;
@@ -874,6 +772,12 @@ public:
return *v;
}
bool shouldCreatePList() const
{
const ProjectType::Target::TargetFileType fileType = getTargetFileType();
return (fileType == executable && type != ConsoleApp) || fileType == pluginBundle || fileType == macOSAppex;
}
//==============================================================================
StringArray getTargetSettings (const XcodeBuildConfiguration& config) const
{
@@ -904,7 +808,7 @@ public:
s.add ("HEADER_SEARCH_PATHS = " + owner.getHeaderSearchPaths (config));
s.add ("GCC_OPTIMIZATION_LEVEL = " + config.getGCCOptimisationFlag());
if (xcodeCreatePList)
if (shouldCreatePList())
s.add ("INFOPLIST_FILE = " + infoPlistFile.getFileName());
if (config.linkTimeOptimisationEnabled.get())
@@ -930,7 +834,7 @@ public:
}
}
if (xcodeIsBundle)
if (getTargetFileType() == pluginBundle)
{
s.add ("LIBRARY_STYLE = Bundle");
s.add ("WRAPPER_EXTENSION = " + xcodeBundleExtension.substring (1));
@@ -970,9 +874,7 @@ public:
// if the user doesn't set it, then use the last known version that works well with JUCE
String deploymentTarget = "10.11";
int oldestAllowedSDKVersion = (type == AudioUnitv3PlugIn || type == StandalonePlugIn) ? minimumAUv3SDKVersion : oldestSDKVersion;
for (int ver = oldestAllowedSDKVersion; ver <= currentSDKVersion; ++ver)
for (int ver = oldestSDKVersion; ver <= currentSDKVersion; ++ver)
{
if (sdk == getSDKName (ver)) s.add ("SDKROOT = macosx10." + String (ver));
if (sdkCompat == getSDKName (ver)) deploymentTarget = "10." + String (ver);
@@ -1052,24 +954,10 @@ public:
s.add ("SEPARATE_STRIP = YES");
}
if (type == Target::SharedCodeTarget)
defines.set ("JUCE_SHARED_CODE", "1");
if (owner.project.getProjectType().isAudioPlugin() && type == Target::AudioUnitv3PlugIn && owner.isOSX())
s.add (String ("CODE_SIGN_ENTITLEMENTS = \"") + owner.getEntitlementsFileName() + String ("\""));
if (owner.project.getProjectType().isAudioPlugin())
{
defines.set ("JucePlugin_Build_VST", (shouldBuildVST() ? "1" : "0"));
defines.set ("JucePlugin_Build_VST3", (shouldBuildVST3() ? "1" : "0"));
defines.set ("JucePlugin_Build_AU", (shouldBuildAU() ? "1" : "0"));
defines.set ("JucePlugin_Build_AUv3", (shouldBuildAUv3() ? "1" : "0"));
defines.set ("JucePlugin_Build_RTAS", (shouldBuildRTAS() ? "1" : "0"));
defines.set ("JucePlugin_Build_AAX", (shouldBuildAAX() ? "1" : "0"));
defines.set ("JucePlugin_Build_Standalone", (shouldBuildStandalone() ? "1" : "0"));
}
defines = mergePreprocessorDefs (defines, owner.getAllPreprocessorDefs (config));
defines = mergePreprocessorDefs (defines, owner.getAllPreprocessorDefs (config, type));
StringArray defsList;
@@ -1109,7 +997,7 @@ public:
//==============================================================================
void getLinkerSettings (const BuildConfiguration& config, StringArray& flags, StringArray& librarySearchPaths) const
{
if (xcodeIsBundle)
if (getTargetFileType() == pluginBundle)
flags.add (owner.isiOS() ? "-bitcode_bundle" : "-bundle");
const Array<RelativePath>& extraLibs = config.isDebug() ? xcodeExtraLibrariesDebug
@@ -1147,7 +1035,7 @@ public:
//========================================================================== c
void writeInfoPlistFile() const
{
if (! xcodeCreatePList)
if (! shouldCreatePList())
return;
ScopedPointer<XmlElement> plist (XmlDocument::parse (owner.getPListToMergeString()));
@@ -1409,7 +1297,7 @@ public:
private:
//==============================================================================
bool xcodeCanUseDwarf;
OwnedArray<Target> targets;
OwnedArray<XCodeTarget> targets;
mutable OwnedArray<ValueTree> pbxBuildFiles, pbxFileReferences, pbxGroups, misc, projectConfigs, targetConfigs;
mutable StringArray resourceIDs, sourceIDs, targetIDs;
@@ -1471,7 +1359,7 @@ private:
{
for (auto* target : targets)
{
if (target->type == Target::AggregateTarget)
if (target->type == XCodeTarget::AggregateTarget)
continue;
target->addMainBuildProduct();
@@ -1495,10 +1383,10 @@ private:
{
for (auto* target : targets)
{
if (target->type == Target::AggregateTarget)
if (target->type == XCodeTarget::AggregateTarget)
continue;
if (target->xcodeCreatePList)
if (target->shouldCreatePList())
{
RelativePath plistPath (target->infoPlistFile, getTargetFolder(), RelativePath::buildTargetFolder);
addFileReference (plistPath.toUnixStyle());
@@ -1576,7 +1464,7 @@ private:
// add build phases
for (auto* target : targets)
{
if (target->type != Target::AggregateTarget)
if (target->type != XCodeTarget::AggregateTarget)
buildProducts.add (createID (String ("__productFileID") + String (target->getName())));
for (ConstConfigIterator config (*this); config.next();)
@@ -1589,11 +1477,11 @@ private:
target->addShellScriptBuildPhase ("Pre-build script", getPreBuildScript());
if (target->type != Target::AggregateTarget)
if (target->type != XCodeTarget::AggregateTarget)
{
// TODO: ideally resources wouldn't be copied into the AUv3 bundle as well.
// However, fixing this requires supporting App groups -> TODO: add app groups
if (! projectType.isStaticLibrary() && target->type != Target::SharedCodeTarget)
if (! projectType.isStaticLibrary() && target->type != XCodeTarget::SharedCodeTarget)
target->addBuildPhase ("PBXResourcesBuildPhase", resourceIDs);
StringArray rezFiles (rezFileIDs);
@@ -1604,20 +1492,20 @@ private:
StringArray sourceFiles (target->sourceIDs);
if (target->type == Target::SharedCodeTarget
if (target->type == XCodeTarget::SharedCodeTarget
|| (! project.getProjectType().isAudioPlugin()))
sourceFiles.addArray (sourceIDs);
target->addBuildPhase ("PBXSourcesBuildPhase", sourceFiles);
if (! projectType.isStaticLibrary() && target->type != Target::SharedCodeTarget)
if (! projectType.isStaticLibrary() && target->type != XCodeTarget::SharedCodeTarget)
target->addBuildPhase ("PBXFrameworksBuildPhase", target->frameworkIDs);
}
target->addShellScriptBuildPhase ("Post-build script", getPostBuildScript());
if (project.getProjectType().isAudioPlugin() && project.shouldBuildAUv3().getValue()
&& project.shouldBuildStandalone().getValue() && target->type == Target::StandalonePlugIn)
if (project.getProjectType().isAudioPlugin() && project.shouldBuildAUv3()
&& project.shouldBuildStandalonePlugin() && target->type == XCodeTarget::StandalonePlugIn)
embedAppExtension();
addTargetObject (*target);
@@ -1626,9 +1514,9 @@ private:
void embedAppExtension() const
{
if (auto* standaloneTarget = getTargetOfType (Target::StandalonePlugIn))
if (auto* standaloneTarget = getTargetOfType (XCodeTarget::StandalonePlugIn))
{
if (auto* auv3Target = getTargetOfType (Target::AudioUnitv3PlugIn))
if (auto* auv3Target = getTargetOfType (XCodeTarget::AudioUnitv3PlugIn))
{
StringArray files;
files.add (auv3Target->mainBuildProductID);
@@ -1662,7 +1550,7 @@ private:
}
//==============================================================================
Target* getTargetOfType (Target::Type type) const
XCodeTarget* getTargetOfType (ProjectType::Target::Type type) const
{
for (auto& target : targets)
if (target->type == type)
@@ -1671,13 +1559,13 @@ private:
return nullptr;
}
void addTargetObject (Target& target) const
void addTargetObject (XCodeTarget& target) const
{
String targetName = target.getName();
String targetID = target.getID();
ValueTree* const v = new ValueTree (targetID);
v->setProperty ("isa", target.type == Target::AggregateTarget ? "PBXAggregateTarget" : "PBXNativeTarget", nullptr);
v->setProperty ("isa", target.type == XCodeTarget::AggregateTarget ? "PBXAggregateTarget" : "PBXNativeTarget", nullptr);
v->setProperty ("buildConfigurationList", createID (String ("__configList") + targetName), nullptr);
v->setProperty ("buildPhases", indentParenthesisedList (target.buildPhaseIDs), nullptr);
@@ -1687,7 +1575,7 @@ private:
v->setProperty (Ids::name, target.getXCodeSchemeName(), nullptr);
v->setProperty ("productName", projectName, nullptr);
if (target.type != Target::AggregateTarget)
if (target.type != XCodeTarget::AggregateTarget)
{
v->setProperty ("productReference", createID (String ("__productFileID") + targetName), nullptr);
@@ -1699,28 +1587,28 @@ private:
misc.add (v);
}
StringArray getTargetDependencies (const Target& target) const
StringArray getTargetDependencies (const XCodeTarget& target) const
{
StringArray dependencies;
if (project.getProjectType().isAudioPlugin())
{
if (target.type == Target::StandalonePlugIn) // depends on AUv3 and shared code
if (target.type == XCodeTarget::StandalonePlugIn) // depends on AUv3 and shared code
{
if (Target* auv3Target = getTargetOfType (Target::AudioUnitv3PlugIn))
if (XCodeTarget* auv3Target = getTargetOfType (XCodeTarget::AudioUnitv3PlugIn))
dependencies.add (auv3Target->getDependencyID());
if (Target* sharedCodeTarget = getTargetOfType (Target::SharedCodeTarget))
if (XCodeTarget* sharedCodeTarget = getTargetOfType (XCodeTarget::SharedCodeTarget))
dependencies.add (sharedCodeTarget->getDependencyID());
}
else if (target.type == Target::AggregateTarget) // depends on all other targets
else if (target.type == XCodeTarget::AggregateTarget) // depends on all other targets
{
for (int i = 1; i < targets.size(); ++i)
dependencies.add (targets[i]->getDependencyID());
}
else if (target.type != Target::SharedCodeTarget) // shared code doesn't depend on anything; all other targets depend only on the shared code
else if (target.type != XCodeTarget::SharedCodeTarget) // shared code doesn't depend on anything; all other targets depend only on the shared code
{
if (Target* sharedCodeTarget = getTargetOfType (Target::SharedCodeTarget))
if (XCodeTarget* sharedCodeTarget = getTargetOfType (XCodeTarget::SharedCodeTarget))
dependencies.add (sharedCodeTarget->getDependencyID());
}
}
@@ -2099,7 +1987,7 @@ private:
output << "\t};\n\trootObject = " << createID ("__root") << ";\n}\n";
}
String addBuildFile (const String& path, const String& fileRefID, bool addToSourceBuildPhase, bool inhibitWarnings, Target* xcodeTarget = nullptr) const
String addBuildFile (const String& path, const String& fileRefID, bool addToSourceBuildPhase, bool inhibitWarnings, XCodeTarget* xcodeTarget = nullptr) const
{
String fileID (createID (path + "buildref"));
@@ -2120,7 +2008,7 @@ private:
return fileID;
}
String addBuildFile (const RelativePath& path, bool addToSourceBuildPhase, bool inhibitWarnings, Target* xcodeTarget = nullptr) const
String addBuildFile (const RelativePath& path, bool addToSourceBuildPhase, bool inhibitWarnings, XCodeTarget* xcodeTarget = nullptr) const
{
return addBuildFile (path.toUnixStyle(), createFileRefID (path), addToSourceBuildPhase, inhibitWarnings, xcodeTarget);
}
@@ -2204,7 +2092,7 @@ private:
}
String addFile (const RelativePath& path, bool shouldBeCompiled, bool shouldBeAddedToBinaryResources,
bool shouldBeAddedToXcodeResources, bool inhibitWarnings, Target* xcodeTarget) const
bool shouldBeAddedToXcodeResources, bool inhibitWarnings, XCodeTarget* xcodeTarget) const
{
const String pathAsString (path.toUnixStyle());
const String refID (addFileReference (path.toUnixStyle()));
@@ -2234,7 +2122,7 @@ private:
if (projectItem.isModuleCode())
{
if (Target* xcodeTarget = getTargetOfType (getTargetTypeFromFilePath (projectItem.getFile(), false)))
if (XCodeTarget* xcodeTarget = getTargetOfType (getProject().getTargetTypeFromFilePath (projectItem.getFile(), false)))
{
String rezFileID = addBuildFile (pathAsString, refID, false, false, xcodeTarget);
xcodeTarget->rezFileIDs.add (rezFileID);
@@ -2299,9 +2187,9 @@ private:
if (path.hasFileExtension (".r"))
return addRezFile (projectItem, path);
Target* xcodeTarget = nullptr;
XCodeTarget* xcodeTarget = nullptr;
if (projectItem.isModuleCode() && projectItem.shouldBeCompiled())
xcodeTarget = getTargetOfType (getTargetTypeFromFilePath (projectItem.getFile(), false));
xcodeTarget = getTargetOfType (project.getTargetTypeFromFilePath (projectItem.getFile(), false));
return addFile (path, projectItem.shouldBeCompiled(),
projectItem.shouldBeAddedToBinaryResources(),
@@ -2357,7 +2245,7 @@ private:
projectConfigs.add (v);
}
void addConfigList (Target& target, const OwnedArray<ValueTree>& configsToUse, const String& listID) const
void addConfigList (XCodeTarget& target, const OwnedArray <ValueTree>& configsToUse, const String& listID) const
{
ValueTree* v = new ValueTree (listID);
v->setProperty ("isa", "XCConfigurationList", nullptr);
@@ -2370,7 +2258,7 @@ private:
misc.add (v);
}
void addProjectConfigList (const OwnedArray<ValueTree>& configsToUse, const String& listID) const
void addProjectConfigList (const OwnedArray <ValueTree>& configsToUse, const String& listID) const
{
StringArray configIDs;
@@ -2405,19 +2293,6 @@ private:
misc.add (v);
}
static Target::Type getTargetTypeFromFilePath (const File& file, bool returnSharedTargetIfNoValidSuffic)
{
if (LibraryModule::CompileUnit::hasSuffix (file, "_AU")) return Target::AudioUnitPlugIn;
else if (LibraryModule::CompileUnit::hasSuffix (file, "_AUv3")) return Target::AudioUnitv3PlugIn;
else if (LibraryModule::CompileUnit::hasSuffix (file, "_AAX")) return Target::AAXPlugIn;
else if (LibraryModule::CompileUnit::hasSuffix (file, "_RTAS")) return Target::RTASPlugIn;
else if (LibraryModule::CompileUnit::hasSuffix (file, "_VST2")) return Target::VSTPlugIn;
else if (LibraryModule::CompileUnit::hasSuffix (file, "_VST3")) return Target::VST3PlugIn;
else if (LibraryModule::CompileUnit::hasSuffix (file, "_Standalone")) return Target::StandalonePlugIn;
return (returnSharedTargetIfNoValidSuffic ? Target::SharedCodeTarget : Target::unspecified);
}
//==============================================================================
void removeMismatchedXcuserdata() const
{


+ 68
- 34
extras/Projucer/Source/Project Saving/jucer_ProjectExporter.cpp View File

@@ -173,15 +173,11 @@ bool ProjectExporter::canProjectBeLaunched (Project* project)
//==============================================================================
ProjectExporter::ProjectExporter (Project& p, const ValueTree& state)
: makefileIsDLL (false),
msvcIsDLL (false),
msvcIsWindowsSubsystem (true),
settings (state),
: settings (state),
project (p),
projectType (p.getProjectType()),
projectName (p.getTitle()),
projectFolder (p.getProjectFolder()),
modulesGroup (nullptr)
projectFolder (p.getProjectFolder())
{
}
@@ -242,19 +238,19 @@ void ProjectExporter::createPropertyEditors (PropertyListBuilder& props)
void ProjectExporter::createDependencyPathProperties (PropertyListBuilder& props)
{
if (supportsVST3() && (project.shouldBuildVST3().getValue() || project.isVST3PluginHost()))
if (shouldBuildTargetType (ProjectType::Target::VST3PlugIn) || project.isVST3PluginHost())
{
props.add (new DependencyPathPropertyComponent (project.getFile().getParentDirectory(), getVST3PathValue(), "VST3 SDK Folder"),
"If you're building a VST3 plugin or host, this must be the folder containing the VST3 SDK. This can be an absolute path, or a path relative to the Projucer project file.");
}
if (supportsAAX() && project.shouldBuildAAX().getValue())
if (shouldBuildTargetType (ProjectType::Target::AAXPlugIn) && project.shouldBuildAAX())
{
props.add (new DependencyPathPropertyComponent (project.getFile().getParentDirectory(), getAAXPathValue(), "AAX SDK Folder"),
"If you're building an AAX plugin, this must be the folder containing the AAX SDK. This can be an absolute path, or a path relative to the Projucer project file.");
}
if (supportsRTAS() && project.shouldBuildRTAS().getValue())
if (shouldBuildTargetType (ProjectType::Target::RTASPlugIn) && project.shouldBuildRTAS())
{
props.add (new DependencyPathPropertyComponent (project.getFile().getParentDirectory(), getRTASPathValue(), "RTAS SDK Folder"),
"If you're building an RTAS, this must be the folder containing the RTAS SDK. This can be an absolute path, or a path relative to the Projucer project file.");
@@ -300,25 +296,17 @@ void ProjectExporter::addSettingsForProjectType (const ProjectType& type)
void ProjectExporter::addVSTPathsIfPluginOrHost()
{
if (supportsVST() && project.shouldBuildVST().getValue())
makefileTargetSuffix = ".so";
if (supportsVST3())
{
if (project.shouldBuildVST3().getValue())
makefileTargetSuffix = ".so";
if (project.shouldBuildVST3().getValue() || project.isVST3PluginHost())
addVST3FolderToPath();
}
if (shouldBuildTargetType (ProjectType::Target::VST3PlugIn) || project.isVST3PluginHost())
addVST3FolderToPath();
}
void ProjectExporter::addCommonAudioPluginSettings()
{
if (isLinux() && (getProject().shouldBuildVST().getValue() || getProject().shouldBuildVST3().getValue()))
if (isLinux()
&& (shouldBuildTargetType (ProjectType::Target::VSTPlugIn) || shouldBuildTargetType (ProjectType::Target::VST3PlugIn)))
makefileExtraLinkerFlags.add ("-Wl,--no-undefined");
if (supportsAAX() && getProject().shouldBuildAAX().getValue())
if (shouldBuildTargetType (ProjectType::Target::AAXPlugIn))
addAAXFoldersToPath();
// Note: RTAS paths are platform-dependent, impl -> addPlatformSpecificSettingsForProjectType
@@ -347,11 +335,13 @@ void ProjectExporter::addAAXFoldersToPath()
}
//==============================================================================
StringPairArray ProjectExporter::getAllPreprocessorDefs (const ProjectExporter::BuildConfiguration& config) const
StringPairArray ProjectExporter::getAllPreprocessorDefs (const BuildConfiguration& config, const ProjectType::Target::Type targetType) const
{
StringPairArray defs (mergePreprocessorDefs (config.getAllPreprocessorDefs(),
parsePreprocessorDefs (getExporterPreprocessorDefsString())));
addDefaultPreprocessorDefs (defs);
addTargetSpecificPreprocessorDefs (defs, targetType);
return defs;
}
@@ -363,6 +353,31 @@ StringPairArray ProjectExporter::getAllPreprocessorDefs() const
return defs;
}
void ProjectExporter::addTargetSpecificPreprocessorDefs (StringPairArray& defs, const ProjectType::Target::Type targetType) const
{
if (targetType == ProjectType::Target::SharedCodeTarget)
{
defs.set ("JucePlugin_Build_VST", (shouldBuildTargetType (ProjectType::Target::VSTPlugIn) ? "1" : "0"));
defs.set ("JucePlugin_Build_VST3", (shouldBuildTargetType (ProjectType::Target::VST3PlugIn) ? "1" : "0"));
defs.set ("JucePlugin_Build_AU", (shouldBuildTargetType (ProjectType::Target::AudioUnitPlugIn) ? "1" : "0"));
defs.set ("JucePlugin_Build_AUv3", (shouldBuildTargetType (ProjectType::Target::AudioUnitv3PlugIn) ? "1" : "0"));
defs.set ("JucePlugin_Build_RTAS", (shouldBuildTargetType (ProjectType::Target::RTASPlugIn) ? "1" : "0"));
defs.set ("JucePlugin_Build_AAX", (shouldBuildTargetType (ProjectType::Target::AAXPlugIn) ? "1" : "0"));
defs.set ("JucePlugin_Build_Standalone", (shouldBuildTargetType (ProjectType::Target::StandalonePlugIn) ? "1" : "0"));
defs.set ("JUCE_SHARED_CODE", "1");
}
else if (targetType != ProjectType::Target::unspecified)
{
defs.set ("JucePlugin_Build_VST", (targetType == ProjectType::Target::VSTPlugIn ? "1" : "0"));
defs.set ("JucePlugin_Build_VST3", (targetType == ProjectType::Target::VST3PlugIn ? "1" : "0"));
defs.set ("JucePlugin_Build_AU", (targetType == ProjectType::Target::AudioUnitPlugIn ? "1" : "0"));
defs.set ("JucePlugin_Build_AUv3", (targetType == ProjectType::Target::AudioUnitv3PlugIn ? "1" : "0"));
defs.set ("JucePlugin_Build_RTAS", (targetType == ProjectType::Target::RTASPlugIn ? "1" : "0"));
defs.set ("JucePlugin_Build_AAX", (targetType == ProjectType::Target::AAXPlugIn ? "1" : "0"));
defs.set ("JucePlugin_Build_Standalone", (targetType == ProjectType::Target::StandalonePlugIn ? "1" : "0"));
}
}
void ProjectExporter::addDefaultPreprocessorDefs (StringPairArray& defs) const
{
defs.set (getExporterIdentifierMacro(), "1");
@@ -370,9 +385,10 @@ void ProjectExporter::addDefaultPreprocessorDefs (StringPairArray& defs) const
defs.set ("JUCE_APP_VERSION_HEX", project.getVersionAsHex());
}
String ProjectExporter::replacePreprocessorTokens (const ProjectExporter::BuildConfiguration& config, const String& sourceString) const
String ProjectExporter::replacePreprocessorTokens (const ProjectExporter::BuildConfiguration& config,
const String& sourceString) const
{
return replacePreprocessorDefs (getAllPreprocessorDefs (config), sourceString);
return replacePreprocessorDefs (getAllPreprocessorDefs (config, ProjectType::Target::unspecified), sourceString);
}
void ProjectExporter::copyMainGroupFromProject()
@@ -393,14 +409,24 @@ Project::Item& ProjectExporter::getModulesGroup()
return *modulesGroup;
}
void ProjectExporter::addToExtraSearchPaths (const RelativePath& pathFromProjectFolder, int index)
void ProjectExporter::addProjectPathToBuildPathList (StringArray& pathList, const RelativePath& pathFromProjectFolder, int index)
{
RelativePath localPath (rebaseFromProjectFolderToBuildTarget (pathFromProjectFolder));
const auto localPath = RelativePath (rebaseFromProjectFolderToBuildTarget (pathFromProjectFolder));
const auto path = isVisualStudio() ? localPath.toWindowsStyle() : localPath.toUnixStyle();
const String path (isVisualStudio() ? localPath.toWindowsStyle() : localPath.toUnixStyle());
if (! pathList.contains (path))
pathList.insert (index, path);
}
if (! extraSearchPaths.contains (path))
extraSearchPaths.insert (index, path);
void ProjectExporter::addToModuleLibPaths (const RelativePath& pathFromProjectFolder)
{
addProjectPathToBuildPathList (moduleLibSearchPaths, pathFromProjectFolder);
}
void ProjectExporter::addToExtraSearchPaths (const RelativePath& pathFromProjectFolder, int index)
{
addProjectPathToBuildPathList (extraSearchPaths, pathFromProjectFolder, index);
}
Value ProjectExporter::getPathForModuleValue (const String& moduleID)
@@ -810,16 +836,24 @@ StringArray ProjectExporter::BuildConfiguration::getHeaderSearchPaths() const
StringArray ProjectExporter::BuildConfiguration::getLibrarySearchPaths() const
{
return getSearchPathsFromString (getLibrarySearchPathString());
auto separator = exporter.isVisualStudio() ? "\\" : "/";
auto s = getSearchPathsFromString (getLibrarySearchPathString());
for (auto path : exporter.moduleLibSearchPaths)
s.add (path + separator + getLibrarySubdirPath());
return s;
}
String ProjectExporter::BuildConfiguration::getGCCLibraryPathFlags() const
{
String s;
const StringArray libraryPaths (getLibrarySearchPaths());
const auto libraryPaths = getSearchPathsFromString (getLibrarySearchPathString());
for (auto path : libraryPaths)
s << " -L" << escapeSpaces (path).replace ("~", "$(HOME)");
for (int i = 0; i < libraryPaths.size(); ++i)
s << " -L" << escapeSpaces (libraryPaths[i]).replace ("~", "$(HOME)");
for (auto path : exporter.moduleLibSearchPaths)
s << " -L" << escapeSpaces (path).replace ("~", "$(HOME)") << "/" << getLibrarySubdirPath();
return s;
}


+ 24
- 14
extras/Projucer/Source/Project Saving/jucer_ProjectExporter.h View File

@@ -84,14 +84,21 @@ public:
virtual bool isOSX() const = 0;
virtual bool isiOS() const = 0;
//==============================================================================
// cross-platform audio plug-ins supported by exporter
virtual bool supportsVST() const = 0;
virtual bool supportsVST3() const = 0;
virtual bool supportsAAX() const = 0;
virtual bool supportsRTAS() const = 0;
virtual bool supportsAU() const = 0;
virtual bool supportsAUv3() const = 0;
virtual bool supportsStandalone() const = 0; // as in Standalong plug-in type, not GUIApp or ConsoleApp
virtual bool supportsTargetType (ProjectType::Target::Type type) const = 0;
inline bool shouldBuildTargetType (ProjectType::Target::Type type) const
{
return project.shouldBuildTargetType (type) && supportsTargetType (type);
}
inline void callForAllSupportedTargets (std::function<void (ProjectType::Target::Type)> callback)
{
for (int i = 0; i < ProjectType::Target::unspecified; ++i)
if (shouldBuildTargetType (static_cast<ProjectType::Target::Type> (i)))
callback (static_cast<ProjectType::Target::Type> (i));
}
//==============================================================================
bool mayCompileOnCurrentOS() const
@@ -150,6 +157,7 @@ public:
RelativePath rebaseFromProjectFolderToBuildTarget (const RelativePath& path) const;
void addToExtraSearchPaths (const RelativePath& pathFromProjectFolder, int index = -1);
void addToModuleLibPaths (const RelativePath& pathFromProjectFolder);
Value getBigIconImageItemID() { return getSetting (Ids::bigIcon); }
Value getSmallIconImageItemID() { return getSetting (Ids::smallIcon); }
@@ -187,19 +195,16 @@ public:
Project::Item& getModulesGroup();
//==============================================================================
String makefileTargetSuffix;
bool makefileIsDLL;
StringArray linuxLibs, linuxPackages, makefileExtraLinkerFlags;
//==============================================================================
String msvcTargetSuffix;
StringPairArray msvcExtraPreprocessorDefs;
bool msvcIsDLL, msvcIsWindowsSubsystem;
String msvcDelayLoadedDLLs;
StringArray mingwLibs;
StringArray mingwLibs, windowsLibs;
//==============================================================================
StringArray extraSearchPaths;
StringArray moduleLibSearchPaths;
//==============================================================================
class BuildConfiguration : public ReferenceCountedObject
@@ -213,6 +218,8 @@ public:
//==============================================================================
virtual void createConfigProperties (PropertyListBuilder&) = 0;
virtual var getDefaultOptimisationLevel() const = 0;
virtual String getLibrarySubdirPath() const { return String(); }
//==============================================================================
Value getNameValue() { return getValue (Ids::name); }
@@ -316,10 +323,12 @@ public:
String getExporterPreprocessorDefsString() const { return getSettingString (Ids::extraDefs); }
// includes exporter, project + config defs
StringPairArray getAllPreprocessorDefs (const BuildConfiguration& config) const;
StringPairArray getAllPreprocessorDefs (const BuildConfiguration& config, const ProjectType::Target::Type targetType) const;
// includes exporter + project defs..
StringPairArray getAllPreprocessorDefs() const;
void addTargetSpecificPreprocessorDefs (StringPairArray& defs, const ProjectType::Target::Type targetType) const;
String replacePreprocessorTokens (const BuildConfiguration&, const String& sourceString) const;
ValueTree settings;
@@ -345,7 +354,7 @@ protected:
mutable Array<Project::Item> itemGroups;
void initItemGroups() const;
Project::Item* modulesGroup;
Project::Item* modulesGroup = nullptr;
virtual BuildConfiguration::Ptr createBuildConfig (const ValueTree&) const = 0;
@@ -408,6 +417,7 @@ private:
void addCommonAudioPluginSettings();
void addVST3FolderToPath();
void addAAXFoldersToPath();
void addProjectPathToBuildPathList (StringArray&, const RelativePath&, int index = -1);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjectExporter)
};


+ 7
- 7
extras/Projucer/Source/Project Saving/jucer_ProjectSaver.cpp View File

@@ -73,13 +73,13 @@ namespace
void ProjectSaver::writePluginCharacteristicsFile()
{
StringPairArray flags;
flags.set ("JucePlugin_Build_VST", valueToBool (project.shouldBuildVST()));
flags.set ("JucePlugin_Build_VST3", valueToBool (project.shouldBuildVST3()));
flags.set ("JucePlugin_Build_AU", valueToBool (project.shouldBuildAU()));
flags.set ("JucePlugin_Build_AUv3", valueToBool (project.shouldBuildAUv3()));
flags.set ("JucePlugin_Build_RTAS", valueToBool (project.shouldBuildRTAS()));
flags.set ("JucePlugin_Build_AAX", valueToBool (project.shouldBuildAAX()));
flags.set ("JucePlugin_Build_STANDALONE", valueToBool (project.shouldBuildStandalone()));
flags.set ("JucePlugin_Build_VST", valueToBool (project.getShouldBuildVSTAsValue()));
flags.set ("JucePlugin_Build_VST3", valueToBool (project.getShouldBuildVST3AsValue()));
flags.set ("JucePlugin_Build_AU", valueToBool (project.getShouldBuildAUAsValue()));
flags.set ("JucePlugin_Build_AUv3", valueToBool (project.getShouldBuildAUv3AsValue()));
flags.set ("JucePlugin_Build_RTAS", valueToBool (project.getShouldBuildRTASAsValue()));
flags.set ("JucePlugin_Build_AAX", valueToBool (project.getShouldBuildAAXAsValue()));
flags.set ("JucePlugin_Build_STANDALONE", valueToBool (project.getShouldBuildStandalonePluginAsValue()));
flags.set ("JucePlugin_Name", valueToStringLiteral (project.getPluginName()));
flags.set ("JucePlugin_Desc", valueToStringLiteral (project.getPluginDesc()));
flags.set ("JucePlugin_Manufacturer", valueToStringLiteral (project.getPluginManufacturer()));


+ 28
- 17
extras/Projucer/Source/Project/jucer_Module.cpp View File

@@ -303,21 +303,34 @@ static void parseAndAddLibs (StringArray& libList, const String& libs)
void LibraryModule::addSettingsForModuleToExporter (ProjectExporter& exporter, ProjectSaver& projectSaver) const
{
Project& project = exporter.getProject();
auto& project = exporter.getProject();
RelativePath modulePath = exporter.getModuleFolderRelativeToProject (getID());
const auto moduleRelativePath = exporter.getModuleFolderRelativeToProject (getID());
exporter.addToExtraSearchPaths (modulePath.getParentDirectory());
exporter.addToExtraSearchPaths (moduleRelativePath.getParentDirectory());
const String extraInternalSearchPaths (moduleInfo.getExtraSearchPaths().trim());
String libDirPlatform;
if (exporter.isLinux())
libDirPlatform = "Linux";
else if (exporter.isCodeBlocks() && exporter.isWindows())
libDirPlatform = "MinGW";
else
libDirPlatform = exporter.getTargetFolder().getFileName();
const auto libSubdirPath = String (moduleRelativePath.toUnixStyle() + "/libs/") + libDirPlatform;
const auto moduleLibDir = File (project.getProjectFolder().getFullPathName() + "/" + libSubdirPath);
if (moduleLibDir.exists())
exporter.addToModuleLibPaths (RelativePath (libSubdirPath, moduleRelativePath.getRoot()));
const auto extraInternalSearchPaths = moduleInfo.getExtraSearchPaths().trim();
if (extraInternalSearchPaths.isNotEmpty())
{
StringArray paths;
paths.addTokens (extraInternalSearchPaths, true);
for (int i = 0; i < paths.size(); ++i)
exporter.addToExtraSearchPaths (modulePath.getChildFile (paths.getReference(i)));
exporter.addToExtraSearchPaths (moduleRelativePath.getChildFile (paths.getReference(i)));
}
{
@@ -357,9 +370,12 @@ void LibraryModule::addSettingsForModuleToExporter (ProjectExporter& exporter, P
parseAndAddLibs (exporter.linuxLibs, moduleInfo.moduleInfo ["linuxLibs"].toString());
parseAndAddLibs (exporter.linuxPackages, moduleInfo.moduleInfo ["linuxPackages"].toString());
}
else if (exporter.isCodeBlocks() && exporter.isWindows())
else if (exporter.isWindows())
{
parseAndAddLibs (exporter.mingwLibs, moduleInfo.moduleInfo ["mingwLibs"].toString());
if (exporter.isCodeBlocks())
parseAndAddLibs (exporter.mingwLibs, moduleInfo.moduleInfo ["mingwLibs"].toString());
else
parseAndAddLibs (exporter.windowsLibs, moduleInfo.moduleInfo ["windowsLibs"].toString());
}
}
@@ -424,20 +440,15 @@ void LibraryModule::CompileUnit::writeInclude (MemoryOutputStream&) const
bool LibraryModule::CompileUnit::isNeededForExporter (ProjectExporter& exporter) const
{
Project& project = exporter.getProject();
if ((hasSuffix (file, "_OSX") && ! exporter.isOSX())
|| (hasSuffix (file, "_iOS") && ! exporter.isiOS())
|| (hasSuffix (file, "_Windows") && ! exporter.isWindows())
|| (hasSuffix (file, "_Linux") && ! exporter.isLinux())
|| (hasSuffix (file, "_Android") && ! exporter.isAndroid())
|| (hasSuffix (file, "_AU") && ! (project.shouldBuildAU() .getValue() && exporter.supportsAU()))
|| (hasSuffix (file, "_AUv3") && ! (project.shouldBuildAUv3().getValue() && exporter.supportsAUv3()))
|| (hasSuffix (file, "_AAX") && ! (project.shouldBuildAAX() .getValue() && exporter.supportsAAX()))
|| (hasSuffix (file, "_RTAS") && ! (project.shouldBuildRTAS().getValue() && exporter.supportsRTAS()))
|| (hasSuffix (file, "_VST2") && ! (project.shouldBuildVST() .getValue() && exporter.supportsVST()))
|| (hasSuffix (file, "_VST3") && ! (project.shouldBuildVST3().getValue() && exporter.supportsVST3()))
|| (hasSuffix (file, "_Standalone") && ! (project.shouldBuildStandalone().getValue() && exporter.supportsStandalone())))
|| (hasSuffix (file, "_Android") && ! exporter.isAndroid()))
return false;
const ProjectType::Target::Type targetType = Project::getTargetTypeFromFilePath (file, false);
if (targetType != ProjectType::Target::unspecified && ! exporter.shouldBuildTargetType (targetType))
return false;
return exporter.usesMMFiles() ? isCompiledForObjC


+ 118
- 23
extras/Projucer/Source/Project/jucer_Project.cpp View File

@@ -24,7 +24,6 @@
#include "../jucer_Headers.h"
#include "jucer_Project.h"
#include "jucer_ProjectType.h"
#include "../Project Saving/jucer_ProjectExporter.h"
#include "../Project Saving/jucer_ProjectSaver.h"
#include "../Application/jucer_OpenDocumentManager.h"
@@ -147,13 +146,13 @@ void Project::setMissingAudioPluginDefaultValues()
{
const String sanitisedProjectName (CodeHelpers::makeValidIdentifier (getTitle(), false, true, false));
setValueIfVoid (shouldBuildVST(), true);
setValueIfVoid (shouldBuildVST3(), false);
setValueIfVoid (shouldBuildAU(), true);
setValueIfVoid (shouldBuildAUv3(), false);
setValueIfVoid (shouldBuildRTAS(), false);
setValueIfVoid (shouldBuildAAX(), false);
setValueIfVoid (shouldBuildStandalone(), false);
setValueIfVoid (getShouldBuildVSTAsValue(), true);
setValueIfVoid (getShouldBuildVST3AsValue(), false);
setValueIfVoid (getShouldBuildAUAsValue(), true);
setValueIfVoid (getShouldBuildAUv3AsValue(), false);
setValueIfVoid (getShouldBuildRTASAsValue(), false);
setValueIfVoid (getShouldBuildAAXAsValue(), false);
setValueIfVoid (getShouldBuildStandalonePluginAsValue(), false);
setValueIfVoid (getPluginName(), getTitle());
setValueIfVoid (getPluginDesc(), getTitle());
@@ -222,10 +221,19 @@ void Project::removeDefunctExporters()
for (;;)
{
ValueTree oldVC6Exporter (exporters.getChildWithName ("MSVC6"));
ValueTree oldVC6Exporter (exporters.getChildWithName ("MSVC6"));
ValueTree oldAndroidAntExporter (exporters.getChildWithName ("ANDROID"));
if (oldVC6Exporter.isValid())
if (oldVC6Exporter.isValid())
exporters.removeChild (oldVC6Exporter, nullptr);
else if (oldAndroidAntExporter.isValid())
{
AlertWindow::showMessageBox (AlertWindow::WarningIcon,
TRANS("Android Ant Exporter"),
TRANS("The Android Ant Exporter is deprecated. The exporter will be removed from this project."));
exporters.removeChild (oldAndroidAntExporter, nullptr);
}
else
break;
}
@@ -436,6 +444,98 @@ const ProjectType& Project::getProjectType() const
return *guiType;
}
bool Project::shouldBuildTargetType (ProjectType::Target::Type targetType) const noexcept
{
const ProjectType& projectType = getProjectType();
if (! projectType.supportsTargetType (targetType))
return false;
switch (targetType)
{
case ProjectType::Target::VSTPlugIn:
return shouldBuildVST();
case ProjectType::Target::VST3PlugIn:
return shouldBuildVST3();
case ProjectType::Target::AAXPlugIn:
return shouldBuildAAX();
case ProjectType::Target::RTASPlugIn:
return shouldBuildRTAS();
case ProjectType::Target::AudioUnitPlugIn:
return shouldBuildAU();
case ProjectType::Target::AudioUnitv3PlugIn:
return shouldBuildAUv3();
case ProjectType::Target::StandalonePlugIn:
return shouldBuildStandalonePlugin();
case ProjectType::Target::AggregateTarget:
case ProjectType::Target::SharedCodeTarget:
return projectType.isAudioPlugin();
case ProjectType::Target::unspecified:
return false;
default:
break;
}
return true;
}
ProjectType::Target::Type Project::getTargetTypeFromFilePath (const File& file, bool returnSharedTargetIfNoValidSuffix)
{
if (LibraryModule::CompileUnit::hasSuffix (file, "_AU")) return ProjectType::Target::AudioUnitPlugIn;
else if (LibraryModule::CompileUnit::hasSuffix (file, "_AUv3")) return ProjectType::Target::AudioUnitv3PlugIn;
else if (LibraryModule::CompileUnit::hasSuffix (file, "_AAX")) return ProjectType::Target::AAXPlugIn;
else if (LibraryModule::CompileUnit::hasSuffix (file, "_RTAS")) return ProjectType::Target::RTASPlugIn;
else if (LibraryModule::CompileUnit::hasSuffix (file, "_VST2")) return ProjectType::Target::VSTPlugIn;
else if (LibraryModule::CompileUnit::hasSuffix (file, "_VST3")) return ProjectType::Target::VST3PlugIn;
else if (LibraryModule::CompileUnit::hasSuffix (file, "_Standalone")) return ProjectType::Target::StandalonePlugIn;
return (returnSharedTargetIfNoValidSuffix ? ProjectType::Target::SharedCodeTarget : ProjectType::Target::unspecified);
}
const char* ProjectType::Target::getName() const noexcept
{
switch (type)
{
case GUIApp: return "App";
case ConsoleApp: return "ConsoleApp";
case StaticLibrary: return "Static Library";
case DynamicLibrary: return "Dynamic Library";
case VSTPlugIn: return "VST";
case VST3PlugIn: return "VST3";
case AudioUnitPlugIn: return "AU";
case StandalonePlugIn: return "Standalone Plugin";
case AudioUnitv3PlugIn: return "AUv3 AppExtension";
case AAXPlugIn: return "AAX";
case RTASPlugIn: return "RTAS";
case SharedCodeTarget: return "Shared Code";
case AggregateTarget: return "All";
default: return "undefined";
}
}
ProjectType::Target::TargetFileType ProjectType::Target::getTargetFileType() const noexcept
{
switch (type)
{
case GUIApp: return executable;
case ConsoleApp: return executable;
case StaticLibrary: return staticLibrary;
case DynamicLibrary: return sharedLibraryOrDLL;
case VSTPlugIn: return pluginBundle;
case VST3PlugIn: return pluginBundle;
case AudioUnitPlugIn: return pluginBundle;
case StandalonePlugIn: return executable;
case AudioUnitv3PlugIn: return macOSAppex;
case AAXPlugIn: return pluginBundle;
case RTASPlugIn: return pluginBundle;
case SharedCodeTarget: return staticLibrary;
default:
break;
}
return unknown;
}
//==============================================================================
void Project::createPropertyEditors (PropertyListBuilder& props)
{
@@ -515,25 +615,20 @@ void Project::createPropertyEditors (PropertyListBuilder& props)
void Project::createAudioPluginPropertyEditors (PropertyListBuilder& props)
{
props.add (new BooleanPropertyComponent (shouldBuildVST(), "Build VST", "Enabled"),
props.add (new BooleanPropertyComponent (getShouldBuildVSTAsValue(), "Build VST", "Enabled"),
"Whether the project should produce a VST plugin.");
props.add (new BooleanPropertyComponent (shouldBuildVST3(), "Build VST3", "Enabled"),
props.add (new BooleanPropertyComponent (getShouldBuildVST3AsValue(), "Build VST3", "Enabled"),
"Whether the project should produce a VST3 plugin.");
props.add (new BooleanPropertyComponent (shouldBuildAU(), "Build AudioUnit", "Enabled"),
props.add (new BooleanPropertyComponent (getShouldBuildAUAsValue(), "Build AudioUnit", "Enabled"),
"Whether the project should produce an AudioUnit plugin.");
props.add (new BooleanPropertyComponent (shouldBuildAUv3(), "Build AudioUnit v3", "Enabled"),
props.add (new BooleanPropertyComponent (getShouldBuildAUv3AsValue(), "Build AudioUnit v3", "Enabled"),
"Whether the project should produce an AudioUnit version 3 plugin.");
props.add (new BooleanPropertyComponent (shouldBuildRTAS(), "Build RTAS", "Enabled"),
props.add (new BooleanPropertyComponent (getShouldBuildRTASAsValue(), "Build RTAS", "Enabled"),
"Whether the project should produce an RTAS plugin.");
props.add (new BooleanPropertyComponent (shouldBuildAAX(), "Build AAX", "Enabled"),
props.add (new BooleanPropertyComponent (getShouldBuildAAXAsValue(), "Build AAX", "Enabled"),
"Whether the project should produce an AAX plugin.");
/* TODO: this property editor is temporarily disabled because right now we build standalone if and only if
we also build AUv3. However as soon as targets are supported on non-Xcode exporters as well, we should
re-enable this option and allow to build the standalone plug-in independently from AUv3.
*/
// props.add (new BooleanPropertyComponent (shouldBuildStandalone(), "Build Standalone", "Enabled"),
// "Whether the project should produce a standalone version of the plugin. Required for AUv3.");
props.add (new BooleanPropertyComponent (getShouldBuildStandalonePluginAsValue(), "Build Standalone Plug-In", "Enabled"),
"Whether the project should produce a standalone version of your plugin.");
props.add (new TextPropertyComponent (getPluginName(), "Plugin Name", 128, false),
"The name of your plugin (keep it short!)");


+ 25
- 9
extras/Projucer/Source/Project/jucer_Project.h View File

@@ -25,8 +25,9 @@
#ifndef JUCER_PROJECT_H_INCLUDED
#define JUCER_PROJECT_H_INCLUDED
#include "jucer_ProjectType.h"
class ProjectExporter;
class ProjectType;
class LibraryModule;
class EnabledModuleList;
@@ -95,7 +96,8 @@ public:
Value getCompanyEmail() { return getProjectValue (Ids::companyEmail); }
//==============================================================================
Value getProjectValue (const Identifier& name) { return projectRoot.getPropertyAsValue (name, getUndoManagerFor (projectRoot)); }
Value getProjectValue (const Identifier& name) { return projectRoot.getPropertyAsValue (name, getUndoManagerFor (projectRoot)); }
var getProjectVar (const Identifier& name) const { return projectRoot.getProperty (name); }
Value getProjectPreprocessorDefs() { return getProjectValue (Ids::defines); }
StringPairArray getPreprocessorDefs() const;
@@ -122,13 +124,23 @@ public:
//==============================================================================
// Some helper methods for audio plugin/host projects.
Value shouldBuildVST() { return getProjectValue ("buildVST"); }
Value shouldBuildVST3() { return getProjectValue ("buildVST3"); }
Value shouldBuildAU() { return getProjectValue ("buildAU"); }
Value shouldBuildAUv3() { return getProjectValue ("buildAUv3"); }
Value shouldBuildRTAS() { return getProjectValue ("buildRTAS"); }
Value shouldBuildAAX() { return getProjectValue ("buildAAX"); }
Value shouldBuildStandalone() { return shouldBuildAUv3(); /* TODO: enable this when standalone becomes independent from AUv3: getProjectValue ("buildStandalone"); */}
Value getShouldBuildVSTAsValue() { return getProjectValue ("buildVST"); }
Value getShouldBuildVST3AsValue() { return getProjectValue ("buildVST3"); }
Value getShouldBuildAUAsValue() { return getProjectValue ("buildAU"); }
Value getShouldBuildAUv3AsValue() { return getProjectValue ("buildAUv3"); }
Value getShouldBuildRTASAsValue() { return getProjectValue ("buildRTAS"); }
Value getShouldBuildAAXAsValue() { return getProjectValue ("buildAAX"); }
Value getShouldBuildStandalonePluginAsValue() { return getProjectValue ("buildStandalone");}
bool shouldBuildVST() const { return getProjectVar ("buildVST"); }
bool shouldBuildVST3() const { return getProjectVar ("buildVST3"); }
bool shouldBuildAU() const { return getProjectVar ("buildAU"); }
bool shouldBuildAUv3() const { return getProjectVar ("buildAUv3"); }
bool shouldBuildRTAS() const { return getProjectVar ("buildRTAS"); }
bool shouldBuildAAX() const { return getProjectVar ("buildAAX"); }
bool shouldBuildStandalonePlugin() const { return getProjectVar ("buildStandalone"); }
//==============================================================================
Value getPluginName() { return getProjectValue ("pluginName"); }
Value getPluginDesc() { return getProjectValue ("pluginDesc"); }
Value getPluginManufacturer() { return getProjectValue ("pluginManufacturer"); }
@@ -158,6 +170,10 @@ public:
bool isVSTPluginHost();
bool isVST3PluginHost();
bool shouldBuildTargetType (ProjectType::Target::Type targetType) const noexcept;
static ProjectType::Target::Type getTargetTypeFromFilePath (const File& file, bool returnSharedTargetIfNoValidSuffix);
//==============================================================================
void updateDeprecatedProjectSettingsInteractively();
//==============================================================================


+ 82
- 8
extras/Projucer/Source/Project/jucer_ProjectType.h View File

@@ -49,6 +49,55 @@ public:
virtual bool isCommandLineApp() const { return false; }
virtual bool isAudioPlugin() const { return false; }
//==============================================================================
struct Target
{
enum Type
{
GUIApp = 0,
ConsoleApp = 1,
StaticLibrary = 2,
DynamicLibrary = 3,
VSTPlugIn = 10,
VST3PlugIn = 11,
AAXPlugIn = 12,
RTASPlugIn = 13,
AudioUnitPlugIn = 14,
AudioUnitv3PlugIn = 15,
StandalonePlugIn = 16,
SharedCodeTarget = 20, // internal
AggregateTarget = 21,
unspecified = 30
};
enum TargetFileType
{
executable = 0,
staticLibrary = 1,
sharedLibraryOrDLL = 2,
pluginBundle = 3,
macOSAppex = 4,
unknown = 5
};
//==============================================================================
Target (Type targetType) : type (targetType) {}
const char* getName() const noexcept;
TargetFileType getTargetFileType() const noexcept;
const Type type;
private:
//==============================================================================
Target& operator= (const Target&) JUCE_DELETED_FUNCTION;
};
virtual bool supportsTargetType (Target::Type /*targetType*/) const { return false; }
protected:
ProjectType (const String& type, const String& desc);
@@ -86,32 +135,36 @@ struct ProjectType_GUIApp : public ProjectType
{
ProjectType_GUIApp() : ProjectType (getTypeName(), "GUI Application") {}
static const char* getTypeName() noexcept { return "guiapp"; }
bool isGUIApplication() const override { return true; }
static const char* getTypeName() noexcept { return "guiapp"; }
bool isGUIApplication() const override { return true; }
bool supportsTargetType (Target::Type targetType) const override { return (targetType == Target::GUIApp); }
};
struct ProjectType_ConsoleApp : public ProjectType
{
ProjectType_ConsoleApp() : ProjectType (getTypeName(), "Console Application") {}
static const char* getTypeName() noexcept { return "consoleapp"; }
bool isCommandLineApp() const override { return true; }
static const char* getTypeName() noexcept { return "consoleapp"; }
bool isCommandLineApp() const override { return true; }
bool supportsTargetType (Target::Type targetType) const override { return (targetType == Target::ConsoleApp); }
};
struct ProjectType_StaticLibrary : public ProjectType
{
ProjectType_StaticLibrary() : ProjectType (getTypeName(), "Static Library") {}
static const char* getTypeName() noexcept { return "library"; }
bool isStaticLibrary() const override { return true; }
static const char* getTypeName() noexcept { return "library"; }
bool isStaticLibrary() const override { return true; }
bool supportsTargetType (Target::Type targetType) const override { return (targetType == Target::StaticLibrary); }
};
struct ProjectType_DLL : public ProjectType
{
ProjectType_DLL() : ProjectType (getTypeName(), "Dynamic Library") {}
static const char* getTypeName() noexcept { return "dll"; }
bool isDynamicLibrary() const override { return true; }
static const char* getTypeName() noexcept { return "dll"; }
bool isDynamicLibrary() const override { return true; }
bool supportsTargetType (Target::Type targetType) const override { return (targetType == Target::DynamicLibrary); }
};
struct ProjectType_AudioPlugin : public ProjectType
@@ -120,6 +173,27 @@ struct ProjectType_AudioPlugin : public ProjectType
static const char* getTypeName() noexcept { return "audioplug"; }
bool isAudioPlugin() const override { return true; }
bool supportsTargetType (Target::Type targetType) const override
{
switch (targetType)
{
case Target::VSTPlugIn:
case Target::VST3PlugIn:
case Target::AAXPlugIn:
case Target::RTASPlugIn:
case Target::AudioUnitPlugIn:
case Target::AudioUnitv3PlugIn:
case Target::StandalonePlugIn:
case Target::SharedCodeTarget:
case Target::AggregateTarget:
return true;
default:
break;
}
return false;
}
};
//==============================================================================


+ 3
- 2
extras/Projucer/Source/Utility/jucer_PresetIDs.h View File

@@ -104,6 +104,8 @@ namespace Ids
DECLARE_ID (winWarningLevel);
DECLARE_ID (warningsAreErrors);
DECLARE_ID (linuxArchitecture);
DECLARE_ID (linuxCodeBlocksArchitecture);
DECLARE_ID (windowsCodeBlocksArchitecture);
DECLARE_ID (toolset);
DECLARE_ID (IPPLibrary);
DECLARE_ID (msvcModuleDefinitionFile);
@@ -112,7 +114,6 @@ namespace Ids
DECLARE_ID (jucerVersion);
DECLARE_ID (prebuildCommand);
DECLARE_ID (postbuildCommand);
DECLARE_ID (internalPostBuildComamnd);
DECLARE_ID (generateManifest);
DECLARE_ID (useRuntimeLibDLL);
DECLARE_ID (wholeProgramOptimisation);
@@ -173,7 +174,7 @@ namespace Ids
DECLARE_ID (iosDevelopmentTeamID);
DECLARE_ID (buildToolsVersion);
DECLARE_ID (gradleVersion);
DECLARE_ID (gradleWrapperVersion);
const Identifier androidPluginVersion ("gradleWrapperVersion"); // old name is very confusing, but we need to remain backward compatible
DECLARE_ID (gradleToolchain);
DECLARE_ID (gradleToolchainVersion);
DECLARE_ID (linuxExtraPkgConfig);


Loading…
Cancel
Save