Coverage Report

Created: 2026-02-09 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}