/src/CMake/Source/cmExportInstallSbomGenerator.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 "cmExportInstallSbomGenerator.h" |
4 | | |
5 | | #include <functional> |
6 | | #include <map> |
7 | | #include <memory> |
8 | | #include <set> |
9 | | #include <sstream> |
10 | | #include <utility> |
11 | | #include <vector> |
12 | | |
13 | | #include <cmext/string_view> |
14 | | |
15 | | #include "cmExportSet.h" |
16 | | #include "cmFileSetMetadata.h" |
17 | | #include "cmGeneratorExpression.h" |
18 | | #include "cmGeneratorFileSet.h" |
19 | | #include "cmGeneratorTarget.h" |
20 | | #include "cmInstallExportGenerator.h" |
21 | | #include "cmInstallFileSetGenerator.h" |
22 | | #include "cmLocalGenerator.h" |
23 | | #include "cmMakefile.h" |
24 | | #include "cmMessageType.h" |
25 | | #include "cmOutputConverter.h" |
26 | | #include "cmSbomArguments.h" |
27 | | #include "cmSbomObject.h" |
28 | | #include "cmSpdx.h" |
29 | | #include "cmStateTypes.h" |
30 | | #include "cmStringAlgorithms.h" |
31 | | #include "cmSystemTools.h" |
32 | | #include "cmTarget.h" |
33 | | #include "cmTargetExport.h" |
34 | | |
35 | | cmExportInstallSbomGenerator::cmExportInstallSbomGenerator( |
36 | | cmInstallExportGenerator* iegen, cmSbomArguments args) |
37 | 0 | : cmExportSbomGenerator(std::move(args)) |
38 | 0 | , cmExportInstallFileGenerator(iegen) |
39 | 0 | { |
40 | 0 | this->SetNamespace(cmStrCat(this->GetPackageName(), "::"_s)); |
41 | 0 | } Unexecuted instantiation: cmExportInstallSbomGenerator::cmExportInstallSbomGenerator(cmInstallExportGenerator*, cmSbomArguments) Unexecuted instantiation: cmExportInstallSbomGenerator::cmExportInstallSbomGenerator(cmInstallExportGenerator*, cmSbomArguments) |
42 | | |
43 | | std::string cmExportInstallSbomGenerator::GetConfigImportFileGlob() const |
44 | 0 | { |
45 | 0 | std::string glob = cmStrCat(this->FileBase, "@*", this->FileExt); |
46 | 0 | return glob; |
47 | 0 | } |
48 | | |
49 | | std::string const& cmExportInstallSbomGenerator::GetExportName() const |
50 | 0 | { |
51 | 0 | return this->GetPackageName(); |
52 | 0 | } |
53 | | |
54 | | cm::string_view cmExportInstallSbomGenerator::GetImportPrefixWithSlash() const |
55 | 0 | { |
56 | 0 | return "@prefix@/"_s; |
57 | 0 | } |
58 | | |
59 | | bool cmExportInstallSbomGenerator::GenerateMainFile(std::ostream& os) |
60 | 0 | { |
61 | 0 | std::vector<cmTargetExport const*> allTargets; |
62 | 0 | { |
63 | 0 | auto visitor = [&](cmTargetExport const* te) { allTargets.push_back(te); }; |
64 | |
|
65 | 0 | if (!this->CollectExports(visitor)) { |
66 | 0 | return false; |
67 | 0 | } |
68 | 0 | } |
69 | 0 | cmSbomDocument doc; |
70 | 0 | doc.Graph.reserve(256); |
71 | |
|
72 | 0 | cmSpdxCreationInfo const* ci = |
73 | 0 | insert_back(doc.Graph, this->GenerateCreationInfo()); |
74 | 0 | cmSpdxDocument* project = insert_back(doc.Graph, this->GenerateSbom(ci)); |
75 | 0 | std::vector<TargetProperties> targets; |
76 | 0 | targets.reserve(allTargets.size()); |
77 | |
|
78 | 0 | for (cmTargetExport const* te : allTargets) { |
79 | 0 | cmGeneratorTarget const* gt = te->Target; |
80 | 0 | ImportPropertyMap properties; |
81 | 0 | if (!this->PopulateInterfaceProperties(te, properties)) { |
82 | 0 | return false; |
83 | 0 | } |
84 | 0 | this->PopulateLinkLibrariesProperty( |
85 | 0 | gt, cmGeneratorExpression::InstallInterface, properties); |
86 | 0 | this->PopulateInterfaceLinkLibrariesProperty( |
87 | 0 | gt, cmGeneratorExpression::InstallInterface, properties); |
88 | |
|
89 | 0 | targets.push_back(TargetProperties{ |
90 | 0 | insert_back(project->RootElements, |
91 | 0 | this->GenerateImportTarget(ci, te->Target)), |
92 | 0 | te->Target, std::move(properties) }); |
93 | 0 | } |
94 | | |
95 | 0 | for (auto const& target : targets) { |
96 | 0 | this->GenerateProperties(doc, project, ci, target, targets); |
97 | 0 | } |
98 | |
|
99 | 0 | this->WriteSbom(doc, os); |
100 | 0 | return true; |
101 | 0 | } |
102 | | |
103 | | void cmExportInstallSbomGenerator::GenerateImportTargetsConfig( |
104 | | std::ostream& os, std::string const& config, std::string const& suffix) |
105 | 0 | { |
106 | 0 | cmSbomDocument doc; |
107 | 0 | doc.Graph.reserve(256); |
108 | |
|
109 | 0 | cmSpdxCreationInfo const* ci = |
110 | 0 | insert_back(doc.Graph, this->GenerateCreationInfo()); |
111 | 0 | cmSpdxDocument* project = insert_back(doc.Graph, this->GenerateSbom(ci)); |
112 | |
|
113 | 0 | std::vector<TargetProperties> targets; |
114 | 0 | std::string cfg = (config.empty() ? "noconfig" : config); |
115 | |
|
116 | 0 | for (auto const& te : this->GetExportSet()->GetTargetExports()) { |
117 | 0 | ImportPropertyMap properties; |
118 | 0 | std::set<std::string> importedLocations; |
119 | |
|
120 | 0 | if (this->GetExportTargetType(te.get()) != |
121 | 0 | cmStateEnums::INTERFACE_LIBRARY) { |
122 | 0 | this->PopulateImportProperties(config, suffix, te.get(), properties, |
123 | 0 | importedLocations); |
124 | 0 | } |
125 | 0 | this->PopulateInterfaceProperties(te.get(), properties); |
126 | 0 | this->PopulateInterfaceLinkLibrariesProperty( |
127 | 0 | te->Target, cmGeneratorExpression::InstallInterface, properties); |
128 | 0 | this->PopulateLinkLibrariesProperty( |
129 | 0 | te->Target, cmGeneratorExpression::InstallInterface, properties); |
130 | |
|
131 | 0 | targets.push_back(TargetProperties{ |
132 | 0 | insert_back(project->RootElements, |
133 | 0 | this->GenerateImportTarget(ci, te->Target)), |
134 | 0 | te->Target, std::move(properties) }); |
135 | 0 | } |
136 | |
|
137 | 0 | for (auto const& target : targets) { |
138 | 0 | this->GenerateProperties(doc, project, ci, target, targets); |
139 | 0 | } |
140 | |
|
141 | 0 | this->WriteSbom(doc, os); |
142 | 0 | } |
143 | | |
144 | | std::string cmExportInstallSbomGenerator::GenerateImportPrefix() const |
145 | 0 | { |
146 | 0 | std::string expDest = this->IEGen->GetDestination(); |
147 | 0 | if (cmSystemTools::FileIsFullPath(expDest)) { |
148 | 0 | std::string const& installPrefix = |
149 | 0 | this->IEGen->GetLocalGenerator()->GetMakefile()->GetSafeDefinition( |
150 | 0 | "CMAKE_INSTALL_PREFIX"); |
151 | 0 | if (cmHasPrefix(expDest, installPrefix)) { |
152 | 0 | auto n = installPrefix.length(); |
153 | 0 | while (n < expDest.length() && expDest[n] == '/') { |
154 | 0 | ++n; |
155 | 0 | } |
156 | 0 | expDest = expDest.substr(n); |
157 | 0 | } else { |
158 | 0 | this->ReportError( |
159 | 0 | cmStrCat("install(SBOM \"", this->GetExportName(), |
160 | 0 | "\" ...) specifies DESTINATION \"", expDest, |
161 | 0 | "\" which is not a subdirectory of the install prefix.")); |
162 | 0 | return {}; |
163 | 0 | } |
164 | 0 | } |
165 | | |
166 | 0 | if (expDest.empty()) { |
167 | 0 | return this->GetInstallPrefix(); |
168 | 0 | } |
169 | 0 | return cmStrCat(this->GetImportPrefixWithSlash(), expDest); |
170 | 0 | } |
171 | | |
172 | | void cmExportInstallSbomGenerator::HandleMissingTarget( |
173 | | std::string& /* link_libs */, cmGeneratorTarget const* /* depender */, |
174 | | cmGeneratorTarget* /* dependee */) |
175 | 0 | { |
176 | 0 | } |
177 | | |
178 | | bool cmExportInstallSbomGenerator::CheckInterfaceDirs( |
179 | | std::string const& /* prepro */, cmGeneratorTarget const* /* target */, |
180 | | std::string const& /* prop */) const |
181 | 0 | { |
182 | 0 | return true; |
183 | 0 | } |
184 | | |
185 | | std::string cmExportInstallSbomGenerator::InstallNameDir( |
186 | | cmGeneratorTarget const* target, std::string const& config) |
187 | 0 | { |
188 | 0 | std::string install_name_dir; |
189 | |
|
190 | 0 | cmMakefile* mf = target->Target->GetMakefile(); |
191 | 0 | if (mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) { |
192 | 0 | install_name_dir = |
193 | 0 | target->GetInstallNameDirForInstallTree(config, "@prefix@"); |
194 | 0 | } |
195 | |
|
196 | 0 | return install_name_dir; |
197 | 0 | } |
198 | | |
199 | | std::string cmExportInstallSbomGenerator::GetCxxModulesDirectory() const |
200 | 0 | { |
201 | 0 | return {}; |
202 | 0 | } |
203 | | |
204 | | void cmExportInstallSbomGenerator::GenerateCxxModuleConfigInformation( |
205 | | std::string const&, std::ostream&) const |
206 | 0 | { |
207 | 0 | } |
208 | | |
209 | | std::string cmExportInstallSbomGenerator::GetCxxModuleFile( |
210 | | std::string const& /* name */) const |
211 | 0 | { |
212 | 0 | return {}; |
213 | 0 | } |
214 | | |
215 | | cm::optional<std::string> cmExportInstallSbomGenerator::GetFileSetDirectory( |
216 | | cmGeneratorTarget* gte, cmTargetExport const* te, |
217 | | cmGeneratorFileSet const* fileSet, cm::optional<std::string> const& config) |
218 | 0 | { |
219 | 0 | cmGeneratorExpression ge(*gte->Makefile->GetCMakeInstance()); |
220 | 0 | auto cge = |
221 | 0 | ge.Parse(te->FileSetGenerators.at(fileSet->GetName())->GetDestination()); |
222 | |
|
223 | 0 | std::string const unescapedDest = |
224 | 0 | cge->Evaluate(gte->LocalGenerator, config.value_or(""), gte); |
225 | 0 | bool const isConfigDependent = cge->GetHadContextSensitiveCondition(); |
226 | |
|
227 | 0 | if (config && !isConfigDependent) { |
228 | 0 | return {}; |
229 | 0 | } |
230 | | |
231 | 0 | std::string const& type = fileSet->GetType(); |
232 | 0 | if (config && (type == cm::FileSetMetadata::CXX_MODULES)) { |
233 | 0 | cmMakefile* mf = gte->LocalGenerator->GetMakefile(); |
234 | 0 | std::ostringstream e; |
235 | 0 | e << "The \"" << gte->GetName() << "\" target's interface file set \"" |
236 | 0 | << fileSet->GetName() << "\" of type \"" << type |
237 | 0 | << "\" contains context-sensitive base file entries which is not " |
238 | 0 | "supported."; |
239 | 0 | mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); |
240 | 0 | return {}; |
241 | 0 | } |
242 | | |
243 | 0 | cm::optional<std::string> dest = cmOutputConverter::EscapeForCMake( |
244 | 0 | unescapedDest, cmOutputConverter::WrapQuotes::NoWrap); |
245 | |
|
246 | 0 | if (!cmSystemTools::FileIsFullPath(unescapedDest)) { |
247 | 0 | dest = cmStrCat("@prefix@/"_s, *dest); |
248 | 0 | } |
249 | |
|
250 | 0 | return dest; |
251 | 0 | } |