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"
10 #include <cmext/algorithm>
12 #include "cmGeneratorTarget.h"
13 #include "cmLinkItem.h"
15 #include "cmMakefile.h"
16 #include "cmMessageType.h"
17 #include "cmPolicies.h"
18 #include "cmStateTypes.h"
19 #include "cmStringAlgorithms.h"
20 #include "cmSystemTools.h"
23 cmExportBuildAndroidMKGenerator::cmExportBuildAndroidMKGenerator()
26 this->ExportSet
= nullptr;
29 void cmExportBuildAndroidMKGenerator::GenerateImportHeaderCode(
30 std::ostream
& os
, const std::string
&)
32 os
<< "LOCAL_PATH := $(call my-dir)\n\n";
35 void cmExportBuildAndroidMKGenerator::GenerateImportFooterCode(std::ostream
&)
39 void cmExportBuildAndroidMKGenerator::GenerateExpectedTargetsCode(
40 std::ostream
&, const std::string
&)
44 void cmExportBuildAndroidMKGenerator::GenerateImportTargetCode(
45 std::ostream
& os
, cmGeneratorTarget
const* target
,
46 cmStateEnums::TargetType
/*targetType*/)
48 std::string targetName
= cmStrCat(this->Namespace
, target
->GetExportName());
49 os
<< "include $(CLEAR_VARS)\n";
50 os
<< "LOCAL_MODULE := ";
51 os
<< targetName
<< "\n";
52 os
<< "LOCAL_SRC_FILES := ";
53 std::string
const noConfig
; // FIXME: What config to use here?
55 cmSystemTools::ConvertToOutputPath(target
->GetFullPath(noConfig
));
59 void cmExportBuildAndroidMKGenerator::GenerateImportPropertyCode(
60 std::ostream
&, const std::string
&, const std::string
&,
61 cmGeneratorTarget
const*, ImportPropertyMap
const&, const std::string
&)
65 void cmExportBuildAndroidMKGenerator::GenerateMissingTargetsCheckCode(
70 void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
71 const cmGeneratorTarget
* target
, std::ostream
& os
,
72 const ImportPropertyMap
& properties
)
75 if (!this->Configurations
.empty()) {
76 config
= this->Configurations
[0];
78 cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
79 target
, os
, properties
, cmExportBuildAndroidMKGenerator::BUILD
, config
);
82 void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
83 const cmGeneratorTarget
* target
, std::ostream
& os
,
84 const ImportPropertyMap
& properties
, GenerateType type
,
85 std::string
const& config
)
87 const bool newCMP0022Behavior
=
88 target
->GetPolicyStatusCMP0022() != cmPolicies::WARN
&&
89 target
->GetPolicyStatusCMP0022() != cmPolicies::OLD
;
90 if (!newCMP0022Behavior
) {
92 if (type
== cmExportBuildAndroidMKGenerator::BUILD
) {
93 w
<< "export(TARGETS ... ANDROID_MK) called with policy CMP0022";
95 w
<< "install( EXPORT_ANDROID_MK ...) called with policy CMP0022";
97 w
<< " set to OLD for target " << target
->Target
->GetName() << ". "
98 << "The export will only work with CMP0022 set to NEW.";
99 target
->Makefile
->IssueMessage(MessageType::AUTHOR_WARNING
, w
.str());
101 if (!properties
.empty()) {
102 os
<< "LOCAL_CPP_FEATURES := rtti exceptions\n";
103 for (auto const& property
: properties
) {
104 if (property
.first
== "INTERFACE_COMPILE_OPTIONS") {
105 os
<< "LOCAL_CPP_FEATURES += ";
106 os
<< (property
.second
) << "\n";
107 } else if (property
.first
== "INTERFACE_LINK_LIBRARIES") {
108 std::string staticLibs
;
109 std::string sharedLibs
;
111 cmLinkInterfaceLibraries
const* linkIFace
=
112 target
->GetLinkInterfaceLibraries(config
, target
,
113 cmGeneratorTarget::UseTo::Link
);
114 for (cmLinkItem
const& item
: linkIFace
->Libraries
) {
115 cmGeneratorTarget
const* gt
= item
.Target
;
116 std::string
const& lib
= item
.AsStr();
119 if (gt
->GetType() == cmStateEnums::SHARED_LIBRARY
||
120 gt
->GetType() == cmStateEnums::MODULE_LIBRARY
) {
121 sharedLibs
+= " " + lib
;
123 staticLibs
+= " " + lib
;
126 bool relpath
= false;
127 if (type
== cmExportBuildAndroidMKGenerator::INSTALL
) {
128 relpath
= cmHasLiteralPrefix(lib
, "../");
130 // check for full path or if it already has a -l, or
131 // in the case of an install check for relative paths
132 // if it is full or a link library then use string directly
133 if (cmSystemTools::FileIsFullPath(lib
) ||
134 cmHasLiteralPrefix(lib
, "-l") || relpath
) {
136 // if it is not a path and does not have a -l then add -l
137 } else if (!lib
.empty()) {
138 ldlibs
+= " -l" + lib
;
142 if (!sharedLibs
.empty()) {
143 os
<< "LOCAL_SHARED_LIBRARIES :=" << sharedLibs
<< "\n";
145 if (!staticLibs
.empty()) {
146 os
<< "LOCAL_STATIC_LIBRARIES :=" << staticLibs
<< "\n";
148 if (!ldlibs
.empty()) {
149 os
<< "LOCAL_EXPORT_LDLIBS :=" << ldlibs
<< "\n";
151 } else if (property
.first
== "INTERFACE_INCLUDE_DIRECTORIES") {
152 std::string includes
= property
.second
;
153 cmList includeList
{ includes
};
154 os
<< "LOCAL_EXPORT_C_INCLUDES := ";
156 for (std::string
const& i
: includeList
) {
161 } else if (property
.first
== "INTERFACE_LINK_OPTIONS") {
162 os
<< "LOCAL_EXPORT_LDFLAGS := ";
163 cmList linkFlagsList
{ property
.second
};
164 os
<< linkFlagsList
.join(" ") << "\n";
166 os
<< "# " << property
.first
<< " " << (property
.second
) << "\n";
171 // Tell the NDK build system if prebuilt static libraries use C++.
172 if (target
->GetType() == cmStateEnums::STATIC_LIBRARY
) {
173 cmLinkImplementation
const* li
=
174 target
->GetLinkImplementation(config
, cmGeneratorTarget::UseTo::Link
);
175 if (cm::contains(li
->Languages
, "CXX")) {
176 os
<< "LOCAL_HAS_CPP := true\n";
180 switch (target
->GetType()) {
181 case cmStateEnums::SHARED_LIBRARY
:
182 case cmStateEnums::MODULE_LIBRARY
:
183 os
<< "include $(PREBUILT_SHARED_LIBRARY)\n";
185 case cmStateEnums::STATIC_LIBRARY
:
186 os
<< "include $(PREBUILT_STATIC_LIBRARY)\n";
188 case cmStateEnums::EXECUTABLE
:
189 case cmStateEnums::UTILITY
:
190 case cmStateEnums::OBJECT_LIBRARY
:
191 case cmStateEnums::GLOBAL_TARGET
:
192 case cmStateEnums::INTERFACE_LIBRARY
:
193 case cmStateEnums::UNKNOWN_LIBRARY
: