| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
| file Copyright.txt or https://cmake.org/licensing for details. */ | |
| #include "cmExportBuildAndroidMKGenerator.h" | |
| #include <sstream> | |
| #include <utility> | |
| #include <cmext/algorithm> | |
| #include "cmGeneratorTarget.h" | |
| #include "cmLinkItem.h" | |
| #include "cmMakefile.h" | |
| #include "cmMessageType.h" | |
| #include "cmPolicies.h" | |
| #include "cmStateTypes.h" | |
| #include "cmStringAlgorithms.h" | |
| #include "cmSystemTools.h" | |
| #include "cmTarget.h" | |
| cmExportBuildAndroidMKGenerator::cmExportBuildAndroidMKGenerator() | |
| { | |
| this->LG = nullptr; | |
| this->ExportSet = nullptr; | |
| } | |
| void cmExportBuildAndroidMKGenerator::GenerateImportHeaderCode( | |
| std::ostream& os, const std::string&) | |
| { | |
| os << "LOCAL_PATH := $(call my-dir)\n\n"; | |
| } | |
| void cmExportBuildAndroidMKGenerator::GenerateImportFooterCode(std::ostream&) | |
| { | |
| } | |
| void cmExportBuildAndroidMKGenerator::GenerateExpectedTargetsCode( | |
| std::ostream&, const std::string&) | |
| { | |
| } | |
| void cmExportBuildAndroidMKGenerator::GenerateImportTargetCode( | |
| std::ostream& os, cmGeneratorTarget const* target, | |
| cmStateEnums::TargetType /*targetType*/) | |
| { | |
| std::string targetName = cmStrCat(this->Namespace, target->GetExportName()); | |
| os << "include $(CLEAR_VARS)\n"; | |
| os << "LOCAL_MODULE := "; | |
| os << targetName << "\n"; | |
| os << "LOCAL_SRC_FILES := "; | |
| std::string const noConfig; // FIXME: What config to use here? | |
| std::string path = | |
| cmSystemTools::ConvertToOutputPath(target->GetFullPath(noConfig)); | |
| os << path << "\n"; | |
| } | |
| void cmExportBuildAndroidMKGenerator::GenerateImportPropertyCode( | |
| std::ostream&, const std::string&, cmGeneratorTarget const*, | |
| ImportPropertyMap const&) | |
| { | |
| } | |
| void cmExportBuildAndroidMKGenerator::GenerateMissingTargetsCheckCode( | |
| std::ostream&, const std::vector<std::string>&) | |
| { | |
| } | |
| void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties( | |
| const cmGeneratorTarget* target, std::ostream& os, | |
| const ImportPropertyMap& properties) | |
| { | |
| std::string config; | |
| if (!this->Configurations.empty()) { | |
| config = this->Configurations[0]; | |
| } | |
| cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties( | |
| target, os, properties, cmExportBuildAndroidMKGenerator::BUILD, config); | |
| } | |
| void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties( | |
| const cmGeneratorTarget* target, std::ostream& os, | |
| const ImportPropertyMap& properties, GenerateType type, | |
| std::string const& config) | |
| { | |
| const bool newCMP0022Behavior = | |
| target->GetPolicyStatusCMP0022() != cmPolicies::WARN && | |
| target->GetPolicyStatusCMP0022() != cmPolicies::OLD; | |
| if (!newCMP0022Behavior) { | |
| std::ostringstream w; | |
| if (type == cmExportBuildAndroidMKGenerator::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, false); | |
| 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 == cmExportBuildAndroidMKGenerator::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; | |
| std::vector<std::string> includeList = cmExpandedList(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 := "; | |
| std::vector<std::string> linkFlagsList = | |
| cmExpandedList(property.second); | |
| os << cmJoin(linkFlagsList, " ") << "\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); | |
| 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"; | |
| } |