diff --git a/extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h b/extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h index eb88708d0a..8ea1d70004 100644 --- a/extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h +++ b/extras/Projucer/Source/Project Saving/jucer_ProjectExport_MSVC.h @@ -38,6 +38,99 @@ public: initialiseDependencyPathValues(); } + virtual int getVisualStudioVersion() const = 0; + + virtual String getSolutionComment() const = 0; + virtual String getToolsVersion() const = 0; + virtual String getDefaultToolset() const = 0; + virtual String getDefaultWindowsTargetPlatformVersion() const = 0; + + //============================================================================== + Value getIPPLibraryValue() { return getSetting (Ids::IPPLibrary); } + String getIPPLibrary() const { return settings [Ids::IPPLibrary]; } + + Value getPlatformToolsetValue() { return getSetting (Ids::toolset); } + String getPlatformToolset() const + { + const String s (settings [Ids::toolset].toString()); + return s.isNotEmpty() ? s : getDefaultToolset(); + } + + Value getWindowsTargetPlatformVersionValue() { return getSetting (Ids::windowsTargetPlatformVersion); } + String getWindowsTargetPlatformVersion() const + { + String targetPlatform = settings [Ids::windowsTargetPlatformVersion]; + return (targetPlatform.isNotEmpty() ? targetPlatform : getDefaultWindowsTargetPlatformVersion()); + } + + Value getCppStandardValue() { return getSetting (Ids::cppLanguageStandard); } + String getCppLanguageStandard() const { return settings [Ids::cppLanguageStandard]; } + + //============================================================================== + void addToolsetProperty (PropertyListBuilder& props, const char** names, const var* values, int num) + { + props.add (new ChoicePropertyComponent (getPlatformToolsetValue(), "Platform Toolset", + StringArray (names, num), Array (values, num))); + } + + void addIPPLibraryProperty (PropertyListBuilder& props) + { + static const char* ippOptions[] = { "No", "Yes (Default Mode)", "Multi-Threaded Static Library", "Single-Threaded Static Library", "Multi-Threaded DLL", "Single-Threaded DLL" }; + static const var ippValues[] = { var(), "true", "Parallel_Static", "Sequential", "Parallel_Dynamic", "Sequential_Dynamic" }; + + props.add (new ChoicePropertyComponent (getIPPLibraryValue(), "Use IPP Library", + StringArray (ippOptions, numElementsInArray (ippValues)), + Array (ippValues, numElementsInArray (ippValues)))); + } + + void addCppStandardProperty (PropertyListBuilder& props, const char** names, const var* values, int num) + { + props.add (new ChoicePropertyComponent (getCppStandardValue(), "C++ standard to use", + StringArray (names, num), Array (values, num))); + } + + void addPlatformToolsetToPropertyGroup (XmlElement& p) const + { + forEachXmlChildElementWithTagName (p, e, "PropertyGroup") + e->createNewChildElement ("PlatformToolset")->addTextElement (getPlatformToolset()); + } + + void addWindowsTargetPlatformVersionToPropertyGroup (XmlElement& p) const + { + const String& targetVersion = getWindowsTargetPlatformVersion(); + + if (targetVersion.isNotEmpty()) + forEachXmlChildElementWithTagName (p, e, "PropertyGroup") + e->createNewChildElement ("WindowsTargetPlatformVersion")->addTextElement (getWindowsTargetPlatformVersion()); + } + + void addWindowsTargetPlatformProperties (PropertyListBuilder& props) + { + static const char* targetPlatformNames[] = { "(default)", "8.1", "10.0.10240.0", "10.0.10586.0", "10.0.14393.0", "10.0.15063.0", nullptr }; + const var targetPlatforms[] = { var(), "8.1", "10.0.10240.0", "10.0.10586.0", "10.0.14393.0", "10.0.15063.0" }; + + props.add (new ChoicePropertyComponent (getWindowsTargetPlatformVersionValue(), "Windows Target Platform", + StringArray (targetPlatformNames), Array (targetPlatforms, numElementsInArray (targetPlatforms))), + "Specifies the version of the Windows SDK that will be used when building this project. " + "The default value for this exporter is " + getDefaultWindowsTargetPlatformVersion()); + } + + void create (const OwnedArray&) const override + { + createResourcesAndIcon(); + + for (int i = 0; i < targets.size(); ++i) + if (MSVCTargetBase* target = targets[i]) + target->writeProjectFile(); + + { + MemoryOutputStream mo; + writeSolutionFile (mo, "11.00", getSolutionComment()); + + overwriteFileIfDifferentOrThrow (getSLNFile(), mo); + } + } + //============================================================================== class MSVCBuildConfiguration : public BuildConfiguration { @@ -616,8 +709,6 @@ public: //============================================================================== const String& getProjectName() const { return projectName; } - virtual int getVisualStudioVersion() const = 0; - bool launchProject() override { #if JUCE_WINDOWS @@ -1094,789 +1185,23 @@ protected: }; //============================================================================== -class MSVCProjectExporterVC2010 : public MSVCProjectExporterBase -{ -public: - MSVCProjectExporterVC2010 (Project& p, const ValueTree& t, const char* folderName = "VisualStudio2010") - : MSVCProjectExporterBase (p, t, folderName) - { - name = getName(); - } - - //============================================================================== - class MSVC2010Target : public MSVCTargetBase - { - public: - MSVC2010Target (ProjectType::Target::Type targetType, const MSVCProjectExporterVC2010& exporter) - : MSVCTargetBase (targetType, exporter) - {} - - const MSVCProjectExporterVC2010& getOwner() const { return dynamic_cast (owner); } - String getProjectVersionString() const override { return "10.00"; } - String getProjectFileSuffix() const override { return ".vcxproj"; } - String getFiltersFileSuffix() const override { return ".vcxproj.filters"; } - String getTopLevelXmlEntity() const override { return "Project"; } - - //============================================================================== - void fillInProjectXml (XmlElement& projectXml) const override - { - projectXml.setAttribute ("DefaultTargets", "Build"); - projectXml.setAttribute ("ToolsVersion", getOwner().getToolsVersion()); - projectXml.setAttribute ("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"); - - { - XmlElement* configsGroup = projectXml.createNewChildElement ("ItemGroup"); - configsGroup->setAttribute ("Label", "ProjectConfigurations"); - - for (ConstConfigIterator i (owner); i.next();) - { - const MSVCBuildConfiguration& config = dynamic_cast (*i); - XmlElement* e = configsGroup->createNewChildElement ("ProjectConfiguration"); - e->setAttribute ("Include", config.createMSVCConfigName()); - e->createNewChildElement ("Configuration")->addTextElement (config.getName()); - e->createNewChildElement ("Platform")->addTextElement (is64Bit (config) ? "x64" : "Win32"); - } - } - - { - XmlElement* globals = projectXml.createNewChildElement ("PropertyGroup"); - globals->setAttribute ("Label", "Globals"); - globals->createNewChildElement ("ProjectGuid")->addTextElement (getProjectGuid()); - } - - { - XmlElement* imports = projectXml.createNewChildElement ("Import"); - imports->setAttribute ("Project", "$(VCTargetsPath)\\Microsoft.Cpp.Default.props"); - } - - for (ConstConfigIterator i (owner); i.next();) - { - const VC2010BuildConfiguration& config = dynamic_cast (*i); - - XmlElement* e = projectXml.createNewChildElement ("PropertyGroup"); - setConditionAttribute (*e, config); - e->setAttribute ("Label", "Configuration"); - e->createNewChildElement ("ConfigurationType")->addTextElement (getProjectType()); - e->createNewChildElement ("UseOfMfc")->addTextElement ("false"); - - const String charSet (config.getCharacterSet()); - - if (charSet.isNotEmpty()) - e->createNewChildElement ("CharacterSet")->addTextElement (charSet); - - if (! (config.isDebug() || config.shouldDisableWholeProgramOpt())) - e->createNewChildElement ("WholeProgramOptimization")->addTextElement ("true"); - - if (config.shouldLinkIncremental()) - e->createNewChildElement ("LinkIncremental")->addTextElement ("true"); - - if (config.is64Bit()) - e->createNewChildElement ("PlatformToolset")->addTextElement (getOwner().getPlatformToolset()); - } - - { - XmlElement* e = projectXml.createNewChildElement ("Import"); - e->setAttribute ("Project", "$(VCTargetsPath)\\Microsoft.Cpp.props"); - } - - { - XmlElement* e = projectXml.createNewChildElement ("ImportGroup"); - e->setAttribute ("Label", "ExtensionSettings"); - } - - { - XmlElement* e = projectXml.createNewChildElement ("ImportGroup"); - e->setAttribute ("Label", "PropertySheets"); - XmlElement* p = e->createNewChildElement ("Import"); - p->setAttribute ("Project", "$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props"); - p->setAttribute ("Condition", "exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')"); - p->setAttribute ("Label", "LocalAppDataPlatform"); - } - - { - XmlElement* e = projectXml.createNewChildElement ("PropertyGroup"); - e->setAttribute ("Label", "UserMacros"); - } - - { - XmlElement* props = projectXml.createNewChildElement ("PropertyGroup"); - props->createNewChildElement ("_ProjectFileVersion")->addTextElement ("10.0.30319.1"); - props->createNewChildElement ("TargetExt")->addTextElement (getTargetSuffix()); - - for (ConstConfigIterator i (owner); i.next();) - { - const VC2010BuildConfiguration& config = dynamic_cast (*i); - - if (getConfigTargetPath (config).isNotEmpty()) - { - XmlElement* outdir = props->createNewChildElement ("OutDir"); - setConditionAttribute (*outdir, config); - outdir->addTextElement (FileHelpers::windowsStylePath (getConfigTargetPath (config)) + "\\"); - } - - { - XmlElement* intdir = props->createNewChildElement("IntDir"); - setConditionAttribute (*intdir, config); - - String intermediatesPath = getIntermediatesPath (config); - if (! intermediatesPath.endsWithChar (L'\\')) - intermediatesPath += L'\\'; - - intdir->addTextElement (FileHelpers::windowsStylePath (intermediatesPath)); - } - - - { - XmlElement* targetName = props->createNewChildElement ("TargetName"); - setConditionAttribute (*targetName, config); - targetName->addTextElement (config.getOutputFilename ("", false)); - } - - { - XmlElement* manifest = props->createNewChildElement ("GenerateManifest"); - setConditionAttribute (*manifest, config); - manifest->addTextElement (config.shouldGenerateManifest() ? "true" : "false"); - } - - const StringArray librarySearchPaths (getLibrarySearchPaths (config)); - if (librarySearchPaths.size() > 0) - { - XmlElement* libPath = props->createNewChildElement ("LibraryPath"); - setConditionAttribute (*libPath, config); - libPath->addTextElement ("$(LibraryPath);" + librarySearchPaths.joinIntoString (";")); - } - } - } - - for (ConstConfigIterator i (owner); i.next();) - { - const VC2010BuildConfiguration& config = dynamic_cast (*i); - - const bool isDebug = config.isDebug(); - - XmlElement* group = projectXml.createNewChildElement ("ItemDefinitionGroup"); - setConditionAttribute (*group, config); - - { - XmlElement* midl = group->createNewChildElement ("Midl"); - midl->createNewChildElement ("PreprocessorDefinitions")->addTextElement (isDebug ? "_DEBUG;%(PreprocessorDefinitions)" - : "NDEBUG;%(PreprocessorDefinitions)"); - midl->createNewChildElement ("MkTypLibCompatible")->addTextElement ("true"); - midl->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); - midl->createNewChildElement ("TargetEnvironment")->addTextElement ("Win32"); - midl->createNewChildElement ("HeaderFileName"); - } - - bool isUsingEditAndContinue = false; - - { - XmlElement* cl = group->createNewChildElement ("ClCompile"); - - cl->createNewChildElement ("Optimization")->addTextElement (getOptimisationLevelString (config.getOptimisationLevelInt())); - - if (isDebug && config.getOptimisationLevelInt() <= optimisationOff) - { - isUsingEditAndContinue = ! config.is64Bit(); - - cl->createNewChildElement ("DebugInformationFormat") - ->addTextElement (isUsingEditAndContinue ? "EditAndContinue" - : "ProgramDatabase"); - } - - StringArray includePaths (getOwner().getHeaderSearchPaths (config)); - includePaths.addArray (getExtraSearchPaths()); - includePaths.add ("%(AdditionalIncludeDirectories)"); - - cl->createNewChildElement ("AdditionalIncludeDirectories")->addTextElement (includePaths.joinIntoString (";")); - cl->createNewChildElement ("PreprocessorDefinitions")->addTextElement (getPreprocessorDefs (config, ";") + ";%(PreprocessorDefinitions)"); - - const bool runtimeDLL = shouldUseRuntimeDLL (config); - cl->createNewChildElement ("RuntimeLibrary")->addTextElement (runtimeDLL ? (isDebug ? "MultiThreadedDebugDLL" : "MultiThreadedDLL") - : (isDebug ? "MultiThreadedDebug" : "MultiThreaded")); - cl->createNewChildElement ("RuntimeTypeInfo")->addTextElement ("true"); - cl->createNewChildElement ("PrecompiledHeader"); - cl->createNewChildElement ("AssemblerListingLocation")->addTextElement ("$(IntDir)\\"); - cl->createNewChildElement ("ObjectFileName")->addTextElement ("$(IntDir)\\"); - cl->createNewChildElement ("ProgramDataBaseFileName")->addTextElement ("$(IntDir)\\"); - cl->createNewChildElement ("WarningLevel")->addTextElement ("Level" + String (config.getWarningLevel())); - cl->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); - cl->createNewChildElement ("MultiProcessorCompilation")->addTextElement ("true"); - - if (config.isFastMathEnabled()) - cl->createNewChildElement ("FloatingPointModel")->addTextElement ("Fast"); - - const String extraFlags (getOwner().replacePreprocessorTokens (config, getOwner().getExtraCompilerFlagsString()).trim()); - if (extraFlags.isNotEmpty()) - cl->createNewChildElement ("AdditionalOptions")->addTextElement (extraFlags + " %(AdditionalOptions)"); - - if (config.areWarningsTreatedAsErrors()) - cl->createNewChildElement ("TreatWarningAsError")->addTextElement ("true"); - - String cppLanguageStandard = getOwner().getCppLanguageStandard(); - if (cppLanguageStandard.isNotEmpty()) - cl->createNewChildElement ("LanguageStandard")->addTextElement (cppLanguageStandard); - } - - { - XmlElement* res = group->createNewChildElement ("ResourceCompile"); - res->createNewChildElement ("PreprocessorDefinitions")->addTextElement (isDebug ? "_DEBUG;%(PreprocessorDefinitions)" - : "NDEBUG;%(PreprocessorDefinitions)"); - } - - { - XmlElement* link = group->createNewChildElement ("Link"); - link->createNewChildElement ("OutputFile")->addTextElement (getOutputFilePath (config)); - link->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); - link->createNewChildElement ("IgnoreSpecificDefaultLibraries")->addTextElement (isDebug ? "libcmt.lib; msvcrt.lib;;%(IgnoreSpecificDefaultLibraries)" - : "%(IgnoreSpecificDefaultLibraries)"); - link->createNewChildElement ("GenerateDebugInformation")->addTextElement ((isDebug || config.shouldGenerateDebugSymbols()) ? "true" : "false"); - link->createNewChildElement ("ProgramDatabaseFile")->addTextElement (getOwner().getIntDirFile (config, config.getOutputFilename (".pdb", true))); - link->createNewChildElement ("SubSystem")->addTextElement (type == ConsoleApp ? "Console" : "Windows"); - - if (! config.is64Bit()) - link->createNewChildElement ("TargetMachine")->addTextElement ("MachineX86"); - - if (isUsingEditAndContinue) - link->createNewChildElement ("ImageHasSafeExceptionHandlers")->addTextElement ("false"); - - if (! isDebug) - { - link->createNewChildElement ("OptimizeReferences")->addTextElement ("true"); - link->createNewChildElement ("EnableCOMDATFolding")->addTextElement ("true"); - } - - const StringArray librarySearchPaths (config.getLibrarySearchPaths()); - if (librarySearchPaths.size() > 0) - link->createNewChildElement ("AdditionalLibraryDirectories")->addTextElement (getOwner().replacePreprocessorTokens (config, librarySearchPaths.joinIntoString (";")) - + ";%(AdditionalLibraryDirectories)"); - - link->createNewChildElement ("LargeAddressAware")->addTextElement ("true"); - - const String externalLibraries (getExternalLibraries (config, getOwner().getExternalLibrariesString())); - if (externalLibraries.isNotEmpty()) - link->createNewChildElement ("AdditionalDependencies")->addTextElement (getOwner().replacePreprocessorTokens (config, externalLibraries).trim() - + ";%(AdditionalDependencies)"); - - String extraLinkerOptions (getOwner().getExtraLinkerFlagsString()); - if (extraLinkerOptions.isNotEmpty()) - link->createNewChildElement ("AdditionalOptions")->addTextElement (getOwner().replacePreprocessorTokens (config, extraLinkerOptions).trim() - + " %(AdditionalOptions)"); - - const String delayLoadedDLLs (getDelayLoadedDLLs()); - if (delayLoadedDLLs.isNotEmpty()) - link->createNewChildElement ("DelayLoadDLLs")->addTextElement (delayLoadedDLLs); - - const String moduleDefinitionsFile (getModuleDefinitions (config)); - if (moduleDefinitionsFile.isNotEmpty()) - link->createNewChildElement ("ModuleDefinitionFile") - ->addTextElement (moduleDefinitionsFile); - } - - { - XmlElement* bsc = group->createNewChildElement ("Bscmake"); - bsc->createNewChildElement ("SuppressStartupBanner")->addTextElement ("true"); - bsc->createNewChildElement ("OutputFile")->addTextElement (getOwner().getIntDirFile (config, config.getOutputFilename (".bsc", true))); - } - - const RelativePath& manifestFile = getOwner().getManifestPath(); - if (manifestFile.getRoot() != RelativePath::unknown) - { - XmlElement* bsc = group->createNewChildElement ("Manifest"); - bsc->createNewChildElement ("AdditionalManifestFiles") - ->addTextElement (manifestFile.rebased (getOwner().getProject().getFile().getParentDirectory(), - getOwner().getTargetFolder(), - RelativePath::buildTargetFolder).toWindowsStyle()); - } - - if (getTargetFileType() == staticLibrary && ! config.is64Bit()) - { - XmlElement* lib = group->createNewChildElement ("Lib"); - lib->createNewChildElement ("TargetMachine")->addTextElement ("MachineX86"); - } - - const String preBuild = getPreBuildSteps (config); - if (preBuild.isNotEmpty()) - group->createNewChildElement ("PreBuildEvent") - ->createNewChildElement ("Command") - ->addTextElement (preBuild); - - const String postBuild = getPostBuildSteps (config); - if (postBuild.isNotEmpty()) - group->createNewChildElement ("PostBuildEvent") - ->createNewChildElement ("Command") - ->addTextElement (postBuild); - } - - ScopedPointer otherFilesGroup (new XmlElement ("ItemGroup")); - - { - XmlElement* cppFiles = projectXml.createNewChildElement ("ItemGroup"); - XmlElement* headerFiles = projectXml.createNewChildElement ("ItemGroup"); - - for (int i = 0; i < getOwner().getAllGroups().size(); ++i) - { - const Project::Item& group = getOwner().getAllGroups().getReference (i); - - if (group.getNumChildren() > 0) - addFilesToCompile (group, *cppFiles, *headerFiles, *otherFilesGroup); - } - } - - if (getOwner().iconFile != File()) - { - XmlElement* e = otherFilesGroup->createNewChildElement ("None"); - e->setAttribute ("Include", prependDot (getOwner().iconFile.getFileName())); - } - - if (otherFilesGroup->getFirstChildElement() != nullptr) - projectXml.addChildElement (otherFilesGroup.release()); - - if (getOwner().hasResourceFile()) - { - XmlElement* rcGroup = projectXml.createNewChildElement ("ItemGroup"); - XmlElement* e = rcGroup->createNewChildElement ("ResourceCompile"); - e->setAttribute ("Include", prependDot (getOwner().rcFile.getFileName())); - } - - { - XmlElement* e = projectXml.createNewChildElement ("Import"); - e->setAttribute ("Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets"); - } - - { - XmlElement* e = projectXml.createNewChildElement ("ImportGroup"); - e->setAttribute ("Label", "ExtensionTargets"); - } - - getOwner().addPlatformToolsetToPropertyGroup (projectXml); - getOwner().addWindowsTargetPlatformVersionToPropertyGroup (projectXml); - getOwner().addIPPSettingToPropertyGroup (projectXml); - } - - String getProjectType() const - { - switch (getTargetFileType()) - { - case executable: - return "Application"; - case staticLibrary: - return "StaticLibrary"; - default: - break; - } - - return "DynamicLibrary"; - } - - //============================================================================== - void addFilesToCompile (const Project::Item& projectItem, XmlElement& cpps, XmlElement& headers, XmlElement& otherFiles) const - { - const Type targetType = (getOwner().getProject().getProjectType().isAudioPlugin() ? type : SharedCodeTarget); - - if (projectItem.isGroup()) - { - for (int i = 0; i < projectItem.getNumChildren(); ++i) - addFilesToCompile (projectItem.getChild (i), cpps, headers, otherFiles); - } - else if (projectItem.shouldBeAddedToTargetProject() - && getOwner().getProject().getTargetTypeFromFilePath (projectItem.getFile(), true) == targetType) - { - const RelativePath path (projectItem.getFile(), getOwner().getTargetFolder(), RelativePath::buildTargetFolder); - - jassert (path.getRoot() == RelativePath::buildTargetFolder); - - if (path.hasFileExtension (cOrCppFileExtensions) || path.hasFileExtension (asmFileExtensions)) - { - if (targetType == SharedCodeTarget || projectItem.shouldBeCompiled()) - { - auto* e = cpps.createNewChildElement ("ClCompile"); - e->setAttribute ("Include", path.toWindowsStyle()); - - if (shouldUseStdCall (path)) - e->createNewChildElement ("CallingConvention")->addTextElement ("StdCall"); - - if (! projectItem.shouldBeCompiled()) - e->createNewChildElement ("ExcludedFromBuild")->addTextElement ("true"); - } - } - else if (path.hasFileExtension (headerFileExtensions)) - { - headers.createNewChildElement ("ClInclude")->setAttribute ("Include", path.toWindowsStyle()); - } - else if (! path.hasFileExtension (objCFileExtensions)) - { - otherFiles.createNewChildElement ("None")->setAttribute ("Include", path.toWindowsStyle()); - } - } - } - - void setConditionAttribute (XmlElement& xml, const BuildConfiguration& config) const - { - const MSVCBuildConfiguration& msvcConfig = dynamic_cast (config); - xml.setAttribute ("Condition", "'$(Configuration)|$(Platform)'=='" + msvcConfig.createMSVCConfigName() + "'"); - } - - //============================================================================== - void addFilterGroup (XmlElement& groups, const String& path) const - { - XmlElement* e = groups.createNewChildElement ("Filter"); - e->setAttribute ("Include", path); - e->createNewChildElement ("UniqueIdentifier")->addTextElement (createGUID (path + "_guidpathsaltxhsdf")); - } - - void addFileToFilter (const RelativePath& file, const String& groupPath, - XmlElement& cpps, XmlElement& headers, XmlElement& otherFiles) const - { - XmlElement* e; - - if (file.hasFileExtension (headerFileExtensions)) - e = headers.createNewChildElement ("ClInclude"); - else if (file.hasFileExtension (sourceFileExtensions)) - e = cpps.createNewChildElement ("ClCompile"); - else - e = otherFiles.createNewChildElement ("None"); - - jassert (file.getRoot() == RelativePath::buildTargetFolder); - e->setAttribute ("Include", file.toWindowsStyle()); - e->createNewChildElement ("Filter")->addTextElement (groupPath); - } - - bool addFilesToFilter (const Project::Item& projectItem, const String& path, - XmlElement& cpps, XmlElement& headers, XmlElement& otherFiles, XmlElement& groups) const - { - const Type targetType = (getOwner().getProject().getProjectType().isAudioPlugin() ? type : SharedCodeTarget); - - if (projectItem.isGroup()) - { - bool filesWereAdded = false; - - for (int i = 0; i < projectItem.getNumChildren(); ++i) - if (addFilesToFilter (projectItem.getChild(i), - (path.isEmpty() ? String() : (path + "\\")) + projectItem.getChild(i).getName(), - cpps, headers, otherFiles, groups)) - filesWereAdded = true; - - if (filesWereAdded) - addFilterGroup (groups, path); - - return filesWereAdded; - } - else if (projectItem.shouldBeAddedToTargetProject()) - { - const RelativePath relativePath (projectItem.getFile(), getOwner().getTargetFolder(), RelativePath::buildTargetFolder); - - jassert (relativePath.getRoot() == RelativePath::buildTargetFolder); - - if (getOwner().getProject().getTargetTypeFromFilePath (projectItem.getFile(), true) == targetType - && (targetType == SharedCodeTarget || projectItem.shouldBeCompiled())) - { - addFileToFilter (relativePath, path.upToLastOccurrenceOf ("\\", false, false), cpps, headers, otherFiles); - return true; - } - } - - return false; - } - - bool addFilesToFilter (const Array& files, const String& path, - XmlElement& cpps, XmlElement& headers, XmlElement& otherFiles, XmlElement& groups) - { - if (files.size() > 0) - { - addFilterGroup (groups, path); - - for (int i = 0; i < files.size(); ++i) - addFileToFilter (files.getReference(i), path, cpps, headers, otherFiles); - - return true; - } - - return false; - } - - void fillInFiltersXml (XmlElement& filterXml) const override - { - filterXml.setAttribute ("ToolsVersion", getOwner().getToolsVersion()); - filterXml.setAttribute ("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"); - - XmlElement* groupsXml = filterXml.createNewChildElement ("ItemGroup"); - XmlElement* cpps = filterXml.createNewChildElement ("ItemGroup"); - XmlElement* headers = filterXml.createNewChildElement ("ItemGroup"); - ScopedPointer otherFilesGroup (new XmlElement ("ItemGroup")); - - for (int i = 0; i < getOwner().getAllGroups().size(); ++i) - { - const Project::Item& group = getOwner().getAllGroups().getReference(i); - - if (group.getNumChildren() > 0) - addFilesToFilter (group, group.getName(), *cpps, *headers, *otherFilesGroup, *groupsXml); - } - - if (getOwner().iconFile.exists()) - { - XmlElement* e = otherFilesGroup->createNewChildElement ("None"); - e->setAttribute ("Include", prependDot (getOwner().iconFile.getFileName())); - e->createNewChildElement ("Filter")->addTextElement (ProjectSaver::getJuceCodeGroupName()); - } - - if (otherFilesGroup->getFirstChildElement() != nullptr) - filterXml.addChildElement (otherFilesGroup.release()); - - if (getOwner().hasResourceFile()) - { - XmlElement* rcGroup = filterXml.createNewChildElement ("ItemGroup"); - XmlElement* e = rcGroup->createNewChildElement ("ResourceCompile"); - e->setAttribute ("Include", prependDot (getOwner().rcFile.getFileName())); - e->createNewChildElement ("Filter")->addTextElement (ProjectSaver::getJuceCodeGroupName()); - } - } - - }; - - static const char* getName() { return "Visual Studio 2010"; } - static const char* getValueTreeTypeName() { return "VS2010"; } - int getVisualStudioVersion() const override { return 10; } - virtual String getSolutionComment() const { return "# Visual Studio 2010"; } - virtual String getToolsVersion() const { return "4.0"; } - virtual String getDefaultToolset() const { return "Windows7.1SDK"; } - Value getPlatformToolsetValue() { return getSetting (Ids::toolset); } - Value getIPPLibraryValue() { return getSetting (Ids::IPPLibrary); } - String getIPPLibrary() const { return settings [Ids::IPPLibrary]; } - virtual String getCppLanguageStandard() const { return {}; } - virtual String getDefaultWindowsTargetPlatformVersion() const { return "8.1"; } - - String getPlatformToolset() const - { - const String s (settings [Ids::toolset].toString()); - return s.isNotEmpty() ? s : getDefaultToolset(); - } - - static MSVCProjectExporterVC2010* createForSettings (Project& project, const ValueTree& settings) - { - if (settings.hasType (getValueTreeTypeName())) - return new MSVCProjectExporterVC2010 (project, settings); - - return nullptr; - } - - void addToolsetProperty (PropertyListBuilder& props, const char** names, const var* values, int num) - { - props.add (new ChoicePropertyComponent (getPlatformToolsetValue(), "Platform Toolset", - StringArray (names, num), Array (values, num))); - } - - void addIPPLibraryProperty (PropertyListBuilder& props) - { - static const char* ippOptions[] = { "No", "Yes (Default Mode)", "Multi-Threaded Static Library", "Single-Threaded Static Library", "Multi-Threaded DLL", "Single-Threaded DLL" }; - static const var ippValues[] = { var(), "true", "Parallel_Static", "Sequential", "Parallel_Dynamic", "Sequential_Dynamic" }; - - props.add (new ChoicePropertyComponent (getIPPLibraryValue(), "Use IPP Library", - StringArray (ippOptions, numElementsInArray (ippValues)), - Array (ippValues, numElementsInArray (ippValues)))); - } - - void createExporterProperties (PropertyListBuilder& props) override - { - MSVCProjectExporterBase::createExporterProperties (props); - - static const char* toolsetNames[] = { "(default)", "v100", "v100_xp", "Windows7.1SDK", "CTP_Nov2013" }; - const var toolsets[] = { var(), "v100", "v100_xp", "Windows7.1SDK", "CTP_Nov2013" }; - - addToolsetProperty (props, toolsetNames, toolsets, numElementsInArray (toolsets)); - addIPPLibraryProperty (props); - } - - //============================================================================== - void addPlatformSpecificSettingsForProjectType (const ProjectType& type) override - { - MSVCProjectExporterBase::addPlatformSpecificSettingsForProjectType (type); - - callForAllSupportedTargets ([this] (ProjectType::Target::Type targetType) - { - if (MSVCTargetBase* target = new MSVC2010Target (targetType, *this)) - { - if (targetType != ProjectType::Target::AggregateTarget) - 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); - } - - void create (const OwnedArray&) const override - { - createResourcesAndIcon(); - - for (int i = 0; i < targets.size(); ++i) - if (MSVCTargetBase* target = targets[i]) - target->writeProjectFile(); - - { - MemoryOutputStream mo; - writeSolutionFile (mo, "11.00", getSolutionComment()); - - overwriteFileIfDifferentOrThrow (getSLNFile(), mo); - } - } - -protected: - //============================================================================== - class VC2010BuildConfiguration : public MSVCBuildConfiguration - { - public: - VC2010BuildConfiguration (Project& p, const ValueTree& settings, const ProjectExporter& e) - : MSVCBuildConfiguration (p, settings, e) - { - if (getArchitectureType().toString().isEmpty()) - getArchitectureType() = get64BitArchName(); - } - - //============================================================================== - static const char* get32BitArchName() { return "32-bit"; } - static const char* get64BitArchName() { return "x64"; } - - Value getArchitectureType() { return getValue (Ids::winArchitecture); } - bool is64Bit() const { return config [Ids::winArchitecture].toString() == get64BitArchName(); } - - Value getFastMathValue() { return getValue (Ids::fastMath); } - bool isFastMathEnabled() const { return config [Ids::fastMath]; } - - //============================================================================== - void createConfigProperties (PropertyListBuilder& props) override - { - MSVCBuildConfiguration::createConfigProperties (props); - - const char* const archTypes[] = { get32BitArchName(), get64BitArchName() }; - - props.add (new ChoicePropertyComponent (getArchitectureType(), "Architecture", - StringArray (archTypes, numElementsInArray (archTypes)), - Array (archTypes, numElementsInArray (archTypes)))); - - props.add (new BooleanPropertyComponent (getFastMathValue(), "Relax IEEE compliance", "Enabled"), - "Enable this to use FAST_MATH non-IEEE mode. (Warning: this can have unexpected results!)"); - } - }; - - virtual void addPlatformToolsetToPropertyGroup (XmlElement&) const {} - virtual void addWindowsTargetPlatformVersionToPropertyGroup (XmlElement&) const {} - - void addIPPSettingToPropertyGroup (XmlElement& p) const - { - String ippLibrary = getIPPLibrary(); - - if (ippLibrary.isNotEmpty()) - forEachXmlChildElementWithTagName (p, e, "PropertyGroup") - e->createNewChildElement ("UseIntelIPP")->addTextElement (ippLibrary); - } - - BuildConfiguration::Ptr createBuildConfig (const ValueTree& v) const override - { - return new VC2010BuildConfiguration (project, v, *this); - } - - static bool is64Bit (const BuildConfiguration& config) - { - return dynamic_cast (config).is64Bit(); - } - - //============================================================================== - File getVCProjFile() const { return getProjectFile (".vcxproj", "App"); } - File getVCProjFiltersFile() const { return getProjectFile (".vcxproj.filters", String()); } - - JUCE_DECLARE_NON_COPYABLE (MSVCProjectExporterVC2010) -}; - -//============================================================================== -class MSVCProjectExporterVC2012 : public MSVCProjectExporterVC2010 -{ -public: - MSVCProjectExporterVC2012 (Project& p, const ValueTree& t, - const char* folderName = "VisualStudio2012") - : MSVCProjectExporterVC2010 (p, t, folderName) - { - name = getName(); - } - - static const char* getName() { return "Visual Studio 2012"; } - static const char* getValueTreeTypeName() { return "VS2012"; } - int getVisualStudioVersion() const override { return 11; } - String getSolutionComment() const override { return "# Visual Studio 2012"; } - String getDefaultToolset() const override { return "v110"; } - Value getWindowsTargetPlatformVersionValue() { return getSetting (Ids::windowsTargetPlatformVersion); } - - String getWindowsTargetPlatformVersion() const - { - String targetPlatform = settings [Ids::windowsTargetPlatformVersion]; - return (targetPlatform.isNotEmpty() ? targetPlatform : getDefaultWindowsTargetPlatformVersion()); - } - - static MSVCProjectExporterVC2012* createForSettings (Project& project, const ValueTree& settings) - { - if (settings.hasType (getValueTreeTypeName())) - return new MSVCProjectExporterVC2012 (project, settings); - - return nullptr; - } - - void createExporterProperties (PropertyListBuilder& props) override - { - MSVCProjectExporterBase::createExporterProperties (props); - - static const char* toolsetNames[] = { "(default)", "v110", "v110_xp", "Windows7.1SDK", "CTP_Nov2013" }; - const var toolsets[] = { var(), "v110", "v110_xp", "Windows7.1SDK", "CTP_Nov2013" }; - - addToolsetProperty (props, toolsetNames, toolsets, numElementsInArray (toolsets)); - addIPPLibraryProperty (props); - } - - void addWindowsTargetPlatformProperties (PropertyListBuilder& props) - { - static const char* targetPlatformNames[] = { "(default)", "8.1", "10.0.10240.0", "10.0.10586.0", "10.0.14393.0", "10.0.15063.0", nullptr }; - const var targetPlatforms[] = { var(), "8.1", "10.0.10240.0", "10.0.10586.0", "10.0.14393.0", "10.0.15063.0" }; - - props.add (new ChoicePropertyComponent (getWindowsTargetPlatformVersionValue(), "Windows Target Platform", - StringArray (targetPlatformNames), Array (targetPlatforms, numElementsInArray (targetPlatforms))), - "Specifies the version of the Windows SDK that will be used when building this project. " - "The default value for this exporter is " + getDefaultWindowsTargetPlatformVersion()); - } - -private: - void addPlatformToolsetToPropertyGroup (XmlElement& p) const override - { - forEachXmlChildElementWithTagName (p, e, "PropertyGroup") - e->createNewChildElement ("PlatformToolset")->addTextElement (getPlatformToolset()); - } - - void addWindowsTargetPlatformVersionToPropertyGroup (XmlElement& p) const override - { - const String& targetVersion = getWindowsTargetPlatformVersion(); - - if (targetVersion.isNotEmpty()) - forEachXmlChildElementWithTagName (p, e, "PropertyGroup") - e->createNewChildElement ("WindowsTargetPlatformVersion")->addTextElement (getWindowsTargetPlatformVersion()); - } - - JUCE_DECLARE_NON_COPYABLE (MSVCProjectExporterVC2012) -}; - -//============================================================================== -class MSVCProjectExporterVC2013 : public MSVCProjectExporterVC2012 +class MSVCProjectExporterVC2013 : public MSVCProjectExporterBase { public: MSVCProjectExporterVC2013 (Project& p, const ValueTree& t) - : MSVCProjectExporterVC2012 (p, t, "VisualStudio2013") + : MSVCProjectExporterBase (p, t, "VisualStudio2013") { name = getName(); } - static const char* getName() { return "Visual Studio 2013"; } - static const char* getValueTreeTypeName() { return "VS2013"; } - int getVisualStudioVersion() const override { return 12; } - String getSolutionComment() const override { return "# Visual Studio 2013"; } - String getToolsVersion() const override { return "12.0"; } - String getDefaultToolset() const override { return "v120"; } + static const char* getName() { return "Visual Studio 2013"; } + static const char* getValueTreeTypeName() { return "VS2013"; } + int getVisualStudioVersion() const override { return 12; } + String getSolutionComment() const override { return "# Visual Studio 2013"; } + String getToolsVersion() const override { return "12.0"; } + String getDefaultToolset() const override { return "v120"; } + String getDefaultWindowsTargetPlatformVersion() const override { return "8.1"; } + static MSVCProjectExporterVC2013* createForSettings (Project& project, const ValueTree& settings) { @@ -1892,9 +1217,10 @@ public: static const char* toolsetNames[] = { "(default)", "v120", "v120_xp", "Windows7.1SDK", "CTP_Nov2013" }; const var toolsets[] = { var(), "v120", "v120_xp", "Windows7.1SDK", "CTP_Nov2013" }; - addToolsetProperty (props, toolsetNames, toolsets, numElementsInArray (toolsets)); + addIPPLibraryProperty (props); + addWindowsTargetPlatformProperties (props); } @@ -1902,21 +1228,22 @@ public: }; //============================================================================== -class MSVCProjectExporterVC2015 : public MSVCProjectExporterVC2012 +class MSVCProjectExporterVC2015 : public MSVCProjectExporterBase { public: MSVCProjectExporterVC2015 (Project& p, const ValueTree& t) - : MSVCProjectExporterVC2012 (p, t, "VisualStudio2015") + : MSVCProjectExporterBase (p, t, "VisualStudio2015") { name = getName(); } - static const char* getName() { return "Visual Studio 2015"; } - static const char* getValueTreeTypeName() { return "VS2015"; } - int getVisualStudioVersion() const override { return 14; } - String getSolutionComment() const override { return "# Visual Studio 2015"; } - String getToolsVersion() const override { return "14.0"; } - String getDefaultToolset() const override { return "v140"; } + static const char* getName() { return "Visual Studio 2015"; } + static const char* getValueTreeTypeName() { return "VS2015"; } + int getVisualStudioVersion() const override { return 14; } + String getSolutionComment() const override { return "# Visual Studio 2015"; } + String getToolsVersion() const override { return "14.0"; } + String getDefaultToolset() const override { return "v140"; } + String getDefaultWindowsTargetPlatformVersion() const override { return "8.1"; } static MSVCProjectExporterVC2015* createForSettings (Project& project, const ValueTree& settings) { @@ -1932,9 +1259,10 @@ public: static const char* toolsetNames[] = { "(default)", "v140", "v140_xp", "CTP_Nov2013" }; const var toolsets[] = { var(), "v140", "v140_xp", "CTP_Nov2013" }; - addToolsetProperty (props, toolsetNames, toolsets, numElementsInArray (toolsets)); + addIPPLibraryProperty (props); + addWindowsTargetPlatformProperties (props); } @@ -1942,23 +1270,22 @@ public: }; //============================================================================== -class MSVCProjectExporterVC2017 : public MSVCProjectExporterVC2012 +class MSVCProjectExporterVC2017 : public MSVCProjectExporterBase { public: MSVCProjectExporterVC2017 (Project& p, const ValueTree& t) - : MSVCProjectExporterVC2012 (p, t, "VisualStudio2017") + : MSVCProjectExporterBase (p, t, "VisualStudio2017") { name = getName(); } - static const char* getName() { return "Visual Studio 2017"; } - static const char* getValueTreeTypeName() { return "VS2017"; } - int getVisualStudioVersion() const override { return 15; } - String getSolutionComment() const override { return "# Visual Studio 2017"; } - String getToolsVersion() const override { return "15.0"; } - String getDefaultToolset() const override { return "v141"; } - - String getDefaultWindowsTargetPlatformVersion() const override { return "10.0.15063.0"; } + static const char* getName() { return "Visual Studio 2017"; } + static const char* getValueTreeTypeName() { return "VS2017"; } + int getVisualStudioVersion() const override { return 15; } + String getSolutionComment() const override { return "# Visual Studio 2017"; } + String getToolsVersion() const override { return "15.0"; } + String getDefaultToolset() const override { return "v141"; } + String getDefaultWindowsTargetPlatformVersion() const override { return "10.0.15063.0"; } static MSVCProjectExporterVC2017* createForSettings (Project& project, const ValueTree& settings) { @@ -1968,30 +1295,21 @@ public: return nullptr; } - Value getCppStandardValue() { return getSetting (Ids::cppLanguageStandard); } - String getCppLanguageStandard() const override { return settings [Ids::cppLanguageStandard]; } - void createExporterProperties (PropertyListBuilder& props) override { MSVCProjectExporterBase::createExporterProperties (props); static const char* toolsetNames[] = { "(default)", "v140", "v140_xp", "v141", "v141_xp" }; const var toolsets[] = { var(), "v140", "v140_xp", "v141", "v141_xp" }; - addToolsetProperty (props, toolsetNames, toolsets, numElementsInArray (toolsets)); - addIPPLibraryProperty (props); - addWindowsTargetPlatformProperties (props); - static const char* cppStandardNames[] = { "(default)", "C++14", "Latest C++ Standard", nullptr }; + addIPPLibraryProperty (props); - Array cppStandardValues; - cppStandardValues.add (var()); - cppStandardValues.add ("stdcpp14"); - cppStandardValues.add ("stdcpplatest"); + addWindowsTargetPlatformProperties (props); - props.add (new ChoicePropertyComponent (getCppStandardValue(), "C++ standard to use", - StringArray (cppStandardNames), cppStandardValues), - "The C++ language standard to use"); + static const char* cppStandardNames[] = { "(default)", "C++14", "Latest C++ Standard"}; + const var standards[] = { var(), "stdcpp14", "stdcpplatest" }; + addCppStandardProperty (props, cppStandardNames, standards, numElementsInArray (standards)); } JUCE_DECLARE_NON_COPYABLE (MSVCProjectExporterVC2017)