From 1c0597c25bf69a9c73e3d4f6ab68d16b5e56a271 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 7 Feb 2013 17:36:29 +0100 Subject: [PATCH] Add a new Export generator for IMPORTED targets. This is to be used during try_compile using LINK_LIBRARIES in the srcfile signature and, in the future, TARGETS in the binary dir signature. --- Source/CMakeLists.txt | 2 + Source/cmExportFileGenerator.cxx | 3 + Source/cmExportTryCompileFileGenerator.cxx | 114 +++++++++++++++++++++ Source/cmExportTryCompileFileGenerator.h | 55 ++++++++++ bootstrap | 1 + 5 files changed, 175 insertions(+) create mode 100644 Source/cmExportTryCompileFileGenerator.cxx create mode 100644 Source/cmExportTryCompileFileGenerator.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 675f576f9..fde9677d1 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -176,6 +176,8 @@ set(SRCS cmExportFileGenerator.cxx cmExportInstallFileGenerator.h cmExportInstallFileGenerator.cxx + cmExportTryCompileFileGenerator.h + cmExportTryCompileFileGenerator.cxx cmExportSet.h cmExportSet.cxx cmExportSetMap.h diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index ef4ea3800..d8a705947 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -679,6 +679,9 @@ cmExportFileGenerator case cmTarget::MODULE_LIBRARY: os << "add_library(" << targetName << " MODULE IMPORTED)\n"; break; + case cmTarget::UNKNOWN_LIBRARY: + os << "add_library(" << targetName << " UNKNOWN IMPORTED)\n"; + break; default: // should never happen break; } diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx new file mode 100644 index 000000000..75f2651ba --- /dev/null +++ b/Source/cmExportTryCompileFileGenerator.cxx @@ -0,0 +1,114 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2013 Stephen Kelly + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmExportTryCompileFileGenerator.h" + +#include "cmGeneratedFileStream.h" +#include "cmGeneratorExpressionDAGChecker.h" + +//---------------------------------------------------------------------------- +bool cmExportTryCompileFileGenerator::GenerateMainFile(std::ostream& os) +{ + std::set emitted; + std::set emittedDeps; + while(!this->Exports.empty()) + { + cmTarget* te = this->Exports.back(); + this->Exports.pop_back(); + if (emitted.insert(te).second) + { + emittedDeps.insert(te); + this->GenerateImportTargetCode(os, te); + + ImportPropertyMap properties; + + this->FindTargets("INTERFACE_INCLUDE_DIRECTORIES", te, emittedDeps); + this->FindTargets("INTERFACE_COMPILE_DEFINITIONS", te, emittedDeps); + + this->PopulateProperties(te, properties, emittedDeps); + + this->GenerateInterfaceProperties(te, os, properties); + } + } + return true; +} + +std::string cmExportTryCompileFileGenerator::FindTargets(const char *propName, + cmTarget *tgt, + std::set &emitted) +{ + const char *prop = tgt->GetProperty(propName); + if(!prop) + { + return std::string(); + } + + cmListFileBacktrace lfbt; + cmGeneratorExpression ge(lfbt); + + cmGeneratorExpressionDAGChecker dagChecker(lfbt, + tgt->GetName(), + propName, 0, 0); + + cmsys::auto_ptr cge = ge.Parse(prop); + + cmTarget dummyHead; + dummyHead.SetType(cmTarget::EXECUTABLE, "try_compile_dummy_exe"); + dummyHead.SetMakefile(tgt->GetMakefile()); + + std::string result = cge->Evaluate(tgt->GetMakefile(), this->Config, + false, &dummyHead, tgt, &dagChecker); + + const std::set &allTargets = cge->GetAllTargetsSeen(); + for(std::set::const_iterator li = allTargets.begin(); + li != allTargets.end(); ++li) + { + if(emitted.insert(*li).second) + { + this->Exports.push_back(*li); + } + } + return result; +} + +//---------------------------------------------------------------------------- +void +cmExportTryCompileFileGenerator::PopulateProperties(cmTarget* target, + ImportPropertyMap& properties, + std::set &emitted) +{ + cmPropertyMap props = target->GetProperties(); + for(cmPropertyMap::const_iterator i = props.begin(); i != props.end(); ++i) + { + properties[i->first] = i->second.GetValue(); + + if(i->first.find("IMPORTED_LINK_INTERFACE_LIBRARIES") == 0) + { + const std::string libs = i->second.GetValue(); + + std::string evalResult = this->FindTargets(i->first.c_str(), + target, emitted); + + std::vector depends; + cmSystemTools::ExpandListArgument(evalResult, depends); + for(std::vector::const_iterator li = depends.begin(); + li != depends.end(); ++li) + { + cmTarget *tgt = target->GetMakefile()->FindTargetToUse(li->c_str()); + if(tgt && emitted.insert(tgt).second) + { + this->Exports.push_back(tgt); + } + } + } + } +} diff --git a/Source/cmExportTryCompileFileGenerator.h b/Source/cmExportTryCompileFileGenerator.h new file mode 100644 index 000000000..ed393abf4 --- /dev/null +++ b/Source/cmExportTryCompileFileGenerator.h @@ -0,0 +1,55 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2013 Stephen Kelly + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmExportInstallFileGenerator_h +#define cmExportInstallFileGenerator_h + +#include "cmExportFileGenerator.h" + +class cmInstallExportGenerator; +class cmInstallTargetGenerator; + +class cmExportTryCompileFileGenerator: public cmExportFileGenerator +{ +public: + /** Set the list of targets to export. */ + void SetExports(const std::vector &exports) + { this->Exports = exports; } + void SetConfig(const char *config) { this->Config = config; } +protected: + + // Implement virtual methods from the superclass. + virtual bool GenerateMainFile(std::ostream& os); + + virtual void GenerateImportTargetsConfig(std::ostream&, + const char*, + std::string const&, + std::vector&) {} + virtual void HandleMissingTarget(std::string&, + std::vector&, + cmMakefile*, + cmTarget*, + cmTarget*) {} + + void PopulateProperties(cmTarget* target, + ImportPropertyMap& properties, + std::set &emitted); + +private: + std::string FindTargets(const char *prop, cmTarget *tgt, + std::set &emitted); + + + std::vector Exports; + const char *Config; +}; + +#endif diff --git a/bootstrap b/bootstrap index 9a4f796fe..5c2addb50 100755 --- a/bootstrap +++ b/bootstrap @@ -214,6 +214,7 @@ CMAKE_CXX_SOURCES="\ cmMakefile \ cmExportFileGenerator \ cmExportInstallFileGenerator \ + cmExportTryCompileFileGenerator \ cmExportSet \ cmExportSetMap \ cmInstallDirectoryGenerator \