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