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 isAndroidStudio() const override { return false; }
bool isAndroidAnt() const override { return true; } 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"; } static const char* getName() { return "Android Ant Project"; }
@@ -340,7 +348,7 @@ private:
flags << " -std=gnu++11"; flags << " -std=gnu++11";
defines = mergePreprocessorDefs (defines, getAllPreprocessorDefs (config));
defines = mergePreprocessorDefs (defines, getAllPreprocessorDefs ());
return flags + createGCCPreprocessorFlags (defines); 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 isOSX() const override { return false; }
bool isiOS() 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 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) AndroidStudioProjectExporter (Project& p, const ValueTree& t)
: AndroidProjectExporterBase (p, t), : AndroidProjectExporterBase (p, t),
gradleVersion (settings, Ids::gradleVersion, nullptr, "2.14.1"), 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"), gradleToolchain (settings, Ids::gradleToolchain, nullptr, "clang"),
buildToolsVersion (settings, Ids::buildToolsVersion, nullptr, "23.0.2"), buildToolsVersion (settings, Ids::buildToolsVersion, nullptr, "23.0.2"),
androidStudioExecutable (findAndroidStudioExecutable()) 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 isOSX() const override { return false; }
bool isiOS() 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 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: private:
@@ -151,14 +184,52 @@ private:
CodeBlocksBuildConfiguration (Project& p, const ValueTree& settings, const ProjectExporter& e) CodeBlocksBuildConfiguration (Project& p, const ValueTree& settings, const ProjectExporter& e)
: BuildConfiguration (p, settings, 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 void createConfigProperties (PropertyListBuilder& props) override
{ {
addGCCOptimisationProperty (props); 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 BuildConfiguration::Ptr createBuildConfig (const ValueTree& tree) const override
@@ -166,6 +237,59 @@ private:
return new CodeBlocksBuildConfiguration (project, tree, *this); 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 void addVersion (XmlElement& xml) const
{ {
@@ -181,7 +305,7 @@ private:
xml.createNewChildElement ("Option")->setAttribute ("compiler", "gcc"); xml.createNewChildElement ("Option")->setAttribute ("compiler", "gcc");
} }
StringArray getDefines (const BuildConfiguration& config) const
StringArray getDefines (const BuildConfiguration& config, CodeBlocksTarget& target) const
{ {
StringPairArray defines; StringPairArray defines;
@@ -205,7 +329,7 @@ private:
defines.set ("NDEBUG", "1"); defines.set ("NDEBUG", "1");
} }
defines = mergePreprocessorDefs (defines, getAllPreprocessorDefs (config));
defines = mergePreprocessorDefs (defines, getAllPreprocessorDefs (config, target.type));
StringArray defs; StringArray defs;
for (int i = 0; i < defines.size(); ++i) for (int i = 0; i < defines.size(); ++i)
@@ -214,9 +338,12 @@ private:
return getCleanedStringArray (defs); return getCleanedStringArray (defs);
} }
StringArray getCompilerFlags (const BuildConfiguration& config) const
StringArray getCompilerFlags (const BuildConfiguration& config, CodeBlocksTarget& target) const
{ {
StringArray flags; StringArray flags;
if (const auto codeBlocksConfig = dynamic_cast<const CodeBlocksBuildConfiguration*> (&config))
flags.add (codeBlocksConfig->getArchitectureTypeVar());
flags.add ("-O" + config.getGCCOptimisationFlag()); flags.add ("-O" + config.getGCCOptimisationFlag());
flags.add ("-std=c++11"); flags.add ("-std=c++11");
flags.add ("-mstackrealign"); flags.add ("-mstackrealign");
@@ -228,7 +355,7 @@ private:
" \n", "\"'"); " \n", "\"'");
{ {
const StringArray defines (getDefines (config));
const StringArray defines (getDefines (config, target));
for (int i = 0; i < defines.size(); ++i) for (int i = 0; i < defines.size(); ++i)
{ {
@@ -243,7 +370,7 @@ private:
if (config.exporter.isLinux()) if (config.exporter.isLinux())
{ {
if (createDynamicLibrary)
if (target.isDynamicLibrary() || getProject().getProjectType().isAudioPlugin())
flags.add ("-fPIC"); flags.add ("-fPIC");
if (linuxPackages.size() > 0) if (linuxPackages.size() > 0)
@@ -263,19 +390,25 @@ private:
return getCleanedStringArray (flags); return getCleanedStringArray (flags);
} }
StringArray getLinkerFlags (const BuildConfiguration& config) const
StringArray getLinkerFlags (const BuildConfiguration& config, CodeBlocksTarget& target) const
{ {
StringArray flags (makefileExtraLinkerFlags); StringArray flags (makefileExtraLinkerFlags);
if (const auto codeBlocksConfig = dynamic_cast<const CodeBlocksBuildConfiguration*> (&config))
flags.add (codeBlocksConfig->getArchitectureTypeVar());
if (! config.isDebug()) if (! config.isDebug())
flags.add ("-s"); flags.add ("-s");
flags.addTokens (replacePreprocessorTokens (config, getExtraLinkerFlagsString()).trim(), flags.addTokens (replacePreprocessorTokens (config, getExtraLinkerFlagsString()).trim(),
" \n", "\"'"); " \n", "\"'");
if (getProject().getProjectType().isAudioPlugin() && target.type != ProjectType::Target::SharedCodeTarget)
flags.add ("-l" + config.getTargetBinaryNameString());
if (config.exporter.isLinux() && linuxPackages.size() > 0) if (config.exporter.isLinux() && linuxPackages.size() > 0)
{ {
if (createDynamicLibrary)
if (target.isDynamicLibrary())
flags.add ("-shared"); flags.add ("-shared");
auto pkgconfigLibs = String ("`pkg-config --libs"); auto pkgconfigLibs = String ("`pkg-config --libs");
@@ -303,80 +436,119 @@ private:
return getCleanedStringArray (paths); 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; 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"); 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") xml.createNewChildElement ("Option")
->setAttribute ("object_output", "obj/" + File::createLegalFileName (config.getName().trim())); ->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"); 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"); 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)); 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"); 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; 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"); XmlElement* const build = xml.createNewChildElement ("Build");
for (ConstConfigIterator config (*this); config.next();) 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 void addProjectCompilerOptions (XmlElement& xml) const
@@ -416,6 +617,54 @@ private:
setAddOption (*linker, "library", replacePreprocessorDefs (getAllPreprocessorDefs(), libs[i])); 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 void addCompileUnits (const Project::Item& projectItem, XmlElement& xml) const
{ {
if (projectItem.isGroup()) if (projectItem.isGroup())
@@ -430,10 +679,16 @@ private:
XmlElement* unit = xml.createNewChildElement ("Unit"); XmlElement* unit = xml.createNewChildElement ("Unit");
unit->setAttribute ("filename", file.toUnixStyle()); 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()) 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); addOptions (xml);
addBuild (xml); addBuild (xml);
addVirtualTargets (xml);
addProjectCompilerOptions (xml); addProjectCompilerOptions (xml);
addProjectLinkerOptions (xml); addProjectLinkerOptions (xml);
addCompileUnits (xml); addCompileUnits (xml);
@@ -473,7 +729,8 @@ private:
} }
CodeBlocksOS os; CodeBlocksOS os;
bool createDynamicLibrary = false;
OwnedArray<CodeBlocksTarget> targets;
JUCE_DECLARE_NON_COPYABLE (CodeBlocksProjectExporter) 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 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: 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* getNameLinux() { return "Linux Makefile"; }
static const char* getValueTreeTypeName() { return "LINUX_MAKE"; } static const char* getValueTreeTypeName() { return "LINUX_MAKE"; }
@@ -72,13 +308,25 @@ public:
bool isOSX() const override { return false; } bool isOSX() const override { return false; }
bool isiOS() 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); } Value getCppStandardValue() { return getSetting (Ids::cppLanguageStandard); }
String getCppStandardString() const { return settings[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: 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 void writeDefineFlags (OutputStream& out, const BuildConfiguration& config) const
{ {
StringPairArray defines; StringPairArray defines;
@@ -189,7 +405,7 @@ private:
defines.set ("NDEBUG", "1"); 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 void writeHeaderPathFlags (OutputStream& out, const BuildConfiguration& config) const
@@ -239,9 +455,6 @@ private:
{ {
StringArray flags (makefileExtraLinkerFlags); StringArray flags (makefileExtraLinkerFlags);
if (makefileIsDLL)
flags.add ("-shared");
if (! config.isDebug()) if (! config.isDebug())
flags.add ("-fvisibility=hidden"); flags.add ("-fvisibility=hidden");
@@ -282,6 +495,36 @@ private:
<< " $(LDFLAGS)" << newLine; << " $(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 void writeConfig (OutputStream& out, const BuildConfiguration& config) const
{ {
const String buildDirName ("build"); const String buildDirName ("build");
@@ -307,14 +550,24 @@ private:
writeCppFlags (out, config); 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)"; out << " JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH)";
if (anyTargetIsSharedLibrary())
out << " -fPIC";
if (config.isDebug()) if (config.isDebug())
out << " -g -ggdb"; out << " -g -ggdb";
if (makefileIsDLL)
out << " -fPIC";
out << " -O" << config.getGCCOptimisationFlag() out << " -O" << config.getGCCOptimisationFlag()
<< (" " + replacePreprocessorTokens (config, getExtraCompilerFlagsString())).trimEnd() << (" " + replacePreprocessorTokens (config, getExtraCompilerFlagsString())).trimEnd()
<< " $(CFLAGS)" << newLine; << " $(CFLAGS)" << newLine;
@@ -324,44 +577,19 @@ private:
if (cppStandardToUse.isEmpty()) if (cppStandardToUse.isEmpty())
cppStandardToUse = "-std=c++11"; cppStandardToUse = "-std=c++11";
out << " JUCE_CXXFLAGS += $(JUCE_CFLAGS) "
out << " JUCE_CXXFLAGS += $(CXXFLAGS) $(JUCE_CFLAGS) "
<< cppStandardToUse << " $(CXXFLAGS)" << newLine; << cppStandardToUse << " $(CXXFLAGS)" << newLine;
writeLinkerFlags (out, config); writeLinkerFlags (out, config);
out << newLine; 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 out << " CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR)" << newLine
<< "endif" << newLine << "endif" << newLine
<< 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 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 << "# 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();) for (ConstConfigIterator config (*this); config.next();)
writeConfig (out, *config); writeConfig (out, *config);
writeObjects (out, files);
for (auto target : targets)
target->writeObjects (out);
out << ".PHONY: clean" << newLine
out << ".PHONY: clean all" << newLine
<< newLine; << newLine;
StringArray packages; StringArray packages;
packages.addTokens (getExtraPkgConfigString(), " ", "\"'"); packages.addTokens (getExtraPkgConfigString(), " ", "\"'");
packages.removeEmptyStrings(); 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) if (useLinuxPackages)
{ {
@@ -442,25 +666,9 @@ private:
out << "strip:" << newLine out << "strip:" << newLine
<< "\t@echo Stripping " << projectName << 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; << 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; out << "-include $(OBJECTS:%.o=%.d)" << newLine;
} }
@@ -486,5 +694,7 @@ private:
TargetOS::linux))); TargetOS::linux)));
} }
OwnedArray<MakefileTarget> targets;
JUCE_DECLARE_NON_COPYABLE (MakefileProjectExporter) 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 isOSX() const override { return ! iOS; }
bool isiOS() 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 void createExporterProperties (PropertyListBuilder& props) override
{ {
@@ -206,7 +224,8 @@ public:
"You can find this string in the OS X app Keychain Access under \"Certificates\"."); "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"), 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 bool launchProject() override
@@ -231,7 +250,7 @@ public:
void create (const OwnedArray<LibraryModule>&) const override void create (const OwnedArray<LibraryModule>&) const override
{ {
for (auto& target : targets) for (auto& target : targets)
if (target->xcodeCreatePList)
if (target->shouldCreatePList())
target->infoPlistFile = getTargetFolder().getChildFile (target->getInfoPlistName()); target->infoPlistFile = getTargetFolder().getChildFile (target->getInfoPlistName());
menuNibFile = getTargetFolder().getChildFile ("RecentFilesMenuTemplate.nib"); 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 // If you hit this assert, you tried to generate a project for an exporter
// that does not support any of your targets! // that does not support any of your targets!
@@ -400,7 +385,9 @@ protected:
osxVersionNames.add ("Use Default"); osxVersionNames.add ("Use Default");
versionValues.add (osxVersionDefault); 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)); sdkVersionNames.add (getSDKName (ver));
osxVersionNames.add (getOSXVersionName (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."); "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: private:
//========================================================================== //==========================================================================
void addXcodePluginInstallPathProperties (PropertyListBuilder& props) void addXcodePluginInstallPathProperties (PropertyListBuilder& props)
{ {
if (project.shouldBuildVST().getValue())
if (project.shouldBuildVST())
props.add (new TextWithDefaultPropertyComponent<String> (vstBinaryLocation, "VST Binary location", 1024), props.add (new TextWithDefaultPropertyComponent<String> (vstBinaryLocation, "VST Binary location", 1024),
"The folder in which the compiled VST binary should be placed."); "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), props.add (new TextWithDefaultPropertyComponent<String> (vst3BinaryLocation, "VST3 Binary location", 1024),
"The folder in which the compiled VST3 binary should be placed."); "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), props.add (new TextWithDefaultPropertyComponent<String> (auBinaryLocation, "AU Binary location", 1024),
"The folder in which the compiled AU binary should be placed."); "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), props.add (new TextWithDefaultPropertyComponent<String> (rtasBinaryLocation, "RTAS Binary location", 1024),
"The folder in which the compiled RTAS binary should be placed."); "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), props.add (new TextWithDefaultPropertyComponent<String> (aaxBinaryLocation, "AAX Binary location", 1024),
"The folder in which the compiled AAX binary should be placed."); "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) owner (exporter)
{ {
switch (type) switch (type)
{ {
case GUIApp: case GUIApp:
xcodeIsBundle = false;
xcodeIsExecutable = true;
xcodeCreatePList = true;
xcodePackageType = "APPL"; xcodePackageType = "APPL";
xcodeBundleSignature = "????"; xcodeBundleSignature = "????";
xcodeFileType = "wrapper.application"; xcodeFileType = "wrapper.application";
@@ -556,9 +524,6 @@ public:
break; break;
case ConsoleApp: case ConsoleApp:
xcodeIsBundle = false;
xcodeIsExecutable = true;
xcodeCreatePList = false;
xcodeFileType = "compiled.mach-o.executable"; xcodeFileType = "compiled.mach-o.executable";
xcodeBundleExtension = String(); xcodeBundleExtension = String();
xcodeProductType = "com.apple.product-type.tool"; xcodeProductType = "com.apple.product-type.tool";
@@ -566,55 +531,37 @@ public:
break; break;
case StaticLibrary: case StaticLibrary:
xcodeIsBundle = false;
xcodeIsExecutable = false;
xcodeCreatePList = false;
xcodeFileType = "archive.ar"; xcodeFileType = "archive.ar";
xcodeProductType = "com.apple.product-type.library.static"; xcodeProductType = "com.apple.product-type.library.static";
xcodeCopyToProductInstallPathAfterBuild = false; xcodeCopyToProductInstallPathAfterBuild = false;
break; break;
case DynamicLibrary: case DynamicLibrary:
xcodeIsBundle = false;
xcodeIsExecutable = false;
xcodeCreatePList = false;
xcodeFileType = "compiled.mach-o.dylib"; xcodeFileType = "compiled.mach-o.dylib";
xcodeProductType = "com.apple.product-type.library.dynamic"; xcodeProductType = "com.apple.product-type.library.dynamic";
xcodeBundleExtension = ".dylib"; xcodeBundleExtension = ".dylib";
xcodeCopyToProductInstallPathAfterBuild = false; xcodeCopyToProductInstallPathAfterBuild = false;
break; break;
case VSTPlugIn: case VSTPlugIn:
xcodeIsBundle = true;
xcodeIsExecutable = false;
xcodeCreatePList = true;
xcodePackageType = "BNDL"; xcodePackageType = "BNDL";
xcodeBundleSignature = "????"; xcodeBundleSignature = "????";
xcodeFileType = "wrapper.cfbundle"; xcodeFileType = "wrapper.cfbundle";
xcodeBundleExtension = ".vst"; xcodeBundleExtension = ".vst";
xcodeProductType = "com.apple.product-type.bundle"; xcodeProductType = "com.apple.product-type.bundle";
xcodeCopyToProductInstallPathAfterBuild = true; xcodeCopyToProductInstallPathAfterBuild = true;
break; break;
case VST3PlugIn: case VST3PlugIn:
xcodeIsBundle = true;
xcodeIsExecutable = false;
xcodeCreatePList = true;
xcodePackageType = "BNDL"; xcodePackageType = "BNDL";
xcodeBundleSignature = "????"; xcodeBundleSignature = "????";
xcodeFileType = "wrapper.cfbundle"; xcodeFileType = "wrapper.cfbundle";
xcodeBundleExtension = ".vst3"; xcodeBundleExtension = ".vst3";
xcodeProductType = "com.apple.product-type.bundle"; xcodeProductType = "com.apple.product-type.bundle";
xcodeCopyToProductInstallPathAfterBuild = true; xcodeCopyToProductInstallPathAfterBuild = true;
break; break;
case AudioUnitPlugIn: case AudioUnitPlugIn:
xcodeIsBundle = true;
xcodeIsExecutable = false;
xcodeCreatePList = true;
xcodePackageType = "BNDL"; xcodePackageType = "BNDL";
xcodeBundleSignature = "????"; xcodeBundleSignature = "????";
xcodeFileType = "wrapper.cfbundle"; xcodeFileType = "wrapper.cfbundle";
@@ -626,12 +573,8 @@ public:
break; break;
case StandalonePlugIn: case StandalonePlugIn:
xcodeIsBundle = false;
xcodeIsExecutable = true;
xcodeCreatePList = true;
xcodePackageType = "APPL"; xcodePackageType = "APPL";
xcodeBundleSignature = "????"; xcodeBundleSignature = "????";
xcodeCreatePList = true;
xcodeFileType = "wrapper.application"; xcodeFileType = "wrapper.application";
xcodeBundleExtension = ".app"; xcodeBundleExtension = ".app";
xcodeProductType = "com.apple.product-type.application"; xcodeProductType = "com.apple.product-type.application";
@@ -639,9 +582,6 @@ public:
break; break;
case AudioUnitv3PlugIn: case AudioUnitv3PlugIn:
xcodeIsBundle = false;
xcodeIsExecutable = false;
xcodeCreatePList = true;
xcodePackageType = "XPC!"; xcodePackageType = "XPC!";
xcodeBundleSignature = "????"; xcodeBundleSignature = "????";
xcodeFileType = "wrapper.app-extension"; xcodeFileType = "wrapper.app-extension";
@@ -654,9 +594,6 @@ public:
break; break;
case AAXPlugIn: case AAXPlugIn:
xcodeIsBundle = true;
xcodeIsExecutable = false;
xcodeCreatePList = true;
xcodePackageType = "TDMw"; xcodePackageType = "TDMw";
xcodeBundleSignature = "PTul"; xcodeBundleSignature = "PTul";
xcodeFileType = "wrapper.cfbundle"; xcodeFileType = "wrapper.cfbundle";
@@ -668,9 +605,6 @@ public:
break; break;
case RTASPlugIn: case RTASPlugIn:
xcodeIsBundle = true;
xcodeIsExecutable = false;
xcodeCreatePList = true;
xcodePackageType = "TDMw"; xcodePackageType = "TDMw";
xcodeBundleSignature = "PTul"; xcodeBundleSignature = "PTul";
xcodeFileType = "wrapper.cfbundle"; xcodeFileType = "wrapper.cfbundle";
@@ -682,18 +616,12 @@ public:
break; break;
case SharedCodeTarget: case SharedCodeTarget:
xcodeIsBundle = false;
xcodeIsExecutable = false;
xcodeCreatePList = false;
xcodeFileType = "archive.ar"; xcodeFileType = "archive.ar";
xcodeProductType = "com.apple.product-type.library.static"; xcodeProductType = "com.apple.product-type.library.static";
xcodeCopyToProductInstallPathAfterBuild = false; xcodeCopyToProductInstallPathAfterBuild = false;
break; break;
case AggregateTarget: case AggregateTarget:
xcodeIsBundle = false;
xcodeIsExecutable = false;
xcodeCreatePList = false;
xcodeCopyToProductInstallPathAfterBuild = false; xcodeCopyToProductInstallPathAfterBuild = false;
break; 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 String getXCodeSchemeName() const
{ {
return owner.projectName + " (" + getName() + ")"; 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 String getID() const
{ {
return owner.createID (String ("__target") + getName()); return owner.createID (String ("__target") + getName());
@@ -751,9 +650,8 @@ public:
String xcodePackageType, xcodeBundleSignature, xcodeBundleExtension; String xcodePackageType, xcodeBundleSignature, xcodeBundleExtension;
String xcodeProductType, xcodeFileType; String xcodeProductType, xcodeFileType;
String xcodeOtherRezFlags, xcodeExcludedFiles64Bit, xcodeBundleIDSubPath; String xcodeOtherRezFlags, xcodeExcludedFiles64Bit, xcodeBundleIDSubPath;
bool xcodeIsBundle, xcodeCreatePList, xcodeIsExecutable, xcodeCopyToProductInstallPathAfterBuild;
bool xcodeCopyToProductInstallPathAfterBuild;
StringArray xcodeFrameworks, xcodeLibs; StringArray xcodeFrameworks, xcodeLibs;
Type type;
Array<XmlElement> xcodeExtraPListEntries; Array<XmlElement> xcodeExtraPListEntries;
Array<RelativePath> xcodeExtraLibrariesDebug, xcodeExtraLibrariesRelease; Array<RelativePath> xcodeExtraLibrariesDebug, xcodeExtraLibrariesRelease;
@@ -874,6 +772,12 @@ public:
return *v; 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 StringArray getTargetSettings (const XcodeBuildConfiguration& config) const
{ {
@@ -904,7 +808,7 @@ public:
s.add ("HEADER_SEARCH_PATHS = " + owner.getHeaderSearchPaths (config)); s.add ("HEADER_SEARCH_PATHS = " + owner.getHeaderSearchPaths (config));
s.add ("GCC_OPTIMIZATION_LEVEL = " + config.getGCCOptimisationFlag()); s.add ("GCC_OPTIMIZATION_LEVEL = " + config.getGCCOptimisationFlag());
if (xcodeCreatePList)
if (shouldCreatePList())
s.add ("INFOPLIST_FILE = " + infoPlistFile.getFileName()); s.add ("INFOPLIST_FILE = " + infoPlistFile.getFileName());
if (config.linkTimeOptimisationEnabled.get()) if (config.linkTimeOptimisationEnabled.get())
@@ -930,7 +834,7 @@ public:
} }
} }
if (xcodeIsBundle)
if (getTargetFileType() == pluginBundle)
{ {
s.add ("LIBRARY_STYLE = Bundle"); s.add ("LIBRARY_STYLE = Bundle");
s.add ("WRAPPER_EXTENSION = " + xcodeBundleExtension.substring (1)); 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 // if the user doesn't set it, then use the last known version that works well with JUCE
String deploymentTarget = "10.11"; 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 (sdk == getSDKName (ver)) s.add ("SDKROOT = macosx10." + String (ver));
if (sdkCompat == getSDKName (ver)) deploymentTarget = "10." + String (ver); if (sdkCompat == getSDKName (ver)) deploymentTarget = "10." + String (ver);
@@ -1052,24 +954,10 @@ public:
s.add ("SEPARATE_STRIP = YES"); 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()) if (owner.project.getProjectType().isAudioPlugin() && type == Target::AudioUnitv3PlugIn && owner.isOSX())
s.add (String ("CODE_SIGN_ENTITLEMENTS = \"") + owner.getEntitlementsFileName() + String ("\"")); 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; StringArray defsList;
@@ -1109,7 +997,7 @@ public:
//============================================================================== //==============================================================================
void getLinkerSettings (const BuildConfiguration& config, StringArray& flags, StringArray& librarySearchPaths) const void getLinkerSettings (const BuildConfiguration& config, StringArray& flags, StringArray& librarySearchPaths) const
{ {
if (xcodeIsBundle)
if (getTargetFileType() == pluginBundle)
flags.add (owner.isiOS() ? "-bitcode_bundle" : "-bundle"); flags.add (owner.isiOS() ? "-bitcode_bundle" : "-bundle");
const Array<RelativePath>& extraLibs = config.isDebug() ? xcodeExtraLibrariesDebug const Array<RelativePath>& extraLibs = config.isDebug() ? xcodeExtraLibrariesDebug
@@ -1147,7 +1035,7 @@ public:
//========================================================================== c //========================================================================== c
void writeInfoPlistFile() const void writeInfoPlistFile() const
{ {
if (! xcodeCreatePList)
if (! shouldCreatePList())
return; return;
ScopedPointer<XmlElement> plist (XmlDocument::parse (owner.getPListToMergeString())); ScopedPointer<XmlElement> plist (XmlDocument::parse (owner.getPListToMergeString()));
@@ -1409,7 +1297,7 @@ public:
private: private:
//============================================================================== //==============================================================================
bool xcodeCanUseDwarf; bool xcodeCanUseDwarf;
OwnedArray<Target> targets;
OwnedArray<XCodeTarget> targets;
mutable OwnedArray<ValueTree> pbxBuildFiles, pbxFileReferences, pbxGroups, misc, projectConfigs, targetConfigs; mutable OwnedArray<ValueTree> pbxBuildFiles, pbxFileReferences, pbxGroups, misc, projectConfigs, targetConfigs;
mutable StringArray resourceIDs, sourceIDs, targetIDs; mutable StringArray resourceIDs, sourceIDs, targetIDs;
@@ -1471,7 +1359,7 @@ private:
{ {
for (auto* target : targets) for (auto* target : targets)
{ {
if (target->type == Target::AggregateTarget)
if (target->type == XCodeTarget::AggregateTarget)
continue; continue;
target->addMainBuildProduct(); target->addMainBuildProduct();
@@ -1495,10 +1383,10 @@ private:
{ {
for (auto* target : targets) for (auto* target : targets)
{ {
if (target->type == Target::AggregateTarget)
if (target->type == XCodeTarget::AggregateTarget)
continue; continue;
if (target->xcodeCreatePList)
if (target->shouldCreatePList())
{ {
RelativePath plistPath (target->infoPlistFile, getTargetFolder(), RelativePath::buildTargetFolder); RelativePath plistPath (target->infoPlistFile, getTargetFolder(), RelativePath::buildTargetFolder);
addFileReference (plistPath.toUnixStyle()); addFileReference (plistPath.toUnixStyle());
@@ -1576,7 +1464,7 @@ private:
// add build phases // add build phases
for (auto* target : targets) for (auto* target : targets)
{ {
if (target->type != Target::AggregateTarget)
if (target->type != XCodeTarget::AggregateTarget)
buildProducts.add (createID (String ("__productFileID") + String (target->getName()))); buildProducts.add (createID (String ("__productFileID") + String (target->getName())));
for (ConstConfigIterator config (*this); config.next();) for (ConstConfigIterator config (*this); config.next();)
@@ -1589,11 +1477,11 @@ private:
target->addShellScriptBuildPhase ("Pre-build script", getPreBuildScript()); 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. // TODO: ideally resources wouldn't be copied into the AUv3 bundle as well.
// However, fixing this requires supporting App groups -> TODO: add app groups // 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); target->addBuildPhase ("PBXResourcesBuildPhase", resourceIDs);
StringArray rezFiles (rezFileIDs); StringArray rezFiles (rezFileIDs);
@@ -1604,20 +1492,20 @@ private:
StringArray sourceFiles (target->sourceIDs); StringArray sourceFiles (target->sourceIDs);
if (target->type == Target::SharedCodeTarget
if (target->type == XCodeTarget::SharedCodeTarget
|| (! project.getProjectType().isAudioPlugin())) || (! project.getProjectType().isAudioPlugin()))
sourceFiles.addArray (sourceIDs); sourceFiles.addArray (sourceIDs);
target->addBuildPhase ("PBXSourcesBuildPhase", sourceFiles); target->addBuildPhase ("PBXSourcesBuildPhase", sourceFiles);
if (! projectType.isStaticLibrary() && target->type != Target::SharedCodeTarget)
if (! projectType.isStaticLibrary() && target->type != XCodeTarget::SharedCodeTarget)
target->addBuildPhase ("PBXFrameworksBuildPhase", target->frameworkIDs); target->addBuildPhase ("PBXFrameworksBuildPhase", target->frameworkIDs);
} }
target->addShellScriptBuildPhase ("Post-build script", getPostBuildScript()); 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(); embedAppExtension();
addTargetObject (*target); addTargetObject (*target);
@@ -1626,9 +1514,9 @@ private:
void embedAppExtension() const 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; StringArray files;
files.add (auv3Target->mainBuildProductID); 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) for (auto& target : targets)
if (target->type == type) if (target->type == type)
@@ -1671,13 +1559,13 @@ private:
return nullptr; return nullptr;
} }
void addTargetObject (Target& target) const
void addTargetObject (XCodeTarget& target) const
{ {
String targetName = target.getName(); String targetName = target.getName();
String targetID = target.getID(); String targetID = target.getID();
ValueTree* const v = new ValueTree (targetID); 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 ("buildConfigurationList", createID (String ("__configList") + targetName), nullptr);
v->setProperty ("buildPhases", indentParenthesisedList (target.buildPhaseIDs), nullptr); v->setProperty ("buildPhases", indentParenthesisedList (target.buildPhaseIDs), nullptr);
@@ -1687,7 +1575,7 @@ private:
v->setProperty (Ids::name, target.getXCodeSchemeName(), nullptr); v->setProperty (Ids::name, target.getXCodeSchemeName(), nullptr);
v->setProperty ("productName", projectName, nullptr); v->setProperty ("productName", projectName, nullptr);
if (target.type != Target::AggregateTarget)
if (target.type != XCodeTarget::AggregateTarget)
{ {
v->setProperty ("productReference", createID (String ("__productFileID") + targetName), nullptr); v->setProperty ("productReference", createID (String ("__productFileID") + targetName), nullptr);
@@ -1699,28 +1587,28 @@ private:
misc.add (v); misc.add (v);
} }
StringArray getTargetDependencies (const Target& target) const
StringArray getTargetDependencies (const XCodeTarget& target) const
{ {
StringArray dependencies; StringArray dependencies;
if (project.getProjectType().isAudioPlugin()) 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()); dependencies.add (auv3Target->getDependencyID());
if (Target* sharedCodeTarget = getTargetOfType (Target::SharedCodeTarget))
if (XCodeTarget* sharedCodeTarget = getTargetOfType (XCodeTarget::SharedCodeTarget))
dependencies.add (sharedCodeTarget->getDependencyID()); 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) for (int i = 1; i < targets.size(); ++i)
dependencies.add (targets[i]->getDependencyID()); 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()); dependencies.add (sharedCodeTarget->getDependencyID());
} }
} }
@@ -2099,7 +1987,7 @@ private:
output << "\t};\n\trootObject = " << createID ("__root") << ";\n}\n"; 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")); String fileID (createID (path + "buildref"));
@@ -2120,7 +2008,7 @@ private:
return fileID; 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); return addBuildFile (path.toUnixStyle(), createFileRefID (path), addToSourceBuildPhase, inhibitWarnings, xcodeTarget);
} }
@@ -2204,7 +2092,7 @@ private:
} }
String addFile (const RelativePath& path, bool shouldBeCompiled, bool shouldBeAddedToBinaryResources, 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 pathAsString (path.toUnixStyle());
const String refID (addFileReference (path.toUnixStyle())); const String refID (addFileReference (path.toUnixStyle()));
@@ -2234,7 +2122,7 @@ private:
if (projectItem.isModuleCode()) 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); String rezFileID = addBuildFile (pathAsString, refID, false, false, xcodeTarget);
xcodeTarget->rezFileIDs.add (rezFileID); xcodeTarget->rezFileIDs.add (rezFileID);
@@ -2299,9 +2187,9 @@ private:
if (path.hasFileExtension (".r")) if (path.hasFileExtension (".r"))
return addRezFile (projectItem, path); return addRezFile (projectItem, path);
Target* xcodeTarget = nullptr;
XCodeTarget* xcodeTarget = nullptr;
if (projectItem.isModuleCode() && projectItem.shouldBeCompiled()) if (projectItem.isModuleCode() && projectItem.shouldBeCompiled())
xcodeTarget = getTargetOfType (getTargetTypeFromFilePath (projectItem.getFile(), false));
xcodeTarget = getTargetOfType (project.getTargetTypeFromFilePath (projectItem.getFile(), false));
return addFile (path, projectItem.shouldBeCompiled(), return addFile (path, projectItem.shouldBeCompiled(),
projectItem.shouldBeAddedToBinaryResources(), projectItem.shouldBeAddedToBinaryResources(),
@@ -2357,7 +2245,7 @@ private:
projectConfigs.add (v); 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); ValueTree* v = new ValueTree (listID);
v->setProperty ("isa", "XCConfigurationList", nullptr); v->setProperty ("isa", "XCConfigurationList", nullptr);
@@ -2370,7 +2258,7 @@ private:
misc.add (v); 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; StringArray configIDs;
@@ -2405,19 +2293,6 @@ private:
misc.add (v); 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 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) ProjectExporter::ProjectExporter (Project& p, const ValueTree& state)
: makefileIsDLL (false),
msvcIsDLL (false),
msvcIsWindowsSubsystem (true),
settings (state),
: settings (state),
project (p), project (p),
projectType (p.getProjectType()), projectType (p.getProjectType()),
projectName (p.getTitle()), 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) 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"), 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 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"), 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 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"), 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."); "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() 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() 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"); makefileExtraLinkerFlags.add ("-Wl,--no-undefined");
if (supportsAAX() && getProject().shouldBuildAAX().getValue())
if (shouldBuildTargetType (ProjectType::Target::AAXPlugIn))
addAAXFoldersToPath(); addAAXFoldersToPath();
// Note: RTAS paths are platform-dependent, impl -> addPlatformSpecificSettingsForProjectType // 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(), StringPairArray defs (mergePreprocessorDefs (config.getAllPreprocessorDefs(),
parsePreprocessorDefs (getExporterPreprocessorDefsString()))); parsePreprocessorDefs (getExporterPreprocessorDefsString())));
addDefaultPreprocessorDefs (defs); addDefaultPreprocessorDefs (defs);
addTargetSpecificPreprocessorDefs (defs, targetType);
return defs; return defs;
} }
@@ -363,6 +353,31 @@ StringPairArray ProjectExporter::getAllPreprocessorDefs() const
return defs; 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 void ProjectExporter::addDefaultPreprocessorDefs (StringPairArray& defs) const
{ {
defs.set (getExporterIdentifierMacro(), "1"); defs.set (getExporterIdentifierMacro(), "1");
@@ -370,9 +385,10 @@ void ProjectExporter::addDefaultPreprocessorDefs (StringPairArray& defs) const
defs.set ("JUCE_APP_VERSION_HEX", project.getVersionAsHex()); 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() void ProjectExporter::copyMainGroupFromProject()
@@ -393,14 +409,24 @@ Project::Item& ProjectExporter::getModulesGroup()
return *modulesGroup; 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) Value ProjectExporter::getPathForModuleValue (const String& moduleID)
@@ -810,16 +836,24 @@ StringArray ProjectExporter::BuildConfiguration::getHeaderSearchPaths() const
StringArray ProjectExporter::BuildConfiguration::getLibrarySearchPaths() 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 ProjectExporter::BuildConfiguration::getGCCLibraryPathFlags() const
{ {
String s; 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; 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 isOSX() const = 0;
virtual bool isiOS() const = 0; virtual bool isiOS() const = 0;
//==============================================================================
// cross-platform audio plug-ins supported by exporter // 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 bool mayCompileOnCurrentOS() const
@@ -150,6 +157,7 @@ public:
RelativePath rebaseFromProjectFolderToBuildTarget (const RelativePath& path) const; RelativePath rebaseFromProjectFolderToBuildTarget (const RelativePath& path) const;
void addToExtraSearchPaths (const RelativePath& pathFromProjectFolder, int index = -1); void addToExtraSearchPaths (const RelativePath& pathFromProjectFolder, int index = -1);
void addToModuleLibPaths (const RelativePath& pathFromProjectFolder);
Value getBigIconImageItemID() { return getSetting (Ids::bigIcon); } Value getBigIconImageItemID() { return getSetting (Ids::bigIcon); }
Value getSmallIconImageItemID() { return getSetting (Ids::smallIcon); } Value getSmallIconImageItemID() { return getSetting (Ids::smallIcon); }
@@ -187,19 +195,16 @@ public:
Project::Item& getModulesGroup(); Project::Item& getModulesGroup();
//============================================================================== //==============================================================================
String makefileTargetSuffix;
bool makefileIsDLL;
StringArray linuxLibs, linuxPackages, makefileExtraLinkerFlags; StringArray linuxLibs, linuxPackages, makefileExtraLinkerFlags;
//============================================================================== //==============================================================================
String msvcTargetSuffix;
StringPairArray msvcExtraPreprocessorDefs; StringPairArray msvcExtraPreprocessorDefs;
bool msvcIsDLL, msvcIsWindowsSubsystem;
String msvcDelayLoadedDLLs; String msvcDelayLoadedDLLs;
StringArray mingwLibs;
StringArray mingwLibs, windowsLibs;
//============================================================================== //==============================================================================
StringArray extraSearchPaths; StringArray extraSearchPaths;
StringArray moduleLibSearchPaths;
//============================================================================== //==============================================================================
class BuildConfiguration : public ReferenceCountedObject class BuildConfiguration : public ReferenceCountedObject
@@ -213,6 +218,8 @@ public:
//============================================================================== //==============================================================================
virtual void createConfigProperties (PropertyListBuilder&) = 0; virtual void createConfigProperties (PropertyListBuilder&) = 0;
virtual var getDefaultOptimisationLevel() const = 0; virtual var getDefaultOptimisationLevel() const = 0;
virtual String getLibrarySubdirPath() const { return String(); }
//============================================================================== //==============================================================================
Value getNameValue() { return getValue (Ids::name); } Value getNameValue() { return getValue (Ids::name); }
@@ -316,10 +323,12 @@ public:
String getExporterPreprocessorDefsString() const { return getSettingString (Ids::extraDefs); } String getExporterPreprocessorDefsString() const { return getSettingString (Ids::extraDefs); }
// includes exporter, project + config defs // 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.. // includes exporter + project defs..
StringPairArray getAllPreprocessorDefs() const; StringPairArray getAllPreprocessorDefs() const;
void addTargetSpecificPreprocessorDefs (StringPairArray& defs, const ProjectType::Target::Type targetType) const;
String replacePreprocessorTokens (const BuildConfiguration&, const String& sourceString) const; String replacePreprocessorTokens (const BuildConfiguration&, const String& sourceString) const;
ValueTree settings; ValueTree settings;
@@ -345,7 +354,7 @@ protected:
mutable Array<Project::Item> itemGroups; mutable Array<Project::Item> itemGroups;
void initItemGroups() const; void initItemGroups() const;
Project::Item* modulesGroup;
Project::Item* modulesGroup = nullptr;
virtual BuildConfiguration::Ptr createBuildConfig (const ValueTree&) const = 0; virtual BuildConfiguration::Ptr createBuildConfig (const ValueTree&) const = 0;
@@ -408,6 +417,7 @@ private:
void addCommonAudioPluginSettings(); void addCommonAudioPluginSettings();
void addVST3FolderToPath(); void addVST3FolderToPath();
void addAAXFoldersToPath(); void addAAXFoldersToPath();
void addProjectPathToBuildPathList (StringArray&, const RelativePath&, int index = -1);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjectExporter) 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() void ProjectSaver::writePluginCharacteristicsFile()
{ {
StringPairArray flags; 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_Name", valueToStringLiteral (project.getPluginName()));
flags.set ("JucePlugin_Desc", valueToStringLiteral (project.getPluginDesc())); flags.set ("JucePlugin_Desc", valueToStringLiteral (project.getPluginDesc()));
flags.set ("JucePlugin_Manufacturer", valueToStringLiteral (project.getPluginManufacturer())); 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 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()) if (extraInternalSearchPaths.isNotEmpty())
{ {
StringArray paths; StringArray paths;
paths.addTokens (extraInternalSearchPaths, true); paths.addTokens (extraInternalSearchPaths, true);
for (int i = 0; i < paths.size(); ++i) 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.linuxLibs, moduleInfo.moduleInfo ["linuxLibs"].toString());
parseAndAddLibs (exporter.linuxPackages, moduleInfo.moduleInfo ["linuxPackages"].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 bool LibraryModule::CompileUnit::isNeededForExporter (ProjectExporter& exporter) const
{ {
Project& project = exporter.getProject();
if ((hasSuffix (file, "_OSX") && ! exporter.isOSX()) if ((hasSuffix (file, "_OSX") && ! exporter.isOSX())
|| (hasSuffix (file, "_iOS") && ! exporter.isiOS()) || (hasSuffix (file, "_iOS") && ! exporter.isiOS())
|| (hasSuffix (file, "_Windows") && ! exporter.isWindows()) || (hasSuffix (file, "_Windows") && ! exporter.isWindows())
|| (hasSuffix (file, "_Linux") && ! exporter.isLinux()) || (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 false;
return exporter.usesMMFiles() ? isCompiledForObjC 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_Headers.h"
#include "jucer_Project.h" #include "jucer_Project.h"
#include "jucer_ProjectType.h"
#include "../Project Saving/jucer_ProjectExporter.h" #include "../Project Saving/jucer_ProjectExporter.h"
#include "../Project Saving/jucer_ProjectSaver.h" #include "../Project Saving/jucer_ProjectSaver.h"
#include "../Application/jucer_OpenDocumentManager.h" #include "../Application/jucer_OpenDocumentManager.h"
@@ -147,13 +146,13 @@ void Project::setMissingAudioPluginDefaultValues()
{ {
const String sanitisedProjectName (CodeHelpers::makeValidIdentifier (getTitle(), false, true, false)); 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 (getPluginName(), getTitle());
setValueIfVoid (getPluginDesc(), getTitle()); setValueIfVoid (getPluginDesc(), getTitle());
@@ -222,10 +221,19 @@ void Project::removeDefunctExporters()
for (;;) 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); 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 else
break; break;
} }
@@ -436,6 +444,98 @@ const ProjectType& Project::getProjectType() const
return *guiType; 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) void Project::createPropertyEditors (PropertyListBuilder& props)
{ {
@@ -515,25 +615,20 @@ void Project::createPropertyEditors (PropertyListBuilder& props)
void Project::createAudioPluginPropertyEditors (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."); "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."); "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."); "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."); "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."); "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."); "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), props.add (new TextPropertyComponent (getPluginName(), "Plugin Name", 128, false),
"The name of your plugin (keep it short!)"); "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 #ifndef JUCER_PROJECT_H_INCLUDED
#define JUCER_PROJECT_H_INCLUDED #define JUCER_PROJECT_H_INCLUDED
#include "jucer_ProjectType.h"
class ProjectExporter; class ProjectExporter;
class ProjectType;
class LibraryModule; class LibraryModule;
class EnabledModuleList; class EnabledModuleList;
@@ -95,7 +96,8 @@ public:
Value getCompanyEmail() { return getProjectValue (Ids::companyEmail); } 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); } Value getProjectPreprocessorDefs() { return getProjectValue (Ids::defines); }
StringPairArray getPreprocessorDefs() const; StringPairArray getPreprocessorDefs() const;
@@ -122,13 +124,23 @@ public:
//============================================================================== //==============================================================================
// Some helper methods for audio plugin/host projects. // 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 getPluginName() { return getProjectValue ("pluginName"); }
Value getPluginDesc() { return getProjectValue ("pluginDesc"); } Value getPluginDesc() { return getProjectValue ("pluginDesc"); }
Value getPluginManufacturer() { return getProjectValue ("pluginManufacturer"); } Value getPluginManufacturer() { return getProjectValue ("pluginManufacturer"); }
@@ -158,6 +170,10 @@ public:
bool isVSTPluginHost(); bool isVSTPluginHost();
bool isVST3PluginHost(); bool isVST3PluginHost();
bool shouldBuildTargetType (ProjectType::Target::Type targetType) const noexcept;
static ProjectType::Target::Type getTargetTypeFromFilePath (const File& file, bool returnSharedTargetIfNoValidSuffix);
//==============================================================================
void updateDeprecatedProjectSettingsInteractively(); 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 isCommandLineApp() const { return false; }
virtual bool isAudioPlugin() 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: protected:
ProjectType (const String& type, const String& desc); ProjectType (const String& type, const String& desc);
@@ -86,32 +135,36 @@ struct ProjectType_GUIApp : public ProjectType
{ {
ProjectType_GUIApp() : ProjectType (getTypeName(), "GUI Application") {} 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 struct ProjectType_ConsoleApp : public ProjectType
{ {
ProjectType_ConsoleApp() : ProjectType (getTypeName(), "Console Application") {} 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 struct ProjectType_StaticLibrary : public ProjectType
{ {
ProjectType_StaticLibrary() : ProjectType (getTypeName(), "Static Library") {} 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 struct ProjectType_DLL : public ProjectType
{ {
ProjectType_DLL() : ProjectType (getTypeName(), "Dynamic Library") {} 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 struct ProjectType_AudioPlugin : public ProjectType
@@ -120,6 +173,27 @@ struct ProjectType_AudioPlugin : public ProjectType
static const char* getTypeName() noexcept { return "audioplug"; } static const char* getTypeName() noexcept { return "audioplug"; }
bool isAudioPlugin() const override { return true; } 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 (winWarningLevel);
DECLARE_ID (warningsAreErrors); DECLARE_ID (warningsAreErrors);
DECLARE_ID (linuxArchitecture); DECLARE_ID (linuxArchitecture);
DECLARE_ID (linuxCodeBlocksArchitecture);
DECLARE_ID (windowsCodeBlocksArchitecture);
DECLARE_ID (toolset); DECLARE_ID (toolset);
DECLARE_ID (IPPLibrary); DECLARE_ID (IPPLibrary);
DECLARE_ID (msvcModuleDefinitionFile); DECLARE_ID (msvcModuleDefinitionFile);
@@ -112,7 +114,6 @@ namespace Ids
DECLARE_ID (jucerVersion); DECLARE_ID (jucerVersion);
DECLARE_ID (prebuildCommand); DECLARE_ID (prebuildCommand);
DECLARE_ID (postbuildCommand); DECLARE_ID (postbuildCommand);
DECLARE_ID (internalPostBuildComamnd);
DECLARE_ID (generateManifest); DECLARE_ID (generateManifest);
DECLARE_ID (useRuntimeLibDLL); DECLARE_ID (useRuntimeLibDLL);
DECLARE_ID (wholeProgramOptimisation); DECLARE_ID (wholeProgramOptimisation);
@@ -173,7 +174,7 @@ namespace Ids
DECLARE_ID (iosDevelopmentTeamID); DECLARE_ID (iosDevelopmentTeamID);
DECLARE_ID (buildToolsVersion); DECLARE_ID (buildToolsVersion);
DECLARE_ID (gradleVersion); 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 (gradleToolchain);
DECLARE_ID (gradleToolchainVersion); DECLARE_ID (gradleToolchainVersion);
DECLARE_ID (linuxExtraPkgConfig); DECLARE_ID (linuxExtraPkgConfig);


Loading…
Cancel
Save