Commit a0b15968 authored by Brad King's avatar Brad King Committed by Kitware Robot

Merge topic 'vs_targets_file_as_library'

883bd34a VS: Treat libraries ending in `.targets` as msbuild imports
parents 5733d3fb 883bd34a
......@@ -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``).
......
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")
......
......@@ -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)
{
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment