cmExportAndroidMKGenerator.cxx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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 "cmExportAndroidMKGenerator.h"
  4. #include <sstream>
  5. #include <utility>
  6. #include <vector>
  7. #include <cmext/algorithm>
  8. #include <cmext/string_view>
  9. #include "cmGeneratorTarget.h"
  10. #include "cmLinkItem.h"
  11. #include "cmList.h"
  12. #include "cmMakefile.h"
  13. #include "cmMessageType.h"
  14. #include "cmPolicies.h"
  15. #include "cmStateTypes.h"
  16. #include "cmStringAlgorithms.h"
  17. #include "cmSystemTools.h"
  18. #include "cmTarget.h"
  19. cmExportAndroidMKGenerator::cmExportAndroidMKGenerator() = default;
  20. cm::string_view cmExportAndroidMKGenerator::GetImportPrefixWithSlash() const
  21. {
  22. return "$(_IMPORT_PREFIX)/"_s;
  23. }
  24. bool cmExportAndroidMKGenerator::GenerateImportFile(std::ostream& os)
  25. {
  26. if (!this->AppendMode) {
  27. // Start with the import file header.
  28. this->GenerateImportHeaderCode(os);
  29. }
  30. // Create all the imported targets.
  31. std::stringstream mainFileBuffer;
  32. bool result = this->GenerateMainFile(mainFileBuffer);
  33. // Write cached import code.
  34. os << mainFileBuffer.rdbuf();
  35. return result;
  36. }
  37. void cmExportAndroidMKGenerator::GenerateInterfaceProperties(
  38. cmGeneratorTarget const* target, std::ostream& os,
  39. ImportPropertyMap const& properties)
  40. {
  41. std::string const config =
  42. (this->Configurations.empty() ? std::string{} : this->Configurations[0]);
  43. GenerateType const type = this->GetGenerateType();
  44. bool const newCMP0022Behavior =
  45. target->GetPolicyStatusCMP0022() != cmPolicies::WARN &&
  46. target->GetPolicyStatusCMP0022() != cmPolicies::OLD;
  47. if (!newCMP0022Behavior) {
  48. std::ostringstream w;
  49. if (type == BUILD) {
  50. w << "export(TARGETS ... ANDROID_MK) called with policy CMP0022";
  51. } else {
  52. w << "install( EXPORT_ANDROID_MK ...) called with policy CMP0022";
  53. }
  54. w << " set to OLD for target " << target->Target->GetName() << ". "
  55. << "The export will only work with CMP0022 set to NEW.";
  56. target->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
  57. }
  58. if (!properties.empty()) {
  59. os << "LOCAL_CPP_FEATURES := rtti exceptions\n";
  60. for (auto const& property : properties) {
  61. if (property.first == "INTERFACE_COMPILE_OPTIONS") {
  62. os << "LOCAL_CPP_FEATURES += ";
  63. os << (property.second) << "\n";
  64. } else if (property.first == "INTERFACE_LINK_LIBRARIES") {
  65. std::string staticLibs;
  66. std::string sharedLibs;
  67. std::string ldlibs;
  68. cmLinkInterfaceLibraries const* linkIFace =
  69. target->GetLinkInterfaceLibraries(config, target,
  70. cmGeneratorTarget::UseTo::Link);
  71. for (cmLinkItem const& item : linkIFace->Libraries) {
  72. cmGeneratorTarget const* gt = item.Target;
  73. std::string const& lib = item.AsStr();
  74. if (gt) {
  75. if (gt->GetType() == cmStateEnums::SHARED_LIBRARY ||
  76. gt->GetType() == cmStateEnums::MODULE_LIBRARY) {
  77. sharedLibs += " " + lib;
  78. } else {
  79. staticLibs += " " + lib;
  80. }
  81. } else {
  82. bool relpath = false;
  83. if (type == INSTALL) {
  84. relpath = cmHasLiteralPrefix(lib, "../");
  85. }
  86. // check for full path or if it already has a -l, or
  87. // in the case of an install check for relative paths
  88. // if it is full or a link library then use string directly
  89. if (cmSystemTools::FileIsFullPath(lib) ||
  90. cmHasLiteralPrefix(lib, "-l") || relpath) {
  91. ldlibs += " " + lib;
  92. // if it is not a path and does not have a -l then add -l
  93. } else if (!lib.empty()) {
  94. ldlibs += " -l" + lib;
  95. }
  96. }
  97. }
  98. if (!sharedLibs.empty()) {
  99. os << "LOCAL_SHARED_LIBRARIES :=" << sharedLibs << "\n";
  100. }
  101. if (!staticLibs.empty()) {
  102. os << "LOCAL_STATIC_LIBRARIES :=" << staticLibs << "\n";
  103. }
  104. if (!ldlibs.empty()) {
  105. os << "LOCAL_EXPORT_LDLIBS :=" << ldlibs << "\n";
  106. }
  107. } else if (property.first == "INTERFACE_INCLUDE_DIRECTORIES") {
  108. std::string includes = property.second;
  109. cmList includeList{ includes };
  110. os << "LOCAL_EXPORT_C_INCLUDES := ";
  111. std::string end;
  112. for (std::string const& i : includeList) {
  113. os << end << i;
  114. end = "\\\n";
  115. }
  116. os << "\n";
  117. } else if (property.first == "INTERFACE_LINK_OPTIONS") {
  118. os << "LOCAL_EXPORT_LDFLAGS := ";
  119. cmList linkFlagsList{ property.second };
  120. os << linkFlagsList.join(" ") << "\n";
  121. } else {
  122. os << "# " << property.first << " " << (property.second) << "\n";
  123. }
  124. }
  125. }
  126. // Tell the NDK build system if prebuilt static libraries use C++.
  127. if (target->GetType() == cmStateEnums::STATIC_LIBRARY) {
  128. cmLinkImplementation const* li =
  129. target->GetLinkImplementation(config, cmGeneratorTarget::UseTo::Link);
  130. if (cm::contains(li->Languages, "CXX")) {
  131. os << "LOCAL_HAS_CPP := true\n";
  132. }
  133. }
  134. switch (target->GetType()) {
  135. case cmStateEnums::SHARED_LIBRARY:
  136. case cmStateEnums::MODULE_LIBRARY:
  137. os << "include $(PREBUILT_SHARED_LIBRARY)\n";
  138. break;
  139. case cmStateEnums::STATIC_LIBRARY:
  140. os << "include $(PREBUILT_STATIC_LIBRARY)\n";
  141. break;
  142. case cmStateEnums::EXECUTABLE:
  143. case cmStateEnums::UTILITY:
  144. case cmStateEnums::OBJECT_LIBRARY:
  145. case cmStateEnums::GLOBAL_TARGET:
  146. case cmStateEnums::INTERFACE_LIBRARY:
  147. case cmStateEnums::UNKNOWN_LIBRARY:
  148. break;
  149. }
  150. os << "\n";
  151. }