1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-15 00:24:19 +00:00

Projucer: Added PCH support for Xcode and Visual Studio exporters

This commit is contained in:
ed 2020-08-25 08:51:13 +01:00
parent 58652ce490
commit d677fd6264
18 changed files with 459 additions and 186 deletions

View file

@ -563,16 +563,11 @@ public:
m.addItem (4, "Rename File...");
m.addSeparator();
if (auto* group = dynamic_cast<GroupItem*> (getParentItem()))
{
if (group->isRoot())
{
m.addItem (5, "Binary Resource", true, item.shouldBeAddedToBinaryResources());
m.addItem (6, "Xcode Resource", true, item.shouldBeAddedToXcodeResources());
m.addItem (7, "Compile", true, item.shouldBeCompiled());
m.addSeparator();
}
}
m.addItem (5, "Binary Resource", true, item.shouldBeAddedToBinaryResources());
m.addItem (6, "Xcode Resource", true, item.shouldBeAddedToXcodeResources());
m.addItem (7, "Compile", item.isSourceFile(), item.shouldBeCompiled());
m.addItem (8, "Skip PCH", item.shouldBeCompiled(), item.shouldSkipPCH());
m.addSeparator();
m.addItem (3, "Delete");
@ -589,13 +584,14 @@ public:
{
switch (resultCode)
{
case 1: getFile().startAsProcess(); break;
case 2: revealInFinder(); break;
case 3: deleteAllSelectedItems(); break;
case 4: triggerAsyncRename (item); break;
case 5: item.getShouldAddToBinaryResourcesValue().setValue (! item.shouldBeAddedToBinaryResources()); break;
case 6: item.getShouldAddToXcodeResourcesValue().setValue (! item.shouldBeAddedToXcodeResources()); break;
case 7: item.getShouldCompileValue().setValue (! item.shouldBeCompiled()); break;
case 1: getFile().startAsProcess(); break;
case 2: revealInFinder(); break;
case 3: deleteAllSelectedItems(); break;
case 4: triggerAsyncRename (item); break;
case 5: item.getShouldAddToBinaryResourcesValue().setValue (! item.shouldBeAddedToBinaryResources()); break;
case 6: item.getShouldAddToXcodeResourcesValue().setValue (! item.shouldBeAddedToXcodeResources()); break;
case 7: item.getShouldCompileValue().setValue (! item.shouldBeCompiled()); break;
case 8: item.getShouldSkipPCHValue().setValue (! item.shouldSkipPCH()); break;
default:
if (auto* parentGroup = dynamic_cast<GroupItem*> (getParentProjectItem()))

View file

@ -223,7 +223,7 @@ private:
g.setColour (findColour (defaultTextColourId));
g.setFont (Font (14.0f));
g.drawFittedText (stringToDisplay, getLocalBounds(), Justification::centred, 10, 1.0f);
g.drawFittedText (stringToDisplay, getLocalBounds(), Justification::centred, 15, 0.75f);
}
String stringToDisplay;

View file

@ -36,8 +36,8 @@ public:
: item (group),
header (item.getName(), { getIcons().openFolder, Colours::transparentBlack })
{
list.setHeaderComponent (std::make_unique<ListBoxHeader> (Array<String> { "File", "Binary Resource", "Xcode Resource", "Compile", "Compiler Flag Scheme" },
Array<float> { 0.3f, 0.15f, 0.15f, 0.15f, 0.25f }));
list.setHeaderComponent (std::make_unique<ListBoxHeader> (Array<String> { "File", "Binary Resource", "Xcode Resource", "Compile", "Skip PCH", "Compiler Flag Scheme" },
Array<float> { 0.25f, 0.125f, 0.125f, 0.125f, 0.125f, 0.25f }));
list.setModel (this);
list.setColour (ListBox::backgroundColourId, Colours::transparentBlack);
addAndMakeVisible (list);
@ -136,9 +136,14 @@ private:
{
if (item.isFile())
{
addAndMakeVisible (compileButton);
compileButton.getToggleStateValue().referTo (item.getShouldCompileValue());
compileButton.onStateChange = [this] { compilerFlagSchemeSelector.setVisible (compileButton.getToggleState()); };
auto isSourceFile = item.isSourceFile();
if (isSourceFile)
{
addAndMakeVisible (compileButton);
compileButton.getToggleStateValue().referTo (item.getShouldCompileValue());
compileButton.onStateChange = [this] { compileEnablementChanged(); };
}
addAndMakeVisible (binaryResourceButton);
binaryResourceButton.getToggleStateValue().referTo (item.getShouldAddToBinaryResourcesValue());
@ -146,8 +151,15 @@ private:
addAndMakeVisible (xcodeResourceButton);
xcodeResourceButton.getToggleStateValue().referTo (item.getShouldAddToXcodeResourcesValue());
addChildComponent (compilerFlagSchemeSelector);
compilerFlagSchemeSelector.setVisible (compileButton.getToggleState());
if (isSourceFile)
{
addChildComponent (skipPCHButton);
skipPCHButton.getToggleStateValue().referTo (item.getShouldSkipPCHValue());
addChildComponent (compilerFlagSchemeSelector);
compileEnablementChanged();
}
}
}
@ -182,7 +194,8 @@ private:
binaryResourceButton.setBounds (bounds.removeFromLeft (roundToInt (header->getProportionAtIndex (1) * width)));
xcodeResourceButton.setBounds (bounds.removeFromLeft (roundToInt (header->getProportionAtIndex (2) * width)));
compileButton.setBounds (bounds.removeFromLeft (roundToInt (header->getProportionAtIndex (3) * width)));
compilerFlagSchemeSelector.setBounds (bounds.removeFromLeft (roundToInt (header->getProportionAtIndex (4) * width)));
skipPCHButton.setBounds (bounds.removeFromLeft (roundToInt (header->getProportionAtIndex (4) * width)));
compilerFlagSchemeSelector.setBounds (bounds.removeFromLeft (roundToInt (header->getProportionAtIndex (5) * width)));
}
}
@ -331,10 +344,18 @@ private:
Label newSchemeLabel;
};
void compileEnablementChanged()
{
auto shouldBeCompiled = compileButton.getToggleState();
skipPCHButton.setVisible (shouldBeCompiled);
compilerFlagSchemeSelector.setVisible (shouldBeCompiled);
}
//==============================================================================
ListBoxHeader* header;
ToggleButton compileButton, binaryResourceButton, xcodeResourceButton;
ToggleButton compileButton, binaryResourceButton, xcodeResourceButton, skipPCHButton;
CompilerFlagSchemeSelector compilerFlagSchemeSelector;
};

View file

