cmExportBuildAndroidMKGenerator.cxx 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmExportBuildAndroidMKGenerator.h"
  4. #include <algorithm>
  5. #include <sstream>
  6. #include <utility>
  7. #include "cmAlgorithms.h"
  8. #include "cmGeneratorTarget.h"
  9. #include "cmLinkItem.h"
  10. #include "cmMakefile.h"
  11. #include "cmMessageType.h"
  12. #include "cmPolicies.h"
  13. #include "cmStateTypes.h"
  14. #include "cmSystemTools.h"
  15. #include "cmTarget.h"
  16. cmExportBuildAndroidMKGenerator::cmExportBuildAndroidMKGenerator()
  17. {
  18. this->LG = nullptr;
  19. this->ExportSet = nullptr;
  20. }
  21. void cmExportBuildAndroidMKGenerator::GenerateImportHeaderCode(
  22. std::ostream& os, const std::string&)
  23. {
  24. os << "LOCAL_PATH := $(call my-dir)\n\n";
  25. }
  26. void cmExportBuildAndroidMKGenerator::GenerateImportFooterCode(std::ostream&)
  27. {
  28. }
  29. void cmExportBuildAndroidMKGenerator::GenerateExpectedTargetsCode(
  30. std::ostream&, const std::string&)
  31. {
  32. }
  33. void cmExportBuildAndroidMKGenerator::GenerateImportTargetCode(
  34. std::ostream& os, cmGeneratorTarget const* target,
  35. cmStateEnums::TargetType /*targetType*/)
  36. {
  37. std::string targetName = this->Namespace;
  38. targetName += target->GetExportName();
  39. os << "include $(CLEAR_VARS)\n";
  40. os << "LOCAL_MODULE := ";
  41. os << targetName << "\n";
  42. os << "LOCAL_SRC_FILES := ";
  43. std::string path = cmSystemTools::ConvertToOutputPath(target->GetFullPath());
  44. os << path << "\n";
  45. }
  46. void cmExportBuildAndroidMKGenerator::GenerateImportPropertyCode(
  47. std::ostream&, const std::string&, cmGeneratorTarget const*,
  48. ImportPropertyMap const&)
  49. {
  50. }
  51. void cmExportBuildAndroidMKGenerator::GenerateMissingTargetsCheckCode(
  52. std::ostream&, const std::vector<std::string>&)
  53. {
  54. }
  55. void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
  56. const cmGeneratorTarget* target, std::ostream& os,
  57. const ImportPropertyMap& properties)
  58. {
  59. std::string config;
  60. if (!this->Configurations.empty()) {
  61. config = this->Configurations[0];
  62. }
  63. cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
  64. target, os, properties, cmExportBuildAndroidMKGenerator::BUILD, config);
  65. }
  66. void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
  67. const cmGeneratorTarget* target, std::ostream& os,
  68. const ImportPropertyMap& properties, GenerateType type,
  69. std::string const& config)
  70. {
  71. const bool newCMP0022Behavior =
  72. target->GetPolicyStatusCMP0022() != cmPolicies::WARN &&
  73. target->GetPolicyStatusCMP0022() != cmPolicies::OLD;
  74. if (!newCMP0022Behavior) {
  75. std::ostringstream w;
  76. if (type == cmExportBuildAndroidMKGenerator::BUILD) {
  77. w << "export(TARGETS ... ANDROID_MK) called with policy CMP0022";
  78. } else {
  79. w << "install( EXPORT_ANDROID_MK ...) called with policy CMP0022";
  80. }
  81. w << " set to OLD for target " << target->Target->GetName() << ". "
  82. << "The export will only work with CMP0022 set to NEW.";
  83. target->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
  84. }
  85. if (!properties.empty()) {
  86. os << "LOCAL_CPP_FEATURES := rtti exceptions\n";
  87. for (auto const& property : properties) {
  88. if (property.first == "INTERFACE_COMPILE_OPTIONS") {
  89. os << "LOCAL_CPP_FEATURES += ";
  90. os << (property.second) << "\n";
  91. } else if (property.first == "INTERFACE_LINK_LIBRARIES") {
  92. std::string staticLibs;
  93. std::string sharedLibs;
  94. std::string ldlibs;
  95. cmLinkInterfaceLibraries const* linkIFace =
  96. target->GetLinkInterfaceLibraries(config, target, false);
  97. for (cmLinkItem const& item : linkIFace->Libraries) {
  98. cmGeneratorTarget const* gt = item.Target;
  99. std::string const& lib = item.AsStr();
  100. if (gt) {
  101. if (gt->GetType() == cmStateEnums::SHARED_LIBRARY ||
  102. gt->GetType() == cmStateEnums::MODULE_LIBRARY) {
  103. sharedLibs += " " + lib;
  104. } else {
  105. staticLibs += " " + lib;
  106. }
  107. } else {
  108. bool relpath = false;
  109. if (type == cmExportBuildAndroidMKGenerator::INSTALL) {
  110. relpath = lib.substr(0, 3) == "../";
  111. }
  112. // check for full path or if it already has a -l, or
  113. // in the case of an install check for relative paths
  114. // if it is full or a link library then use string directly
  115. if (cmSystemTools::FileIsFullPath(lib) ||
  116. lib.substr(0, 2) == "-l" || relpath) {
  117. ldlibs += " " + lib;
  118. // if it is not a path and does not have a -l then add -l
  119. } else if (!lib.empty()) {
  120. ldlibs += " -l" + lib;
  121. }
  122. }
  123. }
  124. if (!sharedLibs.empty()) {
  125. os << "LOCAL_SHARED_LIBRARIES :=" << sharedLibs << "\n";
  126. }
  127. if (!staticLibs.empty()) {
  128. os << "LOCAL_STATIC_LIBRARIES :=" << staticLibs << "\n";
  129. }
  130. if (!ldlibs.empty()) {
  131. os << "LOCAL_EXPORT_LDLIBS :=" << ldlibs << "\n";
  132. }
  133. } else if (property.first == "INTERFACE_INCLUDE_DIRECTORIES") {
  134. std::string includes = property.second;
  135. std::vector<std::string> includeList;
  136. cmSystemTools::ExpandListArgument(includes, includeList);
  137. os << "LOCAL_EXPORT_C_INCLUDES := ";
  138. std::string end;
  139. for (std::string const& i : includeList) {
  140. os << end << i;
  141. end = "\\\n";
  142. }
  143. os << "\n";
  144. } else if (property.first == "INTERFACE_LINK_OPTIONS") {
  145. os << "LOCAL_EXPORT_LDFLAGS := ";
  146. std::vector<std::string> linkFlagsList;
  147. cmSystemTools::ExpandListArgument(property.second, linkFlagsList);
  148. os << cmJoin(linkFlagsList, " ") << "\n";
  149. } else {
  150. os << "# " << property.first << " " << (property.second) << "\n";
  151. }
  152. }
  153. }
  154. // Tell the NDK build system if prebuilt static libraries use C++.
  155. if (target->GetType() == cmStateEnums::STATIC_LIBRARY) {
  156. cmLinkImplementation const* li = target->GetLinkImplementation(config);
  157. if (std::find(li->Languages.begin(), li->Languages.end(), "CXX") !=
  158. li->Languages.end()) {
  159. os << "LOCAL_HAS_CPP := true\n";
  160. }
  161. }
  162. switch (target->GetType()) {
  163. case cmStateEnums::SHARED_LIBRARY:
  164. case cmStateEnums::MODULE_LIBRARY:
  165. os << "include $(PREBUILT_SHARED_LIBRARY)\n";
  166. break;
  167. case cmStateEnums::STATIC_LIBRARY:
  168. os << "include $(PREBUILT_STATIC_LIBRARY)\n";
  169. break;
  170. case cmStateEnums::EXECUTABLE:
  171. case cmStateEnums::UTILITY:
  172. case cmStateEnums::OBJECT_LIBRARY:
  173. case cmStateEnums::GLOBAL_TARGET:
  174. case cmStateEnums::INTERFACE_LIBRARY:
  175. case cmStateEnums::UNKNOWN_LIBRARY:
  176. break;
  177. }
  178. os << "\n";
  179. }