cmExportBuildAndroidMKGenerator.cxx 7.0 KB

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