diff options
author | Brad King <brad.king@kitware.com> | 2016-11-11 15:44:20 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2016-11-11 15:44:20 (GMT) |
commit | a0b159685ea4383255e46de5456d6a9204457c1f (patch) | |
tree | 81f89a516293c1e47ce9f0426f58d01a1fa996a5 | |
parent | 5733d3fbb96a0f48b58b44e5b256ec1978cbbf61 (diff) | |
parent | 883bd34a1fa31273929c7baf2f43b3c6f5ec0c01 (diff) | |
download | CMake-a0b159685ea4383255e46de5456d6a9204457c1f.zip CMake-a0b159685ea4383255e46de5456d6a9204457c1f.tar.gz CMake-a0b159685ea4383255e46de5456d6a9204457c1f.tar.bz2 |
Merge topic 'vs_targets_file_as_library'
883bd34a VS: Treat libraries ending in `.targets` as msbuild imports
-rw-r--r-- | Help/command/target_link_libraries.rst | 5 | ||||
-rw-r--r-- | Help/release/dev/vs_targets_file_as_library.rst | 6 | ||||
-rw-r--r-- | Modules/Platform/Windows.cmake | 1 | ||||
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.cxx | 118 | ||||
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.h | 15 |
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 97eb3c7..5dd9e48 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -53,6 +53,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) { @@ -160,6 +166,9 @@ void cmVisualStudio10TargetGenerator::Generate() if (!this->ComputeLinkOptions()) { return; } + if (!this->ComputeLibOptions()) { + return; + } } std::string path = this->LocalGenerator->GetCurrentBinaryDirectory(); path += "/"; @@ -364,6 +373,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", @@ -479,6 +489,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; @@ -2148,9 +2183,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(); @@ -2305,6 +2347,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) { @@ -2329,10 +2414,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) { @@ -2340,7 +2426,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); @@ -2348,6 +2438,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 54b9569..1fa844c 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); @@ -132,6 +144,7 @@ private: OptionsMap LinkOptions; std::string PathToVcxproj; std::vector<std::string> Configurations; + std::vector<TargetsFileAndConfigs> TargetsFileAndConfigsVec; cmGeneratorTarget* GeneratorTarget; cmMakefile* Makefile; std::string Platform; |