summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSoji Yamakawa <soji@andrew.cmu.edu>2016-11-04 16:02:22 (GMT)
committerBrad King <brad.king@kitware.com>2016-11-09 21:19:07 (GMT)
commit883bd34a1fa31273929c7baf2f43b3c6f5ec0c01 (patch)
tree4505cdc5e38feabd73d036374ce140160f07aeec
parent2a567c68ce6605071f3e21638560493b71ed2841 (diff)
downloadCMake-883bd34a1fa31273929c7baf2f43b3c6f5ec0c01.zip
CMake-883bd34a1fa31273929c7baf2f43b3c6f5ec0c01.tar.gz
CMake-883bd34a1fa31273929c7baf2f43b3c6f5ec0c01.tar.bz2
VS: Treat libraries ending in `.targets` as msbuild imports
Generate `<Import Project="..." .../>` to import the `.targets` files into `.vcxproj` files. Closes: #16340
-rw-r--r--Help/command/target_link_libraries.rst5
-rw-r--r--Help/release/dev/vs_targets_file_as_library.rst6
-rw-r--r--Modules/Platform/Windows.cmake1
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx118
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h15
5 files changed, 140 insertions, 5 deletions
diff --git a/Help/command/target_link_libraries.rst b/Help/command/target_link_libraries.rst
index 90b6575..30d69f2 100644
--- a/Help/command/target_link_libraries.rst
+++ b/Help/command/target_link_libraries.rst
@@ -53,6 +53,11 @@ Each ``<item>`` may be:
:ref:`usage requirement <Target Usage Requirements>`. This has the same
effect as passing the framework directory as an include directory.
+ On :ref:`Visual Studio Generators` for VS 2010 and above, library files
+ ending in ``.targets`` will be treated as MSBuild targets files and
+ imported into generated project files. This is not supported by other
+ generators.
+
* **A plain library name**: The generated link line will ask the linker
to search for the library (e.g. ``foo`` becomes ``-lfoo`` or ``foo.lib``).
diff --git a/Help/release/dev/vs_targets_file_as_library.rst b/Help/release/dev/vs_targets_file_as_library.rst
new file mode 100644
index 0000000..9c923fa
--- /dev/null
+++ b/Help/release/dev/vs_targets_file_as_library.rst
@@ -0,0 +1,6 @@
+vs_targets_file_as_library
+--------------------------
+
+* :ref:`Visual Studio Generators` learned to treat files passed to
+ :command:`target_link_libraries` whose names end in ``.targets``
+ as MSBuild targets files to be imported into generated project files.
diff --git a/Modules/Platform/Windows.cmake b/Modules/Platform/Windows.cmake
index 9a937a7..d8b3957 100644
--- a/Modules/Platform/Windows.cmake
+++ b/Modules/Platform/Windows.cmake
@@ -17,6 +17,7 @@ set(CMAKE_IMPORT_LIBRARY_SUFFIX ".lib")
set(CMAKE_EXECUTABLE_SUFFIX ".exe") # .exe
set(CMAKE_LINK_LIBRARY_SUFFIX ".lib")
set(CMAKE_DL_LIBS "")
+set(CMAKE_EXTRA_LINK_EXTENSIONS ".targets")
set(CMAKE_FIND_LIBRARY_PREFIXES "")
set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 9c857f2..c00e556 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -170,6 +170,12 @@ static std::string cmVS10EscapeComment(std::string comment)
return echoable;
}
+static bool cmVS10IsTargetsFile(std::string const& path)
+{
+ std::string const ext = cmSystemTools::GetFilenameLastExtension(path);
+ return cmSystemTools::Strucmp(ext.c_str(), ".targets") == 0;
+}
+
cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator(
cmGeneratorTarget* target, cmGlobalVisualStudio10Generator* gg)
{
@@ -277,6 +283,9 @@ void cmVisualStudio10TargetGenerator::Generate()
if (!this->ComputeLinkOptions()) {
return;
}
+ if (!this->ComputeLibOptions()) {
+ return;
+ }
}
std::string path = this->LocalGenerator->GetCurrentBinaryDirectory();
path += "/";
@@ -481,6 +490,7 @@ void cmVisualStudio10TargetGenerator::Generate()
1);
this->WriteTargetSpecificReferences();
this->WriteString("<ImportGroup Label=\"ExtensionTargets\">\n", 1);
+ this->WriteTargetsFileReferences();
if (this->GlobalGenerator->IsMasmEnabled()) {
this->WriteString("<Import Project=\"$(VCTargetsPath)\\"
"BuildCustomizations\\masm.targets\" />\n",
@@ -596,6 +606,31 @@ void cmVisualStudio10TargetGenerator::WriteTargetSpecificReferences()
}
}
+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;
@@ -2239,9 +2274,16 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
}
// add the libraries for the target to libs string
cmComputeLinkInformation& cli = *pcli;
- this->AddLibraries(cli, libVec);
+ std::vector<std::string> vsTargetVec;
+ this->AddLibraries(cli, libVec, vsTargetVec);
linkOptions.AddFlag("AdditionalDependencies", libVec);
+ // Populate TargetsFileAndConfigsVec
+ for (std::vector<std::string>::iterator ti = vsTargetVec.begin();
+ ti != vsTargetVec.end(); ++ti) {
+ this->AddTargetsFileAndConfigPair(*ti, config);
+ }
+
std::vector<std::string> const& ldirs = cli.GetDirectories();
std::vector<std::string> linkDirs;
for (std::vector<std::string>::const_iterator d = ldirs.begin();
@@ -2396,6 +2438,49 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
return true;
}
+bool cmVisualStudio10TargetGenerator::ComputeLibOptions()
+{
+ if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) {
+ for (std::vector<std::string>::const_iterator i =
+ this->Configurations.begin();
+ i != this->Configurations.end(); ++i) {
+ if (!this->ComputeLibOptions(*i)) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool cmVisualStudio10TargetGenerator::ComputeLibOptions(
+ std::string const& config)
+{
+ cmComputeLinkInformation* pcli =
+ this->GeneratorTarget->GetLinkInformation(config.c_str());
+ 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 (ItemVector::const_iterator l = libs.begin(); l != libs.end(); ++l) {
+ if (l->IsPath && cmVS10IsTargetsFile(l->Value)) {
+ std::string path = this->LocalGenerator->ConvertToRelativePath(
+ currentBinDir, l->Value.c_str());
+ this->ConvertToWindowsSlash(path);
+ this->AddTargetsFileAndConfigPair(path, config);
+ }
+ }
+
+ return true;
+}
+
void cmVisualStudio10TargetGenerator::WriteLinkOptions(
std::string const& config)
{
@@ -2420,10 +2505,11 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(
}
void cmVisualStudio10TargetGenerator::AddLibraries(
- cmComputeLinkInformation& cli, std::vector<std::string>& libVec)
+ cmComputeLinkInformation& cli, std::vector<std::string>& libVec,
+ std::vector<std::string>& vsTargetVec)
{
typedef cmComputeLinkInformation::ItemVector ItemVector;
- ItemVector libs = cli.GetItems();
+ ItemVector const& libs = cli.GetItems();
std::string currentBinDir =
this->LocalGenerator->GetCurrentBinaryDirectory();
for (ItemVector::const_iterator l = libs.begin(); l != libs.end(); ++l) {
@@ -2431,7 +2517,11 @@ void cmVisualStudio10TargetGenerator::AddLibraries(
std::string path = this->LocalGenerator->ConvertToRelativePath(
currentBinDir, l->Value.c_str());
this->ConvertToWindowsSlash(path);
- libVec.push_back(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);
@@ -2439,6 +2529,26 @@ void cmVisualStudio10TargetGenerator::AddLibraries(
}
}
+void cmVisualStudio10TargetGenerator::AddTargetsFileAndConfigPair(
+ std::string const& targetsFile, std::string const& config)
+{
+ for (std::vector<TargetsFileAndConfigs>::iterator i =
+ this->TargetsFileAndConfigsVec.begin();
+ i != this->TargetsFileAndConfigsVec.end(); ++i) {
+ 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& /*config*/, std::vector<std::string> const& includes)
{
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index c62be7e..9ecb089 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -41,6 +41,12 @@ private:
{
};
+ struct TargetsFileAndConfigs
+ {
+ std::string File;
+ std::vector<std::string> Configs;
+ };
+
std::string ConvertPath(std::string const& path, bool forceRelative);
void ConvertToWindowsSlash(std::string& s);
void WriteString(const char* line, int indentLevel);
@@ -77,6 +83,7 @@ private:
std::string const& version);
void WriteCommonMissingFiles(const std::string& manifestFile);
void WriteTargetSpecificReferences();
+ void WriteTargetsFileReferences();
bool ComputeClOptions();
bool ComputeClOptions(std::string const& configName);
@@ -92,6 +99,8 @@ private:
std::vector<std::string> const& includes);
bool ComputeLinkOptions();
bool ComputeLinkOptions(std::string const& config);
+ bool ComputeLibOptions();
+ bool ComputeLibOptions(std::string const& config);
void WriteLinkOptions(std::string const& config);
void WriteMidlOptions(std::string const& config,
std::vector<std::string> const& includes);
@@ -106,7 +115,10 @@ private:
void WriteApplicationTypeSettings();
bool OutputSourceSpecificFlags(cmSourceFile const* source);
void AddLibraries(cmComputeLinkInformation& cli,
- std::vector<std::string>& libVec);
+ std::vector<std::string>& libVec,
+ std::vector<std::string>& vsTargetVec);
+ void AddTargetsFileAndConfigPair(std::string const& targetsFile,
+ std::string const& config);
void WriteLibOptions(std::string const& config);
void WriteManifestOptions(std::string const& config);
void WriteEvents(std::string const& configName);
@@ -138,6 +150,7 @@ private:
OptionsMap LinkOptions;
std::string PathToVcxproj;
std::vector<std::string> Configurations;
+ std::vector<TargetsFileAndConfigs> TargetsFileAndConfigsVec;
cmGeneratorTarget* GeneratorTarget;
cmMakefile* Makefile;
std::string Platform;