diff options
author | Brad King <brad.king@kitware.com> | 2015-09-16 10:24:16 -0400 |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2015-09-17 10:21:32 -0400 |
commit | e134e53b47fc9f0337529ce2b6851cec6319a8af (patch) | |
tree | a712dc8248b379139ca900a531f7a37bddc44057 /Source | |
parent | da00be6359055ffdb2067a9ec1e817eb782ad145 (diff) | |
download | cmake-e134e53b47fc9f0337529ce2b6851cec6319a8af.tar.gz |
Add support for *.manifest source files with MSVC tools
Classify .manifest sources separately, add dependencies on them, and
pass them to the MS manifest tool to merge with linker-generated
manifest files.
Inspired-by: Gilles Khouzam <gillesk@microsoft.com>
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmCommonTargetGenerator.cxx | 17 | ||||
-rw-r--r-- | Source/cmCommonTargetGenerator.h | 1 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 14 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.h | 2 | ||||
-rw-r--r-- | Source/cmLocalGenerator.cxx | 7 | ||||
-rw-r--r-- | Source/cmLocalGenerator.h | 1 | ||||
-rw-r--r-- | Source/cmLocalVisualStudio7Generator.cxx | 14 | ||||
-rw-r--r-- | Source/cmMakefileExecutableTargetGenerator.cxx | 4 | ||||
-rw-r--r-- | Source/cmMakefileLibraryTargetGenerator.cxx | 4 | ||||
-rw-r--r-- | Source/cmMakefileTargetGenerator.cxx | 9 | ||||
-rw-r--r-- | Source/cmNinjaNormalTargetGenerator.cxx | 3 | ||||
-rw-r--r-- | Source/cmNinjaTargetGenerator.cxx | 9 | ||||
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.cxx | 29 | ||||
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.h | 1 | ||||
-rw-r--r-- | Source/cmcmd.cxx | 21 |
15 files changed, 131 insertions, 5 deletions
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index 4840e89879..252e2312d0 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -412,3 +412,20 @@ cmCommonTargetGenerator::GetLinkedTargetDirectories() const } return dirs; } + +std::string cmCommonTargetGenerator::GetManifests() +{ + std::vector<cmSourceFile const*> manifest_srcs; + this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName); + + std::vector<std::string> manifests; + for (std::vector<cmSourceFile const*>::iterator mi = manifest_srcs.begin(); + mi != manifest_srcs.end(); ++mi) + { + manifests.push_back(this->Convert((*mi)->GetFullPath(), + this->WorkingDirectory, + cmOutputConverter::SHELL)); + } + + return cmJoin(manifests, " "); +} diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h index 0a49e12193..a4b2c10ec6 100644 --- a/Source/cmCommonTargetGenerator.h +++ b/Source/cmCommonTargetGenerator.h @@ -88,6 +88,7 @@ protected: ByLanguageMap DefinesByLanguage; std::string GetIncludes(std::string const& l); ByLanguageMap IncludesByLanguage; + std::string GetManifests(); std::vector<std::string> GetLinkedTargetDirectories() const; }; diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 09387b7cdf..fb5805b6cb 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -75,6 +75,7 @@ struct IDLSourcesTag {}; struct ResxTag {}; struct ModuleDefinitionFileTag {}; struct AppManifestTag{}; +struct ManifestsTag{}; struct CertificatesTag{}; struct XamlTag{}; @@ -216,6 +217,10 @@ struct TagVisitor { DoAccept<IsSameTag<Tag, AppManifestTag>::Result>::Do(this->Data, sf); } + else if (ext == "manifest") + { + DoAccept<IsSameTag<Tag, ManifestsTag>::Result>::Do(this->Data, sf); + } else if (ext == "pfx") { DoAccept<IsSameTag<Tag, CertificatesTag>::Result>::Do(this->Data, sf); @@ -626,6 +631,15 @@ cmGeneratorTarget //---------------------------------------------------------------------------- void cmGeneratorTarget +::GetManifests(std::vector<cmSourceFile const*>& data, + const std::string& config) const +{ + IMPLEMENT_VISIT(Manifests); +} + +//---------------------------------------------------------------------------- +void +cmGeneratorTarget ::GetCertificates(std::vector<cmSourceFile const*>& data, const std::string& config) const { diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 06d9a1f355..916f2819c6 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -71,6 +71,8 @@ public: const std::string& config) const; void GetAppManifest(std::vector<cmSourceFile const*>&, const std::string& config) const; + void GetManifests(std::vector<cmSourceFile const*>&, + const std::string& config) const; void GetCertificates(std::vector<cmSourceFile const*>&, const std::string& config) const; void GetXamlSources(std::vector<cmSourceFile const*>&, diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 46d5cd8497..97a9f1e91c 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -525,6 +525,13 @@ cmLocalGenerator::ExpandRuleVariable(std::string const& variable, return replaceValues.LinkFlags; } } + if(replaceValues.Manifests) + { + if(variable == "MANIFESTS") + { + return replaceValues.Manifests; + } + } if(replaceValues.Flags) { if(variable == "FLAGS") diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index b051e5deac..771131f1e8 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -219,6 +219,7 @@ public: const char* TargetSOName; const char* TargetInstallNameDir; const char* LinkFlags; + const char* Manifests; const char* LanguageCompileFlags; const char* Defines; const char* Includes; diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 191f739dd2..a4bce8aa92 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -984,6 +984,20 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, "\t\t\t<Tool\n" "\t\t\t\tName=\"" << manifestTool << "\""; + std::vector<cmSourceFile const*> manifest_srcs; + gt->GetManifests(manifest_srcs, configName); + if (!manifest_srcs.empty()) + { + fout << "\n\t\t\t\tAdditionalManifestFiles=\""; + for (std::vector<cmSourceFile const*>::const_iterator + mi = manifest_srcs.begin(); mi != manifest_srcs.end(); ++mi) + { + std::string m = (*mi)->GetFullPath(); + fout << this->ConvertToXMLOutputPath(m.c_str()) << ";"; + } + fout << "\""; + } + // Check if we need the FAT32 workaround. // Check the filesystem type where the target will be written. if (cmLVS6G_IsFAT(target.GetDirectory(configName).c_str())) diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index ccb097458c..90f679e055 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -353,6 +353,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) useResponseFileForObjects, buildObjs, depends, useWatcomQuote); + std::string manifests = this->GetManifests(); + cmLocalGenerator::RuleVariables vars; vars.RuleLauncher = "RULE_LAUNCH_LINK"; vars.CMTarget = this->Target; @@ -391,6 +393,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) vars.LinkLibraries = linkLibs.c_str(); vars.Flags = flags.c_str(); vars.LinkFlags = linkFlags.c_str(); + vars.Manifests = manifests.c_str(); + // Expand placeholders in the commands. this->LocalGenerator->TargetImplib = targetOutPathImport; for(std::vector<std::string>::iterator i = real_link_commands.begin(); diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 2f995e8c3d..cd387a0d07 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -616,6 +616,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules } } + std::string manifests = this->GetManifests(); + cmLocalGenerator::RuleVariables vars; vars.TargetPDB = targetOutPathPDB.c_str(); @@ -660,6 +662,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules } vars.LinkFlags = linkFlags.c_str(); + vars.Manifests = manifests.c_str(); + // Compute the directory portion of the install_name setting. std::string install_name_dir; if(this->Target->GetType() == cmTarget::SHARED_LIBRARY) diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index cf88a749ca..b278087ffa 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -1493,6 +1493,15 @@ void cmMakefileTargetGenerator depends.push_back(this->ModuleDefinitionFile); } + // Add a dependency on user-specified manifest files, if any. + std::vector<cmSourceFile const*> manifest_srcs; + this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName); + for (std::vector<cmSourceFile const*>::iterator mi = manifest_srcs.begin(); + mi != manifest_srcs.end(); ++mi) + { + depends.push_back((*mi)->GetFullPath()); + } + // Add user-specified dependencies. if(const char* linkDepends = this->Target->GetProperty("LINK_DEPENDS")) diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index f62f8ad0e2..7e7e600220 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -237,6 +237,7 @@ cmNinjaNormalTargetGenerator vars.Flags = "$FLAGS"; vars.LinkFlags = "$LINK_FLAGS"; + vars.Manifests = "$MANIFESTS"; std::string langFlags; if (targetType != cmTarget::EXECUTABLE) @@ -509,6 +510,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() vars["LINK_FLAGS"] = cmGlobalNinjaGenerator ::EncodeLiteral(vars["LINK_FLAGS"]); + vars["MANIFESTS"] = this->GetManifests(); + vars["LINK_PATH"] = frameworkPath + linkPath; // Compute architecture specific link flags. Yes, these go into a different diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 81fdde2422..752c8a7d51 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -209,6 +209,15 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const result.push_back(this->ConvertToNinjaPath(this->ModuleDefinitionFile)); } + // Add a dependency on user-specified manifest files, if any. + std::vector<cmSourceFile const*> manifest_srcs; + this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName); + for (std::vector<cmSourceFile const*>::iterator mi = manifest_srcs.begin(); + mi != manifest_srcs.end(); ++mi) + { + result.push_back(this->ConvertToNinjaPath((*mi)->GetFullPath())); + } + // Add user-specified dependencies. if (const char* linkDepends = this->Target->GetProperty("LINK_DEPENDS")) { diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 4c380f7324..cb5048d56b 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -2203,6 +2203,33 @@ cmVisualStudio10TargetGenerator::WriteLibOptions(std::string const& config) } } +void cmVisualStudio10TargetGenerator::WriteManifestOptions( + std::string const& config) +{ + if (this->Target->GetType() != cmTarget::EXECUTABLE && + this->Target->GetType() != cmTarget::SHARED_LIBRARY && + this->Target->GetType() != cmTarget::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 (std::vector<cmSourceFile const*>::const_iterator + mi = manifest_srcs.begin(); mi != manifest_srcs.end(); ++mi) + { + std::string m = this->ConvertPath((*mi)->GetFullPath(), false); + this->ConvertToWindowsSlash(m); + (*this->BuildFileStream) << m << ";"; + } + (*this->BuildFileStream) << "</AdditionalManifestFiles>\n"; + this->WriteString("</Manifest>\n", 2); + } +} //---------------------------------------------------------------------------- void cmVisualStudio10TargetGenerator::WriteAntBuildOptions( @@ -2740,6 +2767,8 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups() this->WriteLinkOptions(*i); // output lib flags <Lib></Lib> this->WriteLibOptions(*i); + // output manifest flags <Manifest></Manifest> + this->WriteManifestOptions(*i); if(this->NsightTegra && this->Target->GetType() == cmTarget::EXECUTABLE && this->Target->GetPropertyAsBool("ANDROID_GUI")) diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 451f8b20b9..5fadb6047f 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -111,6 +111,7 @@ private: void AddLibraries(cmComputeLinkInformation& cli, std::vector<std::string>& libVec); void WriteLibOptions(std::string const& config); + void WriteManifestOptions(std::string const& config); void WriteEvents(std::string const& configName); void WriteEvent(const char* name, std::vector<cmCustomCommand> const& commands, diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 307e78b0b2..f44c77d6ee 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -1362,6 +1362,7 @@ class cmVSLink bool Incremental; bool LinkGeneratesManifest; std::vector<std::string> LinkCommand; + std::vector<std::string> UserManifests; std::string LinkerManifestFile; std::string ManifestFile; std::string ManifestFileRC; @@ -1480,6 +1481,13 @@ bool cmVSLink::Parse(std::vector<std::string>::const_iterator argBeg, ++arg; break; } + else if (*arg == "--manifests") + { + for (++arg; arg != argEnd && !cmHasLiteralPrefix(*arg, "-"); ++arg) + { + this->UserManifests.push_back(*arg); + } + } else if (cmHasLiteralPrefix(*arg, "--intdir=")) { intDir = arg->substr(9); @@ -1544,10 +1552,11 @@ bool cmVSLink::Parse(std::vector<std::string>::const_iterator argBeg, this->ManifestFileRes = intDir + "/manifest.res"; this->LinkCommand.push_back(this->ManifestFileRes); } - else + else if (this->UserManifests.empty()) { - // CMake places the linker-generated manifest next to the binary (as if it - // were not to be embedded) when not linking incrementally. + // Prior to support for user-specified manifests CMake placed the + // linker-generated manifest next to the binary (as if it were not to be + // embedded) when not linking incrementally. Preserve this behavior. this->ManifestFile = this->TargetFile + ".manifest"; this->LinkerManifestFile = this->ManifestFile; } @@ -1564,7 +1573,7 @@ bool cmVSLink::Parse(std::vector<std::string>::const_iterator argBeg, int cmVSLink::Link() { if (this->Incremental && - this->LinkGeneratesManifest) + (this->LinkGeneratesManifest || !this->UserManifests.empty())) { if (this->Verbose) { @@ -1688,7 +1697,7 @@ int cmVSLink::LinkNonIncremental() } // If we have no manifest files we are done. - if (!this->LinkGeneratesManifest) + if (!this->LinkGeneratesManifest && this->UserManifests.empty()) { return 0; } @@ -1709,6 +1718,8 @@ int cmVSLink::RunMT(std::string const& out, bool notify) { mtCommand.push_back(this->LinkerManifestFile); } + mtCommand.insert(mtCommand.end(), + this->UserManifests.begin(), this->UserManifests.end()); mtCommand.push_back(out); if (notify) { |