| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
| file Copyright.txt or https://cmake.org/licensing for details. */ |
| #include "cmVisualStudio10TargetGenerator.h" |
| |
| #include "cmAlgorithms.h" |
| #include "cmComputeLinkInformation.h" |
| #include "cmCustomCommandGenerator.h" |
| #include "cmGeneratedFileStream.h" |
| #include "cmGeneratorTarget.h" |
| #include "cmGlobalVisualStudio10Generator.h" |
| #include "cmLocalVisualStudio7Generator.h" |
| #include "cmMakefile.h" |
| #include "cmSourceFile.h" |
| #include "cmSystemTools.h" |
| #include "cmVisualStudioGeneratorOptions.h" |
| #include "windows.h" |
| |
| #include <iterator> |
| #include <memory> // IWYU pragma: keep |
| |
| static void ConvertToWindowsSlash(std::string& s); |
| |
| static std::string cmVS10EscapeXML(std::string arg) |
| { |
| cmSystemTools::ReplaceString(arg, "&", "&"); |
| cmSystemTools::ReplaceString(arg, "<", "<"); |
| cmSystemTools::ReplaceString(arg, ">", ">"); |
| return arg; |
| } |
| |
| static std::string cmVS10EscapeQuotes(std::string arg) |
| { |
| cmSystemTools::ReplaceString(arg, "\"", """); |
| return arg; |
| } |
| |
| static std::string cmVS10EscapeComment(std::string comment) |
| { |
| // MSBuild takes the CDATA of a <Message></Message> element and just |
| // does "echo $CDATA" with no escapes. We must encode the string. |
| // http://technet.microsoft.com/en-us/library/cc772462%28WS.10%29.aspx |
| std::string echoable; |
| for (char c : comment) { |
| switch (c) { |
| case '\r': |
| break; |
| case '\n': |
| echoable += '\t'; |
| break; |
| case '"': /* no break */ |
| case '|': /* no break */ |
| case '&': /* no break */ |
| case '<': /* no break */ |
| case '>': /* no break */ |
| case '^': |
| echoable += '^'; /* no break */ |
| CM_FALLTHROUGH; |
| default: |
| echoable += c; |
| break; |
| } |
| } |
| return echoable; |
| } |
| |
| static bool cmVS10IsTargetsFile(std::string const& path) |
| { |
| std::string const ext = cmSystemTools::GetFilenameLastExtension(path); |
| return cmSystemTools::Strucmp(ext.c_str(), ".targets") == 0; |
| } |
| |
| static std::string computeProjectFileExtension(cmGeneratorTarget const* t, |
| const std::string& config) |
| { |
| std::string res; |
| res = ".vcxproj"; |
| std::string lang = t->GetLinkerLanguage(config); |
| if (cmGlobalVisualStudioGenerator::TargetIsCSharpOnly(t) || |
| lang == "CSharp") { |
| res = ".csproj"; |
| } |
| return res; |
| } |
| |
| cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator( |
| cmGeneratorTarget* target, cmGlobalVisualStudio10Generator* gg) |
| { |
| this->GlobalGenerator = gg; |
| this->GeneratorTarget = target; |
| this->Makefile = target->Target->GetMakefile(); |
| this->Makefile->GetConfigurations(this->Configurations); |
| this->LocalGenerator = |
| (cmLocalVisualStudio7Generator*)this->GeneratorTarget->GetLocalGenerator(); |
| this->Name = this->GeneratorTarget->GetName(); |
| this->GUID = this->GlobalGenerator->GetGUID(this->Name); |
| this->Platform = gg->GetPlatformName(); |
| this->NsightTegra = gg->IsNsightTegra(); |
| for (int i = 0; i < 4; ++i) { |
| this->NsightTegraVersion[i] = 0; |
| } |
| sscanf(gg->GetNsightTegraVersion().c_str(), "%u.%u.%u.%u", |
| &this->NsightTegraVersion[0], &this->NsightTegraVersion[1], |
| &this->NsightTegraVersion[2], &this->NsightTegraVersion[3]); |
| this->MSTools = !this->NsightTegra; |
| this->Managed = false; |
| this->TargetCompileAsWinRT = false; |
| this->BuildFileStream = 0; |
| this->IsMissingFiles = false; |
| this->DefaultArtifactDir = |
| this->LocalGenerator->GetCurrentBinaryDirectory() + std::string("/") + |
| this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); |
| this->InSourceBuild = |
| (strcmp(this->Makefile->GetCurrentSourceDirectory(), |
| this->Makefile->GetCurrentBinaryDirectory()) == 0); |
| } |
| |
| cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator() |
| { |
| if (!this->BuildFileStream) { |
| return; |
| } |
| if (this->BuildFileStream->Close()) { |
| this->GlobalGenerator->FileReplacedDuringGenerate(this->PathToProjectFile); |
| } |
| delete this->BuildFileStream; |
| } |
| |
| void cmVisualStudio10TargetGenerator::WritePlatformConfigTag( |
| const char* tag, const std::string& config, int indentLevel, |
| const char* attribute, const char* end, std::ostream* stream) |
| |
| { |
| if (!stream) { |
| stream = this->BuildFileStream; |
| } |
| stream->fill(' '); |
| stream->width(indentLevel * 2); |
| (*stream) << ""; // applies indentation |
| (*stream) << "<" << tag << " Condition=\""; |
| (*stream) << "'$(Configuration)|$(Platform)'=='"; |
| (*stream) << config << "|" << this->Platform; |
| (*stream) << "'"; |
| // handle special case for 32 bit C# targets |
| if (this->ProjectType == csproj && this->Platform == "Win32") { |
| (*stream) << " Or "; |
| (*stream) << "'$(Configuration)|$(Platform)'=='"; |
| (*stream) << config << "|x86"; |
| (*stream) << "'"; |
| } |
| (*stream) << "\""; |
| if (attribute) { |
| (*stream) << attribute; |
| } |
| // close the tag |
| (*stream) << ">"; |
| if (end) { |
| (*stream) << end; |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteString(const char* line, |
| int indentLevel) |
| { |
| this->BuildFileStream->fill(' '); |
| this->BuildFileStream->width(indentLevel * 2); |
| // write an empty string to get the fill level indent to print |
| (*this->BuildFileStream) << ""; |
| (*this->BuildFileStream) << line; |
| } |
| |
| #define VS10_CXX_DEFAULT_PROPS "$(VCTargetsPath)\\Microsoft.Cpp.Default.props" |
| #define VS10_CXX_PROPS "$(VCTargetsPath)\\Microsoft.Cpp.props" |
| #define VS10_CXX_USER_PROPS \ |
| "$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" |
| #define VS10_CXX_TARGETS "$(VCTargetsPath)\\Microsoft.Cpp.targets" |
| |
| #define VS10_CSharp_DEFAULT_PROPS \ |
| "$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props" |
| // This does not seem to exist by default, it's just provided for consistency |
| // in case users want to have default custom props for C# targets |
| #define VS10_CSharp_USER_PROPS \ |
| "$(UserRootDir)\\Microsoft.CSharp.$(Platform).user.props" |
| #define VS10_CSharp_TARGETS "$(MSBuildToolsPath)\\Microsoft.CSharp.targets" |
| |
| void cmVisualStudio10TargetGenerator::Generate() |
| { |
| // do not generate external ms projects |
| if (this->GeneratorTarget->GetType() == cmStateEnums::INTERFACE_LIBRARY || |
| this->GeneratorTarget->GetProperty("EXTERNAL_MSPROJECT")) { |
| return; |
| } |
| this->ProjectFileExtension = computeProjectFileExtension( |
| this->GeneratorTarget, *this->Configurations.begin()); |
| if (this->ProjectFileExtension == ".vcxproj") { |
| this->ProjectType = vcxproj; |
| this->Managed = false; |
| } else if (this->ProjectFileExtension == ".csproj") { |
| this->ProjectType = csproj; |
| this->Managed = true; |
| } |
| // Tell the global generator the name of the project file |
| this->GeneratorTarget->Target->SetProperty("GENERATOR_FILE_NAME", |
| this->Name.c_str()); |
| this->GeneratorTarget->Target->SetProperty( |
| "GENERATOR_FILE_NAME_EXT", this->ProjectFileExtension.c_str()); |
| if (this->GeneratorTarget->GetType() <= cmStateEnums::OBJECT_LIBRARY) { |
| if (!this->ComputeClOptions()) { |
| return; |
| } |
| if (!this->ComputeRcOptions()) { |
| return; |
| } |
| if (!this->ComputeCudaOptions()) { |
| return; |
| } |
| if (!this->ComputeCudaLinkOptions()) { |
| return; |
| } |
| if (!this->ComputeMasmOptions()) { |
| return; |
| } |
| if (!this->ComputeNasmOptions()) { |
| return; |
| } |
| if (!this->ComputeLinkOptions()) { |
| return; |
| } |
| if (!this->ComputeLibOptions()) { |
| return; |
| } |
| } |
| std::string path = this->LocalGenerator->GetCurrentBinaryDirectory(); |
| path += "/"; |
| path += this->Name; |
| path += this->ProjectFileExtension; |
| this->BuildFileStream = new cmGeneratedFileStream(path.c_str()); |
| this->PathToProjectFile = path; |
| this->BuildFileStream->SetCopyIfDifferent(true); |
| |
| // Write the encoding header into the file |
| char magic[] = { char(0xEF), char(0xBB), char(0xBF) }; |
| this->BuildFileStream->write(magic, 3); |
| |
| // get the tools version to use |
| const std::string toolsVer(this->GlobalGenerator->GetToolsVersion()); |
| std::string project_defaults = "<?xml version=\"1.0\" encoding=\"" + |
| this->GlobalGenerator->Encoding() + "\"?>\n"; |
| project_defaults.append("<Project DefaultTargets=\"Build\" ToolsVersion=\""); |
| project_defaults.append(toolsVer + "\" "); |
| project_defaults.append( |
| "xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"); |
| this->WriteString(project_defaults.c_str(), 0); |
| |
| if (this->NsightTegra) { |
| this->WriteString("<PropertyGroup Label=\"NsightTegraProject\">\n", 1); |
| const int nsightTegraMajorVersion = this->NsightTegraVersion[0]; |
| const int nsightTegraMinorVersion = this->NsightTegraVersion[1]; |
| if (nsightTegraMajorVersion >= 2) { |
| this->WriteString("<NsightTegraProjectRevisionNumber>", 2); |
| if (nsightTegraMajorVersion > 3 || |
| (nsightTegraMajorVersion == 3 && nsightTegraMinorVersion >= 1)) { |
| (*this->BuildFileStream) << "11"; |
| } else { |
| // Nsight Tegra 2.0 uses project revision 9. |
| (*this->BuildFileStream) << "9"; |
| } |
| (*this->BuildFileStream) << "</NsightTegraProjectRevisionNumber>\n"; |
| // Tell newer versions to upgrade silently when loading. |
| this->WriteString("<NsightTegraUpgradeOnceWithoutPrompt>" |
| "true" |
| "</NsightTegraUpgradeOnceWithoutPrompt>\n", |
| 2); |
| } else { |
| // Require Nsight Tegra 1.6 for JCompile support. |
| this->WriteString("<NsightTegraProjectRevisionNumber>" |
| "7" |
| "</NsightTegraProjectRevisionNumber>\n", |
| 2); |
| } |
| this->WriteString("</PropertyGroup>\n", 1); |
| } |
| |
| if (const char* hostArch = |
| this->GlobalGenerator->GetPlatformToolsetHostArchitecture()) { |
| this->WriteString("<PropertyGroup>\n", 1); |
| this->WriteString("<PreferredToolArchitecture>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(hostArch) |
| << "</PreferredToolArchitecture>\n"; |
| this->WriteString("</PropertyGroup>\n", 1); |
| } |
| |
| if (this->ProjectType != csproj) { |
| this->WriteProjectConfigurations(); |
| } |
| this->WriteString("<PropertyGroup Label=\"Globals\">\n", 1); |
| this->WriteString("<ProjectGuid>", 2); |
| (*this->BuildFileStream) << "{" << this->GUID << "}</ProjectGuid>\n"; |
| |
| if (this->MSTools && |
| this->GeneratorTarget->GetType() <= cmStateEnums::GLOBAL_TARGET) { |
| this->WriteApplicationTypeSettings(); |
| this->VerifyNecessaryFiles(); |
| } |
| |
| const char* vsProjectTypes = |
| this->GeneratorTarget->GetProperty("VS_GLOBAL_PROJECT_TYPES"); |
| if (vsProjectTypes) { |
| std::string tagName = "ProjectTypes"; |
| if (this->ProjectType == csproj) { |
| tagName = "ProjectTypeGuids"; |
| } |
| this->WriteString("", 2); |
| (*this->BuildFileStream) << "<" << tagName << ">" |
| << cmVS10EscapeXML(vsProjectTypes) << "</" |
| << tagName << ">\n"; |
| } |
| |
| const char* vsProjectName = |
| this->GeneratorTarget->GetProperty("VS_SCC_PROJECTNAME"); |
| const char* vsLocalPath = |
| this->GeneratorTarget->GetProperty("VS_SCC_LOCALPATH"); |
| const char* vsProvider = |
| this->GeneratorTarget->GetProperty("VS_SCC_PROVIDER"); |
| |
| if (vsProjectName && vsLocalPath && vsProvider) { |
| this->WriteString("<SccProjectName>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(vsProjectName) |
| << "</SccProjectName>\n"; |
| this->WriteString("<SccLocalPath>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(vsLocalPath) |
| << "</SccLocalPath>\n"; |
| this->WriteString("<SccProvider>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(vsProvider) |
| << "</SccProvider>\n"; |
| |
| const char* vsAuxPath = |
| this->GeneratorTarget->GetProperty("VS_SCC_AUXPATH"); |
| if (vsAuxPath) { |
| this->WriteString("<SccAuxPath>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(vsAuxPath) |
| << "</SccAuxPath>\n"; |
| } |
| } |
| |
| if (this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT")) { |
| this->WriteString("<WinMDAssembly>true</WinMDAssembly>\n", 2); |
| } |
| |
| const char* vsGlobalKeyword = |
| this->GeneratorTarget->GetProperty("VS_GLOBAL_KEYWORD"); |
| if (!vsGlobalKeyword) { |
| this->WriteString("<Keyword>Win32Proj</Keyword>\n", 2); |
| } else { |
| this->WriteString("<Keyword>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(vsGlobalKeyword) |
| << "</Keyword>\n"; |
| } |
| |
| const char* vsGlobalRootNamespace = |
| this->GeneratorTarget->GetProperty("VS_GLOBAL_ROOTNAMESPACE"); |
| if (vsGlobalRootNamespace) { |
| this->WriteString("<RootNamespace>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(vsGlobalRootNamespace) |
| << "</RootNamespace>\n"; |
| } |
| |
| this->WriteString("<Platform>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(this->Platform) |
| << "</Platform>\n"; |
| const char* projLabel = this->GeneratorTarget->GetProperty("PROJECT_LABEL"); |
| if (!projLabel) { |
| projLabel = this->Name.c_str(); |
| } |
| this->WriteString("<ProjectName>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(projLabel) << "</ProjectName>\n"; |
| if (const char* targetFrameworkVersion = this->GeneratorTarget->GetProperty( |
| "VS_DOTNET_TARGET_FRAMEWORK_VERSION")) { |
| this->WriteString("<TargetFrameworkVersion>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(targetFrameworkVersion) |
| << "</TargetFrameworkVersion>\n"; |
| } |
| |
| // Disable the project upgrade prompt that is displayed the first time a |
| // project using an older toolset version is opened in a newer version of |
| // the IDE (respected by VS 2013 and above). |
| if (this->GlobalGenerator->GetVersion() >= |
| cmGlobalVisualStudioGenerator::VS12) { |
| this->WriteString("<VCProjectUpgraderObjectName>NoUpgrade" |
| "</VCProjectUpgraderObjectName>\n", |
| 2); |
| } |
| |
| std::vector<std::string> keys = this->GeneratorTarget->GetPropertyKeys(); |
| for (std::string const& keyIt : keys) { |
| static const char* prefix = "VS_GLOBAL_"; |
| if (keyIt.find(prefix) != 0) |
| continue; |
| std::string globalKey = keyIt.substr(strlen(prefix)); |
| // Skip invalid or separately-handled properties. |
| if (globalKey.empty() || globalKey == "PROJECT_TYPES" || |
| globalKey == "ROOTNAMESPACE" || globalKey == "KEYWORD") { |
| continue; |
| } |
| const char* value = this->GeneratorTarget->GetProperty(keyIt); |
| if (!value) |
| continue; |
| this->WriteString("<", 2); |
| (*this->BuildFileStream) << globalKey << ">" << cmVS10EscapeXML(value) |
| << "</" << globalKey << ">\n"; |
| } |
| |
| if (this->Managed) { |
| std::string outputType = "<OutputType>"; |
| switch (this->GeneratorTarget->GetType()) { |
| case cmStateEnums::OBJECT_LIBRARY: |
| case cmStateEnums::STATIC_LIBRARY: |
| case cmStateEnums::SHARED_LIBRARY: |
| outputType += "Library"; |
| break; |
| case cmStateEnums::MODULE_LIBRARY: |
| outputType += "Module"; |
| break; |
| case cmStateEnums::EXECUTABLE: |
| if (this->GeneratorTarget->Target->GetPropertyAsBool( |
| "WIN32_EXECUTABLE")) { |
| outputType += "WinExe"; |
| } else { |
| outputType += "Exe"; |
| } |
| break; |
| case cmStateEnums::UTILITY: |
| case cmStateEnums::GLOBAL_TARGET: |
| outputType += "Utility"; |
| break; |
| case cmStateEnums::UNKNOWN_LIBRARY: |
| case cmStateEnums::INTERFACE_LIBRARY: |
| break; |
| } |
| outputType += "</OutputType>\n"; |
| this->WriteString(outputType.c_str(), 2); |
| this->WriteString("<AppDesignerFolder>Properties</AppDesignerFolder>\n", |
| 2); |
| } |
| |
| this->WriteString("</PropertyGroup>\n", 1); |
| |
| switch (this->ProjectType) { |
| case vcxproj: |
| this->WriteString("<Import Project=\"" VS10_CXX_DEFAULT_PROPS "\" />\n", |
| 1); |
| break; |
| case csproj: |
| this->WriteString("<Import Project=\"" VS10_CSharp_DEFAULT_PROPS "\" " |
| "Condition=\"Exists('" VS10_CSharp_DEFAULT_PROPS "')\"" |
| "/>\n", |
| 1); |
| break; |
| } |
| |
| this->WriteProjectConfigurationValues(); |
| |
| if (this->ProjectType == vcxproj) { |
| this->WriteString("<Import Project=\"" VS10_CXX_PROPS "\" />\n", 1); |
| } |
| this->WriteString("<ImportGroup Label=\"ExtensionSettings\">\n", 1); |
| if (this->GlobalGenerator->IsCudaEnabled()) { |
| this->WriteString("<Import Project=\"$(VCTargetsPath)\\" |
| "BuildCustomizations\\CUDA ", |
| 2); |
| (*this->BuildFileStream) |
| << cmVS10EscapeXML(this->GlobalGenerator->GetPlatformToolsetCudaString()) |
| << ".props\" />\n"; |
| } |
| if (this->GlobalGenerator->IsMasmEnabled()) { |
| this->WriteString("<Import Project=\"$(VCTargetsPath)\\" |
| "BuildCustomizations\\masm.props\" />\n", |
| 2); |
| } |
| if (this->GlobalGenerator->IsNasmEnabled()) { |
| // Always search in the standard modules location. |
| std::string propsTemplate = |
| GetCMakeFilePath("Templates/MSBuild/nasm.props.in"); |
| |
| std::string propsLocal; |
| propsLocal += this->DefaultArtifactDir; |
| propsLocal += "\\nasm.props"; |
| ConvertToWindowsSlash(propsLocal); |
| this->Makefile->ConfigureFile(propsTemplate.c_str(), propsLocal.c_str(), |
| false, true, true); |
| std::string import = std::string("<Import Project=\"") + |
| cmVS10EscapeXML(propsLocal) + "\" />\n"; |
| this->WriteString(import.c_str(), 2); |
| } |
| this->WriteString("</ImportGroup>\n", 1); |
| this->WriteString("<ImportGroup Label=\"PropertySheets\">\n", 1); |
| { |
| std::string props; |
| switch (this->ProjectType) { |
| case vcxproj: |
| props = VS10_CXX_USER_PROPS; |
| break; |
| case csproj: |
| props = VS10_CSharp_USER_PROPS; |
| break; |
| } |
| if (const char* p = this->GeneratorTarget->GetProperty("VS_USER_PROPS")) { |
| props = p; |
| } |
| if (!props.empty()) { |
| ConvertToWindowsSlash(props); |
| this->WriteString("", 2); |
| (*this->BuildFileStream) |
| << "<Import Project=\"" << cmVS10EscapeXML(props) << "\"" |
| << " Condition=\"exists('" << cmVS10EscapeXML(props) << "')\"" |
| << " Label=\"LocalAppDataPlatform\" />\n"; |
| } |
| } |
| this->WritePlatformExtensions(); |
| this->WriteString("</ImportGroup>\n", 1); |
| this->WriteString("<PropertyGroup Label=\"UserMacros\" />\n", 1); |
| this->WriteWinRTPackageCertificateKeyFile(); |
| this->WritePathAndIncrementalLinkOptions(); |
| this->WriteItemDefinitionGroups(); |
| this->WriteCustomCommands(); |
| this->WriteAllSources(); |
| this->WriteDotNetReferences(); |
| this->WriteEmbeddedResourceGroup(); |
| this->WriteXamlFilesGroup(); |
| this->WriteWinRTReferences(); |
| this->WriteProjectReferences(); |
| this->WriteSDKReferences(); |
| switch (this->ProjectType) { |
| case vcxproj: |
| this->WriteString("<Import Project=\"" VS10_CXX_TARGETS "\" />\n", 1); |
| break; |
| case csproj: |
| this->WriteString("<Import Project=\"" VS10_CSharp_TARGETS "\" />\n", 1); |
| break; |
| } |
| |
| this->WriteTargetSpecificReferences(); |
| this->WriteString("<ImportGroup Label=\"ExtensionTargets\">\n", 1); |
| this->WriteTargetsFileReferences(); |
| if (this->GlobalGenerator->IsCudaEnabled()) { |
| this->WriteString("<Import Project=\"$(VCTargetsPath)\\" |
| "BuildCustomizations\\CUDA ", |
| 2); |
| (*this->BuildFileStream) |
| << cmVS10EscapeXML(this->GlobalGenerator->GetPlatformToolsetCudaString()) |
| << ".targets\" />\n"; |
| } |
| if (this->GlobalGenerator->IsMasmEnabled()) { |
| this->WriteString("<Import Project=\"$(VCTargetsPath)\\" |
| "BuildCustomizations\\masm.targets\" />\n", |
| 2); |
| } |
| if (this->GlobalGenerator->IsNasmEnabled()) { |
| std::string nasmTargets = |
| GetCMakeFilePath("Templates/MSBuild/nasm.targets"); |
| std::string import = "<Import Project=\""; |
| import += cmVS10EscapeXML(nasmTargets) + "\" />\n"; |
| this->WriteString(import.c_str(), 2); |
| } |
| this->WriteString("</ImportGroup>\n", 1); |
| if (this->ProjectType == csproj) { |
| for (std::string const& i : this->Configurations) { |
| this->WriteString("<PropertyGroup Condition=\"'$(Configuration)' == '", |
| 1); |
| (*this->BuildFileStream) << i << "'\">\n"; |
| this->WriteEvents(i); |
| this->WriteString("</PropertyGroup>\n", 1); |
| } |
| // make sure custom commands are executed before build (if necessary) |
| this->WriteString("<PropertyGroup>\n", 1); |
| this->WriteString("<BuildDependsOn>\n", 2); |
| for (std::string const& i : this->CSharpCustomCommandNames) { |
| this->WriteString(i.c_str(), 3); |
| (*this->BuildFileStream) << ";\n"; |
| } |
| this->WriteString("$(BuildDependsOn)\n", 3); |
| this->WriteString("</BuildDependsOn>\n", 2); |
| this->WriteString("</PropertyGroup>\n", 1); |
| } |
| this->WriteString("</Project>", 0); |
| // The groups are stored in a separate file for VS 10 |
| this->WriteGroups(); |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteDotNetReferences() |
| { |
| std::vector<std::string> references; |
| typedef std::pair<std::string, std::string> HintReference; |
| std::vector<HintReference> hintReferences; |
| if (const char* vsDotNetReferences = |
| this->GeneratorTarget->GetProperty("VS_DOTNET_REFERENCES")) { |
| cmSystemTools::ExpandListArgument(vsDotNetReferences, references); |
| } |
| cmPropertyMap const& props = this->GeneratorTarget->Target->GetProperties(); |
| for (auto const& i : props) { |
| if (i.first.find("VS_DOTNET_REFERENCE_") == 0) { |
| std::string name = i.first.substr(20); |
| if (!name.empty()) { |
| std::string path = i.second.GetValue(); |
| if (!cmsys::SystemTools::FileIsFullPath(path)) { |
| path = std::string(this->GeneratorTarget->Target->GetMakefile() |
| ->GetCurrentSourceDirectory()) + |
| "/" + path; |
| } |
| ConvertToWindowsSlash(path); |
| hintReferences.push_back(HintReference(name, path)); |
| } |
| } |
| } |
| if (!references.empty() || !hintReferences.empty()) { |
| this->WriteString("<ItemGroup>\n", 1); |
| for (std::string const& ri : references) { |
| // if the entry from VS_DOTNET_REFERENCES is an existing file, generate |
| // a new hint-reference and name it from the filename |
| if (cmsys::SystemTools::FileExists(ri, true)) { |
| std::string name = cmsys::SystemTools::GetFilenameWithoutExtension(ri); |
| std::string path = ri; |
| ConvertToWindowsSlash(path); |
| hintReferences.push_back(HintReference(name, path)); |
| } else { |
| this->WriteDotNetReference(ri, ""); |
| } |
| } |
| for (const auto& i : hintReferences) { |
| this->WriteDotNetReference(i.first, i.second); |
| } |
| this->WriteString("</ItemGroup>\n", 1); |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteDotNetReference( |
| std::string const& ref, std::string const& hint) |
| { |
| this->WriteString("<Reference Include=\"", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(ref) << "\">\n"; |
| this->WriteString("<CopyLocalSatelliteAssemblies>true" |
| "</CopyLocalSatelliteAssemblies>\n", |
| 3); |
| this->WriteString("<ReferenceOutputAssembly>true" |
| "</ReferenceOutputAssembly>\n", |
| 3); |
| if (!hint.empty()) { |
| const char* privateReference = "True"; |
| if (const char* value = this->GeneratorTarget->GetProperty( |
| "VS_DOTNET_REFERENCES_COPY_LOCAL")) { |
| if (cmSystemTools::IsOff(value)) { |
| privateReference = "False"; |
| } |
| } |
| this->WriteString("<Private>", 3); |
| (*this->BuildFileStream) << privateReference << "</Private>\n"; |
| this->WriteString("<HintPath>", 3); |
| (*this->BuildFileStream) << hint << "</HintPath>\n"; |
| } |
| this->WriteDotNetReferenceCustomTags(ref); |
| this->WriteString("</Reference>\n", 2); |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteDotNetReferenceCustomTags( |
| std::string const& ref) |
| { |
| |
| static const std::string refpropPrefix = "VS_DOTNET_REFERENCEPROP_"; |
| static const std::string refpropInfix = "_TAG_"; |
| const std::string refPropFullPrefix = refpropPrefix + ref + refpropInfix; |
| typedef std::map<std::string, std::string> CustomTags; |
| CustomTags tags; |
| cmPropertyMap const& props = this->GeneratorTarget->Target->GetProperties(); |
| for (const auto& i : props) { |
| if (i.first.find(refPropFullPrefix) == 0) { |
| std::string refTag = i.first.substr(refPropFullPrefix.length()); |
| std::string refVal = i.second.GetValue(); |
| if (!refTag.empty() && !refVal.empty()) { |
| tags[refTag] = refVal; |
| } |
| } |
| } |
| for (auto const& tag : tags) { |
| this->WriteString("<", 3); |
| (*this->BuildFileStream) << tag.first << ">" << cmVS10EscapeXML(tag.second) |
| << "</" << tag.first << ">\n"; |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup() |
| { |
| std::vector<cmSourceFile const*> resxObjs; |
| this->GeneratorTarget->GetResxSources(resxObjs, ""); |
| if (!resxObjs.empty()) { |
| this->WriteString("<ItemGroup>\n", 1); |
| std::string srcDir = this->Makefile->GetCurrentSourceDirectory(); |
| ConvertToWindowsSlash(srcDir); |
| for (cmSourceFile const* oi : resxObjs) { |
| std::string obj = oi->GetFullPath(); |
| this->WriteString("<EmbeddedResource Include=\"", 2); |
| ConvertToWindowsSlash(obj); |
| bool useRelativePath = false; |
| if (this->ProjectType == csproj && this->InSourceBuild) { |
| // If we do an in-source build and the resource file is in a |
| // subdirectory |
| // of the .csproj file, we have to use relative pathnames, otherwise |
| // visual studio does not show the file in the IDE. Sorry. |
| if (obj.find(srcDir) == 0) { |
| obj = this->ConvertPath(obj, true); |
| ConvertToWindowsSlash(obj); |
| useRelativePath = true; |
| } |
| } |
| (*this->BuildFileStream) << obj << "\">\n"; |
| |
| if (this->ProjectType != csproj) { |
| this->WriteString("<DependentUpon>", 3); |
| std::string hFileName = obj.substr(0, obj.find_last_of(".")) + ".h"; |
| (*this->BuildFileStream) << hFileName << "</DependentUpon>\n"; |
| |
| for (std::string const& i : this->Configurations) { |
| this->WritePlatformConfigTag("LogicalName", i, 3); |
| if (this->GeneratorTarget->GetProperty("VS_GLOBAL_ROOTNAMESPACE") || |
| // Handle variant of VS_GLOBAL_<variable> for RootNamespace. |
| this->GeneratorTarget->GetProperty("VS_GLOBAL_RootNamespace")) { |
| (*this->BuildFileStream) << "$(RootNamespace)."; |
| } |
| (*this->BuildFileStream) << "%(Filename)"; |
| (*this->BuildFileStream) << ".resources"; |
| (*this->BuildFileStream) << "</LogicalName>\n"; |
| } |
| } else { |
| std::string binDir = this->Makefile->GetCurrentBinaryDirectory(); |
| ConvertToWindowsSlash(binDir); |
| // If the resource was NOT added using a relative path (which should |
| // be the default), we have to provide a link here |
| if (!useRelativePath) { |
| std::string link; |
| if (obj.find(srcDir) == 0) { |
| link = obj.substr(srcDir.length() + 1); |
| } else if (obj.find(binDir) == 0) { |
| link = obj.substr(binDir.length() + 1); |
| } else { |
| link = cmsys::SystemTools::GetFilenameName(obj); |
| } |
| if (!link.empty()) { |
| this->WriteString("<Link>", 3); |
| (*this->BuildFileStream) << link << "</Link>\n"; |
| } |
| } |
| // Determine if this is a generated resource from a .Designer.cs file |
| std::string designerResource = |
| cmSystemTools::GetFilenamePath(oi->GetFullPath()) + "/" + |
| cmSystemTools::GetFilenameWithoutLastExtension(oi->GetFullPath()) + |
| ".Designer.cs"; |
| if (cmsys::SystemTools::FileExists(designerResource)) { |
| std::string generator = "PublicResXFileCodeGenerator"; |
| if (const char* g = oi->GetProperty("VS_RESOURCE_GENERATOR")) { |
| generator = g; |
| } |
| if (!generator.empty()) { |
| this->WriteString("<Generator>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(generator) |
| << "</Generator>\n"; |
| if (designerResource.find(srcDir) == 0) { |
| designerResource = designerResource.substr(srcDir.length() + 1); |
| } else if (designerResource.find(binDir) == 0) { |
| designerResource = designerResource.substr(binDir.length() + 1); |
| } else { |
| designerResource = |
| cmsys::SystemTools::GetFilenameName(designerResource); |
| } |
| ConvertToWindowsSlash(designerResource); |
| this->WriteString("<LastGenOutput>", 3); |
| (*this->BuildFileStream) << designerResource |
| << "</LastGenOutput>\n"; |
| } |
| } |
| const cmPropertyMap& props = oi->GetProperties(); |
| for (const auto& p : props) { |
| static const std::string propNamePrefix = "VS_CSHARP_"; |
| if (p.first.find(propNamePrefix) == 0) { |
| std::string tagName = p.first.substr(propNamePrefix.length()); |
| if (!tagName.empty()) { |
| std::string value = props.GetPropertyValue(p.first); |
| if (!value.empty()) { |
| this->WriteString("<", 3); |
| (*this->BuildFileStream) << tagName << ">"; |
| (*this->BuildFileStream) << cmVS10EscapeXML(value); |
| (*this->BuildFileStream) << "</" << tagName << ">\n"; |
| } |
| } |
| } |
| } |
| } |
| |
| this->WriteString("</EmbeddedResource>\n", 2); |
| } |
| this->WriteString("</ItemGroup>\n", 1); |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup() |
| { |
| std::vector<cmSourceFile const*> xamlObjs; |
| this->GeneratorTarget->GetXamlSources(xamlObjs, ""); |
| if (!xamlObjs.empty()) { |
| this->WriteString("<ItemGroup>\n", 1); |
| for (cmSourceFile const* oi : xamlObjs) { |
| std::string obj = oi->GetFullPath(); |
| std::string xamlType; |
| const char* xamlTypeProperty = oi->GetProperty("VS_XAML_TYPE"); |
| if (xamlTypeProperty) { |
| xamlType = xamlTypeProperty; |
| } else { |
| xamlType = "Page"; |
| } |
| |
| this->WriteSource(xamlType, oi, ">\n"); |
| if (this->ProjectType == csproj && !this->InSourceBuild) { |
| // add <Link> tag to written XAML source if necessary |
| const std::string srcDir = this->Makefile->GetCurrentSourceDirectory(); |
| const std::string binDir = this->Makefile->GetCurrentBinaryDirectory(); |
| std::string link; |
| if (obj.find(srcDir) == 0) { |
| link = obj.substr(srcDir.length() + 1); |
| } else if (obj.find(binDir) == 0) { |
| link = obj.substr(binDir.length() + 1); |
| } else { |
| link = cmsys::SystemTools::GetFilenameName(obj); |
| } |
| if (!link.empty()) { |
| ConvertToWindowsSlash(link); |
| this->WriteString("<Link>", 3); |
| (*this->BuildFileStream) << link << "</Link>\n"; |
| } |
| } |
| this->WriteString("<SubType>Designer</SubType>\n", 3); |
| this->WriteString("</", 2); |
| (*this->BuildFileStream) << xamlType << ">\n"; |
| } |
| this->WriteString("</ItemGroup>\n", 1); |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteTargetSpecificReferences() |
| { |
| if (this->MSTools) { |
| if (this->GlobalGenerator->TargetsWindowsPhone() && |
| this->GlobalGenerator->GetSystemVersion() == "8.0") { |
| this->WriteString("<Import Project=\"" |
| "$(MSBuildExtensionsPath)\\Microsoft\\WindowsPhone\\v" |
| "$(TargetPlatformVersion)\\Microsoft.Cpp.WindowsPhone." |
| "$(TargetPlatformVersion).targets\" />\n", |
| 1); |
| } |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteTargetsFileReferences() |
| { |
| for (std::vector<TargetsFileAndConfigs>::iterator i = |
| this->TargetsFileAndConfigsVec.begin(); |
| i != this->TargetsFileAndConfigsVec.end(); ++i) { |
| TargetsFileAndConfigs const& tac = *i; |
| this->WriteString("<Import Project=\"", 3); |
| (*this->BuildFileStream) << tac.File << "\" "; |
| (*this->BuildFileStream) << "Condition=\""; |
| (*this->BuildFileStream) << "Exists('" << tac.File << "')"; |
| if (!tac.Configs.empty()) { |
| (*this->BuildFileStream) << " And ("; |
| for (size_t j = 0; j < tac.Configs.size(); ++j) { |
| if (j > 0) { |
| (*this->BuildFileStream) << " Or "; |
| } |
| (*this->BuildFileStream) << "'$(Configuration)'=='" << tac.Configs[j] |
| << "'"; |
| } |
| (*this->BuildFileStream) << ")"; |
| } |
| (*this->BuildFileStream) << "\" />\n"; |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteWinRTReferences() |
| { |
| std::vector<std::string> references; |
| if (const char* vsWinRTReferences = |
| this->GeneratorTarget->GetProperty("VS_WINRT_REFERENCES")) { |
| cmSystemTools::ExpandListArgument(vsWinRTReferences, references); |
| } |
| |
| if (this->GlobalGenerator->TargetsWindowsPhone() && |
| this->GlobalGenerator->GetSystemVersion() == "8.0" && |
| references.empty()) { |
| references.push_back("platform.winmd"); |
| } |
| if (!references.empty()) { |
| this->WriteString("<ItemGroup>\n", 1); |
| for (std::vector<std::string>::iterator ri = references.begin(); |
| ri != references.end(); ++ri) { |
| this->WriteString("<Reference Include=\"", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(*ri) << "\">\n"; |
| this->WriteString("<IsWinMDFile>true</IsWinMDFile>\n", 3); |
| this->WriteString("</Reference>\n", 2); |
| } |
| this->WriteString("</ItemGroup>\n", 1); |
| } |
| } |
| |
| // ConfigurationType Application, Utility StaticLibrary DynamicLibrary |
| |
| void cmVisualStudio10TargetGenerator::WriteProjectConfigurations() |
| { |
| this->WriteString("<ItemGroup Label=\"ProjectConfigurations\">\n", 1); |
| for (std::vector<std::string>::const_iterator i = |
| this->Configurations.begin(); |
| i != this->Configurations.end(); ++i) { |
| this->WriteString("<ProjectConfiguration Include=\"", 2); |
| (*this->BuildFileStream) << *i << "|" << this->Platform << "\">\n"; |
| this->WriteString("<Configuration>", 3); |
| (*this->BuildFileStream) << *i << "</Configuration>\n"; |
| this->WriteString("<Platform>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(this->Platform) |
| << "</Platform>\n"; |
| this->WriteString("</ProjectConfiguration>\n", 2); |
| } |
| this->WriteString("</ItemGroup>\n", 1); |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues() |
| { |
| for (std::vector<std::string>::const_iterator i = |
| this->Configurations.begin(); |
| i != this->Configurations.end(); ++i) { |
| this->WritePlatformConfigTag("PropertyGroup", *i, 1, |
| " Label=\"Configuration\"", "\n"); |
| |
| if (this->ProjectType != csproj) { |
| std::string configType = "<ConfigurationType>"; |
| if (const char* vsConfigurationType = |
| this->GeneratorTarget->GetProperty("VS_CONFIGURATION_TYPE")) { |
| configType += cmVS10EscapeXML(vsConfigurationType); |
| } else { |
| switch (this->GeneratorTarget->GetType()) { |
| case cmStateEnums::SHARED_LIBRARY: |
| case cmStateEnums::MODULE_LIBRARY: |
| configType += "DynamicLibrary"; |
| break; |
| case cmStateEnums::OBJECT_LIBRARY: |
| case cmStateEnums::STATIC_LIBRARY: |
| configType += "StaticLibrary"; |
| break; |
| case cmStateEnums::EXECUTABLE: |
| if (this->NsightTegra && |
| !this->GeneratorTarget->GetPropertyAsBool("ANDROID_GUI")) { |
| // Android executables are .so too. |
| configType += "DynamicLibrary"; |
| } else { |
| configType += "Application"; |
| } |
| break; |
| case cmStateEnums::UTILITY: |
| case cmStateEnums::GLOBAL_TARGET: |
| if (this->NsightTegra) { |
| // Tegra-Android platform does not understand "Utility". |
| configType += "StaticLibrary"; |
| } else { |
| configType += "Utility"; |
| } |
| break; |
| case cmStateEnums::UNKNOWN_LIBRARY: |
| case cmStateEnums::INTERFACE_LIBRARY: |
| break; |
| } |
| } |
| configType += "</ConfigurationType>\n"; |
| this->WriteString(configType.c_str(), 2); |
| } |
| |
| if (this->MSTools) { |
| if (!this->Managed) { |
| this->WriteMSToolConfigurationValues(*i); |
| } else { |
| this->WriteMSToolConfigurationValuesManaged(*i); |
| } |
| } else if (this->NsightTegra) { |
| this->WriteNsightTegraConfigurationValues(*i); |
| } |
| |
| this->WriteString("</PropertyGroup>\n", 1); |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValues( |
| std::string const& config) |
| { |
| cmGlobalVisualStudio10Generator* gg = |
| static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator); |
| const char* mfcFlag = |
| this->GeneratorTarget->Target->GetMakefile()->GetDefinition( |
| "CMAKE_MFC_FLAG"); |
| if (mfcFlag) { |
| std::string const mfcFlagValue = mfcFlag; |
| |
| std::string useOfMfcValue = "false"; |
| if (this->GeneratorTarget->GetType() <= cmStateEnums::OBJECT_LIBRARY) { |
| if (mfcFlagValue == "1") { |
| useOfMfcValue = "Static"; |
| } else if (mfcFlagValue == "2") { |
| useOfMfcValue = "Dynamic"; |
| } |
| } |
| std::string mfcLine = "<UseOfMfc>"; |
| mfcLine += useOfMfcValue + "</UseOfMfc>\n"; |
| this->WriteString(mfcLine.c_str(), 2); |
| } |
| |
| if ((this->GeneratorTarget->GetType() <= cmStateEnums::OBJECT_LIBRARY && |
| this->ClOptions[config]->UsingUnicode()) || |
| this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT") || |
| this->GlobalGenerator->TargetsWindowsPhone() || |
| this->GlobalGenerator->TargetsWindowsStore() || |
| this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_EXTENSIONS")) { |
| this->WriteString("<CharacterSet>Unicode</CharacterSet>\n", 2); |
| } else if (this->GeneratorTarget->GetType() <= |
| cmStateEnums::MODULE_LIBRARY && |
| this->ClOptions[config]->UsingSBCS()) { |
| this->WriteString("<CharacterSet>NotSet</CharacterSet>\n", 2); |
| } else { |
| this->WriteString("<CharacterSet>MultiByte</CharacterSet>\n", 2); |
| } |
| if (const char* toolset = gg->GetPlatformToolset()) { |
| std::string pts = "<PlatformToolset>"; |
| pts += toolset; |
| pts += "</PlatformToolset>\n"; |
| this->WriteString(pts.c_str(), 2); |
| } |
| if (this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT") || |
| this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_EXTENSIONS")) { |
| this->WriteString("<WindowsAppContainer>true" |
| "</WindowsAppContainer>\n", |
| 2); |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesManaged( |
| std::string const& config) |
| { |
| cmGlobalVisualStudio10Generator* gg = |
| static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator); |
| |
| Options& o = *(this->ClOptions[config]); |
| |
| if (o.IsDebug()) { |
| this->WriteString("<DebugSymbols>true</DebugSymbols>\n", 2); |
| this->WriteString("<DefineDebug>true</DefineDebug>\n", 2); |
| } |
| |
| std::string outDir = this->GeneratorTarget->GetDirectory(config) + "/"; |
| ConvertToWindowsSlash(outDir); |
| this->WriteString("<OutputPath>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(outDir) << "</OutputPath>\n"; |
| |
| if (o.HasFlag("Platform")) { |
| this->WriteString("<PlatformTarget>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(o.GetFlag("Platform")) |
| << "</PlatformTarget>\n"; |
| o.RemoveFlag("Platform"); |
| } |
| |
| if (const char* toolset = gg->GetPlatformToolset()) { |
| this->WriteString("<PlatformToolset>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(toolset) |
| << "</PlatformToolset>\n"; |
| } |
| |
| std::string postfixName = cmSystemTools::UpperCase(config); |
| postfixName += "_POSTFIX"; |
| std::string assemblyName = this->GeneratorTarget->GetOutputName( |
| config, cmStateEnums::RuntimeBinaryArtifact); |
| if (const char* postfix = this->GeneratorTarget->GetProperty(postfixName)) { |
| assemblyName += postfix; |
| } |
| this->WriteString("<AssemblyName>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(assemblyName) |
| << "</AssemblyName>\n"; |
| |
| if (cmStateEnums::EXECUTABLE == this->GeneratorTarget->GetType()) { |
| this->WriteString("<StartAction>Program</StartAction>\n", 2); |
| this->WriteString("<StartProgram>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(outDir) |
| << cmVS10EscapeXML(assemblyName) |
| << ".exe</StartProgram>\n"; |
| } |
| |
| o.OutputFlagMap(*this->BuildFileStream, " "); |
| } |
| |
| //---------------------------------------------------------------------------- |
| void cmVisualStudio10TargetGenerator::WriteNsightTegraConfigurationValues( |
| std::string const&) |
| { |
| cmGlobalVisualStudio10Generator* gg = |
| static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator); |
| const char* toolset = gg->GetPlatformToolset(); |
| std::string ntv = "<NdkToolchainVersion>"; |
| ntv += toolset ? toolset : "Default"; |
| ntv += "</NdkToolchainVersion>\n"; |
| this->WriteString(ntv.c_str(), 2); |
| if (const char* minApi = |
| this->GeneratorTarget->GetProperty("ANDROID_API_MIN")) { |
| this->WriteString("<AndroidMinAPI>", 2); |
| (*this->BuildFileStream) << "android-" << cmVS10EscapeXML(minApi) |
| << "</AndroidMinAPI>\n"; |
| } |
| if (const char* api = this->GeneratorTarget->GetProperty("ANDROID_API")) { |
| this->WriteString("<AndroidTargetAPI>", 2); |
| (*this->BuildFileStream) << "android-" << cmVS10EscapeXML(api) |
| << "</AndroidTargetAPI>\n"; |
| } |
| |
| if (const char* cpuArch = |
| this->GeneratorTarget->GetProperty("ANDROID_ARCH")) { |
| this->WriteString("<AndroidArch>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(cpuArch) << "</AndroidArch>\n"; |
| } |
| |
| if (const char* stlType = |
| this->GeneratorTarget->GetProperty("ANDROID_STL_TYPE")) { |
| this->WriteString("<AndroidStlType>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(stlType) |
| << "</AndroidStlType>\n"; |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteCustomCommands() |
| { |
| this->SourcesVisited.clear(); |
| this->CSharpCustomCommandNames.clear(); |
| std::vector<cmSourceFile const*> customCommands; |
| this->GeneratorTarget->GetCustomCommands(customCommands, ""); |
| for (std::vector<cmSourceFile const*>::const_iterator si = |
| customCommands.begin(); |
| si != customCommands.end(); ++si) { |
| this->WriteCustomCommand(*si); |
| } |
| |
| // Add CMakeLists.txt file with rule to re-run CMake for user convenience. |
| if (this->GeneratorTarget->GetType() != cmStateEnums::GLOBAL_TARGET && |
| this->GeneratorTarget->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) { |
| if (cmSourceFile const* sf = |
| this->LocalGenerator->CreateVCProjBuildRule()) { |
| this->WriteCustomCommand(sf); |
| } |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteCustomCommand( |
| cmSourceFile const* sf) |
| { |
| if (this->SourcesVisited.insert(sf).second) { |
| if (std::vector<cmSourceFile*> const* depends = |
| this->GeneratorTarget->GetSourceDepends(sf)) { |
| for (std::vector<cmSourceFile*>::const_iterator di = depends->begin(); |
| di != depends->end(); ++di) { |
| this->WriteCustomCommand(*di); |
| } |
| } |
| if (cmCustomCommand const* command = sf->GetCustomCommand()) { |
| // C# projects write their <Target> within WriteCustomRule() |
| if (this->ProjectType != csproj) { |
| this->WriteString("<ItemGroup>\n", 1); |
| } |
| this->WriteCustomRule(sf, *command); |
| if (this->ProjectType != csproj) { |
| this->WriteString("</ItemGroup>\n", 1); |
| } |
| } |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteCustomRule( |
| cmSourceFile const* source, cmCustomCommand const& command) |
| { |
| std::string sourcePath = source->GetFullPath(); |
| // VS 10 will always rebuild a custom command attached to a .rule |
| // file that doesn't exist so create the file explicitly. |
| if (source->GetPropertyAsBool("__CMAKE_RULE")) { |
| if (!cmSystemTools::FileExists(sourcePath.c_str())) { |
| // Make sure the path exists for the file |
| std::string path = cmSystemTools::GetFilenamePath(sourcePath); |
| cmSystemTools::MakeDirectory(path.c_str()); |
| cmsys::ofstream fout(sourcePath.c_str()); |
| if (fout) { |
| fout << "# generated from CMake\n"; |
| fout.flush(); |
| fout.close(); |
| // Force given file to have a very old timestamp, thus |
| // preventing dependent rebuilds. |
| this->ForceOld(sourcePath); |
| } else { |
| std::string error = "Could not create file: ["; |
| error += sourcePath; |
| error += "] "; |
| cmSystemTools::Error(error.c_str(), |
| cmSystemTools::GetLastSystemError().c_str()); |
| } |
| } |
| } |
| cmLocalVisualStudio7Generator* lg = this->LocalGenerator; |
| |
| if (this->ProjectType != csproj) { |
| this->WriteSource("CustomBuild", source, ">\n"); |
| } else { |
| this->WriteString("<ItemGroup>\n", 1); |
| std::string link; |
| this->GetCSharpSourceLink(source, link); |
| this->WriteSource("None", source, ">\n"); |
| if (!link.empty()) { |
| this->WriteString("<Link>", 3); |
| (*this->BuildFileStream) << link << "</Link>\n"; |
| } |
| this->WriteString("</None>\n", 2); |
| this->WriteString("</ItemGroup>\n", 1); |
| } |
| for (std::vector<std::string>::const_iterator i = |
| this->Configurations.begin(); |
| i != this->Configurations.end(); ++i) { |
| cmCustomCommandGenerator ccg(command, *i, this->LocalGenerator); |
| std::string comment = lg->ConstructComment(ccg); |
| comment = cmVS10EscapeComment(comment); |
| std::string script = cmVS10EscapeXML(lg->ConstructScript(ccg)); |
| // input files for custom command |
| std::stringstream inputs; |
| inputs << cmVS10EscapeXML(source->GetFullPath()); |
| for (std::vector<std::string>::const_iterator d = ccg.GetDepends().begin(); |
| d != ccg.GetDepends().end(); ++d) { |
| std::string dep; |
| if (this->LocalGenerator->GetRealDependency(*d, *i, dep)) { |
| ConvertToWindowsSlash(dep); |
| inputs << ";" << cmVS10EscapeXML(dep); |
| } |
| } |
| // output files for custom command |
| std::stringstream outputs; |
| const char* sep = ""; |
| for (std::vector<std::string>::const_iterator o = ccg.GetOutputs().begin(); |
| o != ccg.GetOutputs().end(); ++o) { |
| std::string out = *o; |
| ConvertToWindowsSlash(out); |
| outputs << sep << cmVS10EscapeXML(out); |
| sep = ";"; |
| } |
| if (this->ProjectType == csproj) { |
| std::string name = "CustomCommand_" + *i + "_" + |
| cmSystemTools::ComputeStringMD5(sourcePath); |
| std::string inputs_s = inputs.str(); |
| std::string outputs_s = outputs.str(); |
| comment = cmVS10EscapeQuotes(comment); |
| script = cmVS10EscapeQuotes(script); |
| inputs_s = cmVS10EscapeQuotes(inputs_s); |
| outputs_s = cmVS10EscapeQuotes(outputs_s); |
| this->WriteCustomRuleCSharp(*i, name, script, inputs_s, outputs_s, |
| comment); |
| } else { |
| this->WriteCustomRuleCpp(*i, script, inputs.str(), outputs.str(), |
| comment); |
| } |
| } |
| if (this->ProjectType != csproj) { |
| this->WriteString("</CustomBuild>\n", 2); |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteCustomRuleCpp( |
| std::string const& config, std::string const& script, |
| std::string const& inputs, std::string const& outputs, |
| std::string const& comment) |
| { |
| this->WritePlatformConfigTag("Message", config, 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(comment) << "</Message>\n"; |
| this->WritePlatformConfigTag("Command", config, 3); |
| (*this->BuildFileStream) << script << "</Command>\n"; |
| this->WritePlatformConfigTag("AdditionalInputs", config, 3); |
| (*this->BuildFileStream) << inputs; |
| (*this->BuildFileStream) << ";%(AdditionalInputs)</AdditionalInputs>\n"; |
| this->WritePlatformConfigTag("Outputs", config, 3); |
| (*this->BuildFileStream) << outputs << "</Outputs>\n"; |
| if (this->LocalGenerator->GetVersion() > |
| cmGlobalVisualStudioGenerator::VS10) { |
| // VS >= 11 let us turn off linking of custom command outputs. |
| this->WritePlatformConfigTag("LinkObjects", config, 3); |
| (*this->BuildFileStream) << "false</LinkObjects>\n"; |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteCustomRuleCSharp( |
| std::string const& config, std::string const& name, |
| std::string const& script, std::string const& inputs, |
| std::string const& outputs, std::string const& comment) |
| { |
| this->CSharpCustomCommandNames.insert(name); |
| std::stringstream attributes; |
| attributes << "\n Name=\"" << name << "\""; |
| attributes << "\n Inputs=\"" << inputs << "\""; |
| attributes << "\n Outputs=\"" << outputs << "\""; |
| this->WritePlatformConfigTag("Target", config, 1, attributes.str().c_str(), |
| "\n"); |
| if (!comment.empty()) { |
| this->WriteString("<Exec Command=\"", 2); |
| (*this->BuildFileStream) << "echo " << cmVS10EscapeXML(comment) |
| << "\" />\n"; |
| } |
| this->WriteString("<Exec Command=\"", 2); |
| (*this->BuildFileStream) << script << "\" />\n"; |
| this->WriteString("</Target>\n", 1); |
| } |
| |
| std::string cmVisualStudio10TargetGenerator::ConvertPath( |
| std::string const& path, bool forceRelative) |
| { |
| return forceRelative |
| ? cmSystemTools::RelativePath( |
| this->LocalGenerator->GetCurrentBinaryDirectory(), path.c_str()) |
| : path.c_str(); |
| } |
| |
| static void ConvertToWindowsSlash(std::string& s) |
| { |
| // first convert all of the slashes |
| std::string::size_type pos = 0; |
| while ((pos = s.find('/', pos)) != std::string::npos) { |
| s[pos] = '\\'; |
| pos++; |
| } |
| } |
| void cmVisualStudio10TargetGenerator::WriteGroups() |
| { |
| if (this->ProjectType == csproj) { |
| return; |
| } |
| |
| // collect up group information |
| std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups(); |
| |
| std::vector<cmGeneratorTarget::AllConfigSource> const& sources = |
| this->GeneratorTarget->GetAllConfigSources(); |
| |
| std::set<cmSourceGroup*> groupsUsed; |
| for (std::vector<cmGeneratorTarget::AllConfigSource>::const_iterator si = |
| sources.begin(); |
| si != sources.end(); ++si) { |
| std::string const& source = si->Source->GetFullPath(); |
| cmSourceGroup* sourceGroup = |
| this->Makefile->FindSourceGroup(source, sourceGroups); |
| groupsUsed.insert(sourceGroup); |
| } |
| |
| this->AddMissingSourceGroups(groupsUsed, sourceGroups); |
| |
| // Write out group file |
| std::string path = this->LocalGenerator->GetCurrentBinaryDirectory(); |
| path += "/"; |
| path += this->Name; |
| path += computeProjectFileExtension(this->GeneratorTarget, |
| *this->Configurations.begin()); |
| path += ".filters"; |
| cmGeneratedFileStream fout(path.c_str()); |
| fout.SetCopyIfDifferent(true); |
| char magic[] = { char(0xEF), char(0xBB), char(0xBF) }; |
| fout.write(magic, 3); |
| cmGeneratedFileStream* save = this->BuildFileStream; |
| this->BuildFileStream = &fout; |
| |
| // get the tools version to use |
| const std::string toolsVer(this->GlobalGenerator->GetToolsVersion()); |
| std::string project_defaults = "<?xml version=\"1.0\" encoding=\"" + |
| this->GlobalGenerator->Encoding() + "\"?>\n"; |
| project_defaults.append("<Project ToolsVersion=\""); |
| project_defaults.append(toolsVer + "\" "); |
| project_defaults.append( |
| "xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n"); |
| this->WriteString(project_defaults.c_str(), 0); |
| |
| for (ToolSourceMap::const_iterator ti = this->Tools.begin(); |
| ti != this->Tools.end(); ++ti) { |
| this->WriteGroupSources(ti->first.c_str(), ti->second, sourceGroups); |
| } |
| |
| // Added files are images and the manifest. |
| if (!this->AddedFiles.empty()) { |
| this->WriteString("<ItemGroup>\n", 1); |
| for (std::string const& oi : this->AddedFiles) { |
| std::string fileName = |
| cmSystemTools::LowerCase(cmSystemTools::GetFilenameName(oi)); |
| if (fileName == "wmappmanifest.xml") { |
| this->WriteString("<XML Include=\"", 2); |
| (*this->BuildFileStream) << oi << "\">\n"; |
| this->WriteString("<Filter>Resource Files</Filter>\n", 3); |
| this->WriteString("</XML>\n", 2); |
| } else if (cmSystemTools::GetFilenameExtension(fileName) == |
| ".appxmanifest") { |
| this->WriteString("<AppxManifest Include=\"", 2); |
| (*this->BuildFileStream) << oi << "\">\n"; |
| this->WriteString("<Filter>Resource Files</Filter>\n", 3); |
| this->WriteString("</AppxManifest>\n", 2); |
| } else if (cmSystemTools::GetFilenameExtension(fileName) == ".pfx") { |
| this->WriteString("<None Include=\"", 2); |
| (*this->BuildFileStream) << oi << "\">\n"; |
| this->WriteString("<Filter>Resource Files</Filter>\n", 3); |
| this->WriteString("</None>\n", 2); |
| } else { |
| this->WriteString("<Image Include=\"", 2); |
| (*this->BuildFileStream) << oi << "\">\n"; |
| this->WriteString("<Filter>Resource Files</Filter>\n", 3); |
| this->WriteString("</Image>\n", 2); |
| } |
| } |
| this->WriteString("</ItemGroup>\n", 1); |
| } |
| |
| std::vector<cmSourceFile const*> resxObjs; |
| this->GeneratorTarget->GetResxSources(resxObjs, ""); |
| if (!resxObjs.empty()) { |
| this->WriteString("<ItemGroup>\n", 1); |
| for (cmSourceFile const* oi : resxObjs) { |
| std::string obj = oi->GetFullPath(); |
| this->WriteString("<EmbeddedResource Include=\"", 2); |
| ConvertToWindowsSlash(obj); |
| (*this->BuildFileStream) << cmVS10EscapeXML(obj) << "\">\n"; |
| this->WriteString("<Filter>Resource Files</Filter>\n", 3); |
| this->WriteString("</EmbeddedResource>\n", 2); |
| } |
| this->WriteString("</ItemGroup>\n", 1); |
| } |
| |
| this->WriteString("<ItemGroup>\n", 1); |
| std::vector<cmSourceGroup*> groupsVec(groupsUsed.begin(), groupsUsed.end()); |
| std::sort(groupsVec.begin(), groupsVec.end(), |
| [](cmSourceGroup* l, cmSourceGroup* r) { |
| return l->GetFullName() < r->GetFullName(); |
| }); |
| for (cmSourceGroup* sg : groupsVec) { |
| std::string const& name = sg->GetFullName(); |
| if (!name.empty()) { |
| this->WriteString("<Filter Include=\"", 2); |
| (*this->BuildFileStream) << name << "\">\n"; |
| std::string guidName = "SG_Filter_"; |
| guidName += name; |
| this->WriteString("<UniqueIdentifier>", 3); |
| std::string guid = this->GlobalGenerator->GetGUID(guidName); |
| (*this->BuildFileStream) << "{" << guid << "}" |
| << "</UniqueIdentifier>\n"; |
| this->WriteString("</Filter>\n", 2); |
| } |
| } |
| |
| if (!resxObjs.empty() || !this->AddedFiles.empty()) { |
| this->WriteString("<Filter Include=\"Resource Files\">\n", 2); |
| std::string guidName = "SG_Filter_Resource Files"; |
| this->WriteString("<UniqueIdentifier>", 3); |
| std::string guid = this->GlobalGenerator->GetGUID(guidName); |
| (*this->BuildFileStream) << "{" << guid << "}" |
| << "</UniqueIdentifier>\n"; |
| this->WriteString("<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;", 3); |
| (*this->BuildFileStream) << "gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;"; |
| (*this->BuildFileStream) << "mfcribbon-ms</Extensions>\n"; |
| this->WriteString("</Filter>\n", 2); |
| } |
| |
| this->WriteString("</ItemGroup>\n", 1); |
| this->WriteString("</Project>\n", 0); |
| // restore stream pointer |
| this->BuildFileStream = save; |
| |
| if (fout.Close()) { |
| this->GlobalGenerator->FileReplacedDuringGenerate(path); |
| } |
| } |
| |
| // Add to groupsUsed empty source groups that have non-empty children. |
| void cmVisualStudio10TargetGenerator::AddMissingSourceGroups( |
| std::set<cmSourceGroup*>& groupsUsed, |
| const std::vector<cmSourceGroup>& allGroups) |
| { |
| for (cmSourceGroup const& current : allGroups) { |
| std::vector<cmSourceGroup> const& children = current.GetGroupChildren(); |
| if (children.empty()) { |
| continue; // the group is really empty |
| } |
| |
| this->AddMissingSourceGroups(groupsUsed, children); |
| |
| cmSourceGroup* current_ptr = const_cast<cmSourceGroup*>(¤t); |
| if (groupsUsed.find(current_ptr) != groupsUsed.end()) { |
| continue; // group has already been added to set |
| } |
| |
| // check if it least one of the group's descendants is not empty |
| // (at least one child must already have been added) |
| std::vector<cmSourceGroup>::const_iterator child_it = children.begin(); |
| while (child_it != children.end()) { |
| cmSourceGroup* child_ptr = const_cast<cmSourceGroup*>(&(*child_it)); |
| if (groupsUsed.find(child_ptr) != groupsUsed.end()) { |
| break; // found a child that was already added => add current group too |
| } |
| child_it++; |
| } |
| |
| if (child_it == children.end()) { |
| continue; // no descendants have source files => ignore this group |
| } |
| |
| groupsUsed.insert(current_ptr); |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteGroupSources( |
| const char* name, ToolSources const& sources, |
| std::vector<cmSourceGroup>& sourceGroups) |
| { |
| this->WriteString("<ItemGroup>\n", 1); |
| for (ToolSource const& s : sources) { |
| cmSourceFile const* sf = s.SourceFile; |
| std::string const& source = sf->GetFullPath(); |
| cmSourceGroup* sourceGroup = |
| this->Makefile->FindSourceGroup(source, sourceGroups); |
| std::string const& filter = sourceGroup->GetFullName(); |
| this->WriteString("<", 2); |
| std::string path = this->ConvertPath(source, s.RelativePath); |
| ConvertToWindowsSlash(path); |
| (*this->BuildFileStream) << name << " Include=\"" << cmVS10EscapeXML(path); |
| if (!filter.empty()) { |
| (*this->BuildFileStream) << "\">\n"; |
| this->WriteString("<Filter>", 3); |
| (*this->BuildFileStream) << filter << "</Filter>\n"; |
| this->WriteString("</", 2); |
| (*this->BuildFileStream) << name << ">\n"; |
| } else { |
| (*this->BuildFileStream) << "\" />\n"; |
| } |
| } |
| this->WriteString("</ItemGroup>\n", 1); |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteHeaderSource(cmSourceFile const* sf) |
| { |
| std::string const& fileName = sf->GetFullPath(); |
| if (this->IsResxHeader(fileName)) { |
| this->WriteSource("ClInclude", sf, ">\n"); |
| this->WriteString("<FileType>CppForm</FileType>\n", 3); |
| this->WriteString("</ClInclude>\n", 2); |
| } else if (this->IsXamlHeader(fileName)) { |
| this->WriteSource("ClInclude", sf, ">\n"); |
| this->WriteString("<DependentUpon>", 3); |
| std::string xamlFileName = fileName.substr(0, fileName.find_last_of(".")); |
| (*this->BuildFileStream) << xamlFileName << "</DependentUpon>\n"; |
| this->WriteString("</ClInclude>\n", 2); |
| } else { |
| this->WriteSource("ClInclude", sf); |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf) |
| { |
| bool toolHasSettings = false; |
| std::string tool = "None"; |
| std::string shaderType; |
| std::string shaderEntryPoint; |
| std::string shaderModel; |
| std::string shaderAdditionalFlags; |
| std::string shaderDisableOptimizations; |
| std::string shaderEnableDebug; |
| std::string outputHeaderFile; |
| std::string variableName; |
| std::string settingsGenerator; |
| std::string settingsLastGenOutput; |
| std::string sourceLink; |
| std::string subType; |
| std::string copyToOutDir; |
| std::string includeInVsix; |
| std::string ext = cmSystemTools::LowerCase(sf->GetExtension()); |
| if (this->ProjectType == csproj) { |
| // EVERY extra source file must have a <Link>, otherwise it might not |
| // be visible in Visual Studio at all. The path relative to current |
| // source- or binary-dir is used within the link, if the file is |
| // in none of these paths, it is added with the plain filename without |
| // any path. This means the file will show up at root-level of the csproj |
| // (where CMakeLists.txt etc. are). |
| if (!this->InSourceBuild) { |
| toolHasSettings = true; |
| std::string fullFileName = sf->GetFullPath(); |
| std::string srcDir = this->Makefile->GetCurrentSourceDirectory(); |
| std::string binDir = this->Makefile->GetCurrentBinaryDirectory(); |
| if (fullFileName.find(binDir) != std::string::npos) { |
| sourceLink.clear(); |
| } else if (fullFileName.find(srcDir) != std::string::npos) { |
| sourceLink = fullFileName.substr(srcDir.length() + 1); |
| } else { |
| // fallback: add plain filename without any path |
| sourceLink = cmsys::SystemTools::GetFilenameName(fullFileName); |
| } |
| if (!sourceLink.empty()) { |
| ConvertToWindowsSlash(sourceLink); |
| } |
| } |
| } |
| if (ext == "hlsl") { |
| tool = "FXCompile"; |
| // Figure out the type of shader compiler to use. |
| if (const char* st = sf->GetProperty("VS_SHADER_TYPE")) { |
| shaderType = st; |
| toolHasSettings = true; |
| } |
| // Figure out which entry point to use if any |
| if (const char* se = sf->GetProperty("VS_SHADER_ENTRYPOINT")) { |
| shaderEntryPoint = se; |
| toolHasSettings = true; |
| } |
| // Figure out which shader model to use if any |
| if (const char* sm = sf->GetProperty("VS_SHADER_MODEL")) { |
| shaderModel = sm; |
| toolHasSettings = true; |
| } |
| // Figure out which output header file to use if any |
| if (const char* ohf = sf->GetProperty("VS_SHADER_OUTPUT_HEADER_FILE")) { |
| outputHeaderFile = ohf; |
| toolHasSettings = true; |
| } |
| // Figure out which variable name to use if any |
| if (const char* vn = sf->GetProperty("VS_SHADER_VARIABLE_NAME")) { |
| variableName = vn; |
| toolHasSettings = true; |
| } |
| // Figure out if there's any additional flags to use |
| if (const char* saf = sf->GetProperty("VS_SHADER_FLAGS")) { |
| shaderAdditionalFlags = saf; |
| toolHasSettings = true; |
| } |
| // Figure out if debug information should be generated |
| if (const char* sed = sf->GetProperty("VS_SHADER_ENABLE_DEBUG")) { |
| shaderEnableDebug = cmSystemTools::IsOn(sed) ? "true" : "false"; |
| toolHasSettings = true; |
| } |
| // Figure out if optimizations should be disabled |
| if (const char* sdo = sf->GetProperty("VS_SHADER_DISABLE_OPTIMIZATIONS")) { |
| shaderDisableOptimizations = cmSystemTools::IsOn(sdo) ? "true" : "false"; |
| toolHasSettings = true; |
| } |
| } else if (ext == "jpg" || ext == "png") { |
| tool = "Image"; |
| } else if (ext == "resw") { |
| tool = "PRIResource"; |
| } else if (ext == "xml") { |
| tool = "XML"; |
| } else if (ext == "natvis") { |
| tool = "Natvis"; |
| } else if (ext == "settings") { |
| settingsLastGenOutput = |
| cmsys::SystemTools::GetFilenameName(sf->GetFullPath()); |
| std::size_t pos = settingsLastGenOutput.find(".settings"); |
| settingsLastGenOutput.replace(pos, 9, ".Designer.cs"); |
| settingsGenerator = "SettingsSingleFileGenerator"; |
| toolHasSettings = true; |
| } else if (ext == "vsixmanifest") { |
| subType = "Designer"; |
| } |
| if (const char* c = sf->GetProperty("VS_COPY_TO_OUT_DIR")) { |
| copyToOutDir = c; |
| toolHasSettings = true; |
| } |
| if (sf->GetPropertyAsBool("VS_INCLUDE_IN_VSIX")) { |
| includeInVsix = "True"; |
| tool = "Content"; |
| toolHasSettings = true; |
| } |
| |
| // Collect VS_CSHARP_* property values (if some are set) |
| std::map<std::string, std::string> sourceFileTags; |
| this->GetCSharpSourceProperties(sf, sourceFileTags); |
| |
| if (this->NsightTegra) { |
| // Nsight Tegra needs specific file types to check up-to-dateness. |
| std::string name = cmSystemTools::LowerCase(sf->GetLocation().GetName()); |
| if (name == "androidmanifest.xml" || name == "build.xml" || |
| name == "proguard.cfg" || name == "proguard-project.txt" || |
| ext == "properties") { |
| tool = "AndroidBuild"; |
| } else if (ext == "java") { |
| tool = "JCompile"; |
| } else if (ext == "asm" || ext == "s") { |
| tool = "ClCompile"; |
| } |
| } |
| |
| const char* toolOverride = sf->GetProperty("VS_TOOL_OVERRIDE"); |
| if (toolOverride && *toolOverride) { |
| tool = toolOverride; |
| } |
| |
| std::string deployContent; |
| std::string deployLocation; |
| if (this->GlobalGenerator->TargetsWindowsPhone() || |
| this->GlobalGenerator->TargetsWindowsStore()) { |
| const char* content = sf->GetProperty("VS_DEPLOYMENT_CONTENT"); |
| if (content && *content) { |
| toolHasSettings = true; |
| deployContent = content; |
| |
| const char* location = sf->GetProperty("VS_DEPLOYMENT_LOCATION"); |
| if (location && *location) { |
| deployLocation = location; |
| } |
| } |
| } |
| |
| if (toolHasSettings) { |
| this->WriteSource(tool, sf, ">\n"); |
| |
| if (!deployContent.empty()) { |
| cmGeneratorExpression ge; |
| std::unique_ptr<cmCompiledGeneratorExpression> cge = |
| ge.Parse(deployContent); |
| // Deployment location cannot be set on a configuration basis |
| if (!deployLocation.empty()) { |
| this->WriteString("<Link>", 3); |
| (*this->BuildFileStream) << deployLocation |
| << "\\%(FileName)%(Extension)"; |
| this->WriteString("</Link>\n", 0); |
| } |
| for (size_t i = 0; i != this->Configurations.size(); ++i) { |
| if (0 == strcmp(cge->Evaluate(this->LocalGenerator, |
| this->Configurations[i]), |
| "1")) { |
| this->WriteString("<DeploymentContent Condition=\"" |
| "'$(Configuration)|$(Platform)'=='", |
| 3); |
| (*this->BuildFileStream) << this->Configurations[i] << "|" |
| << this->Platform << "'\">true"; |
| this->WriteString("</DeploymentContent>\n", 0); |
| } else { |
| this->WriteString("<ExcludedFromBuild Condition=\"" |
| "'$(Configuration)|$(Platform)'=='", |
| 3); |
| (*this->BuildFileStream) << this->Configurations[i] << "|" |
| << this->Platform << "'\">true"; |
| this->WriteString("</ExcludedFromBuild>\n", 0); |
| } |
| } |
| } |
| if (!shaderType.empty()) { |
| this->WriteString("<ShaderType>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(shaderType) |
| << "</ShaderType>\n"; |
| } |
| if (!shaderEntryPoint.empty()) { |
| this->WriteString("<EntryPointName>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(shaderEntryPoint) |
| << "</EntryPointName>\n"; |
| } |
| if (!shaderModel.empty()) { |
| this->WriteString("<ShaderModel>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(shaderModel) |
| << "</ShaderModel>\n"; |
| } |
| if (!outputHeaderFile.empty()) { |
| for (size_t i = 0; i != this->Configurations.size(); ++i) { |
| this->WriteString("<HeaderFileOutput Condition=\"" |
| "'$(Configuration)|$(Platform)'=='", |
| 3); |
| (*this->BuildFileStream) << this->Configurations[i] << "|" |
| << this->Platform << "'\">" |
| << cmVS10EscapeXML(outputHeaderFile); |
| this->WriteString("</HeaderFileOutput>\n", 0); |
| } |
| } |
| if (!variableName.empty()) { |
| for (size_t i = 0; i != this->Configurations.size(); ++i) { |
| this->WriteString("<VariableName Condition=\"" |
| "'$(Configuration)|$(Platform)'=='", |
| 3); |
| (*this->BuildFileStream) << this->Configurations[i] << "|" |
| << this->Platform << "'\">" |
| << cmVS10EscapeXML(variableName); |
| this->WriteString("</VariableName>\n", 0); |
| } |
| } |
| if (!shaderEnableDebug.empty()) { |
| this->WriteString("<EnableDebuggingInformation>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(shaderEnableDebug) |
| << "</EnableDebuggingInformation>\n"; |
| } |
| if (!shaderDisableOptimizations.empty()) { |
| this->WriteString("<DisableOptimizations>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(shaderDisableOptimizations) |
| << "</DisableOptimizations>\n"; |
| } |
| if (!shaderAdditionalFlags.empty()) { |
| this->WriteString("<AdditionalOptions>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(shaderAdditionalFlags) |
| << "</AdditionalOptions>\n"; |
| } |
| if (!settingsGenerator.empty()) { |
| this->WriteString("<Generator>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(settingsGenerator) |
| << "</Generator>\n"; |
| } |
| if (!settingsLastGenOutput.empty()) { |
| this->WriteString("<LastGenOutput>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(settingsLastGenOutput) |
| << "</LastGenOutput>\n"; |
| } |
| if (!sourceLink.empty()) { |
| this->WriteString("<Link>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(sourceLink) << "</Link>\n"; |
| } |
| if (!subType.empty()) { |
| this->WriteString("<SubType>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(subType) << "</SubType>\n"; |
| } |
| if (!copyToOutDir.empty()) { |
| this->WriteString("<CopyToOutputDirectory>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(copyToOutDir) |
| << "</CopyToOutputDirectory>\n"; |
| } |
| if (!includeInVsix.empty()) { |
| this->WriteString("<IncludeInVSIX>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(includeInVsix) |
| << "</IncludeInVSIX>\n"; |
| } |
| // write source file specific tags |
| this->WriteCSharpSourceProperties(sourceFileTags); |
| this->WriteString("</", 2); |
| (*this->BuildFileStream) << tool << ">\n"; |
| } else { |
| this->WriteSource(tool, sf); |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteSource(std::string const& tool, |
| cmSourceFile const* sf, |
| const char* end) |
| { |
| // Visual Studio tools append relative paths to the current dir, as in: |
| // |
| // c:\path\to\current\dir\..\..\..\relative\path\to\source.c |
| // |
| // and fail if this exceeds the maximum allowed path length. Our path |
| // conversion uses full paths when possible to allow deeper trees. |
| // However, CUDA 8.0 msbuild rules fail on absolute paths so for CUDA |
| // we must use relative paths. |
| bool forceRelative = sf->GetLanguage() == "CUDA"; |
| std::string sourceFile = this->ConvertPath(sf->GetFullPath(), forceRelative); |
| if (this->LocalGenerator->GetVersion() == |
| cmGlobalVisualStudioGenerator::VS10 && |
| cmSystemTools::FileIsFullPath(sourceFile.c_str())) { |
| // Normal path conversion resulted in a full path. VS 10 (but not 11) |
| // refuses to show the property page in the IDE for a source file with a |
| // full path (not starting in a '.' or '/' AFAICT). CMake <= 2.8.4 used a |
| // relative path but to allow deeper build trees CMake 2.8.[5678] used a |
| // full path except for custom commands. Custom commands do not work |
| // without a relative path, but they do not seem to be involved in tools |
| // with the above behavior. For other sources we now use a relative path |
| // when the combined path will not be too long so property pages appear. |
| std::string sourceRel = this->ConvertPath(sf->GetFullPath(), true); |
| size_t const maxLen = 250; |
| if (sf->GetCustomCommand() || |
| ((strlen(this->LocalGenerator->GetCurrentBinaryDirectory()) + 1 + |
| sourceRel.length()) <= maxLen)) { |
| forceRelative = true; |
| sourceFile = sourceRel; |
| } else { |
| this->GlobalGenerator->PathTooLong(this->GeneratorTarget, sf, sourceRel); |
| } |
| } |
| ConvertToWindowsSlash(sourceFile); |
| this->WriteString("<", 2); |
| (*this->BuildFileStream) << tool << " Include=\"" |
| << cmVS10EscapeXML(sourceFile) << "\"" |
| << (end ? end : " />\n"); |
| |
| ToolSource toolSource = { sf, forceRelative }; |
| this->Tools[tool].push_back(toolSource); |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteAllSources() |
| { |
| if (this->GeneratorTarget->GetType() > cmStateEnums::UTILITY) { |
| return; |
| } |
| this->WriteString("<ItemGroup>\n", 1); |
| |
| std::vector<size_t> all_configs; |
| for (size_t ci = 0; ci < this->Configurations.size(); ++ci) { |
| all_configs.push_back(ci); |
| } |
| |
| std::vector<cmGeneratorTarget::AllConfigSource> const& sources = |
| this->GeneratorTarget->GetAllConfigSources(); |
| |
| cmSourceFile const* srcCMakeLists = |
| this->LocalGenerator->CreateVCProjBuildRule(); |
| |
| for (cmGeneratorTarget::AllConfigSource const& si : sources) { |
| if (si.Source == srcCMakeLists) { |
| // Skip explicit reference to CMakeLists.txt source. |
| continue; |
| } |
| std::string tool; |
| switch (si.Kind) { |
| case cmGeneratorTarget::SourceKindAppManifest: |
| tool = "AppxManifest"; |
| break; |
| case cmGeneratorTarget::SourceKindCertificate: |
| tool = "None"; |
| break; |
| case cmGeneratorTarget::SourceKindCustomCommand: |
| // Handled elsewhere. |
| break; |
| case cmGeneratorTarget::SourceKindExternalObject: |
| tool = "Object"; |
| if (this->LocalGenerator->GetVersion() < |
| cmGlobalVisualStudioGenerator::VS11) { |
| // For VS == 10 we cannot use LinkObjects to avoid linking custom |
| // command outputs. If an object file is generated in this target, |
| // then vs10 will use it in the build, and we have to list it as |
| // None instead of Object. |
| std::vector<cmSourceFile*> const* d = |
| this->GeneratorTarget->GetSourceDepends(si.Source); |
| if (d && !d->empty()) { |
| tool = "None"; |
| } |
| } |
| break; |
| case cmGeneratorTarget::SourceKindExtra: |
| this->WriteExtraSource(si.Source); |
| break; |
| case cmGeneratorTarget::SourceKindHeader: |
| this->WriteHeaderSource(si.Source); |
| break; |
| case cmGeneratorTarget::SourceKindIDL: |
| tool = "Midl"; |
| break; |
| case cmGeneratorTarget::SourceKindManifest: |
| // Handled elsewhere. |
| break; |
| case cmGeneratorTarget::SourceKindModuleDefinition: |
| tool = "None"; |
| break; |
| case cmGeneratorTarget::SourceKindObjectSource: { |
| const std::string& lang = si.Source->GetLanguage(); |
| if (lang == "C" || lang == "CXX") { |
| tool = "ClCompile"; |
| } else if (lang == "ASM_MASM" && |
| this->GlobalGenerator->IsMasmEnabled()) { |
| tool = "MASM"; |
| } else if (lang == "ASM_NASM" && |
| this->GlobalGenerator->IsNasmEnabled()) { |
| tool = "NASM"; |
| } else if (lang == "RC") { |
| tool = "ResourceCompile"; |
| } else if (lang == "CSharp") { |
| tool = "Compile"; |
| } else if (lang == "CUDA" && this->GlobalGenerator->IsCudaEnabled()) { |
| tool = "CudaCompile"; |
| } else { |
| tool = "None"; |
| } |
| } break; |
| case cmGeneratorTarget::SourceKindResx: |
| // Handled elsewhere. |
| break; |
| case cmGeneratorTarget::SourceKindXaml: |
| // Handled elsewhere. |
| break; |
| } |
| |
| if (!tool.empty()) { |
| // Compute set of configurations to exclude, if any. |
| std::vector<size_t> const& include_configs = si.Configs; |
| std::vector<size_t> exclude_configs; |
| std::set_difference(all_configs.begin(), all_configs.end(), |
| include_configs.begin(), include_configs.end(), |
| std::back_inserter(exclude_configs)); |
| |
| if (si.Kind == cmGeneratorTarget::SourceKindObjectSource) { |
| // FIXME: refactor generation to avoid tracking XML syntax state. |
| this->WriteSource(tool, si.Source, ""); |
| bool have_nested = this->OutputSourceSpecificFlags(si.Source); |
| if (!exclude_configs.empty()) { |
| if (!have_nested) { |
| (*this->BuildFileStream) << ">\n"; |
| } |
| this->WriteExcludeFromBuild(exclude_configs); |
| have_nested = true; |
| } |
| if (have_nested) { |
| this->WriteString("</", 2); |
| (*this->BuildFileStream) << tool << ">\n"; |
| } else { |
| (*this->BuildFileStream) << " />\n"; |
| } |
| } else if (!exclude_configs.empty()) { |
| this->WriteSource(tool, si.Source, ">\n"); |
| this->WriteExcludeFromBuild(exclude_configs); |
| this->WriteString("</", 2); |
| (*this->BuildFileStream) << tool << ">\n"; |
| } else { |
| this->WriteSource(tool, si.Source); |
| } |
| } |
| } |
| |
| if (this->IsMissingFiles) { |
| this->WriteMissingFiles(); |
| } |
| |
| this->WriteString("</ItemGroup>\n", 1); |
| } |
| |
| bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( |
| cmSourceFile const* source) |
| { |
| cmSourceFile const& sf = *source; |
| |
| std::string objectName; |
| if (this->GeneratorTarget->HasExplicitObjectName(&sf)) { |
| objectName = this->GeneratorTarget->GetObjectName(&sf); |
| } |
| std::string flags; |
| bool configDependentFlags = false; |
| std::string options; |
| bool configDependentOptions = false; |
| std::string defines; |
| bool configDependentDefines = false; |
| std::string includes; |
| bool configDependentIncludes = false; |
| if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) { |
| configDependentFlags = |
| cmGeneratorExpression::Find(cflags) != std::string::npos; |
| flags += cflags; |
| } |
| if (const char* coptions = sf.GetProperty("COMPILE_OPTIONS")) { |
| configDependentOptions = |
| cmGeneratorExpression::Find(coptions) != std::string::npos; |
| options += coptions; |
| } |
| if (const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) { |
| configDependentDefines = |
| cmGeneratorExpression::Find(cdefs) != std::string::npos; |
| defines += cdefs; |
| } |
| if (const char* cincludes = sf.GetProperty("INCLUDE_DIRECTORIES")) { |
| configDependentIncludes = |
| cmGeneratorExpression::Find(cincludes) != std::string::npos; |
| includes += cincludes; |
| } |
| std::string lang = |
| this->GlobalGenerator->GetLanguageFromExtension(sf.GetExtension().c_str()); |
| std::string sourceLang = this->LocalGenerator->GetSourceFileLanguage(sf); |
| const std::string& linkLanguage = |
| this->GeneratorTarget->GetLinkerLanguage(""); |
| bool needForceLang = false; |
| // source file does not match its extension language |
| if (lang != sourceLang) { |
| needForceLang = true; |
| lang = sourceLang; |
| } |
| // if the source file does not match the linker language |
| // then force c or c++ |
| const char* compileAs = 0; |
| if (needForceLang || (linkLanguage != lang)) { |
| if (lang == "CXX") { |
| // force a C++ file type |
| compileAs = "CompileAsCpp"; |
| } else if (lang == "C") { |
| // force to c |
| compileAs = "CompileAsC"; |
| } |
| } |
| bool noWinRT = this->TargetCompileAsWinRT && lang == "C"; |
| bool hasFlags = false; |
| // for the first time we need a new line if there is something |
| // produced here. |
| const char* firstString = ">\n"; |
| if (!objectName.empty()) { |
| (*this->BuildFileStream) << firstString; |
| firstString = ""; |
| hasFlags = true; |
| if (lang == "CUDA") { |
| this->WriteString("<CompileOut>", 3); |
| (*this->BuildFileStream) << "$(IntDir)/" << objectName |
| << "</CompileOut>\n"; |
| } else { |
| this->WriteString("<ObjectFileName>", 3); |
| (*this->BuildFileStream) << "$(IntDir)/" << objectName |
| << "</ObjectFileName>\n"; |
| } |
| } |
| for (std::string const& config : this->Configurations) { |
| std::string configUpper = cmSystemTools::UpperCase(config); |
| std::string configDefines = defines; |
| std::string defPropName = "COMPILE_DEFINITIONS_"; |
| defPropName += configUpper; |
| if (const char* ccdefs = sf.GetProperty(defPropName)) { |
| if (!configDefines.empty()) { |
| configDefines += ";"; |
| } |
| configDependentDefines |= |
| cmGeneratorExpression::Find(ccdefs) != std::string::npos; |
| configDefines += ccdefs; |
| } |
| // if we have flags or defines for this config then |
| // use them |
| if (!flags.empty() || !options.empty() || !configDefines.empty() || |
| !includes.empty() || compileAs || noWinRT) { |
| (*this->BuildFileStream) << firstString; |
| firstString = ""; // only do firstString once |
| hasFlags = true; |
| cmGlobalVisualStudio10Generator* gg = |
| static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator); |
| cmIDEFlagTable const* flagtable = nullptr; |
| const std::string& srclang = source->GetLanguage(); |
| if (srclang == "C" || srclang == "CXX") { |
| flagtable = gg->GetClFlagTable(); |
| } else if (srclang == "ASM_MASM" && |
| this->GlobalGenerator->IsMasmEnabled()) { |
| flagtable = gg->GetMasmFlagTable(); |
| } else if (lang == "ASM_NASM" && |
| this->GlobalGenerator->IsNasmEnabled()) { |
| flagtable = gg->GetNasmFlagTable(); |
| } else if (srclang == "RC") { |
| flagtable = gg->GetRcFlagTable(); |
| } else if (srclang == "CSharp") { |
| flagtable = gg->GetCSharpFlagTable(); |
| } |
| cmGeneratorExpressionInterpreter genexInterpreter( |
| this->LocalGenerator, this->GeneratorTarget, config, |
| this->GeneratorTarget->GetName(), lang); |
| cmVisualStudioGeneratorOptions clOptions( |
| this->LocalGenerator, cmVisualStudioGeneratorOptions::Compiler, |
| flagtable, 0, this); |
| if (compileAs) { |
| clOptions.AddFlag("CompileAs", compileAs); |
| } |
| if (noWinRT) { |
| clOptions.AddFlag("CompileAsWinRT", "false"); |
| } |
| if (configDependentFlags) { |
| clOptions.Parse(genexInterpreter.Evaluate(flags, "COMPILE_FLAGS")); |
| } else { |
| clOptions.Parse(flags.c_str()); |
| } |
| if (!options.empty()) { |
| std::string expandedOptions; |
| if (configDependentOptions) { |
| this->LocalGenerator->AppendCompileOptions( |
| expandedOptions, |
| genexInterpreter.Evaluate(options, "COMPILE_OPTIONS")); |
| } else { |
| this->LocalGenerator->AppendCompileOptions(expandedOptions, options); |
| } |
| clOptions.Parse(expandedOptions.c_str()); |
| } |
| if (clOptions.HasFlag("DisableSpecificWarnings")) { |
| clOptions.AppendFlag("DisableSpecificWarnings", |
| "%(DisableSpecificWarnings)"); |
| } |
| if (configDependentDefines) { |
| clOptions.AddDefines( |
| genexInterpreter.Evaluate(configDefines, "COMPILE_DEFINITIONS")); |
| } else { |
| clOptions.AddDefines(configDefines.c_str()); |
| } |
| std::vector<std::string> includeList; |
| if (configDependentIncludes) { |
| this->LocalGenerator->AppendIncludeDirectories( |
| includeList, |
| genexInterpreter.Evaluate(includes, "INCLUDE_DIRECTORIES"), *source); |
| } else { |
| this->LocalGenerator->AppendIncludeDirectories(includeList, includes, |
| *source); |
| } |
| clOptions.AddIncludes(includeList); |
| clOptions.SetConfiguration(config.c_str()); |
| clOptions.PrependInheritedString("AdditionalOptions"); |
| clOptions.OutputAdditionalIncludeDirectories(*this->BuildFileStream, |
| " ", "\n", lang); |
| clOptions.OutputFlagMap(*this->BuildFileStream, " "); |
| clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ", |
| "\n", lang); |
| } |
| } |
| if (this->IsXamlSource(source->GetFullPath())) { |
| (*this->BuildFileStream) << firstString; |
| firstString = ""; // only do firstString once |
| hasFlags = true; |
| this->WriteString("<DependentUpon>", 3); |
| const std::string& fileName = source->GetFullPath(); |
| std::string xamlFileName = fileName.substr(0, fileName.find_last_of(".")); |
| (*this->BuildFileStream) << xamlFileName << "</DependentUpon>\n"; |
| } |
| if (this->ProjectType == csproj) { |
| std::string f = source->GetFullPath(); |
| typedef std::map<std::string, std::string> CsPropMap; |
| CsPropMap sourceFileTags; |
| // set <Link> tag if necessary |
| std::string link; |
| this->GetCSharpSourceLink(source, link); |
| if (!link.empty()) { |
| sourceFileTags["Link"] = link; |
| } |
| this->GetCSharpSourceProperties(&sf, sourceFileTags); |
| // write source file specific tags |
| if (!sourceFileTags.empty()) { |
| hasFlags = true; |
| (*this->BuildFileStream) << firstString; |
| firstString = ""; |
| this->WriteCSharpSourceProperties(sourceFileTags); |
| } |
| } |
| |
| return hasFlags; |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteExcludeFromBuild( |
| std::vector<size_t> const& exclude_configs) |
| { |
| for (size_t ci : exclude_configs) { |
| this->WriteString("", 3); |
| (*this->BuildFileStream) |
| << "<ExcludedFromBuild Condition=\"'$(Configuration)|$(Platform)'=='" |
| << cmVS10EscapeXML(this->Configurations[ci]) << "|" |
| << cmVS10EscapeXML(this->Platform) << "'\">true</ExcludedFromBuild>\n"; |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions() |
| { |
| cmStateEnums::TargetType ttype = this->GeneratorTarget->GetType(); |
| if (ttype > cmStateEnums::GLOBAL_TARGET) { |
| return; |
| } |
| if (this->ProjectType == csproj) { |
| return; |
| } |
| |
| this->WriteString("<PropertyGroup>\n", 1); |
| this->WriteString("<_ProjectFileVersion>10.0.20506.1" |
| "</_ProjectFileVersion>\n", |
| 2); |
| for (std::string const& config : this->Configurations) { |
| if (ttype >= cmStateEnums::UTILITY) { |
| this->WritePlatformConfigTag("IntDir", config, 2); |
| *this->BuildFileStream |
| << "$(Platform)\\$(Configuration)\\$(ProjectName)\\" |
| << "</IntDir>\n"; |
| } else { |
| std::string intermediateDir = |
| this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); |
| intermediateDir += "/"; |
| intermediateDir += config; |
| intermediateDir += "/"; |
| std::string outDir; |
| std::string targetNameFull; |
| if (ttype == cmStateEnums::OBJECT_LIBRARY) { |
| outDir = intermediateDir; |
| targetNameFull = this->GeneratorTarget->GetName(); |
| targetNameFull += ".lib"; |
| } else { |
| outDir = this->GeneratorTarget->GetDirectory(config) + "/"; |
| targetNameFull = this->GeneratorTarget->GetFullName(config); |
| } |
| ConvertToWindowsSlash(intermediateDir); |
| ConvertToWindowsSlash(outDir); |
| |
| this->WritePlatformConfigTag("OutDir", config, 2); |
| *this->BuildFileStream << cmVS10EscapeXML(outDir) << "</OutDir>\n"; |
| |
| this->WritePlatformConfigTag("IntDir", config, 2); |
| *this->BuildFileStream << cmVS10EscapeXML(intermediateDir) |
| << "</IntDir>\n"; |
| |
| if (const char* workingDir = this->GeneratorTarget->GetProperty( |
| "VS_DEBUGGER_WORKING_DIRECTORY")) { |
| this->WritePlatformConfigTag("LocalDebuggerWorkingDirectory", config, |
| 2); |
| *this->BuildFileStream << cmVS10EscapeXML(workingDir) |
| << "</LocalDebuggerWorkingDirectory>\n"; |
| } |
| |
| std::string name = |
| cmSystemTools::GetFilenameWithoutLastExtension(targetNameFull); |
| this->WritePlatformConfigTag("TargetName", config, 2); |
| *this->BuildFileStream << cmVS10EscapeXML(name) << "</TargetName>\n"; |
| |
| std::string ext = |
| cmSystemTools::GetFilenameLastExtension(targetNameFull); |
| if (ext.empty()) { |
| // An empty TargetExt causes a default extension to be used. |
| // A single "." appears to be treated as an empty extension. |
| ext = "."; |
| } |
| this->WritePlatformConfigTag("TargetExt", config, 2); |
| *this->BuildFileStream << cmVS10EscapeXML(ext) << "</TargetExt>\n"; |
| |
| this->OutputLinkIncremental(config); |
| } |
| } |
| this->WriteString("</PropertyGroup>\n", 1); |
| } |
| |
| void cmVisualStudio10TargetGenerator::OutputLinkIncremental( |
| std::string const& configName) |
| { |
| if (!this->MSTools) { |
| return; |
| } |
| if (this->ProjectType == csproj) { |
| return; |
| } |
| // static libraries and things greater than modules do not need |
| // to set this option |
| if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY || |
| this->GeneratorTarget->GetType() > cmStateEnums::MODULE_LIBRARY) { |
| return; |
| } |
| Options& linkOptions = *(this->LinkOptions[configName]); |
| |
| const char* incremental = linkOptions.GetFlag("LinkIncremental"); |
| this->WritePlatformConfigTag("LinkIncremental", configName, 2); |
| *this->BuildFileStream << (incremental ? incremental : "true") |
| << "</LinkIncremental>\n"; |
| linkOptions.RemoveFlag("LinkIncremental"); |
| |
| const char* manifest = linkOptions.GetFlag("GenerateManifest"); |
| this->WritePlatformConfigTag("GenerateManifest", configName, 2); |
| *this->BuildFileStream << (manifest ? manifest : "true") |
| << "</GenerateManifest>\n"; |
| linkOptions.RemoveFlag("GenerateManifest"); |
| |
| // Some link options belong here. Use them now and remove them so that |
| // WriteLinkOptions does not use them. |
| const char* flags[] = { "LinkDelaySign", "LinkKeyFile", 0 }; |
| for (const char** f = flags; *f; ++f) { |
| const char* flag = *f; |
| if (const char* value = linkOptions.GetFlag(flag)) { |
| this->WritePlatformConfigTag(flag, configName, 2); |
| *this->BuildFileStream << value << "</" << flag << ">\n"; |
| linkOptions.RemoveFlag(flag); |
| } |
| } |
| } |
| |
| std::vector<std::string> cmVisualStudio10TargetGenerator::GetIncludes( |
| std::string const& config, std::string const& lang) const |
| { |
| std::vector<std::string> includes; |
| this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget, |
| lang, config); |
| for (std::string& i : includes) { |
| ConvertToWindowsSlash(i); |
| } |
| return includes; |
| } |
| |
| bool cmVisualStudio10TargetGenerator::ComputeClOptions() |
| { |
| for (std::string const& i : this->Configurations) { |
| if (!this->ComputeClOptions(i)) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| bool cmVisualStudio10TargetGenerator::ComputeClOptions( |
| std::string const& configName) |
| { |
| // much of this was copied from here: |
| // copied from cmLocalVisualStudio7Generator.cxx 805 |
| // TODO: Integrate code below with cmLocalVisualStudio7Generator. |
| |
| cmGlobalVisualStudio10Generator* gg = |
| static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator); |
| std::unique_ptr<Options> pOptions; |
| switch (this->ProjectType) { |
| case vcxproj: |
| pOptions = cm::make_unique<Options>( |
| this->LocalGenerator, Options::Compiler, gg->GetClFlagTable()); |
| break; |
| case csproj: |
| pOptions = |
| cm::make_unique<Options>(this->LocalGenerator, Options::CSharpCompiler, |
| gg->GetCSharpFlagTable()); |
| break; |
| } |
| Options& clOptions = *pOptions; |
| |
| std::string flags; |
| const std::string& linkLanguage = |
| this->GeneratorTarget->GetLinkerLanguage(configName); |
| if (linkLanguage.empty()) { |
| cmSystemTools::Error( |
| "CMake can not determine linker language for target: ", |
| this->Name.c_str()); |
| return false; |
| } |
| |
| // Choose a language whose flags to use for ClCompile. |
| static const char* clLangs[] = { "CXX", "C", "Fortran", "CSharp" }; |
| std::string langForClCompile; |
| if (std::find(cm::cbegin(clLangs), cm::cend(clLangs), linkLanguage) != |
| cm::cend(clLangs)) { |
| langForClCompile = linkLanguage; |
| } else { |
| std::set<std::string> languages; |
| this->GeneratorTarget->GetLanguages(languages, configName); |
| for (const char* const* l = cm::cbegin(clLangs); l != cm::cend(clLangs); |
| ++l) { |
| if (languages.find(*l) != languages.end()) { |
| langForClCompile = *l; |
| break; |
| } |
| } |
| } |
| this->LangForClCompile = langForClCompile; |
| if (!langForClCompile.empty()) { |
| std::string baseFlagVar = "CMAKE_"; |
| baseFlagVar += langForClCompile; |
| baseFlagVar += "_FLAGS"; |
| flags = |
| this->GeneratorTarget->Target->GetMakefile()->GetRequiredDefinition( |
| baseFlagVar); |
| std::string flagVar = |
| baseFlagVar + std::string("_") + cmSystemTools::UpperCase(configName); |
| flags += " "; |
| flags += |
| this->GeneratorTarget->Target->GetMakefile()->GetRequiredDefinition( |
| flagVar); |
| this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, |
| langForClCompile, configName); |
| } |
| // set the correct language |
| if (linkLanguage == "C") { |
| clOptions.AddFlag("CompileAs", "CompileAsC"); |
| } |
| if (linkLanguage == "CXX") { |
| clOptions.AddFlag("CompileAs", "CompileAsCpp"); |
| } |
| |
| // Check IPO related warning/error. |
| this->GeneratorTarget->IsIPOEnabled(linkLanguage, configName); |
| |
| // Get preprocessor definitions for this directory. |
| std::string defineFlags = |
| this->GeneratorTarget->Target->GetMakefile()->GetDefineFlags(); |
| if (this->MSTools) { |
| if (this->ProjectType == vcxproj) { |
| clOptions.FixExceptionHandlingDefault(); |
| clOptions.AddFlag("PrecompiledHeader", "NotUsing"); |
| std::string asmLocation = configName + "/"; |
| clOptions.AddFlag("AssemblerListingLocation", asmLocation); |
| } |
| } |
| clOptions.Parse(flags.c_str()); |
| clOptions.Parse(defineFlags.c_str()); |
| std::vector<std::string> targetDefines; |
| switch (this->ProjectType) { |
| case vcxproj: |
| if (!langForClCompile.empty()) { |
| this->GeneratorTarget->GetCompileDefinitions(targetDefines, configName, |
| langForClCompile); |
| } |
| break; |
| case csproj: |
| this->GeneratorTarget->GetCompileDefinitions(targetDefines, configName, |
| "CSharp"); |
| break; |
| } |
| clOptions.AddDefines(targetDefines); |
| |
| // Get includes for this target |
| if (!this->LangForClCompile.empty()) { |
| clOptions.AddIncludes( |
| this->GetIncludes(configName, this->LangForClCompile)); |
| } |
| |
| if (this->MSTools) { |
| clOptions.SetVerboseMakefile( |
| this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")); |
| } |
| |
| // Add a definition for the configuration name. |
| std::string configDefine = "CMAKE_INTDIR=\""; |
| configDefine += configName; |
| configDefine += "\""; |
| clOptions.AddDefine(configDefine); |
| if (const char* exportMacro = this->GeneratorTarget->GetExportMacro()) { |
| clOptions.AddDefine(exportMacro); |
| } |
| |
| if (this->MSTools) { |
| // If we have the VS_WINRT_COMPONENT set then force Compile as WinRT. |
| if (this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT")) { |
| clOptions.AddFlag("CompileAsWinRT", "true"); |
| // For WinRT components, add the _WINRT_DLL define to produce a lib |
| if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY || |
| this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) { |
| clOptions.AddDefine("_WINRT_DLL"); |
| } |
| } else if (this->GlobalGenerator->TargetsWindowsStore() || |
| this->GlobalGenerator->TargetsWindowsPhone()) { |
| if (!clOptions.IsWinRt()) { |
| clOptions.AddFlag("CompileAsWinRT", "false"); |
| } |
| } |
| if (const char* winRT = clOptions.GetFlag("CompileAsWinRT")) { |
| if (cmSystemTools::IsOn(winRT)) { |
| this->TargetCompileAsWinRT = true; |
| } |
| } |
| } |
| |
| if (this->ProjectType != csproj && clOptions.IsManaged()) { |
| this->Managed = true; |
| std::string managedType = clOptions.GetFlag("CompileAsManaged"); |
| if (managedType == "Safe") { |
| // force empty calling convention if safe clr is used |
| clOptions.AddFlag("CallingConvention", ""); |
| } |
| } |
| if (this->ProjectType == csproj) { |
| // /nowin32manifest overrides /win32manifest: parameter |
| if (clOptions.HasFlag("NoWin32Manifest")) { |
| clOptions.RemoveFlag("ApplicationManifest"); |
| } |
| } |
| |
| this->ClOptions[configName] = std::move(pOptions); |
| return true; |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteClOptions( |
| std::string const& configName) |
| { |
| Options& clOptions = *(this->ClOptions[configName]); |
| if (this->ProjectType == csproj) { |
| return; |
| } |
| this->WriteString("<ClCompile>\n", 2); |
| clOptions.PrependInheritedString("AdditionalOptions"); |
| clOptions.OutputAdditionalIncludeDirectories( |
| *this->BuildFileStream, " ", "\n", this->LangForClCompile); |
| clOptions.OutputFlagMap(*this->BuildFileStream, " "); |
| clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ", |
| "\n", this->LangForClCompile); |
| |
| if (this->NsightTegra) { |
| if (const char* processMax = |
| this->GeneratorTarget->GetProperty("ANDROID_PROCESS_MAX")) { |
| this->WriteString("<ProcessMax>", 3); |
| *this->BuildFileStream << cmVS10EscapeXML(processMax) |
| << "</ProcessMax>\n"; |
| } |
| } |
| |
| if (this->MSTools) { |
| cmsys::RegularExpression clangToolset("v[0-9]+_clang_.*"); |
| const char* toolset = this->GlobalGenerator->GetPlatformToolset(); |
| if (toolset && clangToolset.find(toolset)) { |
| this->WriteString("<ObjectFileName>" |
| "$(IntDir)%(filename).obj" |
| "</ObjectFileName>\n", |
| 3); |
| } else { |
| this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3); |
| } |
| |
| // If not in debug mode, write the DebugInformationFormat field |
| // without value so PDBs don't get generated uselessly. Each tag |
| // goes on its own line because Visual Studio corrects it this |
| // way when saving the project after CMake generates it. |
| if (!clOptions.IsDebug()) { |
| this->WriteString("<DebugInformationFormat>\n", 3); |
| this->WriteString("</DebugInformationFormat>\n", 3); |
| } |
| |
| // Specify the compiler program database file if configured. |
| std::string pdb = this->GeneratorTarget->GetCompilePDBPath(configName); |
| if (!pdb.empty()) { |
| ConvertToWindowsSlash(pdb); |
| this->WriteString("<ProgramDataBaseFileName>", 3); |
| *this->BuildFileStream << cmVS10EscapeXML(pdb) |
| << "</ProgramDataBaseFileName>\n"; |
| } |
| } |
| |
| this->WriteString("</ClCompile>\n", 2); |
| } |
| |
| bool cmVisualStudio10TargetGenerator::ComputeRcOptions() |
| { |
| for (std::string const& i : this->Configurations) { |
| if (!this->ComputeRcOptions(i)) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| bool cmVisualStudio10TargetGenerator::ComputeRcOptions( |
| std::string const& configName) |
| { |
| cmGlobalVisualStudio10Generator* gg = |
| static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator); |
| auto pOptions = cm::make_unique<Options>( |
| this->LocalGenerator, Options::ResourceCompiler, gg->GetRcFlagTable()); |
| Options& rcOptions = *pOptions; |
| |
| std::string CONFIG = cmSystemTools::UpperCase(configName); |
| std::string rcConfigFlagsVar = std::string("CMAKE_RC_FLAGS_") + CONFIG; |
| std::string flags = |
| std::string(this->Makefile->GetSafeDefinition("CMAKE_RC_FLAGS")) + |
| std::string(" ") + |
| std::string(this->Makefile->GetSafeDefinition(rcConfigFlagsVar)); |
| |
| rcOptions.Parse(flags.c_str()); |
| |
| // For historical reasons, add the C preprocessor defines to RC. |
| Options& clOptions = *(this->ClOptions[configName]); |
| rcOptions.AddDefines(clOptions.GetDefines()); |
| |
| // Get includes for this target |
| rcOptions.AddIncludes(this->GetIncludes(configName, "RC")); |
| |
| this->RcOptions[configName] = std::move(pOptions); |
| return true; |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteRCOptions( |
| std::string const& configName) |
| { |
| if (!this->MSTools) { |
| return; |
| } |
| this->WriteString("<ResourceCompile>\n", 2); |
| |
| Options& rcOptions = *(this->RcOptions[configName]); |
| rcOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ", |
| "\n", "RC"); |
| rcOptions.OutputAdditionalIncludeDirectories(*this->BuildFileStream, |
| " ", "\n", "RC"); |
| rcOptions.PrependInheritedString("AdditionalOptions"); |
| rcOptions.OutputFlagMap(*this->BuildFileStream, " "); |
| |
| this->WriteString("</ResourceCompile>\n", 2); |
| } |
| |
| bool cmVisualStudio10TargetGenerator::ComputeCudaOptions() |
| { |
| if (!this->GlobalGenerator->IsCudaEnabled()) { |
| return true; |
| } |
| for (std::string const& i : this->Configurations) { |
| if (!this->ComputeCudaOptions(i)) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| bool cmVisualStudio10TargetGenerator::ComputeCudaOptions( |
| std::string const& configName) |
| { |
| cmGlobalVisualStudio10Generator* gg = |
| static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator); |
| auto pOptions = cm::make_unique<Options>( |
| this->LocalGenerator, Options::CudaCompiler, gg->GetCudaFlagTable()); |
| Options& cudaOptions = *pOptions; |
| |
| // Get compile flags for CUDA in this directory. |
| std::string CONFIG = cmSystemTools::UpperCase(configName); |
| std::string configFlagsVar = std::string("CMAKE_CUDA_FLAGS_") + CONFIG; |
| std::string flags = |
| std::string(this->Makefile->GetSafeDefinition("CMAKE_CUDA_FLAGS")) + |
| std::string(" ") + |
| std::string(this->Makefile->GetSafeDefinition(configFlagsVar)); |
| this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, "CUDA", |
| configName); |
| |
| // Get preprocessor definitions for this directory. |
| std::string defineFlags = |
| this->GeneratorTarget->Target->GetMakefile()->GetDefineFlags(); |
| |
| cudaOptions.Parse(flags.c_str()); |
| cudaOptions.Parse(defineFlags.c_str()); |
| cudaOptions.ParseFinish(); |
| |
| // If we haven't explicitly enabled GPU debug information |
| // explicitly disable it |
| if (!cudaOptions.HasFlag("GPUDebugInfo")) { |
| cudaOptions.AddFlag("GPUDebugInfo", "false"); |
| } |
| |
| // The extension on object libraries the CUDA gives isn't |
| // consistent with how MSVC generates object libraries for C+, so set |
| // the default to not have any extension |
| cudaOptions.AddFlag("CompileOut", "$(IntDir)%(Filename).obj"); |
| |
| bool notPtx = true; |
| if (this->GeneratorTarget->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION")) { |
| cudaOptions.AddFlag("GenerateRelocatableDeviceCode", "true"); |
| } else if (this->GeneratorTarget->GetPropertyAsBool( |
| "CUDA_PTX_COMPILATION")) { |
| cudaOptions.AddFlag("NvccCompilation", "ptx"); |
| // We drop the %(Extension) component as CMake expects all PTX files |
| // to not have the source file extension at all |
| cudaOptions.AddFlag("CompileOut", "$(IntDir)%(Filename).ptx"); |
| notPtx = false; |
| } |
| |
| if (notPtx && |
| cmSystemTools::VersionCompareGreaterEq( |
| "8.0", this->GlobalGenerator->GetPlatformToolsetCudaString())) { |
| // Explicitly state that we want this file to be treated as a |
| // CUDA file no matter what the file extensions is |
| // This is only needed for < CUDA 9 |
| cudaOptions.AppendFlagString("AdditionalOptions", "-x cu"); |
| } |
| |
| // CUDA automatically passes the proper '--machine' flag to nvcc |
| // for the current architecture, but does not reflect this default |
| // in the user-visible IDE settings. Set it explicitly. |
| if (this->Platform == "x64") { |
| cudaOptions.AddFlag("TargetMachinePlatform", "64"); |
| } |
| |
| // Convert the host compiler options to the toolset's abstractions |
| // using a secondary flag table. |
| cudaOptions.ClearTables(); |
| cudaOptions.AddTable(gg->GetCudaHostFlagTable()); |
| cudaOptions.Reparse("AdditionalCompilerOptions"); |
| |
| // `CUDA 8.0.targets` places AdditionalCompilerOptions before nvcc! |
| // Pass them through -Xcompiler in AdditionalOptions instead. |
| if (const char* acoPtr = cudaOptions.GetFlag("AdditionalCompilerOptions")) { |
| std::string aco = acoPtr; |
| cudaOptions.RemoveFlag("AdditionalCompilerOptions"); |
| if (!aco.empty()) { |
| aco = this->LocalGenerator->EscapeForShell(aco, false); |
| cudaOptions.AppendFlagString("AdditionalOptions", "-Xcompiler=" + aco); |
| } |
| } |
| |
| cudaOptions.FixCudaCodeGeneration(); |
| |
| std::vector<std::string> targetDefines; |
| this->GeneratorTarget->GetCompileDefinitions(targetDefines, configName, |
| "CUDA"); |
| cudaOptions.AddDefines(targetDefines); |
| |
| // Add a definition for the configuration name. |
| std::string configDefine = "CMAKE_INTDIR=\""; |
| configDefine += configName; |
| configDefine += "\""; |
| cudaOptions.AddDefine(configDefine); |
| if (const char* exportMacro = this->GeneratorTarget->GetExportMacro()) { |
| cudaOptions.AddDefine(exportMacro); |
| } |
| |
| // Get includes for this target |
| cudaOptions.AddIncludes(this->GetIncludes(configName, "CUDA")); |
| |
| this->CudaOptions[configName] = std::move(pOptions); |
| return true; |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteCudaOptions( |
| std::string const& configName) |
| { |
| if (!this->MSTools || !this->GlobalGenerator->IsCudaEnabled()) { |
| return; |
| } |
| this->WriteString("<CudaCompile>\n", 2); |
| |
| Options& cudaOptions = *(this->CudaOptions[configName]); |
| cudaOptions.OutputAdditionalIncludeDirectories(*this->BuildFileStream, |
| " ", "\n", "CUDA"); |
| cudaOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ", |
| "\n", "CUDA"); |
| cudaOptions.PrependInheritedString("AdditionalOptions"); |
| cudaOptions.OutputFlagMap(*this->BuildFileStream, " "); |
| |
| this->WriteString("</CudaCompile>\n", 2); |
| } |
| |
| bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions() |
| { |
| if (!this->GlobalGenerator->IsCudaEnabled()) { |
| return true; |
| } |
| for (std::string const& i : this->Configurations) { |
| if (!this->ComputeCudaLinkOptions(i)) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions( |
| std::string const& configName) |
| { |
| cmGlobalVisualStudio10Generator* gg = |
| static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator); |
| auto pOptions = cm::make_unique<Options>( |
| this->LocalGenerator, Options::CudaCompiler, gg->GetCudaFlagTable()); |
| Options& cudaLinkOptions = *pOptions; |
| |
| // Determine if we need to do a device link |
| bool doDeviceLinking = false; |
| switch (this->GeneratorTarget->GetType()) { |
| case cmStateEnums::SHARED_LIBRARY: |
| case cmStateEnums::MODULE_LIBRARY: |
| case cmStateEnums::EXECUTABLE: |
| doDeviceLinking = true; |
| break; |
| case cmStateEnums::STATIC_LIBRARY: |
| doDeviceLinking = this->GeneratorTarget->GetPropertyAsBool( |
| "CUDA_RESOLVE_DEVICE_SYMBOLS"); |
| break; |
| default: |
| break; |
| } |
| |
| cudaLinkOptions.AddFlag("PerformDeviceLink", |
| doDeviceLinking ? "true" : "false"); |
| |
| // Suppress deprecation warnings for default GPU targets during device link. |
| if (cmSystemTools::VersionCompareGreaterEq( |
| this->GlobalGenerator->GetPlatformToolsetCudaString(), "8.0")) { |
| cudaLinkOptions.AppendFlagString("AdditionalOptions", |
| "-Wno-deprecated-gpu-targets"); |
| } |
| |
| this->CudaLinkOptions[configName] = std::move(pOptions); |
| return true; |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteCudaLinkOptions( |
| std::string const& configName) |
| { |
| if (this->GeneratorTarget->GetType() > cmStateEnums::MODULE_LIBRARY) { |
| return; |
| } |
| |
| if (!this->MSTools || !this->GlobalGenerator->IsCudaEnabled()) { |
| return; |
| } |
| |
| this->WriteString("<CudaLink>\n", 2); |
| Options& cudaLinkOptions = *(this->CudaLinkOptions[configName]); |
| cudaLinkOptions.OutputFlagMap(*this->BuildFileStream, " "); |
| this->WriteString("</CudaLink>\n", 2); |
| } |
| |
| bool cmVisualStudio10TargetGenerator::ComputeMasmOptions() |
| { |
| if (!this->GlobalGenerator->IsMasmEnabled()) { |
| return true; |
| } |
| for (std::string const& i : this->Configurations) { |
| if (!this->ComputeMasmOptions(i)) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| bool cmVisualStudio10TargetGenerator::ComputeMasmOptions( |
| std::string const& configName) |
| { |
| cmGlobalVisualStudio10Generator* gg = |
| static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator); |
| auto pOptions = cm::make_unique<Options>( |
| this->LocalGenerator, Options::MasmCompiler, gg->GetMasmFlagTable()); |
| Options& masmOptions = *pOptions; |
| |
| std::string CONFIG = cmSystemTools::UpperCase(configName); |
| std::string configFlagsVar = std::string("CMAKE_ASM_MASM_FLAGS_") + CONFIG; |
| std::string flags = |
| std::string(this->Makefile->GetSafeDefinition("CMAKE_ASM_MASM_FLAGS")) + |
| std::string(" ") + |
| std::string(this->Makefile->GetSafeDefinition(configFlagsVar)); |
| |
| masmOptions.Parse(flags.c_str()); |
| |
| // Get includes for this target |
| masmOptions.AddIncludes(this->GetIncludes(configName, "ASM_MASM")); |
| |
| this->MasmOptions[configName] = std::move(pOptions); |
| return true; |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteMasmOptions( |
| std::string const& configName) |
| { |
| if (!this->MSTools || !this->GlobalGenerator->IsMasmEnabled()) { |
| return; |
| } |
| this->WriteString("<MASM>\n", 2); |
| |
| // Preprocessor definitions and includes are shared with clOptions. |
| Options& clOptions = *(this->ClOptions[configName]); |
| clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ", |
| "\n", "ASM_MASM"); |
| |
| Options& masmOptions = *(this->MasmOptions[configName]); |
| masmOptions.OutputAdditionalIncludeDirectories(*this->BuildFileStream, |
| " ", "\n", "ASM_MASM"); |
| masmOptions.PrependInheritedString("AdditionalOptions"); |
| masmOptions.OutputFlagMap(*this->BuildFileStream, " "); |
| |
| this->WriteString("</MASM>\n", 2); |
| } |
| |
| bool cmVisualStudio10TargetGenerator::ComputeNasmOptions() |
| { |
| if (!this->GlobalGenerator->IsNasmEnabled()) { |
| return true; |
| } |
| for (std::string const& i : this->Configurations) { |
| if (!this->ComputeNasmOptions(i)) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| bool cmVisualStudio10TargetGenerator::ComputeNasmOptions( |
| std::string const& configName) |
| { |
| cmGlobalVisualStudio10Generator* gg = |
| static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator); |
| auto pOptions = cm::make_unique<Options>( |
| this->LocalGenerator, Options::NasmCompiler, gg->GetNasmFlagTable()); |
| Options& nasmOptions = *pOptions; |
| |
| std::string CONFIG = cmSystemTools::UpperCase(configName); |
| std::string configFlagsVar = std::string("CMAKE_ASM_NASM_FLAGS_") + CONFIG; |
| std::string flags = |
| std::string(this->Makefile->GetSafeDefinition("CMAKE_ASM_NASM_FLAGS")) + |
| std::string(" -f") + std::string(this->Makefile->GetSafeDefinition( |
| "CMAKE_ASM_NASM_OBJECT_FORMAT")) + |
| std::string(" ") + |
| std::string(this->Makefile->GetSafeDefinition(configFlagsVar)); |
| nasmOptions.Parse(flags.c_str()); |
| |
| // Get includes for this target |
| nasmOptions.AddIncludes(this->GetIncludes(configName, "ASM_NASM")); |
| |
| this->NasmOptions[configName] = std::move(pOptions); |
| return true; |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteNasmOptions( |
| std::string const& configName) |
| { |
| if (!this->GlobalGenerator->IsNasmEnabled()) { |
| return; |
| } |
| this->WriteString("<NASM>\n", 2); |
| |
| std::vector<std::string> includes = |
| this->GetIncludes(configName, "ASM_NASM"); |
| Options& nasmOptions = *(this->NasmOptions[configName]); |
| nasmOptions.OutputAdditionalIncludeDirectories(*this->BuildFileStream, |
| " ", "\n", "ASM_NASM"); |
| nasmOptions.OutputFlagMap(*this->BuildFileStream, " "); |
| nasmOptions.PrependInheritedString("AdditionalOptions"); |
| nasmOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ", |
| "\n", "ASM_NASM"); |
| |
| // Preprocessor definitions and includes are shared with clOptions. |
| Options& clOptions = *(this->ClOptions[configName]); |
| clOptions.OutputPreprocessorDefinitions(*this->BuildFileStream, " ", |
| "\n", "ASM_NASM"); |
| |
| this->WriteString("</NASM>\n", 2); |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteLibOptions( |
| std::string const& config) |
| { |
| if (this->GeneratorTarget->GetType() != cmStateEnums::STATIC_LIBRARY && |
| this->GeneratorTarget->GetType() != cmStateEnums::OBJECT_LIBRARY) { |
| return; |
| } |
| std::string libflags; |
| this->LocalGenerator->GetStaticLibraryFlags( |
| libflags, cmSystemTools::UpperCase(config), this->GeneratorTarget); |
| if (!libflags.empty()) { |
| this->WriteString("<Lib>\n", 2); |
| cmGlobalVisualStudio10Generator* gg = |
| static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator); |
| cmVisualStudioGeneratorOptions libOptions( |
| this->LocalGenerator, cmVisualStudioGeneratorOptions::Linker, |
| gg->GetLibFlagTable(), 0, this); |
| libOptions.Parse(libflags.c_str()); |
| libOptions.PrependInheritedString("AdditionalOptions"); |
| libOptions.OutputFlagMap(*this->BuildFileStream, " "); |
| this->WriteString("</Lib>\n", 2); |
| } |
| |
| // We cannot generate metadata for static libraries. WindowsPhone |
| // and WindowsStore tools look at GenerateWindowsMetadata in the |
| // Link tool options even for static libraries. |
| if (this->GlobalGenerator->TargetsWindowsPhone() || |
| this->GlobalGenerator->TargetsWindowsStore()) { |
| this->WriteString("<Link>\n", 2); |
| this->WriteString("<GenerateWindowsMetadata>false" |
| "</GenerateWindowsMetadata>\n", |
| 3); |
| this->WriteString("</Link>\n", 2); |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteManifestOptions( |
| std::string const& config) |
| { |
| if (this->GeneratorTarget->GetType() != cmStateEnums::EXECUTABLE && |
| this->GeneratorTarget->GetType() != cmStateEnums::SHARED_LIBRARY && |
| this->GeneratorTarget->GetType() != cmStateEnums::MODULE_LIBRARY) { |
| return; |
| } |
| |
| std::vector<cmSourceFile const*> manifest_srcs; |
| this->GeneratorTarget->GetManifests(manifest_srcs, config); |
| if (!manifest_srcs.empty()) { |
| this->WriteString("<Manifest>\n", 2); |
| this->WriteString("<AdditionalManifestFiles>", 3); |
| for (cmSourceFile const* mi : manifest_srcs) { |
| std::string m = this->ConvertPath(mi->GetFullPath(), false); |
| ConvertToWindowsSlash(m); |
| (*this->BuildFileStream) << m << ";"; |
| } |
| (*this->BuildFileStream) << "</AdditionalManifestFiles>\n"; |
| this->WriteString("</Manifest>\n", 2); |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteAntBuildOptions( |
| std::string const& configName) |
| { |
| // Look through the sources for AndroidManifest.xml and use |
| // its location as the root source directory. |
| std::string rootDir = this->LocalGenerator->GetCurrentSourceDirectory(); |
| { |
| std::vector<cmSourceFile const*> extraSources; |
| this->GeneratorTarget->GetExtraSources(extraSources, ""); |
| for (cmSourceFile const* si : extraSources) { |
| if ("androidmanifest.xml" == |
| cmSystemTools::LowerCase(si->GetLocation().GetName())) { |
| rootDir = si->GetLocation().GetDirectory(); |
| break; |
| } |
| } |
| } |
| |
| // Tell MSBuild to launch Ant. |
| { |
| std::string antBuildPath = rootDir; |
| this->WriteString("<AntBuild>\n", 2); |
| this->WriteString("<AntBuildPath>", 3); |
| ConvertToWindowsSlash(antBuildPath); |
| (*this->BuildFileStream) << cmVS10EscapeXML(antBuildPath) |
| << "</AntBuildPath>\n"; |
| } |
| |
| if (this->GeneratorTarget->GetPropertyAsBool("ANDROID_SKIP_ANT_STEP")) { |
| this->WriteString("<SkipAntStep>true</SkipAntStep>\n", 3); |
| } |
| |
| if (this->GeneratorTarget->GetPropertyAsBool("ANDROID_PROGUARD")) { |
| this->WriteString("<EnableProGuard>true</EnableProGuard>\n", 3); |
| } |
| |
| if (const char* proGuardConfigLocation = |
| this->GeneratorTarget->GetProperty("ANDROID_PROGUARD_CONFIG_PATH")) { |
| this->WriteString("<ProGuardConfigLocation>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(proGuardConfigLocation) |
| << "</ProGuardConfigLocation>\n"; |
| } |
| |
| if (const char* securePropertiesLocation = |
| this->GeneratorTarget->GetProperty("ANDROID_SECURE_PROPS_PATH")) { |
| this->WriteString("<SecurePropertiesLocation>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(securePropertiesLocation) |
| << "</SecurePropertiesLocation>\n"; |
| } |
| |
| if (const char* nativeLibDirectoriesExpression = |
| this->GeneratorTarget->GetProperty("ANDROID_NATIVE_LIB_DIRECTORIES")) { |
| cmGeneratorExpression ge; |
| std::unique_ptr<cmCompiledGeneratorExpression> cge = |
| ge.Parse(nativeLibDirectoriesExpression); |
| std::string nativeLibDirs = |
| cge->Evaluate(this->LocalGenerator, configName); |
| this->WriteString("<NativeLibDirectories>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(nativeLibDirs) |
| << "</NativeLibDirectories>\n"; |
| } |
| |
| if (const char* nativeLibDependenciesExpression = |
| this->GeneratorTarget->GetProperty( |
| "ANDROID_NATIVE_LIB_DEPENDENCIES")) { |
| cmGeneratorExpression ge; |
| std::unique_ptr<cmCompiledGeneratorExpression> cge = |
| ge.Parse(nativeLibDependenciesExpression); |
| std::string nativeLibDeps = |
| cge->Evaluate(this->LocalGenerator, configName); |
| this->WriteString("<NativeLibDependencies>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(nativeLibDeps) |
| << "</NativeLibDependencies>\n"; |
| } |
| |
| if (const char* javaSourceDir = |
| this->GeneratorTarget->GetProperty("ANDROID_JAVA_SOURCE_DIR")) { |
| this->WriteString("<JavaSourceDir>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(javaSourceDir) |
| << "</JavaSourceDir>\n"; |
| } |
| |
| if (const char* jarDirectoriesExpression = |
| this->GeneratorTarget->GetProperty("ANDROID_JAR_DIRECTORIES")) { |
| cmGeneratorExpression ge; |
| std::unique_ptr<cmCompiledGeneratorExpression> cge = |
| ge.Parse(jarDirectoriesExpression); |
| std::string jarDirectories = |
| cge->Evaluate(this->LocalGenerator, configName); |
| this->WriteString("<JarDirectories>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(jarDirectories) |
| << "</JarDirectories>\n"; |
| } |
| |
| if (const char* jarDeps = |
| this->GeneratorTarget->GetProperty("ANDROID_JAR_DEPENDENCIES")) { |
| this->WriteString("<JarDependencies>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(jarDeps) |
| << "</JarDependencies>\n"; |
| } |
| |
| if (const char* assetsDirectories = |
| this->GeneratorTarget->GetProperty("ANDROID_ASSETS_DIRECTORIES")) { |
| this->WriteString("<AssetsDirectories>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(assetsDirectories) |
| << "</AssetsDirectories>\n"; |
| } |
| |
| { |
| std::string manifest_xml = rootDir + "/AndroidManifest.xml"; |
| ConvertToWindowsSlash(manifest_xml); |
| this->WriteString("<AndroidManifestLocation>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(manifest_xml) |
| << "</AndroidManifestLocation>\n"; |
| } |
| |
| if (const char* antAdditionalOptions = |
| this->GeneratorTarget->GetProperty("ANDROID_ANT_ADDITIONAL_OPTIONS")) { |
| this->WriteString("<AdditionalOptions>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(antAdditionalOptions) |
| << " %(AdditionalOptions)</AdditionalOptions>\n"; |
| } |
| |
| this->WriteString("</AntBuild>\n", 2); |
| } |
| |
| bool cmVisualStudio10TargetGenerator::ComputeLinkOptions() |
| { |
| if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE || |
| this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY || |
| this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) { |
| for (std::string const& i : this->Configurations) { |
| if (!this->ComputeLinkOptions(i)) { |
| return false; |
| } |
| } |
| } |
| return true; |
| } |
| |
| bool cmVisualStudio10TargetGenerator::ComputeLinkOptions( |
| std::string const& config) |
| { |
| cmGlobalVisualStudio10Generator* gg = |
| static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator); |
| auto pOptions = |
| cm::make_unique<Options>(this->LocalGenerator, Options::Linker, |
| gg->GetLinkFlagTable(), nullptr, this); |
| Options& linkOptions = *pOptions; |
| |
| cmGeneratorTarget::LinkClosure const* linkClosure = |
| this->GeneratorTarget->GetLinkClosure(config); |
| |
| const std::string& linkLanguage = linkClosure->LinkerLanguage; |
| if (linkLanguage.empty()) { |
| cmSystemTools::Error( |
| "CMake can not determine linker language for target: ", |
| this->Name.c_str()); |
| return false; |
| } |
| |
| std::string CONFIG = cmSystemTools::UpperCase(config); |
| |
| const char* linkType = "SHARED"; |
| if (this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) { |
| linkType = "MODULE"; |
| } |
| if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) { |
| linkType = "EXE"; |
| } |
| std::string flags; |
| std::string linkFlagVarBase = "CMAKE_"; |
| linkFlagVarBase += linkType; |
| linkFlagVarBase += "_LINKER_FLAGS"; |
| flags += " "; |
| flags += this->GeneratorTarget->Target->GetMakefile()->GetRequiredDefinition( |
| linkFlagVarBase); |
| std::string linkFlagVar = linkFlagVarBase + "_" + CONFIG; |
| flags += " "; |
| flags += this->GeneratorTarget->Target->GetMakefile()->GetRequiredDefinition( |
| linkFlagVar); |
| const char* targetLinkFlags = |
| this->GeneratorTarget->GetProperty("LINK_FLAGS"); |
| if (targetLinkFlags) { |
| flags += " "; |
| flags += targetLinkFlags; |
| } |
| std::string flagsProp = "LINK_FLAGS_"; |
| flagsProp += CONFIG; |
| if (const char* flagsConfig = |
| this->GeneratorTarget->GetProperty(flagsProp)) { |
| flags += " "; |
| flags += flagsConfig; |
| } |
| |
| cmComputeLinkInformation* pcli = |
| this->GeneratorTarget->GetLinkInformation(config); |
| if (!pcli) { |
| cmSystemTools::Error( |
| "CMake can not compute cmComputeLinkInformation for target: ", |
| this->Name.c_str()); |
| return false; |
| } |
| cmComputeLinkInformation& cli = *pcli; |
| |
| std::vector<std::string> libVec; |
| std::vector<std::string> vsTargetVec; |
| this->AddLibraries(cli, libVec, vsTargetVec); |
| if (std::find(linkClosure->Languages.begin(), linkClosure->Languages.end(), |
| "CUDA") != linkClosure->Languages.end()) { |
| switch (this->CudaOptions[config]->GetCudaRuntime()) { |
| case cmVisualStudioGeneratorOptions::CudaRuntimeStatic: |
| libVec.push_back("cudart_static.lib"); |
| break; |
| case cmVisualStudioGeneratorOptions::CudaRuntimeShared: |
| libVec.push_back("cudart.lib"); |
| break; |
| case cmVisualStudioGeneratorOptions::CudaRuntimeNone: |
| break; |
| } |
| } |
| std::string standardLibsVar = "CMAKE_"; |
| standardLibsVar += linkLanguage; |
| standardLibsVar += "_STANDARD_LIBRARIES"; |
| std::string const libs = this->Makefile->GetSafeDefinition(standardLibsVar); |
| cmSystemTools::ParseWindowsCommandLine(libs.c_str(), libVec); |
| linkOptions.AddFlag("AdditionalDependencies", libVec); |
| |
| // Populate TargetsFileAndConfigsVec |
| for (std::string const& ti : vsTargetVec) { |
| this->AddTargetsFileAndConfigPair(ti, config); |
| } |
| |
| std::vector<std::string> const& ldirs = cli.GetDirectories(); |
| std::vector<std::string> linkDirs; |
| for (std::string const& d : ldirs) { |
| // first just full path |
| linkDirs.push_back(d); |
| // next path with configuration type Debug, Release, etc |
| linkDirs.push_back(d + "/$(Configuration)"); |
| } |
| linkDirs.push_back("%(AdditionalLibraryDirectories)"); |
| linkOptions.AddFlag("AdditionalLibraryDirectories", linkDirs); |
| |
| std::string targetName; |
| std::string targetNameSO; |
| std::string targetNameFull; |
| std::string targetNameImport; |
| std::string targetNamePDB; |
| if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) { |
| this->GeneratorTarget->GetExecutableNames( |
| targetName, targetNameFull, targetNameImport, targetNamePDB, config); |
| } else { |
| this->GeneratorTarget->GetLibraryNames(targetName, targetNameSO, |
| targetNameFull, targetNameImport, |
| targetNamePDB, config); |
| } |
| |
| if (this->MSTools) { |
| if (this->GeneratorTarget->GetPropertyAsBool("WIN32_EXECUTABLE")) { |
| if (this->GlobalGenerator->TargetsWindowsCE()) { |
| linkOptions.AddFlag("SubSystem", "WindowsCE"); |
| if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) { |
| if (this->ClOptions[config]->UsingUnicode()) { |
| linkOptions.AddFlag("EntryPointSymbol", "wWinMainCRTStartup"); |
| } else { |
| linkOptions.AddFlag("EntryPointSymbol", "WinMainCRTStartup"); |
| } |
| } |
| } else { |
| linkOptions.AddFlag("SubSystem", "Windows"); |
| } |
| } else { |
| if (this->GlobalGenerator->TargetsWindowsCE()) { |
| linkOptions.AddFlag("SubSystem", "WindowsCE"); |
| if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) { |
| if (this->ClOptions[config]->UsingUnicode()) { |
| linkOptions.AddFlag("EntryPointSymbol", "mainWCRTStartup"); |
| } else { |
| linkOptions.AddFlag("EntryPointSymbol", "mainACRTStartup"); |
| } |
| } |
| } else { |
| linkOptions.AddFlag("SubSystem", "Console"); |
| }; |
| } |
| |
| if (const char* stackVal = this->Makefile->GetDefinition( |
| "CMAKE_" + linkLanguage + "_STACK_SIZE")) { |
| linkOptions.AddFlag("StackReserveSize", stackVal); |
| } |
| |
| linkOptions.AddFlag("GenerateDebugInformation", "false"); |
| |
| std::string pdb = this->GeneratorTarget->GetPDBDirectory(config); |
| pdb += "/"; |
| pdb += targetNamePDB; |
| std::string imLib = this->GeneratorTarget->GetDirectory( |
| config, cmStateEnums::ImportLibraryArtifact); |
| imLib += "/"; |
| imLib += targetNameImport; |
| |
| linkOptions.AddFlag("ImportLibrary", imLib); |
| linkOptions.AddFlag("ProgramDataBaseFile", pdb); |
| |
| // A Windows Runtime component uses internal .NET metadata, |
| // so does not have an import library. |
| if (this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT") && |
| this->GeneratorTarget->GetType() != cmStateEnums::EXECUTABLE) { |
| linkOptions.AddFlag("GenerateWindowsMetadata", "true"); |
| } else if (this->GlobalGenerator->TargetsWindowsPhone() || |
| this->GlobalGenerator->TargetsWindowsStore()) { |
| // WindowsPhone and WindowsStore components are in an app container |
| // and produce WindowsMetadata. If we are not producing a WINRT |
| // component, then do not generate the metadata here. |
| linkOptions.AddFlag("GenerateWindowsMetadata", "false"); |
| } |
| |
| if (this->GlobalGenerator->TargetsWindowsPhone() && |
| this->GlobalGenerator->GetSystemVersion() == "8.0") { |
| // WindowsPhone 8.0 does not have ole32. |
| linkOptions.AppendFlag("IgnoreSpecificDefaultLibraries", "ole32.lib"); |
| } |
| } else if (this->NsightTegra) { |
| linkOptions.AddFlag("SoName", targetNameSO); |
| } |
| |
| linkOptions.Parse(flags.c_str()); |
| linkOptions.FixManifestUACFlags(); |
| |
| if (this->MSTools) { |
| cmGeneratorTarget::ModuleDefinitionInfo const* mdi = |
| this->GeneratorTarget->GetModuleDefinitionInfo(config); |
| if (mdi && !mdi->DefFile.empty()) { |
| linkOptions.AddFlag("ModuleDefinitionFile", mdi->DefFile.c_str()); |
| } |
| linkOptions.AppendFlag("IgnoreSpecificDefaultLibraries", |
| "%(IgnoreSpecificDefaultLibraries)"); |
| } |
| |
| // VS 2015 without all updates has a v140 toolset whose |
| // GenerateDebugInformation expects No/Debug instead of false/true. |
| if (gg->GetPlatformToolsetNeedsDebugEnum()) { |
| if (const char* debug = linkOptions.GetFlag("GenerateDebugInformation")) { |
| if (strcmp(debug, "false") == 0) { |
| linkOptions.AddFlag("GenerateDebugInformation", "No"); |
| } else if (strcmp(debug, "true") == 0) { |
| linkOptions.AddFlag("GenerateDebugInformation", "Debug"); |
| } |
| } |
| } |
| |
| this->LinkOptions[config] = std::move(pOptions); |
| return true; |
| } |
| |
| bool cmVisualStudio10TargetGenerator::ComputeLibOptions() |
| { |
| if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) { |
| for (std::string const& i : this->Configurations) { |
| if (!this->ComputeLibOptions(i)) { |
| return false; |
| } |
| } |
| } |
| return true; |
| } |
| |
| bool cmVisualStudio10TargetGenerator::ComputeLibOptions( |
| std::string const& config) |
| { |
| cmComputeLinkInformation* pcli = |
| this->GeneratorTarget->GetLinkInformation(config); |
| if (!pcli) { |
| cmSystemTools::Error( |
| "CMake can not compute cmComputeLinkInformation for target: ", |
| this->Name.c_str()); |
| return false; |
| } |
| |
| cmComputeLinkInformation& cli = *pcli; |
| typedef cmComputeLinkInformation::ItemVector ItemVector; |
| const ItemVector& libs = cli.GetItems(); |
| std::string currentBinDir = |
| this->LocalGenerator->GetCurrentBinaryDirectory(); |
| for (cmComputeLinkInformation::Item const& l : libs) { |
| if (l.IsPath && cmVS10IsTargetsFile(l.Value)) { |
| std::string path = |
| this->LocalGenerator->ConvertToRelativePath(currentBinDir, l.Value); |
| ConvertToWindowsSlash(path); |
| this->AddTargetsFileAndConfigPair(path, config); |
| } |
| } |
| |
| return true; |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteLinkOptions( |
| std::string const& config) |
| { |
| if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY || |
| this->GeneratorTarget->GetType() > cmStateEnums::MODULE_LIBRARY) { |
| return; |
| } |
| if (this->ProjectType == csproj) { |
| return; |
| } |
| Options& linkOptions = *(this->LinkOptions[config]); |
| this->WriteString("<Link>\n", 2); |
| |
| linkOptions.PrependInheritedString("AdditionalOptions"); |
| linkOptions.OutputFlagMap(*this->BuildFileStream, " "); |
| |
| this->WriteString("</Link>\n", 2); |
| if (!this->GlobalGenerator->NeedLinkLibraryDependencies( |
| this->GeneratorTarget)) { |
| this->WriteString("<ProjectReference>\n", 2); |
| this->WriteString( |
| "<LinkLibraryDependencies>false</LinkLibraryDependencies>\n", 3); |
| this->WriteString("</ProjectReference>\n", 2); |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::AddLibraries( |
| cmComputeLinkInformation& cli, std::vector<std::string>& libVec, |
| std::vector<std::string>& vsTargetVec) |
| { |
| typedef cmComputeLinkInformation::ItemVector ItemVector; |
| ItemVector const& libs = cli.GetItems(); |
| std::string currentBinDir = |
| this->LocalGenerator->GetCurrentBinaryDirectory(); |
| for (cmComputeLinkInformation::Item const& l : libs) { |
| if (l.IsPath) { |
| std::string path = |
| this->LocalGenerator->ConvertToRelativePath(currentBinDir, l.Value); |
| ConvertToWindowsSlash(path); |
| if (cmVS10IsTargetsFile(l.Value)) { |
| vsTargetVec.push_back(path); |
| } else { |
| libVec.push_back(path); |
| } |
| } else if (!l.Target || |
| l.Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) { |
| libVec.push_back(l.Value); |
| } |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::AddTargetsFileAndConfigPair( |
| std::string const& targetsFile, std::string const& config) |
| { |
| for (TargetsFileAndConfigs& i : this->TargetsFileAndConfigsVec) { |
| if (cmSystemTools::ComparePath(targetsFile, i.File)) { |
| if (std::find(i.Configs.begin(), i.Configs.end(), config) == |
| i.Configs.end()) { |
| i.Configs.push_back(config); |
| } |
| return; |
| } |
| } |
| TargetsFileAndConfigs entry; |
| entry.File = targetsFile; |
| entry.Configs.push_back(config); |
| this->TargetsFileAndConfigsVec.push_back(entry); |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteMidlOptions( |
| std::string const& configName) |
| { |
| if (!this->MSTools) { |
| return; |
| } |
| if (this->ProjectType == csproj) { |
| return; |
| } |
| |
| // This processes *any* of the .idl files specified in the project's file |
| // list (and passed as the item metadata %(Filename) expressing the rule |
| // input filename) into output files at the per-config *build* dir |
| // ($(IntDir)) each. |
| // |
| // IOW, this MIDL section is intended to provide a fully generic syntax |
| // content suitable for most cases (read: if you get errors, then it's quite |
| // probable that the error is on your side of the .idl setup). |
| // |
| // Also, note that the marked-as-generated _i.c file in the Visual Studio |
| // generator case needs to be referred to as $(IntDir)\foo_i.c at the |
| // project's file list, otherwise the compiler-side processing won't pick it |
| // up (for non-directory form, it ends up looking in project binary dir |
| // only). Perhaps there's something to be done to make this more automatic |
| // on the CMake side? |
| this->WriteString("<Midl>\n", 2); |
| this->WriteString("<AdditionalIncludeDirectories>", 3); |
| std::vector<std::string> const includes = |
| this->GetIncludes(configName, "MIDL"); |
| for (std::string const& i : includes) { |
| *this->BuildFileStream << cmVS10EscapeXML(i) << ";"; |
| } |
| this->WriteString("%(AdditionalIncludeDirectories)" |
| "</AdditionalIncludeDirectories>\n", |
| 0); |
| this->WriteString("<OutputDirectory>$(ProjectDir)/$(IntDir)" |
| "</OutputDirectory>\n", |
| 3); |
| this->WriteString("<HeaderFileName>%(Filename).h</HeaderFileName>\n", 3); |
| this->WriteString("<TypeLibraryName>%(Filename).tlb</TypeLibraryName>\n", 3); |
| this->WriteString("<InterfaceIdentifierFileName>" |
| "%(Filename)_i.c</InterfaceIdentifierFileName>\n", |
| 3); |
| this->WriteString("<ProxyFileName>%(Filename)_p.c</ProxyFileName>\n", 3); |
| this->WriteString("</Midl>\n", 2); |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups() |
| { |
| if (this->ProjectType == csproj) { |
| return; |
| } |
| for (const auto& i : this->Configurations) { |
| this->WritePlatformConfigTag("ItemDefinitionGroup", i, 1); |
| *this->BuildFileStream << "\n"; |
| // output cl compile flags <ClCompile></ClCompile> |
| if (this->GeneratorTarget->GetType() <= cmStateEnums::OBJECT_LIBRARY) { |
| this->WriteClOptions(i); |
| // output rc compile flags <ResourceCompile></ResourceCompile> |
| this->WriteRCOptions(i); |
| this->WriteCudaOptions(i); |
| this->WriteMasmOptions(i); |
| this->WriteNasmOptions(i); |
| } |
| // output midl flags <Midl></Midl> |
| this->WriteMidlOptions(i); |
| // write events |
| if (this->ProjectType != csproj) { |
| this->WriteEvents(i); |
| } |
| // output link flags <Link></Link> |
| this->WriteLinkOptions(i); |
| this->WriteCudaLinkOptions(i); |
| // output lib flags <Lib></Lib> |
| this->WriteLibOptions(i); |
| // output manifest flags <Manifest></Manifest> |
| this->WriteManifestOptions(i); |
| if (this->NsightTegra && |
| this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE && |
| this->GeneratorTarget->GetPropertyAsBool("ANDROID_GUI")) { |
| this->WriteAntBuildOptions(i); |
| } |
| this->WriteString("</ItemDefinitionGroup>\n", 1); |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteEvents( |
| std::string const& configName) |
| { |
| bool addedPrelink = false; |
| cmGeneratorTarget::ModuleDefinitionInfo const* mdi = |
| this->GeneratorTarget->GetModuleDefinitionInfo(configName); |
| if (mdi && mdi->DefFileGenerated) { |
| addedPrelink = true; |
| std::vector<cmCustomCommand> commands = |
| this->GeneratorTarget->GetPreLinkCommands(); |
| this->GlobalGenerator->AddSymbolExportCommand(this->GeneratorTarget, |
| commands, configName); |
| this->WriteEvent("PreLinkEvent", commands, configName); |
| } |
| if (!addedPrelink) { |
| this->WriteEvent("PreLinkEvent", |
| this->GeneratorTarget->GetPreLinkCommands(), configName); |
| } |
| this->WriteEvent("PreBuildEvent", |
| this->GeneratorTarget->GetPreBuildCommands(), configName); |
| this->WriteEvent("PostBuildEvent", |
| this->GeneratorTarget->GetPostBuildCommands(), configName); |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteEvent( |
| const char* name, std::vector<cmCustomCommand> const& commands, |
| std::string const& configName) |
| { |
| if (commands.empty()) { |
| return; |
| } |
| this->WriteString("<", 2); |
| (*this->BuildFileStream) << name << ">\n"; |
| cmLocalVisualStudio7Generator* lg = this->LocalGenerator; |
| std::string script; |
| const char* pre = ""; |
| std::string comment; |
| for (cmCustomCommand const& i : commands) { |
| cmCustomCommandGenerator ccg(i, configName, this->LocalGenerator); |
| if (!ccg.HasOnlyEmptyCommandLines()) { |
| comment += pre; |
| comment += lg->ConstructComment(ccg); |
| script += pre; |
| pre = "\n"; |
| script += cmVS10EscapeXML(lg->ConstructScript(ccg)); |
| } |
| } |
| comment = cmVS10EscapeComment(comment); |
| if (this->ProjectType != csproj) { |
| this->WriteString("<Message>", 3); |
| (*this->BuildFileStream) << cmVS10EscapeXML(comment) << "</Message>\n"; |
| this->WriteString("<Command>", 3); |
| } else { |
| std::string strippedComment = comment; |
| strippedComment.erase( |
| std::remove(strippedComment.begin(), strippedComment.end(), '\t'), |
| strippedComment.end()); |
| if (!comment.empty() && !strippedComment.empty()) { |
| (*this->BuildFileStream) << "echo " << cmVS10EscapeXML(comment) << "\n"; |
| } |
| } |
| (*this->BuildFileStream) << script; |
| if (this->ProjectType != csproj) { |
| (*this->BuildFileStream) << "</Command>"; |
| } |
| (*this->BuildFileStream) << "\n"; |
| this->WriteString("</", 2); |
| (*this->BuildFileStream) << name << ">\n"; |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteProjectReferences() |
| { |
| cmGlobalGenerator::TargetDependSet const& unordered = |
| this->GlobalGenerator->GetTargetDirectDepends(this->GeneratorTarget); |
| typedef cmGlobalVisualStudioGenerator::OrderedTargetDependSet |
| OrderedTargetDependSet; |
| OrderedTargetDependSet depends(unordered, CMAKE_CHECK_BUILD_SYSTEM_TARGET); |
| this->WriteString("<ItemGroup>\n", 1); |
| for (cmTargetDepend const& i : depends) { |
| cmGeneratorTarget const* dt = i; |
| if (dt->GetType() == cmStateEnums::INTERFACE_LIBRARY) { |
| continue; |
| } |
| // skip fortran targets as they can not be processed by MSBuild |
| // the only reference will be in the .sln file |
| if (static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator) |
| ->TargetIsFortranOnly(dt)) { |
| continue; |
| } |
| this->WriteString("<ProjectReference Include=\"", 2); |
| cmLocalGenerator* lg = dt->GetLocalGenerator(); |
| std::string name = dt->GetName(); |
| std::string path; |
| const char* p = dt->GetProperty("EXTERNAL_MSPROJECT"); |
| if (p) { |
| path = p; |
| } else { |
| path = lg->GetCurrentBinaryDirectory(); |
| path += "/"; |
| path += dt->GetName(); |
| path += computeProjectFileExtension(dt, *this->Configurations.begin()); |
| } |
| ConvertToWindowsSlash(path); |
| (*this->BuildFileStream) << cmVS10EscapeXML(path) << "\">\n"; |
| this->WriteString("<Project>", 3); |
| (*this->BuildFileStream) << "{" << this->GlobalGenerator->GetGUID(name) |
| << "}"; |
| (*this->BuildFileStream) << "</Project>\n"; |
| this->WriteString("<Name>", 3); |
| (*this->BuildFileStream) << name << "</Name>\n"; |
| this->WriteDotNetReferenceCustomTags(name); |
| if (csproj == this->ProjectType) { |
| if (!static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator) |
| ->TargetCanBeReferenced(dt)) { |
| this->WriteString( |
| "<ReferenceOutputAssembly>false</ReferenceOutputAssembly>\n", 3); |
| } |
| } |
| this->WriteString("</ProjectReference>\n", 2); |
| } |
| this->WriteString("</ItemGroup>\n", 1); |
| } |
| |
| void cmVisualStudio10TargetGenerator::WritePlatformExtensions() |
| { |
| // This only applies to Windows 10 apps |
| if (this->GlobalGenerator->TargetsWindowsStore() && |
| cmHasLiteralPrefix(this->GlobalGenerator->GetSystemVersion(), "10.0")) { |
| const char* desktopExtensionsVersion = |
| this->GeneratorTarget->GetProperty("VS_DESKTOP_EXTENSIONS_VERSION"); |
| if (desktopExtensionsVersion) { |
| this->WriteSinglePlatformExtension("WindowsDesktop", |
| desktopExtensionsVersion); |
| } |
| const char* mobileExtensionsVersion = |
| this->GeneratorTarget->GetProperty("VS_MOBILE_EXTENSIONS_VERSION"); |
| if (mobileExtensionsVersion) { |
| this->WriteSinglePlatformExtension("WindowsMobile", |
| mobileExtensionsVersion); |
| } |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteSinglePlatformExtension( |
| std::string const& extension, std::string const& version) |
| { |
| this->WriteString("<Import Project=", 2); |
| (*this->BuildFileStream) |
| << "\"$([Microsoft.Build.Utilities.ToolLocationHelper]" |
| << "::GetPlatformExtensionSDKLocation(`" << extension |
| << ", Version=" << version |
| << "`, $(TargetPlatformIdentifier), $(TargetPlatformVersion), null, " |
| << "$(ExtensionSDKDirectoryRoot), null))" |
| << "\\DesignTime\\CommonConfiguration\\Neutral\\" << extension |
| << ".props\" " |
| << "Condition=\"exists('$(" |
| << "[Microsoft.Build.Utilities.ToolLocationHelper]" |
| << "::GetPlatformExtensionSDKLocation(`" << extension |
| << ", Version=" << version |
| << "`, $(TargetPlatformIdentifier), $(TargetPlatformVersion), null, " |
| << "$(ExtensionSDKDirectoryRoot), null))" |
| << "\\DesignTime\\CommonConfiguration\\Neutral\\" << extension |
| << ".props')\" />\n"; |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteSDKReferences() |
| { |
| std::vector<std::string> sdkReferences; |
| bool hasWrittenItemGroup = false; |
| if (const char* vsSDKReferences = |
| this->GeneratorTarget->GetProperty("VS_SDK_REFERENCES")) { |
| cmSystemTools::ExpandListArgument(vsSDKReferences, sdkReferences); |
| this->WriteString("<ItemGroup>\n", 1); |
| hasWrittenItemGroup = true; |
| for (std::string const& ri : sdkReferences) { |
| this->WriteString("<SDKReference Include=\"", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(ri) << "\"/>\n"; |
| } |
| } |
| |
| // This only applies to Windows 10 apps |
| if (this->GlobalGenerator->TargetsWindowsStore() && |
| cmHasLiteralPrefix(this->GlobalGenerator->GetSystemVersion(), "10.0")) { |
| const char* desktopExtensionsVersion = |
| this->GeneratorTarget->GetProperty("VS_DESKTOP_EXTENSIONS_VERSION"); |
| const char* mobileExtensionsVersion = |
| this->GeneratorTarget->GetProperty("VS_MOBILE_EXTENSIONS_VERSION"); |
| const char* iotExtensionsVersion = |
| this->GeneratorTarget->GetProperty("VS_IOT_EXTENSIONS_VERSION"); |
| |
| if (desktopExtensionsVersion || mobileExtensionsVersion || |
| iotExtensionsVersion) { |
| if (!hasWrittenItemGroup) { |
| this->WriteString("<ItemGroup>\n", 1); |
| hasWrittenItemGroup = true; |
| } |
| if (desktopExtensionsVersion) { |
| this->WriteSingleSDKReference("WindowsDesktop", |
| desktopExtensionsVersion); |
| } |
| if (mobileExtensionsVersion) { |
| this->WriteSingleSDKReference("WindowsMobile", |
| mobileExtensionsVersion); |
| } |
| if (iotExtensionsVersion) { |
| this->WriteSingleSDKReference("WindowsIoT", iotExtensionsVersion); |
| } |
| } |
| } |
| |
| if (hasWrittenItemGroup) { |
| this->WriteString("</ItemGroup>\n", 1); |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteSingleSDKReference( |
| std::string const& extension, std::string const& version) |
| { |
| this->WriteString("<SDKReference Include=\"", 2); |
| (*this->BuildFileStream) << extension << ", Version=" << version |
| << "\" />\n"; |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile() |
| { |
| if ((this->GlobalGenerator->TargetsWindowsStore() || |
| this->GlobalGenerator->TargetsWindowsPhone()) && |
| (cmStateEnums::EXECUTABLE == this->GeneratorTarget->GetType())) { |
| std::string pfxFile; |
| std::vector<cmSourceFile const*> certificates; |
| this->GeneratorTarget->GetCertificates(certificates, ""); |
| for (cmSourceFile const* si : certificates) { |
| pfxFile = this->ConvertPath(si->GetFullPath(), false); |
| ConvertToWindowsSlash(pfxFile); |
| break; |
| } |
| |
| if (this->IsMissingFiles && |
| !(this->GlobalGenerator->TargetsWindowsPhone() && |
| this->GlobalGenerator->GetSystemVersion() == "8.0")) { |
| // Move the manifest to a project directory to avoid clashes |
| std::string artifactDir = |
| this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); |
| ConvertToWindowsSlash(artifactDir); |
| this->WriteString("<PropertyGroup>\n", 1); |
| this->WriteString("<AppxPackageArtifactsDir>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(artifactDir) |
| << "\\</AppxPackageArtifactsDir>\n"; |
| this->WriteString("<ProjectPriFullPath>", 2); |
| std::string resourcePriFile = |
| this->DefaultArtifactDir + "/resources.pri"; |
| ConvertToWindowsSlash(resourcePriFile); |
| (*this->BuildFileStream) << resourcePriFile << "</ProjectPriFullPath>\n"; |
| |
| // If we are missing files and we don't have a certificate and |
| // aren't targeting WP8.0, add a default certificate |
| if (pfxFile.empty()) { |
| std::string templateFolder = |
| cmSystemTools::GetCMakeRoot() + "/Templates/Windows"; |
| pfxFile = this->DefaultArtifactDir + "/Windows_TemporaryKey.pfx"; |
| cmSystemTools::CopyAFile(templateFolder + "/Windows_TemporaryKey.pfx", |
| pfxFile, false); |
| ConvertToWindowsSlash(pfxFile); |
| this->AddedFiles.push_back(pfxFile); |
| } |
| |
| this->WriteString("<", 2); |
| (*this->BuildFileStream) << "PackageCertificateKeyFile>" << pfxFile |
| << "</PackageCertificateKeyFile>\n"; |
| std::string thumb = cmSystemTools::ComputeCertificateThumbprint(pfxFile); |
| if (!thumb.empty()) { |
| this->WriteString("<PackageCertificateThumbprint>", 2); |
| (*this->BuildFileStream) << thumb |
| << "</PackageCertificateThumbprint>\n"; |
| } |
| this->WriteString("</PropertyGroup>\n", 1); |
| } else if (!pfxFile.empty()) { |
| this->WriteString("<PropertyGroup>\n", 1); |
| this->WriteString("<", 2); |
| (*this->BuildFileStream) << "PackageCertificateKeyFile>" << pfxFile |
| << "</PackageCertificateKeyFile>\n"; |
| std::string thumb = cmSystemTools::ComputeCertificateThumbprint(pfxFile); |
| if (!thumb.empty()) { |
| this->WriteString("<PackageCertificateThumbprint>", 2); |
| (*this->BuildFileStream) << thumb |
| << "</PackageCertificateThumbprint>\n"; |
| } |
| this->WriteString("</PropertyGroup>\n", 1); |
| } |
| } |
| } |
| |
| bool cmVisualStudio10TargetGenerator::IsResxHeader( |
| const std::string& headerFile) |
| { |
| std::set<std::string> expectedResxHeaders; |
| this->GeneratorTarget->GetExpectedResxHeaders(expectedResxHeaders, ""); |
| |
| std::set<std::string>::const_iterator it = |
| expectedResxHeaders.find(headerFile); |
| return it != expectedResxHeaders.end(); |
| } |
| |
| bool cmVisualStudio10TargetGenerator::IsXamlHeader( |
| const std::string& headerFile) |
| { |
| std::set<std::string> expectedXamlHeaders; |
| this->GeneratorTarget->GetExpectedXamlHeaders(expectedXamlHeaders, ""); |
| |
| std::set<std::string>::const_iterator it = |
| expectedXamlHeaders.find(headerFile); |
| return it != expectedXamlHeaders.end(); |
| } |
| |
| bool cmVisualStudio10TargetGenerator::IsXamlSource( |
| const std::string& sourceFile) |
| { |
| std::set<std::string> expectedXamlSources; |
| this->GeneratorTarget->GetExpectedXamlSources(expectedXamlSources, ""); |
| |
| std::set<std::string>::const_iterator it = |
| expectedXamlSources.find(sourceFile); |
| return it != expectedXamlSources.end(); |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings() |
| { |
| cmGlobalVisualStudio10Generator* gg = |
| static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator); |
| bool isAppContainer = false; |
| bool const isWindowsPhone = this->GlobalGenerator->TargetsWindowsPhone(); |
| bool const isWindowsStore = this->GlobalGenerator->TargetsWindowsStore(); |
| std::string const& v = this->GlobalGenerator->GetSystemVersion(); |
| if (isWindowsPhone || isWindowsStore) { |
| this->WriteString("<ApplicationType>", 2); |
| (*this->BuildFileStream) |
| << (isWindowsPhone ? "Windows Phone" : "Windows Store") |
| << "</ApplicationType>\n"; |
| this->WriteString("<DefaultLanguage>en-US" |
| "</DefaultLanguage>\n", |
| 2); |
| if (cmHasLiteralPrefix(v, "10.0")) { |
| this->WriteString("<ApplicationTypeRevision>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML("10.0") |
| << "</ApplicationTypeRevision>\n"; |
| // Visual Studio 14.0 is necessary for building 10.0 apps |
| this->WriteString("<MinimumVisualStudioVersion>14.0" |
| "</MinimumVisualStudioVersion>\n", |
| 2); |
| |
| if (this->GeneratorTarget->GetType() < cmStateEnums::UTILITY) { |
| isAppContainer = true; |
| } |
| } else if (v == "8.1") { |
| this->WriteString("<ApplicationTypeRevision>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(v) |
| << "</ApplicationTypeRevision>\n"; |
| // Visual Studio 12.0 is necessary for building 8.1 apps |
| this->WriteString("<MinimumVisualStudioVersion>12.0" |
| "</MinimumVisualStudioVersion>\n", |
| 2); |
| |
| if (this->GeneratorTarget->GetType() < cmStateEnums::UTILITY) { |
| isAppContainer = true; |
| } |
| } else if (v == "8.0") { |
| this->WriteString("<ApplicationTypeRevision>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(v) |
| << "</ApplicationTypeRevision>\n"; |
| // Visual Studio 11.0 is necessary for building 8.0 apps |
| this->WriteString("<MinimumVisualStudioVersion>11.0" |
| "</MinimumVisualStudioVersion>\n", |
| 2); |
| |
| if (isWindowsStore && |
| this->GeneratorTarget->GetType() < cmStateEnums::UTILITY) { |
| isAppContainer = true; |
| } else if (isWindowsPhone && |
| this->GeneratorTarget->GetType() == |
| cmStateEnums::EXECUTABLE) { |
| this->WriteString("<XapOutputs>true</XapOutputs>\n", 2); |
| this->WriteString("<XapFilename>", 2); |
| (*this->BuildFileStream) |
| << cmVS10EscapeXML(this->Name) |
| << "_$(Configuration)_$(Platform).xap</XapFilename>\n"; |
| } |
| } |
| } |
| if (isAppContainer) { |
| this->WriteString("<AppContainerApplication>true" |
| "</AppContainerApplication>\n", |
| 2); |
| } else if (this->Platform == "ARM64") { |
| this->WriteString("<WindowsSDKDesktopARM64Support>true" |
| "</WindowsSDKDesktopARM64Support>\n", |
| 2); |
| } else if (this->Platform == "ARM") { |
| this->WriteString("<WindowsSDKDesktopARMSupport>true" |
| "</WindowsSDKDesktopARMSupport>\n", |
| 2); |
| } |
| std::string const& targetPlatformVersion = |
| gg->GetWindowsTargetPlatformVersion(); |
| if (!targetPlatformVersion.empty()) { |
| this->WriteString("<WindowsTargetPlatformVersion>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(targetPlatformVersion) |
| << "</WindowsTargetPlatformVersion>\n"; |
| } |
| const char* targetPlatformMinVersion = this->GeneratorTarget->GetProperty( |
| "VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION"); |
| if (targetPlatformMinVersion) { |
| this->WriteString("<WindowsTargetPlatformMinVersion>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(targetPlatformMinVersion) |
| << "</WindowsTargetPlatformMinVersion>\n"; |
| } else if (isWindowsStore && cmHasLiteralPrefix(v, "10.0")) { |
| // If the min version is not set, then use the TargetPlatformVersion |
| if (!targetPlatformVersion.empty()) { |
| this->WriteString("<WindowsTargetPlatformMinVersion>", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(targetPlatformVersion) |
| << "</WindowsTargetPlatformMinVersion>\n"; |
| } |
| } |
| |
| // Added IoT Startup Task support |
| if (this->GeneratorTarget->GetPropertyAsBool("VS_IOT_STARTUP_TASK")) { |
| this->WriteString("<ContainsStartupTask>true</ContainsStartupTask>\n", 2); |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::VerifyNecessaryFiles() |
| { |
| // For Windows and Windows Phone executables, we will assume that if a |
| // manifest is not present that we need to add all the necessary files |
| if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) { |
| std::vector<cmSourceFile const*> manifestSources; |
| this->GeneratorTarget->GetAppManifest(manifestSources, ""); |
| { |
| std::string const& v = this->GlobalGenerator->GetSystemVersion(); |
| if (this->GlobalGenerator->TargetsWindowsPhone()) { |
| if (v == "8.0") { |
| // Look through the sources for WMAppManifest.xml |
| std::vector<cmSourceFile const*> extraSources; |
| this->GeneratorTarget->GetExtraSources(extraSources, ""); |
| bool foundManifest = false; |
| for (cmSourceFile const* si : extraSources) { |
| // Need to do a lowercase comparison on the filename |
| if ("wmappmanifest.xml" == |
| cmSystemTools::LowerCase(si->GetLocation().GetName())) { |
| foundManifest = true; |
| break; |
| } |
| } |
| if (!foundManifest) { |
| this->IsMissingFiles = true; |
| } |
| } else if (v == "8.1") { |
| if (manifestSources.empty()) { |
| this->IsMissingFiles = true; |
| } |
| } |
| } else if (this->GlobalGenerator->TargetsWindowsStore()) { |
| if (manifestSources.empty()) { |
| if (v == "8.0") { |
| this->IsMissingFiles = true; |
| } else if (v == "8.1" || cmHasLiteralPrefix(v, "10.0")) { |
| this->IsMissingFiles = true; |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteMissingFiles() |
| { |
| std::string const& v = this->GlobalGenerator->GetSystemVersion(); |
| if (this->GlobalGenerator->TargetsWindowsPhone()) { |
| if (v == "8.0") { |
| this->WriteMissingFilesWP80(); |
| } else if (v == "8.1") { |
| this->WriteMissingFilesWP81(); |
| } |
| } else if (this->GlobalGenerator->TargetsWindowsStore()) { |
| if (v == "8.0") { |
| this->WriteMissingFilesWS80(); |
| } else if (v == "8.1") { |
| this->WriteMissingFilesWS81(); |
| } else if (cmHasLiteralPrefix(v, "10.0")) { |
| this->WriteMissingFilesWS10_0(); |
| } |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteMissingFilesWP80() |
| { |
| std::string templateFolder = |
| cmSystemTools::GetCMakeRoot() + "/Templates/Windows"; |
| |
| // For WP80, the manifest needs to be in the same folder as the project |
| // this can cause an overwrite problem if projects aren't organized in |
| // folders |
| std::string manifestFile = |
| this->LocalGenerator->GetCurrentBinaryDirectory() + |
| std::string("/WMAppManifest.xml"); |
| std::string artifactDir = |
| this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); |
| ConvertToWindowsSlash(artifactDir); |
| std::string artifactDirXML = cmVS10EscapeXML(artifactDir); |
| std::string targetNameXML = |
| cmVS10EscapeXML(this->GeneratorTarget->GetName()); |
| |
| cmGeneratedFileStream fout(manifestFile.c_str()); |
| fout.SetCopyIfDifferent(true); |
| |
| /* clang-format off */ |
| fout << |
| "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| "<Deployment" |
| " xmlns=\"http://schemas.microsoft.com/windowsphone/2012/deployment\"" |
| " AppPlatformVersion=\"8.0\">\n" |
| "\t<DefaultLanguage xmlns=\"\" code=\"en-US\"/>\n" |
| "\t<App xmlns=\"\" ProductID=\"{" << this->GUID << "}\"" |
| " Title=\"CMake Test Program\" RuntimeType=\"Modern Native\"" |
| " Version=\"1.0.0.0\" Genre=\"apps.normal\" Author=\"CMake\"" |
| " Description=\"Default CMake App\" Publisher=\"CMake\"" |
| " PublisherID=\"{" << this->GUID << "}\">\n" |
| "\t\t<IconPath IsRelative=\"true\" IsResource=\"false\">" |
| << artifactDirXML << "\\ApplicationIcon.png</IconPath>\n" |
| "\t\t<Capabilities/>\n" |
| "\t\t<Tasks>\n" |
| "\t\t\t<DefaultTask Name=\"_default\"" |
| " ImagePath=\"" << targetNameXML << ".exe\" ImageParams=\"\" />\n" |
| "\t\t</Tasks>\n" |
| "\t\t<Tokens>\n" |
| "\t\t\t<PrimaryToken TokenID=\"" << targetNameXML << "Token\"" |
| " TaskName=\"_default\">\n" |
| "\t\t\t\t<TemplateFlip>\n" |
| "\t\t\t\t\t<SmallImageURI IsRelative=\"true\" IsResource=\"false\">" |
| << artifactDirXML << "\\SmallLogo.png</SmallImageURI>\n" |
| "\t\t\t\t\t<Count>0</Count>\n" |
| "\t\t\t\t\t<BackgroundImageURI IsRelative=\"true\" IsResource=\"false\">" |
| << artifactDirXML << "\\Logo.png</BackgroundImageURI>\n" |
| "\t\t\t\t</TemplateFlip>\n" |
| "\t\t\t</PrimaryToken>\n" |
| "\t\t</Tokens>\n" |
| "\t\t<ScreenResolutions>\n" |
| "\t\t\t<ScreenResolution Name=\"ID_RESOLUTION_WVGA\" />\n" |
| "\t\t</ScreenResolutions>\n" |
| "\t</App>\n" |
| "</Deployment>\n"; |
| /* clang-format on */ |
| |
| std::string sourceFile = this->ConvertPath(manifestFile, false); |
| ConvertToWindowsSlash(sourceFile); |
| this->WriteString("<Xml Include=\"", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(sourceFile) << "\">\n"; |
| this->WriteString("<SubType>Designer</SubType>\n", 3); |
| this->WriteString("</Xml>\n", 2); |
| this->AddedFiles.push_back(sourceFile); |
| |
| std::string smallLogo = this->DefaultArtifactDir + "/SmallLogo.png"; |
| cmSystemTools::CopyAFile(templateFolder + "/SmallLogo.png", smallLogo, |
| false); |
| ConvertToWindowsSlash(smallLogo); |
| this->WriteString("<Image Include=\"", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(smallLogo) << "\" />\n"; |
| this->AddedFiles.push_back(smallLogo); |
| |
| std::string logo = this->DefaultArtifactDir + "/Logo.png"; |
| cmSystemTools::CopyAFile(templateFolder + "/Logo.png", logo, false); |
| ConvertToWindowsSlash(logo); |
| this->WriteString("<Image Include=\"", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(logo) << "\" />\n"; |
| this->AddedFiles.push_back(logo); |
| |
| std::string applicationIcon = |
| this->DefaultArtifactDir + "/ApplicationIcon.png"; |
| cmSystemTools::CopyAFile(templateFolder + "/ApplicationIcon.png", |
| applicationIcon, false); |
| ConvertToWindowsSlash(applicationIcon); |
| this->WriteString("<Image Include=\"", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(applicationIcon) << "\" />\n"; |
| this->AddedFiles.push_back(applicationIcon); |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteMissingFilesWP81() |
| { |
| std::string manifestFile = |
| this->DefaultArtifactDir + "/package.appxManifest"; |
| std::string artifactDir = |
| this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); |
| ConvertToWindowsSlash(artifactDir); |
| std::string artifactDirXML = cmVS10EscapeXML(artifactDir); |
| std::string targetNameXML = |
| cmVS10EscapeXML(this->GeneratorTarget->GetName()); |
| |
| cmGeneratedFileStream fout(manifestFile.c_str()); |
| fout.SetCopyIfDifferent(true); |
| |
| /* clang-format off */ |
| fout << |
| "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| "<Package xmlns=\"http://schemas.microsoft.com/appx/2010/manifest\"" |
| " xmlns:m2=\"http://schemas.microsoft.com/appx/2013/manifest\"" |
| " xmlns:mp=\"http://schemas.microsoft.com/appx/2014/phone/manifest\">\n" |
| "\t<Identity Name=\"" << this->GUID << "\" Publisher=\"CN=CMake\"" |
| " Version=\"1.0.0.0\" />\n" |
| "\t<mp:PhoneIdentity PhoneProductId=\"" << this->GUID << "\"" |
| " PhonePublisherId=\"00000000-0000-0000-0000-000000000000\"/>\n" |
| "\t<Properties>\n" |
| "\t\t<DisplayName>" << targetNameXML << "</DisplayName>\n" |
| "\t\t<PublisherDisplayName>CMake</PublisherDisplayName>\n" |
| "\t\t<Logo>" << artifactDirXML << "\\StoreLogo.png</Logo>\n" |
| "\t</Properties>\n" |
| "\t<Prerequisites>\n" |
| "\t\t<OSMinVersion>6.3.1</OSMinVersion>\n" |
| "\t\t<OSMaxVersionTested>6.3.1</OSMaxVersionTested>\n" |
| "\t</Prerequisites>\n" |
| "\t<Resources>\n" |
| "\t\t<Resource Language=\"x-generate\" />\n" |
| "\t</Resources>\n" |
| "\t<Applications>\n" |
| "\t\t<Application Id=\"App\"" |
| " Executable=\"" << targetNameXML << ".exe\"" |
| " EntryPoint=\"" << targetNameXML << ".App\">\n" |
| "\t\t\t<m2:VisualElements\n" |
| "\t\t\t\tDisplayName=\"" << targetNameXML << "\"\n" |
| "\t\t\t\tDescription=\"" << targetNameXML << "\"\n" |
| "\t\t\t\tBackgroundColor=\"#336699\"\n" |
| "\t\t\t\tForegroundText=\"light\"\n" |
| "\t\t\t\tSquare150x150Logo=\"" << artifactDirXML << "\\Logo.png\"\n" |
| "\t\t\t\tSquare30x30Logo=\"" << artifactDirXML << "\\SmallLogo.png\">\n" |
| "\t\t\t\t<m2:DefaultTile ShortName=\"" << targetNameXML << "\">\n" |
| "\t\t\t\t\t<m2:ShowNameOnTiles>\n" |
| "\t\t\t\t\t\t<m2:ShowOn Tile=\"square150x150Logo\" />\n" |
| "\t\t\t\t\t</m2:ShowNameOnTiles>\n" |
| "\t\t\t\t</m2:DefaultTile>\n" |
| "\t\t\t\t<m2:SplashScreen" |
| " Image=\"" << artifactDirXML << "\\SplashScreen.png\" />\n" |
| "\t\t\t</m2:VisualElements>\n" |
| "\t\t</Application>\n" |
| "\t</Applications>\n" |
| "</Package>\n"; |
| /* clang-format on */ |
| |
| this->WriteCommonMissingFiles(manifestFile); |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteMissingFilesWS80() |
| { |
| std::string manifestFile = |
| this->DefaultArtifactDir + "/package.appxManifest"; |
| std::string artifactDir = |
| this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); |
| ConvertToWindowsSlash(artifactDir); |
| std::string artifactDirXML = cmVS10EscapeXML(artifactDir); |
| std::string targetNameXML = |
| cmVS10EscapeXML(this->GeneratorTarget->GetName()); |
| |
| cmGeneratedFileStream fout(manifestFile.c_str()); |
| fout.SetCopyIfDifferent(true); |
| |
| /* clang-format off */ |
| fout << |
| "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| "<Package xmlns=\"http://schemas.microsoft.com/appx/2010/manifest\">\n" |
| "\t<Identity Name=\"" << this->GUID << "\" Publisher=\"CN=CMake\"" |
| " Version=\"1.0.0.0\" />\n" |
| "\t<Properties>\n" |
| "\t\t<DisplayName>" << targetNameXML << "</DisplayName>\n" |
| "\t\t<PublisherDisplayName>CMake</PublisherDisplayName>\n" |
| "\t\t<Logo>" << artifactDirXML << "\\StoreLogo.png</Logo>\n" |
| "\t</Properties>\n" |
| "\t<Prerequisites>\n" |
| "\t\t<OSMinVersion>6.2.1</OSMinVersion>\n" |
| "\t\t<OSMaxVersionTested>6.2.1</OSMaxVersionTested>\n" |
| "\t</Prerequisites>\n" |
| "\t<Resources>\n" |
| "\t\t<Resource Language=\"x-generate\" />\n" |
| "\t</Resources>\n" |
| "\t<Applications>\n" |
| "\t\t<Application Id=\"App\"" |
| " Executable=\"" << targetNameXML << ".exe\"" |
| " EntryPoint=\"" << targetNameXML << ".App\">\n" |
| "\t\t\t<VisualElements" |
| " DisplayName=\"" << targetNameXML << "\"" |
| " Description=\"" << targetNameXML << "\"" |
| " BackgroundColor=\"#336699\" ForegroundText=\"light\"" |
| " Logo=\"" << artifactDirXML << "\\Logo.png\"" |
| " SmallLogo=\"" << artifactDirXML << "\\SmallLogo.png\">\n" |
| "\t\t\t\t<DefaultTile ShowName=\"allLogos\"" |
| " ShortName=\"" << targetNameXML << "\" />\n" |
| "\t\t\t\t<SplashScreen" |
| " Image=\"" << artifactDirXML << "\\SplashScreen.png\" />\n" |
| "\t\t\t</VisualElements>\n" |
| "\t\t</Application>\n" |
| "\t</Applications>\n" |
| "</Package>\n"; |
| /* clang-format on */ |
| |
| this->WriteCommonMissingFiles(manifestFile); |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteMissingFilesWS81() |
| { |
| std::string manifestFile = |
| this->DefaultArtifactDir + "/package.appxManifest"; |
| std::string artifactDir = |
| this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); |
| ConvertToWindowsSlash(artifactDir); |
| std::string artifactDirXML = cmVS10EscapeXML(artifactDir); |
| std::string targetNameXML = |
| cmVS10EscapeXML(this->GeneratorTarget->GetName()); |
| |
| cmGeneratedFileStream fout(manifestFile.c_str()); |
| fout.SetCopyIfDifferent(true); |
| |
| /* clang-format off */ |
| fout << |
| "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| "<Package xmlns=\"http://schemas.microsoft.com/appx/2010/manifest\"" |
| " xmlns:m2=\"http://schemas.microsoft.com/appx/2013/manifest\">\n" |
| "\t<Identity Name=\"" << this->GUID << "\" Publisher=\"CN=CMake\"" |
| " Version=\"1.0.0.0\" />\n" |
| "\t<Properties>\n" |
| "\t\t<DisplayName>" << targetNameXML << "</DisplayName>\n" |
| "\t\t<PublisherDisplayName>CMake</PublisherDisplayName>\n" |
| "\t\t<Logo>" << artifactDirXML << "\\StoreLogo.png</Logo>\n" |
| "\t</Properties>\n" |
| "\t<Prerequisites>\n" |
| "\t\t<OSMinVersion>6.3</OSMinVersion>\n" |
| "\t\t<OSMaxVersionTested>6.3</OSMaxVersionTested>\n" |
| "\t</Prerequisites>\n" |
| "\t<Resources>\n" |
| "\t\t<Resource Language=\"x-generate\" />\n" |
| "\t</Resources>\n" |
| "\t<Applications>\n" |
| "\t\t<Application Id=\"App\"" |
| " Executable=\"" << targetNameXML << ".exe\"" |
| " EntryPoint=\"" << targetNameXML << ".App\">\n" |
| "\t\t\t<m2:VisualElements\n" |
| "\t\t\t\tDisplayName=\"" << targetNameXML << "\"\n" |
| "\t\t\t\tDescription=\"" << targetNameXML << "\"\n" |
| "\t\t\t\tBackgroundColor=\"#336699\"\n" |
| "\t\t\t\tForegroundText=\"light\"\n" |
| "\t\t\t\tSquare150x150Logo=\"" << artifactDirXML << "\\Logo.png\"\n" |
| "\t\t\t\tSquare30x30Logo=\"" << artifactDirXML << "\\SmallLogo.png\">\n" |
| "\t\t\t\t<m2:DefaultTile ShortName=\"" << targetNameXML << "\">\n" |
| "\t\t\t\t\t<m2:ShowNameOnTiles>\n" |
| "\t\t\t\t\t\t<m2:ShowOn Tile=\"square150x150Logo\" />\n" |
| "\t\t\t\t\t</m2:ShowNameOnTiles>\n" |
| "\t\t\t\t</m2:DefaultTile>\n" |
| "\t\t\t\t<m2:SplashScreen" |
| " Image=\"" << artifactDirXML << "\\SplashScreen.png\" />\n" |
| "\t\t\t</m2:VisualElements>\n" |
| "\t\t</Application>\n" |
| "\t</Applications>\n" |
| "</Package>\n"; |
| /* clang-format on */ |
| |
| this->WriteCommonMissingFiles(manifestFile); |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteMissingFilesWS10_0() |
| { |
| std::string manifestFile = |
| this->DefaultArtifactDir + "/package.appxManifest"; |
| std::string artifactDir = |
| this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); |
| ConvertToWindowsSlash(artifactDir); |
| std::string artifactDirXML = cmVS10EscapeXML(artifactDir); |
| std::string targetNameXML = |
| cmVS10EscapeXML(this->GeneratorTarget->GetName()); |
| |
| cmGeneratedFileStream fout(manifestFile.c_str()); |
| fout.SetCopyIfDifferent(true); |
| |
| /* clang-format off */ |
| fout << |
| "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" |
| "<Package\n\t" |
| "xmlns=\"http://schemas.microsoft.com/appx/manifest/foundation/windows10\"" |
| "\txmlns:mp=\"http://schemas.microsoft.com/appx/2014/phone/manifest\"\n" |
| "\txmlns:uap=\"http://schemas.microsoft.com/appx/manifest/uap/windows10\"" |
| "\n\tIgnorableNamespaces=\"uap mp\">\n\n" |
| "\t<Identity Name=\"" << this->GUID << "\" Publisher=\"CN=CMake\"" |
| " Version=\"1.0.0.0\" />\n" |
| "\t<mp:PhoneIdentity PhoneProductId=\"" << this->GUID << |
| "\" PhonePublisherId=\"00000000-0000-0000-0000-000000000000\"/>\n" |
| "\t<Properties>\n" |
| "\t\t<DisplayName>" << targetNameXML << "</DisplayName>\n" |
| "\t\t<PublisherDisplayName>CMake</PublisherDisplayName>\n" |
| "\t\t<Logo>" << artifactDirXML << "\\StoreLogo.png</Logo>\n" |
| "\t</Properties>\n" |
| "\t<Dependencies>\n" |
| "\t\t<TargetDeviceFamily Name=\"Windows.Universal\" " |
| "MinVersion=\"10.0.0.0\" MaxVersionTested=\"10.0.0.0\" />\n" |
| "\t</Dependencies>\n" |
| |
| "\t<Resources>\n" |
| "\t\t<Resource Language=\"x-generate\" />\n" |
| "\t</Resources>\n" |
| "\t<Applications>\n" |
| "\t\t<Application Id=\"App\"" |
| " Executable=\"" << targetNameXML << ".exe\"" |
| " EntryPoint=\"" << targetNameXML << ".App\">\n" |
| "\t\t\t<uap:VisualElements\n" |
| "\t\t\t\tDisplayName=\"" << targetNameXML << "\"\n" |
| "\t\t\t\tDescription=\"" << targetNameXML << "\"\n" |
| "\t\t\t\tBackgroundColor=\"#336699\"\n" |
| "\t\t\t\tSquare150x150Logo=\"" << artifactDirXML << "\\Logo.png\"\n" |
| "\t\t\t\tSquare44x44Logo=\"" << artifactDirXML << |
| "\\SmallLogo44x44.png\">\n" |
| "\t\t\t\t<uap:SplashScreen" |
| " Image=\"" << artifactDirXML << "\\SplashScreen.png\" />\n" |
| "\t\t\t</uap:VisualElements>\n" |
| "\t\t</Application>\n" |
| "\t</Applications>\n" |
| "</Package>\n"; |
| /* clang-format on */ |
| |
| this->WriteCommonMissingFiles(manifestFile); |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteCommonMissingFiles( |
| const std::string& manifestFile) |
| { |
| std::string templateFolder = |
| cmSystemTools::GetCMakeRoot() + "/Templates/Windows"; |
| |
| std::string sourceFile = this->ConvertPath(manifestFile, false); |
| ConvertToWindowsSlash(sourceFile); |
| this->WriteString("<AppxManifest Include=\"", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(sourceFile) << "\">\n"; |
| this->WriteString("<SubType>Designer</SubType>\n", 3); |
| this->WriteString("</AppxManifest>\n", 2); |
| this->AddedFiles.push_back(sourceFile); |
| |
| std::string smallLogo = this->DefaultArtifactDir + "/SmallLogo.png"; |
| cmSystemTools::CopyAFile(templateFolder + "/SmallLogo.png", smallLogo, |
| false); |
| ConvertToWindowsSlash(smallLogo); |
| this->WriteString("<Image Include=\"", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(smallLogo) << "\" />\n"; |
| this->AddedFiles.push_back(smallLogo); |
| |
| std::string smallLogo44 = this->DefaultArtifactDir + "/SmallLogo44x44.png"; |
| cmSystemTools::CopyAFile(templateFolder + "/SmallLogo44x44.png", smallLogo44, |
| false); |
| ConvertToWindowsSlash(smallLogo44); |
| this->WriteString("<Image Include=\"", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(smallLogo44) << "\" />\n"; |
| this->AddedFiles.push_back(smallLogo44); |
| |
| std::string logo = this->DefaultArtifactDir + "/Logo.png"; |
| cmSystemTools::CopyAFile(templateFolder + "/Logo.png", logo, false); |
| ConvertToWindowsSlash(logo); |
| this->WriteString("<Image Include=\"", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(logo) << "\" />\n"; |
| this->AddedFiles.push_back(logo); |
| |
| std::string storeLogo = this->DefaultArtifactDir + "/StoreLogo.png"; |
| cmSystemTools::CopyAFile(templateFolder + "/StoreLogo.png", storeLogo, |
| false); |
| ConvertToWindowsSlash(storeLogo); |
| this->WriteString("<Image Include=\"", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(storeLogo) << "\" />\n"; |
| this->AddedFiles.push_back(storeLogo); |
| |
| std::string splashScreen = this->DefaultArtifactDir + "/SplashScreen.png"; |
| cmSystemTools::CopyAFile(templateFolder + "/SplashScreen.png", splashScreen, |
| false); |
| ConvertToWindowsSlash(splashScreen); |
| this->WriteString("<Image Include=\"", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(splashScreen) << "\" />\n"; |
| this->AddedFiles.push_back(splashScreen); |
| |
| // This file has already been added to the build so don't copy it |
| std::string keyFile = this->DefaultArtifactDir + "/Windows_TemporaryKey.pfx"; |
| ConvertToWindowsSlash(keyFile); |
| this->WriteString("<None Include=\"", 2); |
| (*this->BuildFileStream) << cmVS10EscapeXML(keyFile) << "\" />\n"; |
| } |
| |
| bool cmVisualStudio10TargetGenerator::ForceOld(const std::string& source) const |
| { |
| HANDLE h = |
| CreateFileW(cmSystemTools::ConvertToWindowsExtendedPath(source).c_str(), |
| FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, 0, OPEN_EXISTING, |
| FILE_FLAG_BACKUP_SEMANTICS, 0); |
| if (!h) { |
| return false; |
| } |
| |
| FILETIME const ftime_20010101 = { 3365781504u, 29389701u }; |
| if (!SetFileTime(h, &ftime_20010101, &ftime_20010101, &ftime_20010101)) { |
| CloseHandle(h); |
| return false; |
| } |
| |
| CloseHandle(h); |
| return true; |
| } |
| |
| void cmVisualStudio10TargetGenerator::GetCSharpSourceProperties( |
| cmSourceFile const* sf, std::map<std::string, std::string>& tags) |
| { |
| if (this->ProjectType == csproj) { |
| const cmPropertyMap& props = sf->GetProperties(); |
| for (auto const& p : props) { |
| static const std::string propNamePrefix = "VS_CSHARP_"; |
| if (p.first.find(propNamePrefix) == 0) { |
| std::string tagName = p.first.substr(propNamePrefix.length()); |
| if (!tagName.empty()) { |
| const std::string val = props.GetPropertyValue(p.first); |
| if (!val.empty()) { |
| tags[tagName] = val; |
| } else { |
| tags.erase(tagName); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::WriteCSharpSourceProperties( |
| const std::map<std::string, std::string>& tags) |
| { |
| if (!tags.empty()) { |
| for (const auto& i : tags) { |
| this->WriteString("<", 3); |
| (*this->BuildFileStream) << i.first << ">" << cmVS10EscapeXML(i.second) |
| << "</" << i.first << ">\n"; |
| } |
| } |
| } |
| |
| void cmVisualStudio10TargetGenerator::GetCSharpSourceLink( |
| cmSourceFile const* sf, std::string& link) |
| { |
| std::string f = sf->GetFullPath(); |
| if (!this->InSourceBuild) { |
| const std::string stripFromPath = |
| this->Makefile->GetCurrentSourceDirectory(); |
| if (f.find(stripFromPath) != std::string::npos) { |
| link = f.substr(stripFromPath.length() + 1); |
| if (const char* l = sf->GetProperty("VS_CSHARP_Link")) { |
| link = l; |
| } |
| ConvertToWindowsSlash(link); |
| } |
| } |
| } |
| |
| std::string cmVisualStudio10TargetGenerator::GetCMakeFilePath( |
| const char* relativeFilePath) const |
| { |
| // Always search in the standard modules location. |
| std::string path = cmSystemTools::GetCMakeRoot() + "/"; |
| path += relativeFilePath; |
| ConvertToWindowsSlash(path); |
| |
| return path; |
| } |