diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h index 62d2fb86eb..007b6fef96 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h @@ -407,13 +407,6 @@ private: mo << ")" << newLine << newLine; } - auto cfgExtraLinkerFlags = getExtraLinkerFlagsString(); - if (cfgExtraLinkerFlags.isNotEmpty()) - { - mo << "set( JUCE_LDFLAGS \"" << cfgExtraLinkerFlags.replace ("\"", "\\\"") << "\")" << newLine; - mo << "set( CMAKE_SHARED_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} ${JUCE_LDFLAGS}\")" << newLine << newLine; - } - mo << "enable_language(ASM)" << newLine << newLine; const auto userLibraries = getUserLibraries(); @@ -457,6 +450,14 @@ private: if (cfgDefines.size() > 0) mo << " add_definitions(" << getEscapedPreprocessorDefs (cfgDefines).joinIntoString (" ") << ")" << newLine; + const auto cfgExtraLinkerFlags = cfg.getAllLinkerFlagsString(); + + if (cfgExtraLinkerFlags.isNotEmpty()) + { + mo << " set( JUCE_LDFLAGS \"" << cfgExtraLinkerFlags.replace ("\"", "\\\"") << "\" )" << newLine + << " set( CMAKE_SHARED_LINKER_FLAGS \"${CMAKE_SHARED_LINKER_FLAGS} ${JUCE_LDFLAGS}\" )" << newLine << newLine; + } + writeCmakePathLines (mo, " ", "include_directories( AFTER", cfgHeaderPaths); if (userLibraries.size() > 0) @@ -537,26 +538,27 @@ private: mo << newLine; } - auto flags = getProjectCompilerFlags(); - - if (flags.size() > 0) - mo << "target_compile_options( ${BINARY_NAME} PRIVATE " << flags.joinIntoString (" ") << " )" << newLine << newLine; - for (ConstConfigIterator config (*this); config.next();) { auto& cfg = dynamic_cast (*config); - mo << "if( JUCE_BUILD_CONFIGURATION MATCHES \"" << cfg.getProductFlavourCMakeIdentifier() << "\" )" << newLine; - mo << " target_compile_options( ${BINARY_NAME} PRIVATE"; + mo << "if( JUCE_BUILD_CONFIGURATION MATCHES \"" << cfg.getProductFlavourCMakeIdentifier() << "\" )" << newLine + << " target_compile_options( ${BINARY_NAME} PRIVATE"; - auto recommendedFlags = cfg.getRecommendedCompilerWarningFlags(); + const auto recommendedFlags = cfg.getRecommendedCompilerWarningFlags(); for (auto& recommendedFlagsType : { recommendedFlags.common, recommendedFlags.cpp }) for (auto& flag : recommendedFlagsType) mo << " " << flag; - mo << ")" << newLine; - mo << "endif()" << newLine << newLine; + const auto flags = getConfigCompilerFlags (cfg); + + if (! flags.isEmpty()) + mo << " " << flags.joinIntoString (" "); + + mo << " )" << newLine + << "endif()" << newLine + << newLine; } auto libraries = getAndroidLibraries(); @@ -1371,8 +1373,10 @@ private: } //============================================================================== - void addCompileUnits (const Project::Item& projectItem, MemoryOutputStream& mo, - Array& excludeFromBuild, Array>& extraCompilerFlags) const + void addCompileUnits (const Project::Item& projectItem, + MemoryOutputStream& mo, + Array& excludeFromBuild, + Array>& extraCompilerFlags) const { if (projectItem.isGroup()) { @@ -1405,7 +1409,8 @@ private: } } - void addCompileUnits (MemoryOutputStream& mo, Array& excludeFromBuild, + void addCompileUnits (MemoryOutputStream& mo, + Array& excludeFromBuild, Array>& extraCompilerFlags) const { for (int i = 0; i < getAllGroups().size(); ++i) @@ -1452,10 +1457,10 @@ private: return cFlags; } - StringArray getProjectCompilerFlags() const + StringArray getConfigCompilerFlags (const BuildConfiguration& config) const { auto cFlags = getAndroidCompilerFlags(); - cFlags.addArray (getEscapedFlags (StringArray::fromTokens (getExtraCompilerFlagsString(), true))); + cFlags.addArray (getEscapedFlags (StringArray::fromTokens (config.getAllCompilerFlagsString(), true))); return cFlags; } diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CodeBlocks.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CodeBlocks.h index f8359fb2ab..08e698ea34 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CodeBlocks.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CodeBlocks.h @@ -404,7 +404,7 @@ private: if (config.isDebug()) flags.add ("-g"); - flags.addTokens (replacePreprocessorTokens (config, getExtraCompilerFlagsString()).trim(), + flags.addTokens (replacePreprocessorTokens (config, config.getAllCompilerFlagsString()).trim(), " \n", "\"'"); if (config.exporter.isLinux()) @@ -445,7 +445,7 @@ private: if (config.isLinkTimeOptimisationEnabled()) flags.add ("-flto"); - flags.addTokens (replacePreprocessorTokens (config, getExtraLinkerFlagsString()).trim(), " \n", "\"'"); + flags.addTokens (replacePreprocessorTokens (config, config.getAllLinkerFlagsString()).trim(), " \n", "\"'"); if (config.exporter.isLinux()) { diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h index a5d8370f28..d79e82f2ec 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h @@ -625,7 +625,8 @@ public: if (config.isFastMathEnabled()) cl->createNewChildElement ("FloatingPointModel")->addTextElement ("Fast"); - auto extraFlags = getOwner().replacePreprocessorTokens (config, getOwner().getExtraCompilerFlagsString()).trim(); + auto extraFlags = getOwner().replacePreprocessorTokens (config, config.getAllCompilerFlagsString()).trim(); + if (extraFlags.isNotEmpty()) cl->createNewChildElement ("AdditionalOptions")->addTextElement (extraFlags + " %(AdditionalOptions)"); @@ -684,7 +685,7 @@ public: if (additionalDependencies.isNotEmpty()) link->createNewChildElement ("AdditionalDependencies")->addTextElement (additionalDependencies); - auto extraLinkerOptions = getOwner().getExtraLinkerFlagsString(); + auto extraLinkerOptions = config.getAllLinkerFlagsString(); if (extraLinkerOptions.isNotEmpty()) link->createNewChildElement ("AdditionalOptions")->addTextElement (getOwner().replacePreprocessorTokens (config, extraLinkerOptions).trim() + " %(AdditionalOptions)"); diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Make.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Make.h index 6225e144b0..a685f872ee 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Make.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Make.h @@ -646,7 +646,7 @@ private: for (auto& recommended : config.getRecommendedCompilerWarningFlags().common) result.add (recommended); - auto extra = replacePreprocessorTokens (config, getExtraCompilerFlagsString()).trim(); + auto extra = replacePreprocessorTokens (config, config.getAllCompilerFlagsString()).trim(); if (extra.isNotEmpty()) result.add (extra); @@ -717,7 +717,7 @@ private: if (config.isLinkTimeOptimisationEnabled()) result.add ("-flto"); - auto extraFlags = getExtraLinkerFlagsString().trim(); + const auto extraFlags = config.getAllLinkerFlagsString().trim(); if (extraFlags.isNotEmpty()) result.add (replacePreprocessorTokens (config, extraFlags)); diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h index 98e5588b95..c12a24d683 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h @@ -1614,9 +1614,10 @@ public: for (const auto& xcodeFlags : { XcodeWarningFlags { recommendedWarnings.common, "OTHER_CFLAGS" }, XcodeWarningFlags { recommendedWarnings.cpp, "OTHER_CPLUSPLUSFLAGS" } }) { - auto flags = (xcodeFlags.flags.joinIntoString (" ") - + " " + owner.getExtraCompilerFlagsString()).trim(); - flags = owner.replacePreprocessorTokens (config, flags); + const auto flags = owner.replacePreprocessorTokens (config, + (xcodeFlags.flags.joinIntoString (" ") + + " " + + config.getAllCompilerFlagsString()).trim()); if (flags.isNotEmpty()) s.set (xcodeFlags.variable, flags.quoted()); @@ -1854,7 +1855,7 @@ public: flags.add (getLinkerFlagForLib (l)); } - flags.add (owner.replacePreprocessorTokens (config, owner.getExtraLinkerFlagsString())); + flags.add (owner.replacePreprocessorTokens (config, config.getAllLinkerFlagsString())); flags = getCleanedStringArray (flags); } diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp index a1e08a5ed3..423072ce20 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp @@ -894,33 +894,22 @@ ProjectExporter::BuildConfiguration::BuildConfiguration (Project& p, const Value librarySearchPathValue (config, Ids::libraryPath, getUndoManager()), userNotesValue (config, Ids::userNotes, getUndoManager()), usePrecompiledHeaderFileValue (config, Ids::usePrecompiledHeaderFile, getUndoManager(), false), - precompiledHeaderFileValue (config, Ids::precompiledHeaderFile, getUndoManager()) + precompiledHeaderFileValue (config, Ids::precompiledHeaderFile, getUndoManager()), + configCompilerFlagsValue (config, Ids::extraCompilerFlags, getUndoManager()), + configLinkerFlagsValue (config, Ids::extraLinkerFlags, getUndoManager()) { auto& llvmFlags = recommendedCompilerWarningFlags[CompilerNames::llvm] = BuildConfiguration::CompilerWarningFlags::getRecommendedForGCCAndLLVM(); - llvmFlags.common.addArray ({ - "-Wshorten-64-to-32", "-Wconversion", "-Wint-conversion", - "-Wconditional-uninitialized", "-Wconstant-conversion", "-Wbool-conversion", - "-Wextra-semi", "-Wshift-sign-overflow", - "-Wshadow-all", "-Wnullable-to-nonnull-conversion", - "-Wmissing-prototypes" - }); - llvmFlags.cpp.addArray ({ - "-Wunused-private-field", "-Winconsistent-missing-destructor-override" - }); - llvmFlags.objc.addArray ({ - "-Wunguarded-availability", "-Wunguarded-availability-new" - }); + llvmFlags.common.addArray ({ "-Wshorten-64-to-32", "-Wconversion", "-Wint-conversion", + "-Wconditional-uninitialized", "-Wconstant-conversion", "-Wbool-conversion", + "-Wextra-semi", "-Wshift-sign-overflow", + "-Wshadow-all", "-Wnullable-to-nonnull-conversion", + "-Wmissing-prototypes" }); + llvmFlags.cpp.addArray ({ "-Wunused-private-field", "-Winconsistent-missing-destructor-override" }); + llvmFlags.objc.addArray ({ "-Wunguarded-availability", "-Wunguarded-availability-new" }); auto& gccFlags = recommendedCompilerWarningFlags[CompilerNames::gcc] = BuildConfiguration::CompilerWarningFlags::getRecommendedForGCCAndLLVM(); - gccFlags.common.addArray ({ - "-Wextra", "-Wsign-compare", "-Wno-implicit-fallthrough", "-Wno-maybe-uninitialized", - "-Wredundant-decls", "-Wno-strict-overflow", - "-Wshadow" - }); -} - -ProjectExporter::BuildConfiguration::~BuildConfiguration() -{ + gccFlags.common.addArray ({ "-Wextra", "-Wsign-compare", "-Wno-implicit-fallthrough", "-Wno-maybe-uninitialized", + "-Wredundant-decls", "-Wno-strict-overflow", "-Wshadow" }); } String ProjectExporter::BuildConfiguration::getGCCOptimisationFlag() const @@ -1007,6 +996,12 @@ void ProjectExporter::BuildConfiguration::createPropertyEditors (PropertyListBui "Extra preprocessor definitions. Use the form \"NAME1=value NAME2=value\", using whitespace, commas, or " "new-lines to separate the items - to include a space or comma in a definition, precede it with a backslash."); + props.add (new TextPropertyComponent (configCompilerFlagsValue, "Configuration-specific Compiler Flags", 8192, true), + "Compiler flags that are only to be used in this configuration."); + + props.add (new TextPropertyComponent (configLinkerFlagsValue, "Configuration-specific Linker Flags", 8192, true), + "Linker flags that are only to be used in this configuration."); + props.add (new ChoicePropertyComponent (linkTimeOptimisationValue, "Link-Time Optimisation"), "Enable this to perform link-time code optimisation. This is recommended for release builds."); diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.h index a29ef6d436..0a2084f046 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.h @@ -37,7 +37,6 @@ class ProjectExporter : private Value::Listener { public: ProjectExporter (Project&, const ValueTree& settings); - virtual ~ProjectExporter() override = default; //============================================================================== struct ExporterTypeInfo @@ -140,9 +139,6 @@ public: Value getTargetLocationValue() { return targetLocationValue.getPropertyAsValue(); } String getTargetLocationString() const { return targetLocationValue.get(); } - String getExtraCompilerFlagsString() const { return extraCompilerFlagsValue.get().toString().replaceCharacters ("\r\n", " "); } - String getExtraLinkerFlagsString() const { return extraLinkerFlagsValue.get().toString().replaceCharacters ("\r\n", " "); } - StringArray getExternalLibrariesStringArray() const { return getSearchPathsFromString (externalLibrariesValue.get().toString()); } String getExternalLibrariesString() const { return getExternalLibrariesStringArray().joinIntoString (";"); } @@ -228,7 +224,6 @@ public: { public: BuildConfiguration (Project& project, const ValueTree& configNode, const ProjectExporter&); - ~BuildConfiguration(); using Ptr = ReferenceCountedObjectPtr; @@ -267,6 +262,9 @@ public: bool shouldUsePrecompiledHeaderFile() const { return usePrecompiledHeaderFileValue.get(); } String getPrecompiledHeaderFileContent() const; + String getAllCompilerFlagsString() const { return (exporter.extraCompilerFlagsValue.get().toString() + " " + configCompilerFlagsValue.get().toString()).replaceCharacters ("\r\n", " ").trim(); } + String getAllLinkerFlagsString() const { return (exporter.extraLinkerFlagsValue .get().toString() + " " + configLinkerFlagsValue .get().toString()).replaceCharacters ("\r\n", " ").trim(); } + //============================================================================== Value getValue (const Identifier& nm) { return config.getPropertyAsValue (nm, getUndoManager()); } UndoManager* getUndoManager() const { return project.getUndoManagerFor (config); } @@ -311,7 +309,7 @@ public: protected: ValueTreePropertyWithDefault isDebugValue, configNameValue, targetNameValue, targetBinaryPathValue, recommendedWarningsValue, optimisationLevelValue, linkTimeOptimisationValue, ppDefinesValue, headerSearchPathValue, librarySearchPathValue, userNotesValue, - usePrecompiledHeaderFileValue, precompiledHeaderFileValue; + usePrecompiledHeaderFileValue, precompiledHeaderFileValue, configCompilerFlagsValue, configLinkerFlagsValue; private: std::map recommendedCompilerWarningFlags;