/* 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 "cmExportSet.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmTargetExport.h" #include cmExportBuildAndroidMKGenerator::cmExportBuildAndroidMKGenerator() { this->LG = CM_NULLPTR; this->ExportSet = CM_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, const cmGeneratorTarget* target) { std::string targetName = this->Namespace; targetName += target->GetExportName(); os << "include $(CLEAR_VARS)\n"; os << "LOCAL_MODULE := "; os << targetName << "\n"; os << "LOCAL_SRC_FILES := "; std::string path = cmSystemTools::ConvertToOutputPath(target->GetFullPath().c_str()); os << path << "\n"; } void cmExportBuildAndroidMKGenerator::GenerateImportPropertyCode( std::ostream&, const std::string&, cmGeneratorTarget const*, ImportPropertyMap const&) { } void cmExportBuildAndroidMKGenerator::GenerateMissingTargetsCheckCode( std::ostream&, const std::vector&) { } 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(cmake::AUTHOR_WARNING, w.str()); } if (!properties.empty()) { os << "LOCAL_CPP_FEATURES := rtti exceptions\n"; for (ImportPropertyMap::const_iterator pi = properties.begin(); pi != properties.end(); ++pi) { if (pi->first == "INTERFACE_COMPILE_OPTIONS") { os << "LOCAL_CPP_FEATURES += "; os << (pi->second) << "\n"; } else if (pi->first == "INTERFACE_LINK_LIBRARIES") { // need to look at list in pi->second and see if static or shared // FindTargetToLink // target->GetLocalGenerator()->FindGeneratorTargetToUse() // then add to LOCAL_CPPFLAGS std::vector libraries; cmSystemTools::ExpandListArgument(pi->second, libraries); std::string staticLibs; std::string sharedLibs; std::string ldlibs; for (std::vector::iterator i = libraries.begin(); i != libraries.end(); ++i) { cmGeneratorTarget* gt = target->GetLocalGenerator()->FindGeneratorTargetToUse(*i); if (gt) { if (gt->GetType() == cmStateEnums::SHARED_LIBRARY || gt->GetType() == cmStateEnums::MODULE_LIBRARY) { sharedLibs += " " + *i; } else { staticLibs += " " + *i; } } else { // evaluate any generator expressions with the current // build type of the makefile cmGeneratorExpression ge; CM_AUTO_PTR cge = ge.Parse(*i); std::string evaluated = cge->Evaluate(target->GetLocalGenerator(), config); bool relpath = false; if (type == cmExportBuildAndroidMKGenerator::INSTALL) { relpath = i->substr(0, 3) == "../"; } // 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(evaluated) || evaluated.substr(0, 2) == "-l" || relpath) { ldlibs += " " + evaluated; // if it is not a path and does not have a -l then add -l } else if (!evaluated.empty()) { ldlibs += " -l" + evaluated; } } } 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 (pi->first == "INTERFACE_INCLUDE_DIRECTORIES") { std::string includes = pi->second; std::vector includeList; cmSystemTools::ExpandListArgument(includes, includeList); os << "LOCAL_EXPORT_C_INCLUDES := "; std::string end; for (std::vector::iterator i = includeList.begin(); i != includeList.end(); ++i) { os << end << *i; end = "\\\n"; } os << "\n"; } else { os << "# " << pi->first << " " << (pi->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 (std::find(li->Languages.begin(), li->Languages.end(), "CXX") != li->Languages.end()) { 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"; }