diff options
Diffstat (limited to 'Source/cmExportAndroidMKGenerator.cxx')
-rw-r--r-- | Source/cmExportAndroidMKGenerator.cxx | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/Source/cmExportAndroidMKGenerator.cxx b/Source/cmExportAndroidMKGenerator.cxx new file mode 100644 index 0000000..34dc1a7 --- /dev/null +++ b/Source/cmExportAndroidMKGenerator.cxx @@ -0,0 +1,165 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmExportAndroidMKGenerator.h" + +#include <sstream> +#include <utility> +#include <vector> + +#include <cmext/algorithm> +#include <cmext/string_view> + +#include "cmGeneratorTarget.h" +#include "cmLinkItem.h" +#include "cmList.h" +#include "cmMakefile.h" +#include "cmMessageType.h" +#include "cmPolicies.h" +#include "cmStateTypes.h" +#include "cmStringAlgorithms.h" +#include "cmSystemTools.h" +#include "cmTarget.h" + +cmExportAndroidMKGenerator::cmExportAndroidMKGenerator() = default; + +cm::string_view cmExportAndroidMKGenerator::GetImportPrefixWithSlash() const +{ + return "$(_IMPORT_PREFIX)/"_s; +} + +bool cmExportAndroidMKGenerator::GenerateImportFile(std::ostream& os) +{ + if (!this->AppendMode) { + // Start with the import file header. + this->GenerateImportHeaderCode(os); + } + + // Create all the imported targets. + std::stringstream mainFileBuffer; + bool result = this->GenerateMainFile(mainFileBuffer); + + // Write cached import code. + os << mainFileBuffer.rdbuf(); + + return result; +} + +void cmExportAndroidMKGenerator::GenerateInterfaceProperties( + cmGeneratorTarget const* target, std::ostream& os, + ImportPropertyMap const& properties) +{ + std::string const config = + (this->Configurations.empty() ? std::string{} : this->Configurations[0]); + GenerateType const type = this->GetGenerateType(); + + bool const newCMP0022Behavior = + target->GetPolicyStatusCMP0022() != cmPolicies::WARN && + target->GetPolicyStatusCMP0022() != cmPolicies::OLD; + if (!newCMP0022Behavior) { + std::ostringstream w; + if (type == BUILD) { + w << "export(TARGETS ... ANDROID_MK) called with policy CMP0022"; + } else { + w << "install( EXPORT_ANDROID_MK ...) called with policy CMP0022"; + } + w << " set to OLD for target " << target->Target->GetName() << ". " + << "The export will only work with CMP0022 set to NEW."; + target->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str()); + } + if (!properties.empty()) { + os << "LOCAL_CPP_FEATURES := rtti exceptions\n"; + for (auto const& property : properties) { + if (property.first == "INTERFACE_COMPILE_OPTIONS") { + os << "LOCAL_CPP_FEATURES += "; + os << (property.second) << "\n"; + } else if (property.first == "INTERFACE_LINK_LIBRARIES") { + std::string staticLibs; + std::string sharedLibs; + std::string ldlibs; + cmLinkInterfaceLibraries const* linkIFace = + target->GetLinkInterfaceLibraries(config, target, + cmGeneratorTarget::UseTo::Link); + for (cmLinkItem const& item : linkIFace->Libraries) { + cmGeneratorTarget const* gt = item.Target; + std::string const& lib = item.AsStr(); + if (gt) { + + if (gt->GetType() == cmStateEnums::SHARED_LIBRARY || + gt->GetType() == cmStateEnums::MODULE_LIBRARY) { + sharedLibs += " " + lib; + } else { + staticLibs += " " + lib; + } + } else { + bool relpath = false; + if (type == INSTALL) { + relpath = cmHasLiteralPrefix(lib, "../"); + } + // check for full path or if it already has a -l, or + // in the case of an install check for relative paths + // if it is full or a link library then use string directly + if (cmSystemTools::FileIsFullPath(lib) || + cmHasLiteralPrefix(lib, "-l") || relpath) { + ldlibs += " " + lib; + // if it is not a path and does not have a -l then add -l + } else if (!lib.empty()) { + ldlibs += " -l" + lib; + } + } + } + if (!sharedLibs.empty()) { + os << "LOCAL_SHARED_LIBRARIES :=" << sharedLibs << "\n"; + } + if (!staticLibs.empty()) { + os << "LOCAL_STATIC_LIBRARIES :=" << staticLibs << "\n"; + } + if (!ldlibs.empty()) { + os << "LOCAL_EXPORT_LDLIBS :=" << ldlibs << "\n"; + } + } else if (property.first == "INTERFACE_INCLUDE_DIRECTORIES") { + std::string includes = property.second; + cmList includeList{ includes }; + os << "LOCAL_EXPORT_C_INCLUDES := "; + std::string end; + for (std::string const& i : includeList) { + os << end << i; + end = "\\\n"; + } + os << "\n"; + } else if (property.first == "INTERFACE_LINK_OPTIONS") { + os << "LOCAL_EXPORT_LDFLAGS := "; + cmList linkFlagsList{ property.second }; + os << linkFlagsList.join(" ") << "\n"; + } else { + os << "# " << property.first << " " << (property.second) << "\n"; + } + } + } + + // Tell the NDK build system if prebuilt static libraries use C++. + if (target->GetType() == cmStateEnums::STATIC_LIBRARY) { + cmLinkImplementation const* li = + target->GetLinkImplementation(config, cmGeneratorTarget::UseTo::Link); + if (cm::contains(li->Languages, "CXX")) { + os << "LOCAL_HAS_CPP := true\n"; + } + } + + switch (target->GetType()) { + case cmStateEnums::SHARED_LIBRARY: + case cmStateEnums::MODULE_LIBRARY: + os << "include $(PREBUILT_SHARED_LIBRARY)\n"; + break; + case cmStateEnums::STATIC_LIBRARY: + os << "include $(PREBUILT_STATIC_LIBRARY)\n"; + break; + case cmStateEnums::EXECUTABLE: + case cmStateEnums::UTILITY: + case cmStateEnums::OBJECT_LIBRARY: + case cmStateEnums::GLOBAL_TARGET: + case cmStateEnums::INTERFACE_LIBRARY: + case cmStateEnums::UNKNOWN_LIBRARY: + break; + } + os << "\n"; +} |