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