[Cmake-commits] CMake branch, next, updated. v3.3.1-3036-gde4a71d
Brad King
brad.king at kitware.com
Thu Sep 17 10:22:21 EDT 2015
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".
The branch, next has been updated
via de4a71d2fb812d6a33e97163ef1523c6b1527c47 (commit)
via e134e53b47fc9f0337529ce2b6851cec6319a8af (commit)
via da00be6359055ffdb2067a9ec1e817eb782ad145 (commit)
via d488b5c9764805222d33d50cc070fd4f71aab262 (commit)
via 6d620f5ad7fc9767a7232659cde1d7c9abf78285 (commit)
via 73a058f85680a044aeeecd815f8d6cc34fd29f3d (commit)
via 438fabf242bae84dde71d51298b43c2b6fa760eb (commit)
via f38625be7a6284495d3617bc64725f2873284b01 (commit)
via 1a75a966503c6aa76a564e23c4cf3695c4afc1ea (commit)
from 61be8860d3f7a6ff4b6db6c0d09e408fe6856838 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=de4a71d2fb812d6a33e97163ef1523c6b1527c47
commit de4a71d2fb812d6a33e97163ef1523c6b1527c47
Merge: 61be886 e134e53
Author: Brad King <brad.king at kitware.com>
AuthorDate: Thu Sep 17 10:22:19 2015 -0400
Commit: CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Thu Sep 17 10:22:19 2015 -0400
Merge topic 'ms-manifest-files' into next
e134e53b Add support for *.manifest source files with MSVC tools
da00be63 MSVC: Rewrite manifest file handling with Makefile and Ninja
d488b5c9 Ninja: Always add OBJECT_DIR variable to link rules
6d620f5a VS: Add manifest tool settings to VS 8 and 9 project files
73a058f8 Tests: Add RunCMake.BuildDepends test
438fabf2 Tests: Teach RunCMake infrastructure to use custom check.cmake file
f38625be Tests: Teach RunCMake to tolerate 'Bullseye Testing' lines in test output
1a75a966 Tests: Teach RunCMake to tolerate 'Time Machine' lines in test output
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e134e53b47fc9f0337529ce2b6851cec6319a8af
commit e134e53b47fc9f0337529ce2b6851cec6319a8af
Author: Brad King <brad.king at kitware.com>
AuthorDate: Wed Sep 16 10:24:16 2015 -0400
Commit: Brad King <brad.king at kitware.com>
CommitDate: Thu Sep 17 10:21:32 2015 -0400
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 at microsoft.com>
diff --git a/Help/release/dev/ms-manifest-files.rst b/Help/release/dev/ms-manifest-files.rst
new file mode 100644
index 0000000..94fbe83
--- /dev/null
+++ b/Help/release/dev/ms-manifest-files.rst
@@ -0,0 +1,7 @@
+ms-manifest-files
+-----------------
+
+* CMake learned to honor ``*.manifest`` source files with MSVC tools.
+ Manifest files named as sources of ``.exe`` and ``.dll`` targets
+ will be merged with linker-generated manifests and embedded in the
+ binary.
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index d4b1cd8..8594596 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -274,8 +274,8 @@ set (CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL_INIT ${CMAKE_EXE_LINKER_FLAGS_MINSIZER
macro(__windows_compiler_msvc lang)
if(NOT MSVC_VERSION LESS 1400)
# for 2005 make sure the manifest is put in the dll with mt
- set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll --intdir=<OBJECT_DIR> ")
- set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe --intdir=<OBJECT_DIR> ")
+ set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll --intdir=<OBJECT_DIR> --manifests <MANIFESTS> -- ")
+ set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe --intdir=<OBJECT_DIR> --manifests <MANIFESTS> -- ")
endif()
set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
"${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 4840e89..252e231 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 0a49e12..a4b2c10 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 09387b7..fb5805b 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 06d9a1f..916f281 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 46d5cd8..97a9f1e 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 b051e5d..771131f 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 191f739..a4bce8a 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 ccb0974..90f679e 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 2f995e8..cd387a0 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 cf88a74..b278087 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 f62f8ad..7e7e600 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 81fdde2..752c8a7 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 4c380f7..cb5048d 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 451f8b2..5fadb60 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 307e78b..f44c77d 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)
{
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 2c6a42c..fff04ce 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -276,6 +276,7 @@ if(BUILD_TESTING)
if(TEST_RESOURCES)
ADD_TEST_MACRO(VSResource VSResource)
endif()
+ ADD_TEST_MACRO(MSManifest MSManifest)
ADD_TEST_MACRO(Simple Simple)
ADD_TEST_MACRO(PreOrder PreOrder)
ADD_TEST_MACRO(MissingSourceFile MissingSourceFile)
diff --git a/Tests/MSManifest/CMakeLists.txt b/Tests/MSManifest/CMakeLists.txt
new file mode 100644
index 0000000..300cfa6
--- /dev/null
+++ b/Tests/MSManifest/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.3)
+project(MSManifest C)
+
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+add_subdirectory(Subdir)
diff --git a/Tests/MSManifest/Subdir/CMakeLists.txt b/Tests/MSManifest/Subdir/CMakeLists.txt
new file mode 100644
index 0000000..a47cf00
--- /dev/null
+++ b/Tests/MSManifest/Subdir/CMakeLists.txt
@@ -0,0 +1,9 @@
+configure_file(test.manifest.in test.manifest)
+add_executable(MSManifest main.c ${CMAKE_CURRENT_BINARY_DIR}/test.manifest)
+
+if(MSVC AND NOT MSVC_VERSION LESS 1400)
+ add_custom_command(TARGET MSManifest POST_BUILD VERBATIM
+ COMMAND ${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSManifest>
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake
+ )
+endif()
diff --git a/Tests/MSManifest/Subdir/check.cmake b/Tests/MSManifest/Subdir/check.cmake
new file mode 100644
index 0000000..b7b6841
--- /dev/null
+++ b/Tests/MSManifest/Subdir/check.cmake
@@ -0,0 +1,6 @@
+file(STRINGS "${exe}" content REGEX "name=\"Kitware.CMake.MSManifestTest\"")
+if(content)
+ message(STATUS "Expected manifest content found:\n ${content}")
+else()
+ message(FATAL_ERROR "Expected manifest content not found in\n ${exe}")
+endif()
diff --git a/Tests/MSManifest/Subdir/main.c b/Tests/MSManifest/Subdir/main.c
new file mode 100644
index 0000000..78f2de1
--- /dev/null
+++ b/Tests/MSManifest/Subdir/main.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
diff --git a/Tests/MSManifest/Subdir/test.manifest.in b/Tests/MSManifest/Subdir/test.manifest.in
new file mode 100644
index 0000000..540961a
--- /dev/null
+++ b/Tests/MSManifest/Subdir/test.manifest.in
@@ -0,0 +1,4 @@
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity type="win32" version="1.0.0.0"
+ name="Kitware.CMake.MSManifestTest"/>
+</assembly>
diff --git a/Tests/RunCMake/BuildDepends/C-Exe-Manifest.cmake b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.cmake
new file mode 100644
index 0000000..ef33012
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.cmake
@@ -0,0 +1,19 @@
+enable_language(C)
+
+add_executable(main main.c ${CMAKE_CURRENT_BINARY_DIR}/test.manifest)
+
+if(MSVC AND NOT MSVC_VERSION LESS 1400)
+ set(EXTRA_CHECK [[
+file(STRINGS "$<TARGET_FILE:main>" content REGEX "name=\"Kitware.CMake.C-Exe-Manifest-step[0-9]\"")
+if(NOT "${content}" MATCHES "name=\"Kitware.CMake.C-Exe-Manifest-step${check_step}\"")
+ set(RunCMake_TEST_FAILED "Binary has no manifest with name=\"Kitware.CMake.C-Exe-Manifest-step${check_step}\":\n ${content}")
+endif()
+]])
+endif()
+
+file(GENERATE OUTPUT check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT "
+set(check_pairs
+ \"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/test.manifest\"
+ )
+${EXTRA_CHECK}
+")
diff --git a/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step1.cmake b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step1.cmake
new file mode 100644
index 0000000..c0b939d
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step1.cmake
@@ -0,0 +1,6 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/test.manifest" [[
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity type="win32" version="1.0.0.0"
+ name="Kitware.CMake.C-Exe-Manifest-step1"/>
+</assembly>
+]])
diff --git a/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step2.cmake b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step2.cmake
new file mode 100644
index 0000000..a75bf21
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe-Manifest.step2.cmake
@@ -0,0 +1,6 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/test.manifest" [[
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity type="win32" version="1.0.0.0"
+ name="Kitware.CMake.C-Exe-Manifest-step2"/>
+</assembly>
+]])
diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
index 98132cc..8782ba9 100644
--- a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
+++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
@@ -14,6 +14,9 @@ function(run_BuildDepends CASE)
set(RunCMake-check-file check.cmake)
set(check_step 1)
run_cmake_command(${CASE}-build1 ${CMAKE_COMMAND} --build . --config Debug)
+ if(run_BuildDepends_skip_step_2)
+ return()
+ endif()
execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1.125) # handle 1s resolution
include(${RunCMake_SOURCE_DIR}/${CASE}.step2.cmake OPTIONAL)
set(check_step 2)
@@ -21,3 +24,11 @@ function(run_BuildDepends CASE)
endfunction()
run_BuildDepends(C-Exe)
+if(NOT RunCMake_GENERATOR MATCHES "Visual Studio [67]|Xcode")
+ if(RunCMake_GENERATOR MATCHES "Visual Studio 10")
+ # VS 10 forgets to re-link when a manifest changes
+ set(run_BuildDepends_skip_step_2 1)
+ endif()
+ run_BuildDepends(C-Exe-Manifest)
+ unset(run_BuildDepends_skip_step_2)
+endif()
diff --git a/Tests/RunCMake/BuildDepends/check.cmake b/Tests/RunCMake/BuildDepends/check.cmake
index be6debc..26a9eb6 100644
--- a/Tests/RunCMake/BuildDepends/check.cmake
+++ b/Tests/RunCMake/BuildDepends/check.cmake
@@ -1,5 +1,8 @@
if(EXISTS ${RunCMake_TEST_BINARY_DIR}/check-debug.cmake)
include(${RunCMake_TEST_BINARY_DIR}/check-debug.cmake)
+ if(RunCMake_TEST_FAILED)
+ return()
+ endif()
foreach(exe IN LISTS check_exes)
execute_process(COMMAND ${exe} RESULT_VARIABLE res)
if(NOT res EQUAL ${check_step})
diff --git a/Tests/RunCMake/BuildDepends/main.c b/Tests/RunCMake/BuildDepends/main.c
new file mode 100644
index 0000000..78f2de1
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/main.c
@@ -0,0 +1 @@
+int main(void) { return 0; }
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=da00be6359055ffdb2067a9ec1e817eb782ad145
commit da00be6359055ffdb2067a9ec1e817eb782ad145
Author: Brad King <brad.king at kitware.com>
AuthorDate: Tue Sep 15 15:51:19 2015 -0400
Commit: Brad King <brad.king at kitware.com>
CommitDate: Thu Sep 17 10:21:32 2015 -0400
MSVC: Rewrite manifest file handling with Makefile and Ninja
Add a helper class private to "cmcmd.cxx" to contain the implementation.
Update the link logic to use the intermediate files directory for each
target to hold manifest and resource files before embedding into the
binary. Preserve the old behavior of placing the .manifest file next
to the binary when not linking incrementally even though it will be
embedded.
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index 94470c3..d4b1cd8 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -274,8 +274,8 @@ set (CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL_INIT ${CMAKE_EXE_LINKER_FLAGS_MINSIZER
macro(__windows_compiler_msvc lang)
if(NOT MSVC_VERSION LESS 1400)
# for 2005 make sure the manifest is put in the dll with mt
- set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll ")
- set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe ")
+ set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll --intdir=<OBJECT_DIR> ")
+ set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe --intdir=<OBJECT_DIR> ")
endif()
set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
"${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index aa70aa0..307e78b 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -1355,6 +1355,34 @@ int cmcmd::WindowsCEEnvironment(const char* version, const std::string& name)
return -1;
}
+class cmVSLink
+{
+ int Type;
+ bool Verbose;
+ bool Incremental;
+ bool LinkGeneratesManifest;
+ std::vector<std::string> LinkCommand;
+ std::string LinkerManifestFile;
+ std::string ManifestFile;
+ std::string ManifestFileRC;
+ std::string ManifestFileRes;
+ std::string TargetFile;
+public:
+ cmVSLink(int type, bool verbose)
+ : Type(type)
+ , Verbose(verbose)
+ , Incremental(false)
+ , LinkGeneratesManifest(true)
+ {}
+ bool Parse(std::vector<std::string>::const_iterator argBeg,
+ std::vector<std::string>::const_iterator argEnd);
+ int Link();
+private:
+ int LinkIncremental();
+ int LinkNonIncremental();
+ int RunMT(std::string const& out, bool notify);
+};
+
// For visual studio 2005 and newer manifest files need to be embedded into
// exe and dll's. This code does that in such a way that incremental linking
// still works.
@@ -1364,11 +1392,7 @@ int cmcmd::VisualStudioLink(std::vector<std::string>& args, int type)
{
return -1;
}
- bool verbose = false;
- if(cmSystemTools::GetEnv("VERBOSE"))
- {
- verbose = true;
- }
+ bool verbose = cmSystemTools::GetEnv("VERBOSE")? true:false;
std::vector<std::string> expandedArgs;
for(std::vector<std::string>::iterator i = args.begin();
i != args.end(); ++i)
@@ -1389,79 +1413,19 @@ int cmcmd::VisualStudioLink(std::vector<std::string>& args, int type)
expandedArgs.push_back(*i);
}
}
- bool hasIncremental = false;
- bool hasManifest = true;
- for(std::vector<std::string>::iterator i = expandedArgs.begin();
- i != expandedArgs.end(); ++i)
- {
- if(cmSystemTools::Strucmp(i->c_str(), "/INCREMENTAL:YES") == 0)
- {
- hasIncremental = true;
- }
- if(cmSystemTools::Strucmp(i->c_str(), "/INCREMENTAL") == 0)
- {
- hasIncremental = true;
- }
- if(cmSystemTools::Strucmp(i->c_str(), "/MANIFEST:NO") == 0)
- {
- hasManifest = false;
- }
- }
- if(hasIncremental && hasManifest)
- {
- if(verbose)
- {
- std::cout << "Visual Studio Incremental Link with embedded manifests\n";
- }
- return cmcmd::VisualStudioLinkIncremental(expandedArgs, type, verbose);
- }
- if(verbose)
- {
- if(!hasIncremental)
- {
- std::cout << "Visual Studio Non-Incremental Link\n";
- }
- else
- {
- std::cout << "Visual Studio Incremental Link without manifests\n";
- }
- }
- return cmcmd::VisualStudioLinkNonIncremental(expandedArgs,
- type, hasManifest, verbose);
-}
-int cmcmd::ParseVisualStudioLinkCommand(std::vector<std::string>& args,
- std::vector<std::string>& command,
- std::string& targetName)
-{
- std::vector<std::string>::iterator i = args.begin();
- i++; // skip -E
- i++; // skip vs_link_dll or vs_link_exe
- command.push_back(*i);
- i++; // move past link command
- for(; i != args.end(); ++i)
- {
- command.push_back(*i);
- if(i->find("/Fe") == 0)
- {
- targetName = i->substr(3);
- }
- if(i->find("/out:") == 0)
- {
- targetName = i->substr(5);
- }
- }
- if(targetName.empty() || command.empty())
+ cmVSLink vsLink(type, verbose);
+ if (!vsLink.Parse(expandedArgs.begin()+2, expandedArgs.end()))
{
return -1;
}
- return 0;
+ return vsLink.Link();
}
-bool cmcmd::RunCommand(const char* comment,
+static bool RunCommand(const char* comment,
std::vector<std::string>& command,
bool verbose,
- int* retCodeOut)
+ int* retCodeOut = 0)
{
if(verbose)
{
@@ -1503,8 +1467,126 @@ bool cmcmd::RunCommand(const char* comment,
return retCode == 0;
}
-int cmcmd::VisualStudioLinkIncremental(std::vector<std::string>& args,
- int type, bool verbose)
+bool cmVSLink::Parse(std::vector<std::string>::const_iterator argBeg,
+ std::vector<std::string>::const_iterator argEnd)
+{
+ // Parse our own arguments.
+ std::string intDir;
+ std::vector<std::string>::const_iterator arg = argBeg;
+ while (arg != argEnd && cmHasLiteralPrefix(*arg, "-"))
+ {
+ if (*arg == "--")
+ {
+ ++arg;
+ break;
+ }
+ else if (cmHasLiteralPrefix(*arg, "--intdir="))
+ {
+ intDir = arg->substr(9);
+ ++arg;
+ }
+ else
+ {
+ std::cerr << "unknown argument '" << *arg << "'\n";
+ return false;
+ }
+ }
+ if (intDir.empty())
+ {
+ return false;
+ }
+
+ // The rest of the arguments form the link command.
+ if (arg == argEnd)
+ {
+ return false;
+ }
+ this->LinkCommand.insert(this->LinkCommand.begin(), arg, argEnd);
+
+ // Parse the link command to extract information we need.
+ for (; arg != argEnd; ++arg)
+ {
+ if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL:YES") == 0)
+ {
+ this->Incremental = true;
+ }
+ else if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL") == 0)
+ {
+ this->Incremental = true;
+ }
+ else if (cmSystemTools::Strucmp(arg->c_str(), "/MANIFEST:NO") == 0)
+ {
+ this->LinkGeneratesManifest = false;
+ }
+ else if (cmHasLiteralPrefix(*arg, "/Fe"))
+ {
+ this->TargetFile = arg->substr(3);
+ }
+ else if (cmHasLiteralPrefix(*arg, "/out:"))
+ {
+ this->TargetFile = arg->substr(5);
+ }
+ }
+
+ if (this->TargetFile.empty())
+ {
+ return false;
+ }
+
+ this->ManifestFile = intDir + "/embed.manifest";
+ this->LinkerManifestFile = intDir + "/intermediate.manifest";
+
+ if (this->Incremental)
+ {
+ // We will compile a resource containing the manifest and
+ // pass it to the link command.
+ this->ManifestFileRC = intDir + "/manifest.rc";
+ this->ManifestFileRes = intDir + "/manifest.res";
+ this->LinkCommand.push_back(this->ManifestFileRes);
+ }
+ else
+ {
+ // CMake places the linker-generated manifest next to the binary (as if it
+ // were not to be embedded) when not linking incrementally.
+ this->ManifestFile = this->TargetFile + ".manifest";
+ this->LinkerManifestFile = this->ManifestFile;
+ }
+
+ if (this->LinkGeneratesManifest)
+ {
+ this->LinkCommand.push_back("/MANIFEST");
+ this->LinkCommand.push_back("/MANIFESTFILE:" + this->LinkerManifestFile);
+ }
+
+ return true;
+}
+
+int cmVSLink::Link()
+{
+ if (this->Incremental &&
+ this->LinkGeneratesManifest)
+ {
+ if (this->Verbose)
+ {
+ std::cout << "Visual Studio Incremental Link with embedded manifests\n";
+ }
+ return LinkIncremental();
+ }
+ if (this->Verbose)
+ {
+ if (!this->Incremental)
+ {
+ std::cout << "Visual Studio Non-Incremental Link\n";
+ }
+ else
+ {
+ std::cout << "Visual Studio Incremental Link without manifests\n";
+ }
+ }
+ return LinkNonIncremental();
+}
+
+int cmVSLink::LinkIncremental()
{
// This follows the steps listed here:
// http://blogs.msdn.com/zakramer/archive/2006/05/22/603558.aspx
@@ -1528,161 +1610,116 @@ int cmcmd::VisualStudioLinkIncremental(std::vector<std::string>& args,
// 7. Finally, the Linker does another incremental link, but since the
// only thing that has changed is the *.res file that contains the
// manifest it is a short link.
- std::vector<std::string> linkCommand;
- std::string targetName;
- if(cmcmd::ParseVisualStudioLinkCommand(args, linkCommand, targetName) == -1)
- {
- return -1;
- }
- std::string manifestArg = "/MANIFESTFILE:";
- std::vector<std::string> rcCommand;
- rcCommand.push_back(cmSystemTools::FindProgram("rc.exe"));
- std::vector<std::string> mtCommand;
- mtCommand.push_back(cmSystemTools::FindProgram("mt.exe"));
- std::string tempManifest;
- tempManifest = targetName;
- tempManifest += ".intermediate.manifest";
- std::string resourceInputFile = targetName;
- resourceInputFile += ".resource.txt";
- if(verbose)
+
+ // Create a resource file referencing the manifest.
+ std::string absManifestFile =
+ cmSystemTools::CollapseFullPath(this->ManifestFile);
+ if (this->Verbose)
{
- std::cout << "Create " << resourceInputFile << "\n";
+ std::cout << "Create " << this->ManifestFileRC << "\n";
}
- // Create input file for rc command
- cmsys::ofstream fout(resourceInputFile.c_str());
- if(!fout)
+ {
+ cmsys::ofstream fout(this->ManifestFileRC.c_str());
+ if (!fout)
{
return -1;
}
- std::string manifestFile = targetName;
- manifestFile += ".embed.manifest";
- std::string fullPath= cmSystemTools::CollapseFullPath(manifestFile);
- fout << type << " /* CREATEPROCESS_MANIFEST_RESOURCE_ID "
- "*/ 24 /* RT_MANIFEST */ " << "\"" << fullPath << "\"";
- fout.close();
- manifestArg += tempManifest;
- // add the manifest arg to the linkCommand
- linkCommand.push_back("/MANIFEST");
- linkCommand.push_back(manifestArg);
- // if manifestFile is not yet created, create an
- // empty one
- if(!cmSystemTools::FileExists(manifestFile.c_str()))
+ fout << this->Type << " /* CREATEPROCESS_MANIFEST_RESOURCE_ID */ "
+ "24 /* RT_MANIFEST */ \"" << absManifestFile << "\"";
+ }
+
+ // If we have not previously generated a manifest file,
+ // generate an empty one so the resource compiler succeeds.
+ if (!cmSystemTools::FileExists(this->ManifestFile))
{
- if(verbose)
+ if (this->Verbose)
{
- std::cout << "Create empty: " << manifestFile << "\n";
+ std::cout << "Create empty: " << this->ManifestFile << "\n";
}
- cmsys::ofstream foutTmp(manifestFile.c_str());
- }
- std::string resourceFile = manifestFile;
- resourceFile += ".res";
- // add the resource file to the end of the link command
- linkCommand.push_back(resourceFile);
- std::string outputOpt = "/fo";
- outputOpt += resourceFile;
- rcCommand.push_back(outputOpt);
- rcCommand.push_back(resourceInputFile);
- // Run rc command to create resource
- if(!cmcmd::RunCommand("RC Pass 1", rcCommand, verbose))
- {
- return -1;
+ cmsys::ofstream foutTmp(this->ManifestFile.c_str());
}
- // Now run the link command to link and create manifest
- if(!cmcmd::RunCommand("LINK Pass 1", linkCommand, verbose))
+
+ // Compile the resource file.
+ std::vector<std::string> rcCommand;
+ rcCommand.push_back(cmSystemTools::FindProgram("rc.exe"));
+ rcCommand.push_back("/fo" + this->ManifestFileRes);
+ rcCommand.push_back(this->ManifestFileRC);
+ if (!RunCommand("RC Pass 1", rcCommand, this->Verbose))
{
return -1;
}
- // create mt command
- std::string outArg("/out:");
- outArg+= manifestFile;
- mtCommand.push_back("/nologo");
- mtCommand.push_back(outArg);
- mtCommand.push_back("/notify_update");
- mtCommand.push_back("/manifest");
- mtCommand.push_back(tempManifest);
- // now run mt.exe to create the final manifest file
- int mtRet =0;
- if(!cmcmd::RunCommand("MT", mtCommand, verbose, &mtRet))
+
+ // Run the link command (possibly generates intermediate manifest).
+ if (!RunCommand("LINK Pass 1", this->LinkCommand, this->Verbose))
{
return -1;
}
- // if mt returns 0, then the manifest was not changed and
- // we do not need to do another link step
- if(mtRet == 0)
- {
- return 0;
- }
- // check for magic mt return value if mt returns the magic number
- // 1090650113 then it means that it updated the manifest file and we need
- // to do the final link. If mt has any value other than 0 or 1090650113
- // then there was some problem with the command itself and there was an
- // error so return the error code back out of cmake so make can report it.
- // (when hosted on a posix system the value is 187)
- if(mtRet != 1090650113 && mtRet != 187)
+
+ // Run the manifest tool to create the final manifest.
+ int mtRet = this->RunMT("/out:" + this->ManifestFile, true);
+
+ // If mt returns 1090650113 (or 187 on a posix host) then it updated the
+ // manifest file so we need to embed it again. Otherwise we are done.
+ if (mtRet != 1090650113 && mtRet != 187)
{
return mtRet;
}
- // update the resource file with the new manifest from the mt command.
- if(!cmcmd::RunCommand("RC Pass 2", rcCommand, verbose))
+
+ // Compile the resource file again.
+ if (!RunCommand("RC Pass 2", rcCommand, this->Verbose))
{
return -1;
}
- // Run the final incremental link that will put the new manifest resource
- // into the file incrementally.
- if(!cmcmd::RunCommand("FINAL LINK", linkCommand, verbose))
+
+ // Link incrementally again to use the updated resource.
+ if (!RunCommand("FINAL LINK", this->LinkCommand, this->Verbose))
{
return -1;
}
return 0;
}
-int cmcmd::VisualStudioLinkNonIncremental(std::vector<std::string>& args,
- int type,
- bool hasManifest,
- bool verbose)
+int cmVSLink::LinkNonIncremental()
{
- std::vector<std::string> linkCommand;
- std::string targetName;
- if(cmcmd::ParseVisualStudioLinkCommand(args, linkCommand, targetName) == -1)
+ // Run the link command (possibly generates intermediate manifest).
+ if (!RunCommand("LINK", this->LinkCommand, this->Verbose))
{
return -1;
}
- // Run the link command as given
- if (hasManifest)
- {
- linkCommand.push_back("/MANIFEST");
- }
- if(!cmcmd::RunCommand("LINK", linkCommand, verbose))
- {
- return -1;
- }
- if(!hasManifest)
+
+ // If we have no manifest files we are done.
+ if (!this->LinkGeneratesManifest)
{
return 0;
}
+
+ // Run the manifest tool to embed the final manifest in the binary.
+ std::string mtOut =
+ "/outputresource:" + this->TargetFile + (this->Type == 1? ";#1" : ";#2");
+ return this->RunMT(mtOut, false);
+}
+
+int cmVSLink::RunMT(std::string const& out, bool notify)
+{
std::vector<std::string> mtCommand;
mtCommand.push_back(cmSystemTools::FindProgram("mt.exe"));
mtCommand.push_back("/nologo");
mtCommand.push_back("/manifest");
- std::string manifestFile = targetName;
- manifestFile += ".manifest";
- mtCommand.push_back(manifestFile);
- std::string outresource = "/outputresource:";
- outresource += targetName;
- outresource += ";#";
- if(type == 1)
+ if (this->LinkGeneratesManifest)
{
- outresource += "1";
+ mtCommand.push_back(this->LinkerManifestFile);
}
- else if(type == 2)
+ mtCommand.push_back(out);
+ if (notify)
{
- outresource += "2";
+ // Add an undocumented option that enables a special return
+ // code to notify us when the manifest is modified.
+ mtCommand.push_back("/notify_update");
}
- mtCommand.push_back(outresource);
- // Now use the mt tool to embed the manifest into the exe or dll
- if(!cmcmd::RunCommand("MT", mtCommand, verbose))
+ int mtRet = 0;
+ if (!RunCommand("MT", mtCommand, this->Verbose, &mtRet))
{
return -1;
}
- return 0;
+ return mtRet;
}
diff --git a/Source/cmcmd.h b/Source/cmcmd.h
index 2bfbae7..64b2406 100644
--- a/Source/cmcmd.h
+++ b/Source/cmcmd.h
@@ -35,20 +35,6 @@ protected:
static int WindowsCEEnvironment(const char* version,
const std::string& name);
static int VisualStudioLink(std::vector<std::string>& args, int type);
- static int VisualStudioLinkIncremental(std::vector<std::string>& args,
- int type,
- bool verbose);
- static int VisualStudioLinkNonIncremental(std::vector<std::string>& args,
- int type,
- bool hasManifest,
- bool verbose);
- static int ParseVisualStudioLinkCommand(std::vector<std::string>& args,
- std::vector<std::string>& command,
- std::string& targetName);
- static bool RunCommand(const char* comment,
- std::vector<std::string>& command,
- bool verbose,
- int* retCodeOut = 0);
};
#endif
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d488b5c9764805222d33d50cc070fd4f71aab262
commit d488b5c9764805222d33d50cc070fd4f71aab262
Author: Brad King <brad.king at kitware.com>
AuthorDate: Tue Sep 15 15:57:19 2015 -0400
Commit: Brad King <brad.king at kitware.com>
CommitDate: Thu Sep 17 10:21:32 2015 -0400
Ninja: Always add OBJECT_DIR variable to link rules
The <OBJECT_DIR> placeholder is always available in Makefile
generators so make it available from the Ninja generator too.
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index b855bea..f62f8ad 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -579,11 +579,12 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
vars["TARGET_PDB"] = base + suffix + dbg_suffix;
}
+ const std::string objPath = GetTarget()->GetSupportDirectory();
+ vars["OBJECT_DIR"] = ConvertToNinjaPath(objPath);
+ EnsureDirectoryExists(objPath);
+
if (this->GetGlobalGenerator()->IsGCCOnWindows())
{
- const std::string objPath = GetTarget()->GetSupportDirectory();
- vars["OBJECT_DIR"] = ConvertToNinjaPath(objPath);
- EnsureDirectoryExists(objPath);
// ar.exe can't handle backslashes in rsp files (implicitly used by gcc)
std::string& linkLibraries = vars["LINK_LIBRARIES"];
std::replace(linkLibraries.begin(), linkLibraries.end(), '\\', '/');
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=6d620f5ad7fc9767a7232659cde1d7c9abf78285
commit 6d620f5ad7fc9767a7232659cde1d7c9abf78285
Author: Brad King <brad.king at kitware.com>
AuthorDate: Tue Sep 15 15:36:07 2015 -0400
Commit: Brad King <brad.king at kitware.com>
CommitDate: Thu Sep 17 10:21:31 2015 -0400
VS: Add manifest tool settings to VS 8 and 9 project files
Always generate a VCManifestTool element in targets that compile.
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index cf67251..191f739 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -972,25 +972,29 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
fout << "\t\t\t\tProxyFileName=\"$(InputName)_p.c\"/>\n";
// end of <Tool Name=VCMIDLTool
- // Check if we need the FAT32 workaround.
+ // Add manifest tool settings.
if(targetBuilds && this->GetVersion() >= cmGlobalVisualStudioGenerator::VS8)
{
+ const char* manifestTool = "VCManifestTool";
+ if (this->FortranProject)
+ {
+ manifestTool = "VFManifestTool";
+ }
+ fout <<
+ "\t\t\t<Tool\n"
+ "\t\t\t\tName=\"" << manifestTool << "\"";
+
+ // 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()))
+ if (cmLVS6G_IsFAT(target.GetDirectory(configName).c_str()))
{
// Add a flag telling the manifest tool to use a workaround
// for FAT32 file systems, which can cause an empty manifest
// to be embedded into the resulting executable. See CMake
// bug #2617.
- const char* manifestTool = "VCManifestTool";
- if(this->FortranProject)
- {
- manifestTool = "VFManifestTool";
- }
- fout << "\t\t\t<Tool\n\t\t\t\tName=\"" << manifestTool << "\"\n"
- << "\t\t\t\tUseFAT32Workaround=\"true\"\n"
- << "\t\t\t/>\n";
+ fout << "\n\t\t\t\tUseFAT32Workaround=\"true\"";
}
+ fout << "/>\n";
}
this->OutputTargetRules(fout, configName, target, libName);
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=73a058f85680a044aeeecd815f8d6cc34fd29f3d
commit 73a058f85680a044aeeecd815f8d6cc34fd29f3d
Author: Brad King <brad.king at kitware.com>
AuthorDate: Wed Sep 16 10:09:07 2015 -0400
Commit: Brad King <brad.king at kitware.com>
CommitDate: Thu Sep 17 10:21:09 2015 -0400
Tests: Add RunCMake.BuildDepends test
This will allow more granular checks than the main BuildDepends test.
Start with a simple single-source C program.
diff --git a/Tests/RunCMake/BuildDepends/C-Exe.cmake b/Tests/RunCMake/BuildDepends/C-Exe.cmake
new file mode 100644
index 0000000..5057ca9
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe.cmake
@@ -0,0 +1,12 @@
+enable_language(C)
+
+add_executable(main ${CMAKE_CURRENT_BINARY_DIR}/main.c)
+
+file(GENERATE OUTPUT check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT "
+set(check_pairs
+ \"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/main.c\"
+ )
+set(check_exes
+ \"$<TARGET_FILE:main>\"
+ )
+")
diff --git a/Tests/RunCMake/BuildDepends/C-Exe.step1.cmake b/Tests/RunCMake/BuildDepends/C-Exe.step1.cmake
new file mode 100644
index 0000000..08e2949
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe.step1.cmake
@@ -0,0 +1,3 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.c" [[
+int main(void) { return 1; }
+]])
diff --git a/Tests/RunCMake/BuildDepends/C-Exe.step2.cmake b/Tests/RunCMake/BuildDepends/C-Exe.step2.cmake
new file mode 100644
index 0000000..ee4530c
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/C-Exe.step2.cmake
@@ -0,0 +1,3 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.c" [[
+int main(void) { return 2; }
+]])
diff --git a/Tests/RunCMake/BuildDepends/CMakeLists.txt b/Tests/RunCMake/BuildDepends/CMakeLists.txt
new file mode 100644
index 0000000..74b3ff8
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
new file mode 100644
index 0000000..98132cc
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
@@ -0,0 +1,23 @@
+include(RunCMake)
+
+function(run_BuildDepends CASE)
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${CASE}-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ if(RunCMake_GENERATOR MATCHES "Make|Ninja")
+ set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+ endif()
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ include(${RunCMake_SOURCE_DIR}/${CASE}.step1.cmake OPTIONAL)
+ run_cmake(${CASE})
+ set(RunCMake-check-file check.cmake)
+ set(check_step 1)
+ run_cmake_command(${CASE}-build1 ${CMAKE_COMMAND} --build . --config Debug)
+ execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1.125) # handle 1s resolution
+ include(${RunCMake_SOURCE_DIR}/${CASE}.step2.cmake OPTIONAL)
+ set(check_step 2)
+ run_cmake_command(${CASE}-build2 ${CMAKE_COMMAND} --build . --config Debug)
+endfunction()
+
+run_BuildDepends(C-Exe)
diff --git a/Tests/RunCMake/BuildDepends/check.cmake b/Tests/RunCMake/BuildDepends/check.cmake
new file mode 100644
index 0000000..be6debc
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/check.cmake
@@ -0,0 +1,34 @@
+if(EXISTS ${RunCMake_TEST_BINARY_DIR}/check-debug.cmake)
+ include(${RunCMake_TEST_BINARY_DIR}/check-debug.cmake)
+ foreach(exe IN LISTS check_exes)
+ execute_process(COMMAND ${exe} RESULT_VARIABLE res)
+ if(NOT res EQUAL ${check_step})
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}
+ '${exe}' returned '${res}' but expected '${check_step}'
+")
+ endif()
+ endforeach()
+ foreach(p IN LISTS check_pairs)
+ if("${p}" MATCHES "^(.*)\\|(.*)$")
+ set(lhs "${CMAKE_MATCH_1}")
+ set(rhs "${CMAKE_MATCH_2}")
+ if(NOT EXISTS "${lhs}")
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}
+ '${lhs}' missing
+")
+ elseif(NOT EXISTS "${rhs}")
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}
+ '${rhs}' missing
+")
+ elseif(NOT "${lhs}" IS_NEWER_THAN "${rhs}")
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}
+ '${lhs}' is not newer than '${rhs}'
+")
+ endif()
+ endif()
+ endforeach()
+else()
+ set(RunCMake_TEST_FAILED "
+ '${RunCMake_TEST_BINARY_DIR}/check-debug.cmake' missing
+")
+endif()
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 241cf90..a8f9386 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -124,6 +124,7 @@ if(NOT CMake_TEST_EXTERNAL_CMAKE)
)
endif()
+add_RunCMake_test(BuildDepends)
if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja")
add_RunCMake_test(CompilerChange)
endif()
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=438fabf242bae84dde71d51298b43c2b6fa760eb
commit 438fabf242bae84dde71d51298b43c2b6fa760eb
Author: Brad King <brad.king at kitware.com>
AuthorDate: Wed Sep 16 10:07:49 2015 -0400
Commit: Brad King <brad.king at kitware.com>
CommitDate: Thu Sep 17 10:21:08 2015 -0400
Tests: Teach RunCMake infrastructure to use custom check.cmake file
diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
index e2ad503..db9911d 100644
--- a/Tests/RunCMake/RunCMake.cmake
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -115,7 +115,11 @@ function(run_cmake test)
endif()
endforeach()
unset(RunCMake_TEST_FAILED)
- include(${top_src}/${test}-check.cmake OPTIONAL)
+ if(RunCMake-check-file AND EXISTS ${top_src}/${RunCMake-check-file})
+ include(${top_src}/${RunCMake-check-file})
+ else()
+ include(${top_src}/${test}-check.cmake OPTIONAL)
+ endif()
if(RunCMake_TEST_FAILED)
set(msg "${RunCMake_TEST_FAILED}\n${msg}")
endif()
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f38625be7a6284495d3617bc64725f2873284b01
commit f38625be7a6284495d3617bc64725f2873284b01
Author: Brad King <brad.king at kitware.com>
AuthorDate: Thu Sep 17 09:10:36 2015 -0400
Commit: Brad King <brad.king at kitware.com>
CommitDate: Thu Sep 17 10:20:59 2015 -0400
Tests: Teach RunCMake to tolerate 'Bullseye Testing' lines in test output
When testing under Bullseye coverage, some tests get lines on stderr of
the form:
... Bullseye Testing Technology ...
Remove such lines from output before matching because they are not
representative of the actual test output.
diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
index ffb3e50..e2ad503 100644
--- a/Tests/RunCMake/RunCMake.cmake
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -102,7 +102,7 @@ function(run_cmake test)
endif()
foreach(o out err)
string(REGEX REPLACE "\r\n" "\n" actual_std${o} "${actual_std${o}}")
- string(REGEX REPLACE "(^|\n)((==[0-9]+==|BullseyeCoverage|[a-z]+\\([0-9]+\\) malloc:|Error kstat returned|[^\n]*from Time Machine by path)[^\n]*\n)+" "\\1" actual_std${o} "${actual_std${o}}")
+ string(REGEX REPLACE "(^|\n)((==[0-9]+==|BullseyeCoverage|[a-z]+\\([0-9]+\\) malloc:|Error kstat returned|[^\n]*from Time Machine by path|[^\n]*Bullseye Testing Technology)[^\n]*\n)+" "\\1" actual_std${o} "${actual_std${o}}")
string(REGEX REPLACE "\n+$" "" actual_std${o} "${actual_std${o}}")
set(expect_${o} "")
if(DEFINED expect_std${o})
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1a75a966503c6aa76a564e23c4cf3695c4afc1ea
commit 1a75a966503c6aa76a564e23c4cf3695c4afc1ea
Author: Brad King <brad.king at kitware.com>
AuthorDate: Thu Sep 17 09:08:30 2015 -0400
Commit: Brad King <brad.king at kitware.com>
CommitDate: Thu Sep 17 10:20:58 2015 -0400
Tests: Teach RunCMake to tolerate 'Time Machine' lines in test output
On some OS X machines some tests get lines on stderr of the form:
... attempting to exclude an item from Time Machine by path ...
produced by the system. Remove such lines from output before matching
because they are not representative of the actual test output.
diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
index 46bc494..ffb3e50 100644
--- a/Tests/RunCMake/RunCMake.cmake
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -102,7 +102,7 @@ function(run_cmake test)
endif()
foreach(o out err)
string(REGEX REPLACE "\r\n" "\n" actual_std${o} "${actual_std${o}}")
- string(REGEX REPLACE "(^|\n)((==[0-9]+==|BullseyeCoverage|[a-z]+\\([0-9]+\\) malloc:|Error kstat returned)[^\n]*\n)+" "\\1" actual_std${o} "${actual_std${o}}")
+ string(REGEX REPLACE "(^|\n)((==[0-9]+==|BullseyeCoverage|[a-z]+\\([0-9]+\\) malloc:|Error kstat returned|[^\n]*from Time Machine by path)[^\n]*\n)+" "\\1" actual_std${o} "${actual_std${o}}")
string(REGEX REPLACE "\n+$" "" actual_std${o} "${actual_std${o}}")
set(expect_${o} "")
if(DEFINED expect_std${o})
-----------------------------------------------------------------------
Summary of changes:
hooks/post-receive
--
CMake
More information about the Cmake-commits
mailing list