mirror of
https://github.com/Kitware/CMake.git
synced 2026-02-15 11:46:00 -06:00
VS: Treat libraries ending in .targets as msbuild imports
Generate `<Import Project="..." .../>` to import the `.targets` files into `.vcxproj` files. Closes: #16340
This commit is contained in:
@@ -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``).
|
||||
|
||||
|
||||
6
Help/release/dev/vs_targets_file_as_library.rst
Normal file
6
Help/release/dev/vs_targets_file_as_library.rst
Normal file
@@ -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.
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user