cmExportBuildAndroidMKGenerator.cxx 6.8 KB

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