diff options
Diffstat (limited to 'Source/cmExportFileGenerator.cxx')
-rw-r--r-- | Source/cmExportFileGenerator.cxx | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx new file mode 100644 index 0000000..ec4bc33 --- /dev/null +++ b/Source/cmExportFileGenerator.cxx @@ -0,0 +1,281 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "cmExportFileGenerator.h" + +#include "cmGeneratedFileStream.h" +#include "cmMakefile.h" +#include "cmSystemTools.h" +#include "cmTarget.h" + +//---------------------------------------------------------------------------- +void cmExportFileGenerator::AddConfiguration(const char* config) +{ + this->Configurations.push_back(config); +} + +//---------------------------------------------------------------------------- +void cmExportFileGenerator::SetExportFile(const char* mainFile) +{ + this->MainImportFile = mainFile; + this->FileDir = + cmSystemTools::GetFilenamePath(this->MainImportFile); + this->FileBase = + cmSystemTools::GetFilenameWithoutLastExtension(this->MainImportFile); + this->FileExt = + cmSystemTools::GetFilenameLastExtension(this->MainImportFile); +} + +//---------------------------------------------------------------------------- +bool cmExportFileGenerator::GenerateImportFile() +{ + // Open the output file to generate it. + cmGeneratedFileStream exportFileStream(this->MainImportFile.c_str(), true); + if(!exportFileStream) + { + std::string se = cmSystemTools::GetLastSystemError(); + cmOStringStream e; + e << "cannot write to file \"" << this->MainImportFile + << "\": " << se; + cmSystemTools::Error(e.str().c_str()); + return false; + } + std::ostream& os = exportFileStream; + + // Start with the import file header. + this->GenerateImportHeaderCode(os); + + // Create all the imported targets. + bool result = this->GenerateMainFile(os); + + // End with the import file footer. + this->GenerateImportFooterCode(os); + + return result; +} + +//---------------------------------------------------------------------------- +void cmExportFileGenerator::GenerateImportConfig(std::ostream& os, + const char* config) +{ + // Construct the property configuration suffix. + std::string suffix = "_"; + if(config && *config) + { + suffix += cmSystemTools::UpperCase(config); + } + else + { + suffix += "NOCONFIG"; + } + + // Generate the per-config target information. + this->GenerateImportTargetsConfig(os, config, suffix); +} + +//---------------------------------------------------------------------------- +void +cmExportFileGenerator +::SetImportDetailProperties(const char* config, std::string const& suffix, + cmTarget* target, ImportPropertyMap& properties) +{ + // Get the makefile in which to lookup target information. + cmMakefile* mf = target->GetMakefile(); + + // Add the soname for unix shared libraries. + if(target->GetType() == cmTarget::SHARED_LIBRARY || + target->GetType() == cmTarget::MODULE_LIBRARY) + { + // Check whether this is a DLL platform. + bool dll_platform = + (mf->IsOn("WIN32") || mf->IsOn("CYGWIN") || mf->IsOn("MINGW")); + if(!dll_platform) + { + std::string soname = target->GetSOName(config); + std::string prop = "IMPORTED_SONAME"; + prop += suffix; + properties[prop] = soname; + } + } + + // Add the transitive link dependencies for this configuration. + { + // Compute which library configuration to link. + cmTarget::LinkLibraryType linkType = cmTarget::OPTIMIZED; + if(config && cmSystemTools::UpperCase(config) == "DEBUG") + { + linkType = cmTarget::DEBUG; + } + + // Construct the property value. + cmTarget::LinkLibraryVectorType const& libs = + target->GetOriginalLinkLibraries(); + std::string link_libs; + const char* sep = ""; + for(cmTarget::LinkLibraryVectorType::const_iterator li = libs.begin(); + li != libs.end(); ++li) + { + // Skip entries that will resolve to the target itself, are empty, + // or are not meant for this configuration. + if(li->first == target->GetName() || li->first.empty() || + !(li->second == cmTarget::GENERAL || li->second == linkType)) + { + continue; + } + + // Separate this from the previous entry. + link_libs += sep; + sep = ";"; + + // Append this entry. + if(cmTarget* tgt = mf->FindTargetToUse(li->first.c_str())) + { + // This is a target. Make sure it is included in the export. + if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end()) + { + // The target is in the export. Append it with the export + // namespace. + link_libs += this->Namespace; + link_libs += li->first; + } + else + { + // The target is not in the export. This is probably + // user-error. Warn but add it anyway. + this->ComplainAboutMissingTarget(target, li->first.c_str()); + link_libs += li->first; + } + } + else + { + // Append the raw name. + link_libs += li->first; + } + } + + // Store the property. + std::string prop = "IMPORTED_LINK_LIBRARIES"; + prop += suffix; + properties[prop] = link_libs; + } +} + +//---------------------------------------------------------------------------- +void cmExportFileGenerator::GenerateImportHeaderCode(std::ostream& os, + const char* config) +{ + os << "#----------------------------------------------------------------\n" + << "# Generated CMake target import file"; + if(config) + { + os << " for configuration \"" << config << "\".\n"; + } + else + { + os << ".\n"; + } + os << "#----------------------------------------------------------------\n" + << "\n"; + this->GenerateImportVersionCode(os); +} + +//---------------------------------------------------------------------------- +void cmExportFileGenerator::GenerateImportFooterCode(std::ostream& os) +{ + os << "# Commands beyond this point should not need to know the version.\n" + << "SET(CMAKE_IMPORT_FILE_VERSION)\n"; +} + +//---------------------------------------------------------------------------- +void cmExportFileGenerator::GenerateImportVersionCode(std::ostream& os) +{ + // Store an import file format version. This will let us change the + // format later while still allowing old import files to work. + os << "# Commands may need to know the format version.\n" + << "SET(CMAKE_IMPORT_FILE_VERSION 1)\n" + << "\n"; +} + +//---------------------------------------------------------------------------- +void +cmExportFileGenerator +::GenerateImportTargetCode(std::ostream& os, cmTarget* target) +{ + // Construct the imported target name. + std::string targetName = this->Namespace; + targetName += target->GetName(); + + // Create the imported target. + os << "# Create imported target " << targetName << "\n"; + switch(target->GetType()) + { + case cmTarget::EXECUTABLE: + os << "ADD_EXECUTABLE(" << targetName << " IMPORTED)\n"; + break; + case cmTarget::STATIC_LIBRARY: + os << "ADD_LIBRARY(" << targetName << " STATIC IMPORTED)\n"; + break; + case cmTarget::SHARED_LIBRARY: + os << "ADD_LIBRARY(" << targetName << " SHARED IMPORTED)\n"; + break; + case cmTarget::MODULE_LIBRARY: + os << "ADD_LIBRARY(" << targetName << " MODULE IMPORTED)\n"; + break; + default: // should never happen + break; + } + if(target->IsExecutableWithExports()) + { + os << "SET_PROPERTY(TARGET " << targetName + << " PROPERTY IMPORTED_ENABLE_EXPORTS 1)\n"; + } + os << "\n"; +} + +//---------------------------------------------------------------------------- +void +cmExportFileGenerator +::GenerateImportPropertyCode(std::ostream& os, const char* config, + cmTarget* target, + ImportPropertyMap const& properties) +{ + // Construct the imported target name. + std::string targetName = this->Namespace; + targetName += target->GetName(); + + // Set the import properties. + os << "# Import target \"" << targetName << "\" for configuration \"" + << config << "\"\n"; + os << "SET_PROPERTY(TARGET " << targetName + << " APPEND PROPERTY IMPORTED_CONFIGURATIONS "; + if(config && *config) + { + os << cmSystemTools::UpperCase(config); + } + else + { + os << "NOCONFIG"; + } + os << ")\n"; + os << "SET_TARGET_PROPERTIES(" << targetName << " PROPERTIES\n"; + for(ImportPropertyMap::const_iterator pi = properties.begin(); + pi != properties.end(); ++pi) + { + os << " " << pi->first << " \"" << pi->second << "\"\n"; + } + os << " )\n" + << "\n"; +} |