@ -1510,6 +1510,11 @@ bool Project::Item::isImageFile() const
|| getFile().hasFileExtension ("svg"));
}
bool Project::Item::isSourceFile() const
{
return isFile() && getFile().hasFileExtension (sourceFileExtensions);
}
Project::Item Project::Item::findItemWithID (const String& targetId) const
{
if (state [Ids::ID] == targetId)
@ -1565,6 +1570,9 @@ bool Project::Item::shouldInhibitWarnings() const { return state [Ids:
bool Project::Item::isModuleCode() const { return belongsToModule; }
Value Project::Item::getShouldSkipPCHValue() { return state.getPropertyAsValue (Ids::skipPCH, getUndoManager()); }
bool Project::Item::shouldSkipPCH() const { return isModuleCode() || state [Ids::skipPCH]; }
Value Project::Item::getCompilerFlagSchemeValue() { return state.getPropertyAsValue (Ids::compilerFlagScheme, getUndoManager()); }
String Project::Item::getCompilerFlagSchemeString() const { return state [Ids::compilerFlagScheme]; }

View file

@ -214,11 +214,11 @@ public:
void addCompilerFlagScheme (const String&);
void removeCompilerFlagScheme (const String&);
String getPostExportShellCommandPosixString() const { return postExportShellCommandPosixValue.get(); }
String getPostExportShellCommandWinString() const { return postExportShellCommandWinValue.get(); }
String getPostExportShellCommandPosixString() const { return postExportShellCommandPosixValue.get(); }
String getPostExportShellCommandWinString() const { return postExportShellCommandWinValue.get(); }
bool shouldUseAppConfig() const { return useAppConfigValue.get(); }
bool shouldAddUsingNamespaceToJuceHeader() const { return addUsingNamespaceToJuceHeader.get(); }
bool shouldUseAppConfig() const { return useAppConfigValue.get(); }
bool shouldAddUsingNamespaceToJuceHeader() const { return addUsingNamespaceToJuceHeader.get(); }
//==============================================================================
String getPluginNameString() const { return pluginNameValue.get(); }
@ -340,6 +340,7 @@ public:
bool isGroup() const;
bool isMainGroup() const;
bool isImageFile() const;
bool isSourceFile() const;
String getID() const;
void setID (const String& newID);
@ -374,6 +375,9 @@ public:
bool isModuleCode() const;
Value getShouldSkipPCHValue();
bool shouldSkipPCH() const;
Value getCompilerFlagSchemeValue();
String getCompilerFlagSchemeString() const;

View file

@ -48,6 +48,8 @@ public:
bool canCopeWithDuplicateFiles() override { return false; }
bool supportsUserDefinedConfigurations() const override { return true; }
String getNewLineString() const override { return "\n"; }
bool supportsTargetType (build_tools::ProjectType::Target::Type type) const override
{
return type == build_tools::ProjectType::Target::GUIApp || type == build_tools::ProjectType::Target::StaticLibrary
@ -238,7 +240,7 @@ public:
{
build_tools::writeStreamToFile (gradleProjectFolder.getChildFile (filePath), [&] (MemoryOutputStream& mo)
{
mo.setNewLineString ("\n");
mo.setNewLineString (getNewLineString());
mo << fileContent;
});
}
@ -247,7 +249,7 @@ public:
{
build_tools::writeStreamToFile (gradleProjectFolder.getChildFile (filePath), [&] (MemoryOutputStream& mo)
{
mo.setNewLineString ("\n");
mo.setNewLineString (getNewLineString());
mo.write (binaryData, static_cast<size_t> (binarySize));
});
}
@ -340,7 +342,7 @@ private:
{
build_tools::writeStreamToFile (file, [&] (MemoryOutputStream& mo)
{
mo.setNewLineString ("\n");
mo.setNewLineString (getNewLineString());
mo << "# 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
@ -578,7 +580,7 @@ private:
String getGradleSettingsFileContent() const
{
MemoryOutputStream mo;
mo.setNewLineString ("\n");
mo.setNewLineString (getNewLineString());
mo << "rootProject.name = " << "\'" << projectName << "\'" << newLine;
mo << (isLibrary() ? "include ':lib'" : "include ':app'");
@ -594,7 +596,7 @@ private:
String getProjectBuildGradleFileContent() const
{
MemoryOutputStream mo;
mo.setNewLineString ("\n");
mo.setNewLineString (getNewLineString());
mo << "buildscript {" << newLine;
mo << " repositories {" << newLine;
@ -621,7 +623,7 @@ private:
String getAppBuildGradleFileContent (const OwnedArray<LibraryModule>& modules) const
{
MemoryOutputStream mo;
mo.setNewLineString ("\n");
mo.setNewLineString (getNewLineString());
mo << "apply plugin: 'com.android." << (isLibrary() ? "library" : "application") << "'" << newLine << newLine;
@ -653,7 +655,7 @@ private:
String getAndroidProductFlavours() const
{
MemoryOutputStream mo;
mo.setNewLineString ("\n");
mo.setNewLineString (getNewLineString());
mo << " flavorDimensions \"default\"" << newLine;
mo << " productFlavors {" << newLine;
@ -702,7 +704,7 @@ private:
String getAndroidSigningConfig() const
{
MemoryOutputStream mo;
mo.setNewLineString ("\n");
mo.setNewLineString (getNewLineString());
auto keyStoreFilePath = androidKeyStore.get().toString().replace ("${user.home}", "${System.properties['user.home']}")
.replace ("/", "${File.separator}");
@ -728,7 +730,7 @@ private:
auto targetSdkVersion = static_cast<int> (androidTargetSDK.get());
MemoryOutputStream mo;
mo.setNewLineString ("\n");
mo.setNewLineString (getNewLineString());
mo << " defaultConfig {" << newLine;
@ -753,7 +755,7 @@ private:
String getAndroidBuildTypes() const
{
MemoryOutputStream mo;
mo.setNewLineString ("\n");
mo.setNewLineString (getNewLineString());
mo << " buildTypes {" << newLine;
@ -784,7 +786,7 @@ private:
String getAndroidVariantFilter() const
{
MemoryOutputStream mo;
mo.setNewLineString ("\n");
mo.setNewLineString (getNewLineString());
mo << " variantFilter { variant ->" << newLine;
mo << " def names = variant.flavors*.name" << newLine;
@ -807,7 +809,7 @@ private:
String getAndroidProjectRepositories() const
{
MemoryOutputStream mo;
mo.setNewLineString ("\n");
mo.setNewLineString (getNewLineString());
auto repositories = StringArray::fromLines (androidProjectRepositories.get().toString());
@ -827,7 +829,7 @@ private:
String getAndroidRepositories() const
{
MemoryOutputStream mo;
mo.setNewLineString ("\n");
mo.setNewLineString (getNewLineString());
auto repositories = StringArray::fromLines (androidRepositories.get().toString());
@ -844,7 +846,7 @@ private:
String getAndroidDependencies() const
{
MemoryOutputStream mo;
mo.setNewLineString ("\n");
mo.setNewLineString (getNewLineString());
mo << " dependencies {" << newLine;
@ -871,7 +873,7 @@ private:
String getApplyPlugins() const
{
MemoryOutputStream mo;
mo.setNewLineString ("\n");
mo.setNewLineString (getNewLineString());
if (areRemoteNotificationsEnabled())
mo << "apply plugin: 'com.google.gms.google-services'" << newLine;
@ -931,12 +933,12 @@ private:
addOptJavaFolderToSourceSetsForModule (javaSourceSets, modules, "juce_product_unlocking");
MemoryOutputStream mo;
mo.setNewLineString ("\n");
mo.setNewLineString (getNewLineString());
mo << " sourceSets {" << newLine;
mo << getSourceSetStringFor ("main.java.srcDirs", javaSourceSets);
mo << getSourceSetStringFor ("main.java.srcDirs", javaSourceSets, getNewLineString());
mo << newLine;
mo << getSourceSetStringFor ("main.res.srcDirs", resourceSets);
mo << getSourceSetStringFor ("main.res.srcDirs", resourceSets, getNewLineString());
mo << " }" << newLine;
return mo.toString();
@ -967,7 +969,7 @@ private:
return sourceSets;
}
static String getSourceSetStringFor (const String& type, const StringArray& srcDirs)
static String getSourceSetStringFor (const String& type, const StringArray& srcDirs, const String& newLineString)
{
String s;
@ -987,7 +989,7 @@ private:
s << "]" << newLine;
return replaceLineFeeds (s, "\n");
return replaceLineFeeds (s, newLineString);
}
//==============================================================================
@ -998,7 +1000,7 @@ private:
props << "ndk.dir=" << sanitisePath (getAppSettings().getStoredPath (Ids::androidNDKPath, TargetOS::getThisOS()).get().toString()) << newLine
<< "sdk.dir=" << sanitisePath (getAppSettings().getStoredPath (Ids::androidSDKPath, TargetOS::getThisOS()).get().toString()) << newLine;
return replaceLineFeeds (props, "\n");
return replaceLineFeeds (props, getNewLineString());
}
String getGradleWrapperPropertiesFileContent() const
@ -1302,7 +1304,7 @@ private:
build_tools::writeStreamToFile (file, [&] (MemoryOutputStream& mo)
{
mo.setNewLineString ("\n");
mo.setNewLineString (getNewLineString());
PNGImageFormat png;
@ -1355,7 +1357,7 @@ private:
if (projectItem.isGroup())
{
for (int i = 0; i < projectItem.getNumChildren(); ++i)
addCompileUnits (projectItem.getChild(i), mo, excludeFromBuild, extraCompilerFlags);
addCompileUnits (projectItem.getChild (i), mo, excludeFromBuild, extraCompilerFlags);
}
else if (projectItem.shouldBeAddedToTargetProject() && projectItem.shouldBeAddedToTargetExporter (*this))
{

View file

@ -97,6 +97,8 @@ public:
bool isOSX() const override { return false; }
bool isiOS() const override { return false; }
String getNewLineString() const override { return "\n"; }
bool supportsTargetType (build_tools::ProjectType::Target::Type) const override { return true; }
void addPlatformSpecificSettingsForProjectType (const build_tools::ProjectType&) override {}
@ -168,9 +170,9 @@ public:
void create (const OwnedArray<LibraryModule>&) const override
{
// We'll append to this later.
build_tools::writeStreamToFile (getTargetFolder().getChildFile ("CMakeLists.txt"), [] (MemoryOutputStream& mo)
build_tools::writeStreamToFile (getTargetFolder().getChildFile ("CMakeLists.txt"), [this] (MemoryOutputStream& mo)
{
mo.setNewLineString ("\n");
mo.setNewLineString (getNewLineString());
mo << "# Automatically generated CMakeLists, created by the Projucer" << newLine
<< "# Do not edit this file! Your changes will be overwritten when you re-save the Projucer project!" << newLine
@ -199,7 +201,7 @@ public:
getTargetFolder().getChildFile ("CMakeLists.txt").loadFileAsData (existingContent);
MemoryOutputStream out (existingContent, true);
out.setNewLineString ("\n");
out.setNewLineString (getNewLineString());
out << "###############################################################################" << newLine
<< "# " << exporter->getUniqueName() << newLine
@ -314,7 +316,8 @@ private:
{
auto path = build_tools::RelativePath (projectItem.getFile(), exporter.getTargetFolder(), build_tools::RelativePath::buildTargetFolder).toUnixStyle();
fileInfoList.push_back (std::make_tuple (path, projectItem.shouldBeCompiled(),
fileInfoList.push_back (std::make_tuple (path,
projectItem.shouldBeCompiled(),
exporter.compilerFlagSchemesMap[projectItem.getCompilerFlagSchemeString()].get().toString()));
}
}

View file

@ -98,6 +98,8 @@ public:
bool isOSX() const override { return false; }
bool isiOS() const override { return false; }
String getNewLineString() const override { return isWindows() ? "\r\n" : "\n"; }
bool supportsTargetType (build_tools::ProjectType::Target::Type type) const override
{
switch (type)

View file

@ -478,7 +478,7 @@ public:
}
{
auto* intdir = props->createNewChildElement("IntDir");
auto* intdir = props->createNewChildElement ("IntDir");
setConditionAttribute (*intdir, config);
auto intermediatesPath = getIntermediatesPath (config);
@ -556,7 +556,7 @@ public:
cl->createNewChildElement ("RuntimeLibrary")->addTextElement (config.isUsingRuntimeLibDLL() ? (isDebug ? "MultiThreadedDebugDLL" : "MultiThreadedDLL")
: (isDebug ? "MultiThreadedDebug" : "MultiThreaded"));
cl->createNewChildElement ("RuntimeTypeInfo")->addTextElement ("true");
cl->createNewChildElement ("PrecompiledHeader");
cl->createNewChildElement ("PrecompiledHeader")->addTextElement ("NotUsing");
cl->createNewChildElement ("AssemblerListingLocation")->addTextElement ("$(IntDir)\\");
cl->createNewChildElement ("ObjectFileName")->addTextElement ("$(IntDir)\\");
cl->createNewChildElement ("ProgramDataBaseFileName")->addTextElement ("$(IntDir)\\");
@ -698,6 +698,8 @@ public:
auto* cppFiles = projectXml.createNewChildElement ("ItemGroup");
auto* headerFiles = projectXml.createNewChildElement ("ItemGroup");
writePrecompiledHeaderFiles (*cppFiles);
for (int i = 0; i < getOwner().getAllGroups().size(); ++i)
{
auto& group = getOwner().getAllGroups().getReference (i);
@ -761,6 +763,59 @@ public:
}
//==============================================================================
static void setSourceFilePCHSettings (XmlElement& element, const File& pchFile, const String& option, const BuildConfiguration& config)
{
auto setConfigConditionAttribute = [&config] (XmlElement* elementToSet) -> XmlElement*
{
setConditionAttribute (*elementToSet, config);
return elementToSet;
};
setConfigConditionAttribute (element.createNewChildElement ("PrecompiledHeader"))->addTextElement (option);
setConfigConditionAttribute (element.createNewChildElement ("PrecompiledHeaderFile"))->addTextElement (pchFile.getFileName());
setConfigConditionAttribute (element.createNewChildElement ("PrecompiledHeaderOutputFile"))->addTextElement ("$(Platform)\\$(Configuration)\\JucePrecompiledHeader.pch");
setConfigConditionAttribute (element.createNewChildElement ("ForcedIncludeFiles"))->addTextElement (pchFile.getFileName());
}
void writePrecompiledHeaderFiles (XmlElement& cpps) const
{
for (ConstConfigIterator config (owner); config.next();)
{
if (config->shouldUsePrecompiledHeaderFile())
{
auto pchFileContent = config->getPrecompiledHeaderFileContent();
if (pchFileContent.isNotEmpty())
{
auto pchFile = owner.getTargetFolder().getChildFile (config->getPrecompiledHeaderFilename()).withFileExtension (".h");
build_tools::writeStreamToFile (pchFile, [&] (MemoryOutputStream& mo)
{
mo << pchFileContent;
});
auto pchSourceFile = pchFile.withFileExtension (".cpp");
build_tools::writeStreamToFile (pchSourceFile, [this] (MemoryOutputStream& mo)
{
mo.setNewLineString (owner.getNewLineString());
writeAutoGenWarningComment (mo);
mo << " This is an empty source file generated by JUCE required for Visual Studio PCH." << newLine
<< newLine
<< "*/" << newLine
<< newLine;
});
auto* pchSourceElement = cpps.createNewChildElement ("ClCompile");
pchSourceElement->setAttribute ("Include", prependDot (pchSourceFile.getFileName()));
setSourceFilePCHSettings (*pchSourceElement, pchFile, "Create", *config);
}
}
}
}
void addFilesToCompile (const Project::Item& projectItem, XmlElement& cpps, XmlElement& headers, XmlElement& otherFiles) const
{
auto targetType = (getOwner().getProject().isAudioPluginProject() ? type : SharedCodeTarget);
@ -791,6 +846,20 @@ public:
if (extraCompilerFlags.isNotEmpty())
e->createNewChildElement ("AdditionalOptions")->addTextElement (extraCompilerFlags + " %(AdditionalOptions)");
if (! projectItem.shouldSkipPCH())
{
for (ConstConfigIterator i (owner); i.next();)
{
if (i->shouldUsePrecompiledHeaderFile())
{
auto pchFile = owner.getTargetFolder().getChildFile (i->getPrecompiledHeaderFilename()).withFileExtension (".h");
if (pchFile.existsAsFile())
setSourceFilePCHSettings (*e, pchFile, "Use", *i);
}
}
}
}
else
{
@ -808,7 +877,7 @@ public:
}
}
void setConditionAttribute (XmlElement& xml, const BuildConfiguration& config) const
static void setConditionAttribute (XmlElement& xml, const BuildConfiguration& config)
{
auto& msvcConfig = dynamic_cast<const MSVCBuildConfiguration&> (config);
xml.setAttribute ("Condition", "'$(Configuration)|$(Platform)'=='" + msvcConfig.createMSVCConfigName() + "'");
@ -1314,22 +1383,26 @@ public:
};
//==============================================================================
bool usesMMFiles() const override { return false; }
bool canCopeWithDuplicateFiles() override { return false; }
bool supportsUserDefinedConfigurations() const override { return true; }
bool usesMMFiles() const override { return false; }
bool canCopeWithDuplicateFiles() override { return false; }
bool supportsUserDefinedConfigurations() const override { return true; }
bool isXcode() const override { return false; }
bool isVisualStudio() const override { return true; }
bool isCodeBlocks() const override { return false; }
bool isMakefile() const override { return false; }
bool isAndroidStudio() const override { return false; }
bool isCLion() const override { return false; }
bool isXcode() const override { return false; }
bool isVisualStudio() const override { return true; }
bool isCodeBlocks() const override { return false; }
bool isMakefile() const override { return false; }
bool isAndroidStudio() const override { return false; }
bool isCLion() const override { return false; }
bool isAndroid() const override { return false; }
bool isWindows() const override { return true; }
bool isLinux() const override { return false; }
bool isOSX() const override { return false; }
bool isiOS() const override { return false; }
bool isAndroid() const override { return false; }
bool isWindows() const override { return true; }
bool isLinux() const override { return false; }
bool isOSX() const override { return false; }
bool isiOS() const override { return false; }
bool supportsPrecompiledHeaders() const override { return true; }
String getNewLineString() const override { return "\r\n"; }
bool supportsTargetType (build_tools::ProjectType::Target::Type type) const override
{

View file

@ -255,7 +255,8 @@ public:
out << "OBJECTS_" + getTargetVarName() + String (" := \\") << newLine;
for (auto& f : filesToCompile)
out << " $(JUCE_OBJDIR)/" << escapeSpaces (owner.getObjectFileFor ({ f.first, owner.getTargetFolder(), build_tools::RelativePath::buildTargetFolder })) << " \\" << newLine;
out << " $(JUCE_OBJDIR)/" << escapeSpaces (owner.getObjectFileFor ({ f.first, owner.getTargetFolder(), build_tools::RelativePath::buildTargetFolder }))
<< " \\" << newLine;
out << newLine;
}
@ -274,7 +275,7 @@ public:
<< "\t@echo \"Compiling " << relativePath.getFileName() << "\"" << newLine
<< (relativePath.hasFileExtension ("c;s;S") ? "\t$(V_AT)$(CC) $(JUCE_CFLAGS) " : "\t$(V_AT)$(CXX) $(JUCE_CXXFLAGS) ")
<< "$(" << cppflagsVarName << ") $(" << cflagsVarName << ")"
<< (f.second.isNotEmpty() ? " $(" + owner.getCompilerFlagSchemeVariableName (f.second) + ")" : "") << " -o \"$@\" -c \"$<\"" << newLine
<< (f.second.isNotEmpty() ? " $(" + owner.getCompilerFlagSchemeVariableName (f.second) + ")" : "") << " -o \"$@\" -c \"$<\"" << newLine
<< newLine;
}
}
@ -415,6 +416,8 @@ public:
bool isOSX() const override { return false; }
bool isiOS() const override { return false; }
String getNewLineString() const override { return "\n"; }
bool supportsTargetType (build_tools::ProjectType::Target::Type type) const override
{
switch (type)
@ -474,7 +477,7 @@ public:
{
build_tools::writeStreamToFile (getTargetFolder().getChildFile ("Makefile"), [&] (MemoryOutputStream& mo)
{
mo.setNewLineString ("\n");
mo.setNewLineString (getNewLineString());
writeMakefile (mo);
});
@ -955,7 +958,9 @@ private:
writeCompilerFlagSchemes (out, filesToCompile);
auto getFilesForTarget = [] (const Array<std::pair<File, String>>& files, MakefileTarget* target, const Project& p) -> Array<std::pair<File, String>>
auto getFilesForTarget = [] (const Array<std::pair<File, String>>& files,
MakefileTarget* target,
const Project& p) -> Array<std::pair<File, String>>
{
Array<std::pair<File, String>> targetFiles;

View file

@ -295,6 +295,10 @@ public:
bool isOSX() const override { return ! iOS; }
bool isiOS() const override { return iOS; }
bool supportsPrecompiledHeaders() const override { return true; }
String getNewLineString() const override { return "\n"; }
bool supportsTargetType (build_tools::ProjectType::Target::Type type) const override
{
switch (type)
@ -1387,6 +1391,23 @@ public:
s.set ("GCC_OPTIMIZATION_LEVEL", config.getGCCOptimisationFlag());
if (config.shouldUsePrecompiledHeaderFile())
{
s.set ("GCC_PRECOMPILE_PREFIX_HEADER", "YES");
auto pchFileContent = config.getPrecompiledHeaderFileContent();
if (pchFileContent.isNotEmpty())
{
auto pchFilename = config.getPrecompiledHeaderFilename() + ".h";
build_tools::writeStreamToFile (owner.getTargetFolder().getChildFile (pchFilename),
[&] (MemoryOutputStream& mo) { mo << pchFileContent; });
s.set ("GCC_PREFIX_HEADER", pchFilename);
}
}
if (shouldCreatePList())
{
s.set ("INFOPLIST_FILE", infoPlistFile.getFileName());
@ -1975,8 +1996,7 @@ private:
writeDefaultLaunchStoryboardFile();
else if (getProject().getProjectFolder().getChildFile (customLaunchStoryboard).existsAsFile())
addLaunchStoryboardFileReference (build_tools::RelativePath (customLaunchStoryboard, build_tools::RelativePath::projectFolder)
.rebased (getProject().getProjectFolder(), getTargetFolder(), build_tools::RelativePath::buildTargetFolder)
.toUnixStyle());
.rebased (getProject().getProjectFolder(), getTargetFolder(), build_tools::RelativePath::buildTargetFolder));
}
}
else
@ -2053,7 +2073,7 @@ private:
build_tools::RelativePath menuNibPath (menuNibFile, getTargetFolder(), build_tools::RelativePath::buildTargetFolder);
addFileReference (menuNibPath.toUnixStyle());
resourceIDs.add (addBuildFile (menuNibPath, false, false));
resourceIDs.add (addBuildFile (FileOptions().withRelativePath (menuNibPath)));
resourceFileRefs.add (createFileRefID (menuNibPath));
}
@ -2063,7 +2083,7 @@ private:
{
build_tools::RelativePath iconPath (iconFile, getTargetFolder(), build_tools::RelativePath::buildTargetFolder);
addFileReference (iconPath.toUnixStyle());
resourceIDs.add (addBuildFile (iconPath, false, false));
resourceIDs.add (addBuildFile (FileOptions().withRelativePath (iconPath)));
resourceFileRefs.add (createFileRefID (iconPath));
}
}
@ -2216,7 +2236,8 @@ private:
auto path = scriptPath.toUnixStyle();
auto refID = addFileReference (path);
auto fileID = addBuildFile (path, refID, false, false);
auto fileID = addBuildFile (FileOptions().withPath (path)
.withFileRefID (refID));
resourceIDs.add (fileID);
resourceFileRefs.add (refID);
@ -2281,9 +2302,9 @@ private:
.getChildFile ("xcshareddata")
.getChildFile ("WorkspaceSettings.xcsettings");
build_tools::writeStreamToFile (settingsFile, [] (MemoryOutputStream& mo)
build_tools::writeStreamToFile (settingsFile, [this] (MemoryOutputStream& mo)
{
mo.setNewLineString ("\n");
mo.setNewLineString (getNewLineString());
mo << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << newLine
<< "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" << newLine
@ -2586,7 +2607,7 @@ private:
if (availableBuildProducts.empty())
continue;
auto subprojectFileType = getFileType (build_tools::RelativePath (subprojectFile.getFullPathName(), build_tools::RelativePath::buildTargetFolder));
auto subprojectFileType = getFileType (subprojectFile.getFullPathName());
auto subprojectFileID = addFileOrFolderReference (subprojectFile.getFullPathName(), "<group>", subprojectFileType);
subprojectFileIDs.add (subprojectFileID);
@ -2594,7 +2615,7 @@ private:
for (auto& buildProduct : availableBuildProducts)
{
auto buildProductFileType = getFileType (build_tools::RelativePath (buildProduct.second, build_tools::RelativePath::projectFolder));
auto buildProductFileType = getFileType (buildProduct.second);
auto containerID = addContainerItemProxy (subprojectFileID, buildProduct.first);
auto proxyID = addReferenceProxy (containerID, buildProduct.second, buildProductFileType);
@ -2602,7 +2623,9 @@ private:
if (buildProductFileType == "archive.ar" || buildProductFileType == "wrapper.framework")
{
auto buildFileID = addBuildFile (buildProduct.second, proxyID, false, true);
auto buildFileID = addBuildFile (FileOptions().withPath (buildProduct.second)
.withFileRefID (proxyID)
.withInhibitWarningsEnabled (true));
for (auto& target : targets)
target->frameworkIDs.add (buildFileID);
@ -2649,7 +2672,9 @@ private:
addFileOrFolderReference (folderPath, "<group>", fileType);
resourceIDs.add (addBuildFile (folderPath, fileRefID, false, false));
resourceIDs.add (addBuildFile (FileOptions().withPath (folderPath)
.withFileRefID (fileRefID)));
resourceFileRefs.add (createFileRefID (folderPath));
}
@ -2694,38 +2719,6 @@ private:
output << "\t};\n\trootObject = " << createID ("__root") << ";\n}\n";
}
String addBuildFile (const String& path, const String& fileRefID, bool addToSourceBuildPhase, bool inhibitWarnings,
XcodeTarget* xcodeTarget = nullptr, String compilerFlags = {}) const
{
auto fileID = createID (path + "buildref");
if (addToSourceBuildPhase)
{
if (xcodeTarget != nullptr)
xcodeTarget->sourceIDs.add (fileID);
else
sourceIDs.add (fileID);
}
auto* v = new ValueTree (fileID);
v->setProperty ("isa", "PBXBuildFile", nullptr);
v->setProperty ("fileRef", fileRefID, nullptr);
if (inhibitWarnings)
compilerFlags += " -w";
if (compilerFlags.isNotEmpty())
v->setProperty ("settings", "{ COMPILER_FLAGS = \"" + compilerFlags.trim() + "\"; }", nullptr);
pbxBuildFiles.add (v);
return fileID;
}
String addBuildFile (const build_tools::RelativePath& path, bool addToSourceBuildPhase, bool inhibitWarnings, XcodeTarget* xcodeTarget = nullptr) const
{
return addBuildFile (path.toUnixStyle(), createFileRefID (path), addToSourceBuildPhase, inhibitWarnings, xcodeTarget);
}
String addFileReference (String pathString) const
{
String sourceTree ("SOURCE_ROOT");
@ -2741,9 +2734,7 @@ private:
sourceTree = "<absolute>";
}
auto fileType = getFileType (path);
return addFileOrFolderReference (pathString, sourceTree, fileType);
return addFileOrFolderReference (pathString, sourceTree, getFileType (pathString));
}
void checkAndAddFileReference (std::unique_ptr<ValueTree> v) const
@ -2817,8 +2808,34 @@ public:
}
private:
static String getFileType (const build_tools::RelativePath& file)
struct FileOptions
{
FileOptions& withPath (const String& p) { path = p; return *this; }
FileOptions& withRelativePath (const build_tools::RelativePath& p) { path = p.toUnixStyle(); return *this; }
FileOptions& withFileRefID (const String& fid) { fileRefID = fid; return *this; }
FileOptions& withCompilerFlags (const String& f) { compilerFlags = f; return *this; }
FileOptions& withCompilationEnabled (bool e) { compile = e; return *this; }
FileOptions& withAddToBinaryResourcesEnabled (bool e) { addToBinaryResources = e; return *this; }
FileOptions& withAddToXcodeResourcesEnabled (bool e) { addToXcodeResources = e; return *this; }
FileOptions& withInhibitWarningsEnabled (bool e) { inhibitWarnings = e; return *this; }
FileOptions& withSkipPCHEnabled (bool e) { skipPCH = e; return *this; }
FileOptions& withXcodeTarget (XcodeTarget* t) { xcodeTarget = t; return *this; }
String path;
String fileRefID;
String compilerFlags;
bool compile = false;
bool addToBinaryResources = false;
bool addToXcodeResources = false;
bool inhibitWarnings = false;
bool skipPCH = false;
XcodeTarget* xcodeTarget = nullptr;
};
static String getFileType (const String& filePath)
{
auto file = File::createFileWithoutCheckingPath (filePath);
if (file.hasFileExtension (cppFileExtensions)) return "sourcecode.cpp.cpp";
if (file.hasFileExtension (".mm")) return "sourcecode.cpp.objcpp";
if (file.hasFileExtension (".m")) return "sourcecode.c.objc";
@ -2842,23 +2859,17 @@ private:
return "file" + file.getFileExtension();
}
String addFile (const build_tools::RelativePath& path, bool shouldBeCompiled, bool shouldBeAddedToBinaryResources,
bool shouldBeAddedToXcodeResources, bool inhibitWarnings, XcodeTarget* xcodeTarget, const String& compilerFlags) const
String addFile (const FileOptions& opts) const
{
auto pathAsString = path.toUnixStyle();
auto refID = addFileReference (path.toUnixStyle());
auto refID = addFileReference (opts.path);
if (shouldBeCompiled)
if (opts.compile || opts.addToXcodeResources)
{
addBuildFile (pathAsString, refID, true, inhibitWarnings, xcodeTarget, compilerFlags);
}
else if (! shouldBeAddedToBinaryResources || shouldBeAddedToXcodeResources)
{
auto fileType = getFileType (path);
auto fileID = addBuildFile (FileOptions (opts).withFileRefID (refID));
if (shouldBeAddedToXcodeResources)
if (opts.addToXcodeResources)
{
resourceIDs.add (addBuildFile (pathAsString, refID, false, false));
resourceIDs.add (fileID);
resourceFileRefs.add (refID);
}
}
@ -2866,16 +2877,50 @@ private:
return refID;
}
String addBuildFile (const FileOptions& opts) const
{
auto fileID = createID (opts.path + "buildref");
if (opts.compile)
{
if (opts.xcodeTarget != nullptr)
opts.xcodeTarget->sourceIDs.add (fileID);
else
sourceIDs.add (fileID);
}
auto* v = new ValueTree (fileID);
v->setProperty ("isa", "PBXBuildFile", nullptr);
v->setProperty ("fileRef", opts.fileRefID.isEmpty() ? createFileRefID (opts.path)
: opts.fileRefID,
nullptr);
auto compilerFlags = [&opts]
{
return (opts.compilerFlags
+ (opts.inhibitWarnings ? " -w" : String())
+ (opts.skipPCH ? " -D" + BuildConfiguration::getSkipPrecompiledHeaderDefine() : String())).trim();
}();
if (compilerFlags.isNotEmpty())
v->setProperty ("settings", "{ COMPILER_FLAGS = \"" + compilerFlags + "\"; }", nullptr);
pbxBuildFiles.add (v);
return fileID;
}
String addRezFile (const Project::Item& projectItem, const build_tools::RelativePath& path) const
{
auto pathAsString = path.toUnixStyle();
auto refID = addFileReference (path.toUnixStyle());
if (projectItem.isModuleCode())
{
if (auto* xcodeTarget = getTargetOfType (getProject().getTargetTypeFromFilePath (projectItem.getFile(), false)))
{
auto rezFileID = addBuildFile (pathAsString, refID, false, false, xcodeTarget);
auto rezFileID = addBuildFile (FileOptions().withRelativePath (path)
.withFileRefID (refID)
.withXcodeTarget (xcodeTarget));
xcodeTarget->rezFileIDs.add (rezFileID);
return refID;
@ -2907,7 +2952,7 @@ private:
build_tools::overwriteFileIfDifferentOrThrow (entitlementsFile, options.getEntitlementsFileContent());
build_tools::RelativePath entitlementsPath (entitlementsFile, getTargetFolder(), build_tools::RelativePath::buildTargetFolder);
addFile (entitlementsPath, false, false, false, false, nullptr, {});
addFile (FileOptions().withRelativePath (entitlementsPath));
}
String addProjectItem (const Project::Item& projectItem) const
@ -2951,12 +2996,14 @@ private:
if (projectItem.isModuleCode() && projectItem.shouldBeCompiled())
xcodeTarget = getTargetOfType (project.getTargetTypeFromFilePath (projectItem.getFile(), false));
return addFile (path, projectItem.shouldBeCompiled(),
projectItem.shouldBeAddedToBinaryResources(),
projectItem.shouldBeAddedToXcodeResources(),
projectItem.shouldInhibitWarnings(),
xcodeTarget,
compilerFlagSchemesMap[projectItem.getCompilerFlagSchemeString()].get());
return addFile (FileOptions().withRelativePath (path)
.withCompilerFlags (compilerFlagSchemesMap[projectItem.getCompilerFlagSchemeString()].get())
.withCompilationEnabled (projectItem.shouldBeCompiled())
.withAddToBinaryResourcesEnabled (projectItem.shouldBeAddedToBinaryResources())
.withAddToXcodeResourcesEnabled (projectItem.shouldBeAddedToXcodeResources())
.withInhibitWarningsEnabled (projectItem.shouldInhibitWarnings())
.withSkipPCHEnabled (isPCHEnabledForAnyConfigurations() && projectItem.shouldSkipPCH())
.withXcodeTarget (xcodeTarget));
}
return {};
@ -2978,7 +3025,8 @@ private:
addFileReference (((File::isAbsolutePath (frameworkName) || isRelativePath) ? "" : "${SDKROOT}/") + path);
frameworkFileIDs.add (fileRefID);
return addBuildFile (path, fileRefID, false, false);
return addBuildFile (FileOptions().withPath (path)
.withFileRefID (fileRefID));
}
String addCustomFramework (String frameworkPath) const
@ -2988,19 +3036,20 @@ private:
auto fileRefID = createFileRefID (frameworkPath);
auto fileType = getFileType (build_tools::RelativePath (frameworkPath, build_tools::RelativePath::projectFolder));
auto fileType = getFileType (frameworkPath);
addFileOrFolderReference (frameworkPath, "<group>", fileType);
frameworkFileIDs.add (fileRefID);
return addBuildFile (frameworkPath, fileRefID, false, false);
return addBuildFile (FileOptions().withPath (frameworkPath)
.withFileRefID (fileRefID));
}
String addEmbeddedFramework (const String& path) const
{
auto fileRefID = createFileRefID (path);
auto fileType = getFileType (build_tools::RelativePath (path, build_tools::RelativePath::projectFolder));
auto fileType = getFileType (path);
addFileOrFolderReference (path, "<group>", fileType);
auto fileID = createID (path + "buildref");
@ -3213,13 +3262,16 @@ private:
addLaunchStoryboardFileReference (build_tools::RelativePath (storyboardFile,
getTargetFolder(),
build_tools::RelativePath::buildTargetFolder).toUnixStyle());
build_tools::RelativePath::buildTargetFolder));
}
void addLaunchStoryboardFileReference (const String& relativePath) const
void addLaunchStoryboardFileReference (const build_tools::RelativePath& relativePath) const
{
auto refID = addFileReference (relativePath);
auto fileID = addBuildFile (relativePath, refID, false, false);
auto path = relativePath.toUnixStyle();
auto refID = addFileReference (path);
auto fileID = addBuildFile (FileOptions().withPath (path)
.withFileRefID (refID));
resourceIDs.add (fileID);
resourceFileRefs.add (refID);
@ -3231,7 +3283,7 @@ private:
getTargetFolder(),
project.getProjectFilenameRootString());
addFileReference (assetsPath.toUnixStyle());
resourceIDs.add (addBuildFile (assetsPath, false, false));
resourceIDs.add (addBuildFile (FileOptions().withRelativePath (assetsPath)));
resourceFileRefs.add (createFileRefID (assetsPath));
}
@ -3264,8 +3316,8 @@ private:
}
String createFileRefID (const build_tools::RelativePath& path) const { return createFileRefID (path.toUnixStyle()); }
String createFileRefID (const String& path) const { return createID ("__fileref_" + path); }
String getIDForGroup (const Project::Item& item) const { return createID (item.getID()); }
String createFileRefID (const String& path) const { return createID ("__fileref_" + path); }
String getIDForGroup (const Project::Item& item) const { return createID (item.getID()); }
bool shouldFileBeCompiledByDefault (const File& file) const override
{

View file

@ -845,17 +845,19 @@ bool ProjectExporter::ConstConfigIterator::next()
//==============================================================================
ProjectExporter::BuildConfiguration::BuildConfiguration (Project& p, const ValueTree& configNode, const ProjectExporter& e)
: config (configNode), project (p), exporter (e),
isDebugValue (config, Ids::isDebug, getUndoManager(), getValue (Ids::isDebug)),
configNameValue (config, Ids::name, getUndoManager(), "Build Configuration"),
targetNameValue (config, Ids::targetName, getUndoManager(), project.getProjectFilenameRootString()),
targetBinaryPathValue (config, Ids::binaryPath, getUndoManager()),
recommendedWarningsValue (config, Ids::recommendedWarnings, getUndoManager()),
optimisationLevelValue (config, Ids::optimisation, getUndoManager()),
linkTimeOptimisationValue (config, Ids::linkTimeOptimisation, getUndoManager(), ! isDebug()),
ppDefinesValue (config, Ids::defines, getUndoManager()),
headerSearchPathValue (config, Ids::headerPath, getUndoManager()),
librarySearchPathValue (config, Ids::libraryPath, getUndoManager()),
userNotesValue (config, Ids::userNotes, getUndoManager())
isDebugValue (config, Ids::isDebug, getUndoManager(), getValue (Ids::isDebug)),
configNameValue (config, Ids::name, getUndoManager(), "Build Configuration"),
targetNameValue (config, Ids::targetName, getUndoManager(), project.getProjectFilenameRootString()),
targetBinaryPathValue (config, Ids::binaryPath, getUndoManager()),
recommendedWarningsValue (config, Ids::recommendedWarnings, getUndoManager()),
optimisationLevelValue (config, Ids::optimisation, getUndoManager()),
linkTimeOptimisationValue (config, Ids::linkTimeOptimisation, getUndoManager(), ! isDebug()),
ppDefinesValue (config, Ids::defines, getUndoManager()),
headerSearchPathValue (config, Ids::headerPath, getUndoManager()),
librarySearchPathValue (config, Ids::libraryPath, getUndoManager()),
userNotesValue (config, Ids::userNotes, getUndoManager()),
usePrecompiledHeaderFileValue (config, Ids::usePrecompiledHeaderFile, getUndoManager(), false),
precompiledHeaderFileValue (config, Ids::precompiledHeaderFile, getUndoManager())
{
recommendedCompilerWarningFlags["LLVM"] = { "-Wall", "-Wshadow-all", "-Wshorten-64-to-32", "-Wstrict-aliasing", "-Wuninitialized", "-Wunused-parameter",
"-Wconversion", "-Wsign-compare", "-Wint-conversion", "-Wconditional-uninitialized", "-Woverloaded-virtual",
@ -960,6 +962,22 @@ void ProjectExporter::BuildConfiguration::createPropertyEditors (PropertyListBui
props.add (new ChoicePropertyComponent (linkTimeOptimisationValue, "Link-Time Optimisation"),
"Enable this to perform link-time code optimisation. This is recommended for release builds.");
if (exporter.supportsPrecompiledHeaders())
{
props.add (new ChoicePropertyComponent (usePrecompiledHeaderFileValue, "Use Precompiled Header"),
"Enable this to turn on precompiled header support for this configuration. Use the setting "
"below to specify the header file to use.");
auto quotedHeaderFileName = (getPrecompiledHeaderFilename() + ".h").quoted();
props.add (new FilePathPropertyComponentWithEnablement (precompiledHeaderFileValue, usePrecompiledHeaderFileValue,
"Precompiled Header File", false, true, "*", project.getProjectFolder()),
"Specify an input header file that will be used to generate a file named " + quotedHeaderFileName + " which is used to generate the "
"PCH file artifact for this exporter configuration. This file can be an absolute path, or relative to the jucer project folder. "
"The " + quotedHeaderFileName + " file will be force included to all source files unless the \"Skip PCH\" setting has been enabled. "
"The generated header will be written on project save and placed in the target folder for this exporter.");
}
createConfigProperties (props);
props.add (new TextPropertyComponent (userNotesValue, "Notes", 32768, true),
@ -1010,6 +1028,31 @@ StringArray ProjectExporter::BuildConfiguration::getLibrarySearchPaths() const
return s;
}
String ProjectExporter::BuildConfiguration::getPrecompiledHeaderFileContent() const
{
if (shouldUsePrecompiledHeaderFile())
{
auto f = project.getProjectFolder().getChildFile (precompiledHeaderFileValue.get().toString());
if (f.existsAsFile() && f.hasFileExtension (headerFileExtensions))
{
MemoryOutputStream content;
content.setNewLineString (exporter.getNewLineString());
writeAutoGenWarningComment (content);
content << "*/" << newLine << newLine
<< "#ifndef " << getSkipPrecompiledHeaderDefine() << newLine << newLine
<< f.loadFileAsString() << newLine
<< "#endif" << newLine;
return content.toString();
}
}
return {};
}
String ProjectExporter::getExternalLibraryFlags (const BuildConfiguration& config) const
{
auto libraries = StringArray::fromTokens (getExternalLibrariesString(), ";\n", "\"'");

View file

@ -87,7 +87,10 @@ public:
virtual bool isOSX() const = 0;
virtual bool isiOS() const = 0;
virtual String getDescription() { return {}; }
virtual String getNewLineString() const = 0;
virtual String getDescription() { return {}; }
virtual bool supportsPrecompiledHeaders() const { return false; }
//==============================================================================
// cross-platform audio plug-ins supported by exporter
@ -246,7 +249,12 @@ public:
String getLibrarySearchPathString() const { return librarySearchPathValue.get(); }
StringArray getLibrarySearchPaths() const;
String getGCCLibraryPathFlags() const;
String getPrecompiledHeaderFilename() const { return "JucePrecompiledHeader_" + getName(); }
static String getSkipPrecompiledHeaderDefine() { return "JUCE_SKIP_PRECOMPILED_HEADER"; }
bool shouldUsePrecompiledHeaderFile() const { return usePrecompiledHeaderFileValue.get(); }
String getPrecompiledHeaderFileContent() const;
//==============================================================================
Value getValue (const Identifier& nm) { return config.getPropertyAsValue (nm, getUndoManager()); }
@ -267,7 +275,8 @@ public:
protected:
ValueWithDefault isDebugValue, configNameValue, targetNameValue, targetBinaryPathValue, recommendedWarningsValue, optimisationLevelValue,
linkTimeOptimisationValue, ppDefinesValue, headerSearchPathValue, librarySearchPathValue, userNotesValue;
linkTimeOptimisationValue, ppDefinesValue, headerSearchPathValue, librarySearchPathValue, userNotesValue,
usePrecompiledHeaderFileValue, precompiledHeaderFileValue;
private:
std::map<String, StringArray> recommendedCompilerWarningFlags;
@ -349,6 +358,16 @@ public:
gccOfast = 6
};
bool isPCHEnabledForAnyConfigurations() const
{
if (supportsPrecompiledHeaders())
for (ConstConfigIterator config (*this); config.next();)
if (config->shouldUsePrecompiledHeaderFile())
return true;
return false;
}
protected:
//==============================================================================
String name;

View file

@ -313,14 +313,6 @@ Result ProjectSaver::saveProject (ProjectExporter* specifiedExporterToSave)
}
//==============================================================================
static void writeAutoGenWarningComment (OutputStream& out)
{
out << "/*" << newLine << newLine
<< " IMPORTANT! This file is auto-generated each time you save your" << newLine
<< " project - if you alter its contents, your changes may be overwritten!" << newLine
<< newLine;
}
void ProjectSaver::writePluginDefines (MemoryOutputStream& out) const
{
const auto pluginDefines = getAudioPluginDefines();
@ -329,6 +321,7 @@ void ProjectSaver::writePluginDefines (MemoryOutputStream& out) const
return;
writeAutoGenWarningComment (out);
out << "*/" << newLine << newLine
<< "#pragma once" << newLine << newLine
<< pluginDefines << newLine;

View file

@ -248,6 +248,15 @@ bool fileNeedsCppSyntaxHighlighting (const File& file)
&& String (fileStart).trimStart().startsWith ("// -*- C++ -*-");
}
//==============================================================================
void writeAutoGenWarningComment (OutputStream& outStream)
{
outStream << "/*" << newLine << newLine
<< " IMPORTANT! This file is auto-generated each time you save your" << newLine
<< " project - if you alter its contents, your changes may be overwritten!" << newLine
<< newLine;
}
//==============================================================================
StringArray getJUCEModules() noexcept
{

View file

@ -54,6 +54,8 @@ void setValueIfVoid (Value value, const var& defaultValue);
bool fileNeedsCppSyntaxHighlighting (const File& file);
void writeAutoGenWarningComment (OutputStream& outStream);
StringArray getJUCEModules() noexcept;
bool isJUCEModule (const String& moduleID) noexcept;

View file

@ -49,6 +49,8 @@ namespace Ids
DECLARE_ID (companyEmail);
DECLARE_ID (useAppConfig);
DECLARE_ID (addUsingNamespaceToJuceHeader);
DECLARE_ID (usePrecompiledHeaderFile);
DECLARE_ID (precompiledHeaderFile);
DECLARE_ID (displaySplashScreen);
DECLARE_ID (splashScreenColour);
DECLARE_ID (position);
@ -160,6 +162,7 @@ namespace Ids
DECLARE_ID (aaxFolder);
DECLARE_ID (compile);
DECLARE_ID (noWarnings);
DECLARE_ID (skipPCH);
DECLARE_ID (resource);
DECLARE_ID (xcodeResource);
DECLARE_ID (xcodeValidArchs);

View file

@ -34,7 +34,7 @@
*/
class FilePathPropertyComponent : public PropertyComponent,
public FileDragAndDropTarget,
private Value::Listener
protected Value::Listener
{
public:
FilePathPropertyComponent (Value valueToControl, const String& propertyName, bool isDir, bool thisOS = true,
@ -92,6 +92,12 @@ public:
repaint();
}
protected:
void valueChanged (Value&) override
{
updateEditorColour();
}
private:
//==============================================================================
void init()
@ -165,11 +171,6 @@ private:
}
}
void valueChanged (Value&) override
{
updateEditorColour();
}
void lookAndFeelChanged() override
{
browseButton.setColour (TextButton::buttonColourId, findColour (secondaryButtonBackgroundColourId));
@ -191,3 +192,40 @@ private:
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilePathPropertyComponent)
};
//==============================================================================
class FilePathPropertyComponentWithEnablement : public FilePathPropertyComponent
{
public:
FilePathPropertyComponentWithEnablement (ValueWithDefault& valueToControl,
ValueWithDefault valueToListenTo,
const String& propertyName,
bool isDir,
bool thisOS = true,
const String& wildcardsToUse = "*",
const File& relativeRoot = File())
: FilePathPropertyComponent (valueToControl,
propertyName,
isDir,
thisOS,
wildcardsToUse,
relativeRoot),
valueWithDefault (valueToListenTo),
value (valueToListenTo.getPropertyAsValue())
{
value.addListener (this);
valueChanged (value);
}
~FilePathPropertyComponentWithEnablement() override { value.removeListener (this); }
private:
void valueChanged (Value& v) override
{
FilePathPropertyComponent::valueChanged (v);
setEnabled (valueWithDefault.get());
}
ValueWithDefault valueWithDefault;
Value value;
};