| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
| file LICENSE.rst 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 "cmStringAlgorithms.h" | |
| #include "cmSystemTools.h" | |
| #include "cmTargetTypes.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(); | |
| 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() == cm::TargetType::SHARED_LIBRARY || | |
| gt->GetType() == cm::TargetType::MODULE_LIBRARY) { | |
| sharedLibs = cmStrCat(std::move(sharedLibs), ' ', lib); | |
| } else { | |
| staticLibs = cmStrCat(std::move(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 = cmStrCat(std::move(ldlibs), ' ', lib); | |
| // if it is not a path and does not have a -l then add -l | |
| } else if (!lib.empty()) { | |
| ldlibs = cmStrCat(std::move(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() == cm::TargetType::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 cm::TargetType::SHARED_LIBRARY: | |
| case cm::TargetType::MODULE_LIBRARY: | |
| os << "include $(PREBUILT_SHARED_LIBRARY)\n"; | |
| break; | |
| case cm::TargetType::STATIC_LIBRARY: | |
| os << "include $(PREBUILT_STATIC_LIBRARY)\n"; | |
| break; | |
| case cm::TargetType::EXECUTABLE: | |
| case cm::TargetType::UTILITY: | |
| case cm::TargetType::OBJECT_LIBRARY: | |
| case cm::TargetType::GLOBAL_TARGET: | |
| case cm::TargetType::INTERFACE_LIBRARY: | |
| case cm::TargetType::UNKNOWN_LIBRARY: | |
| break; | |
| } | |
| os << "\n"; | |
| } |