cmake_file_api/objects/codemodel_v2/target.rs
1#![allow(clippy::module_name_repetitions)]
2#![allow(clippy::redundant_closure_for_method_calls)]
3
4use super::backtrace_graph::BacktraceGraph;
5use serde::{Deserialize, Serialize};
6use std::path::PathBuf;
7
8/// A codemodel "target" object is referenced by a "codemodel" version 2 object's targets array.
9#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
10#[serde(rename_all = "camelCase")]
11#[non_exhaustive]
12pub struct Target {
13 /// A string specifying the logical name of the target.
14 pub name: String,
15
16 /// A string uniquely identifying the target.
17 /// The format is unspecified and should not be interpreted by clients.
18 pub id: String,
19
20 /// A string specifying the type of the target.
21 /// The value is one of:
22 /// * EXECUTABLE
23 /// * STATIC_LIBRARY
24 /// * SHARED_LIBRARY
25 /// * MODULE_LIBRARY
26 /// * OBJECT_LIBRARY
27 /// * INTERFACE_LIBRARY
28 /// * UTILITY
29 #[serde(rename = "type")]
30 pub type_name: String,
31
32 /// Optional member that is present when a CMake language backtrace to the command in
33 /// the source code that created the target is available.
34 /// The value is an unsigned integer 0-based index into the backtraceGraph member's nodes array.
35 pub backtrace: Option<usize>,
36
37 /// Optional member that is present when the FOLDER target property is set.
38 pub folder: Option<Folder>,
39
40 /// Paths to the target's build and source directories.
41 pub paths: TargetPaths,
42
43 /// Optional member that is present for executable and library targets that are linked or archived into a single primary artifact.
44 /// The value is a string specifying the file name of that artifact on disk.
45 pub name_on_disk: Option<String>,
46
47 /// Optional member that is present for executable and library targets that
48 /// produce artifacts on disk meant for consumption by dependents.
49 /// The value is a JSON array of entries corresponding to the artifacts.
50 #[serde(default)]
51 pub artifacts: Vec<Artifact>,
52
53 /// Optional member that is present with boolean value true if the target is provided by CMake's
54 /// build system generator rather than by a command in the source code.
55 #[serde(default)]
56 pub is_generator_provided: bool,
57
58 /// Optional member that is present when the target has an install() rule.
59 pub install: Option<Install>,
60
61 /// Optional member that is present on executable targets that have at least one launcher specified by the project.
62 #[serde(default)]
63 pub launchers: Vec<Launcher>,
64
65 /// Optional member that is present for executables and shared library targets that link into a runtime binary.
66 pub link: Option<Link>,
67
68 /// Optional member that is present for static library targets.
69 pub archive: Option<Archive>,
70
71 /// Optional member that is present when the target depends on other targets.
72 #[serde(default)]
73 pub dependencies: Vec<Dependency>,
74
75 /// target's file sets
76 #[serde(default)]
77 pub file_sets: Vec<FileSet>,
78
79 /// target's sources
80 #[serde(default)]
81 pub sources: Vec<Source>,
82
83 /// Optional member that is present when sources are grouped together by the source_group() command or by default.
84 #[serde(default)]
85 pub source_groups: Vec<SourceGroup>,
86
87 /// Optional member that is present when the target has sources that compile.
88 #[serde(default)]
89 pub compile_groups: Vec<CompileGroup>,
90
91 /// A "codemodel" version 2 "backtrace graph" whose nodes are referenced from backtrace members elsewhere in this "target" object.
92 pub backtrace_graph: BacktraceGraph,
93}
94
95#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
96#[serde(rename_all = "camelCase")]
97#[non_exhaustive]
98pub struct Folder {
99 /// A string specifying the name of the target folder.
100 pub name: String,
101}
102
103#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
104#[serde(rename_all = "camelCase")]
105#[non_exhaustive]
106pub struct TargetPaths {
107 /// Path to the target's source directory, represented with forward slashes.
108 /// If the directory is inside the top-level source directory then the path is specified
109 /// relative to that directory (with . for the top-level source directory itself).
110 /// Otherwise, the path is absolute.
111 pub build: PathBuf,
112
113 /// Path to the target's build directory, represented with forward slashes.
114 /// If the directory is inside the top-level build directory then the path is specified
115 /// relative to that directory (with . for the top-level build directory itself).
116 /// Otherwise, the path is absolute.
117 pub source: PathBuf,
118}
119
120#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
121#[serde(rename_all = "camelCase")]
122#[non_exhaustive]
123pub struct Artifact {
124 /// Path to the file on disk, represented with forward slashes.
125 /// If the file is inside the top-level build directory then the path is specified
126 /// relative to that directory.
127 /// Otherwise, the path is absolute.
128 pub path: PathBuf,
129}
130#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
131#[serde(rename_all = "camelCase")]
132#[non_exhaustive]
133pub struct Install {
134 /// installation prefix
135 pub prefix: Prefix,
136
137 /// installation destination paths
138 #[serde(default)]
139 pub destinations: Vec<Destination>,
140}
141#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
142#[serde(rename_all = "camelCase")]
143#[non_exhaustive]
144pub struct Prefix {
145 /// Path value of CMAKE_INSTALL_PREFIX.
146 pub path: PathBuf,
147}
148#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
149#[serde(rename_all = "camelCase")]
150#[non_exhaustive]
151pub struct Destination {
152 /// Path of the installation destination path.
153 /// The path may be absolute or relative to the install prefix.
154 pub path: PathBuf,
155
156 /// Optional member that is present when a CMake language backtrace to the install() command invocation
157 /// that specified this destination is available.
158 /// The value is an unsigned integer 0-based index into the backtraceGraph member's nodes array.
159 pub backtrace: Option<usize>,
160}
161
162#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
163#[serde(rename_all = "camelCase")]
164#[non_exhaustive]
165pub struct Launcher {
166 /// string specifying the path to the launcher on disk, represented with forward slashes.
167 /// If the file is inside the top-level source directory then the path is specified relative to that directory.
168 pub command: String,
169
170 /// Optional member that is present when the launcher command has arguments preceding the executable to be launched.
171 #[serde(default)]
172 pub arguments: Vec<String>,
173
174 /// A string specifying the type of launcher.
175 /// The value is one of the following:
176 /// * emulator: An emulator for the target platform when cross-compiling. See the CROSSCOMPILING_EMULATOR target property.
177 /// * test: A start program for the execution of tests. See the TEST_LAUNCHER target property.
178 pub launcher_type: String,
179}
180
181#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
182#[serde(rename_all = "camelCase")]
183#[non_exhaustive]
184pub struct Link {
185 /// A string specifying the language (e.g. C, CXX, Fortran) of the toolchain is used to invoke the linker.
186 pub language: String,
187
188 /// Optional member that is present when fragments of the link command line invocation are available.
189 #[serde(default)]
190 pub command_fragments: Vec<CommandFragment>,
191
192 /// True when link-time optimization (a.k.a. interprocedural optimization or link-time code generation) is enabled.
193 #[serde(default)]
194 pub lto: bool,
195
196 /// Optional member that is present when the CMAKE_SYSROOT_LINK or CMAKE_SYSROOT variable is defined.
197 #[serde(default)]
198 pub sysroot: Option<SysRootPath>,
199}
200
201#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
202#[serde(rename_all = "camelCase")]
203#[non_exhaustive]
204pub struct CommandFragment {
205 /// A string specifying a fragment of the link command line invocation.
206 /// The value is encoded in the build system's native shell format.
207 pub fragment: String,
208
209 /// A string specifying the role of the fragment's content:
210 /// * flags: archiver flags
211 pub role: String,
212}
213
214#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
215#[serde(rename_all = "camelCase")]
216#[non_exhaustive]
217pub struct SysRootPath {
218 /// Absolute path to the sysroot, represented with forward slashes.
219 pub path: PathBuf,
220}
221
222#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
223#[serde(rename_all = "camelCase")]
224#[non_exhaustive]
225pub struct Archive {
226 /// fragments of the archiver command line invocation.
227 #[serde(default)]
228 pub command_fragments: Vec<CommandFragment>,
229
230 /// True when link-time optimization (a.k.a. interprocedural optimization or link-time code generation) is enabled.
231 #[serde(default)]
232 pub lto: bool,
233}
234
235#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
236#[serde(rename_all = "camelCase")]
237#[non_exhaustive]
238pub struct Dependency {
239 /// A string uniquely identifying the target on which this target depends.
240 /// This matches the main id member of the other target.
241 pub id: String,
242
243 /// Optional member that is present when a CMake language backtrace to the add_dependencies(), target_link_libraries(),
244 /// or other command invocation that created this dependency is available.
245 /// The value is an unsigned integer 0-based index into the backtraceGraph member's nodes array.
246 pub backtrace: Option<usize>,
247}
248
249#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
250#[serde(rename_all = "camelCase")]
251#[non_exhaustive]
252pub struct FileSet {
253 /// A string specifying the name of the file set.
254 pub name: String,
255
256 /// A string specifying the type of the file set. See target_sources() supported file set types.
257 #[serde(rename = "type")]
258 pub type_name: String,
259
260 /// A string specifying the visibility of the file set; one of PUBLIC, PRIVATE, or INTERFACE.
261 pub visibility: String,
262
263 /// Base directories containing sources in the file set.
264 /// If the directory is inside the top-level source directory then the path is specified
265 /// relative to that directory.
266 /// Otherwise, the path is absolute.
267 pub base_directories: Vec<String>,
268}
269
270#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
271#[serde(rename_all = "camelCase")]
272#[non_exhaustive]
273pub struct Source {
274 /// Path to the source file on disk, represented with forward slashes.
275 /// If the file is inside the top-level source directory then the path is specified relative to that directory.
276 /// Otherwise the path is absolute.
277 pub path: PathBuf,
278
279 /// Optional member that is present when the source is compiled.
280 /// The value is an unsigned integer 0-based index into the compileGroups array.
281 pub compile_group_index: Option<usize>,
282
283 /// Optional member that is present when the source is part of a source group either via the source_group() command or by default.
284 /// The value is an unsigned integer 0-based index into the sourceGroups array.
285 pub source_group_index: Option<usize>,
286
287 /// True if the source is GENERATED.
288 #[serde(default)]
289 pub is_generated: bool,
290
291 /// Optional member that is present when the source is part of a file set.
292 /// The value is an unsigned integer 0-based index into the fileSets array.
293 /// This field was added in codemodel version 2.5.
294 pub file_set_index: Option<usize>,
295
296 /// Optional member that is present when a CMake language backtrace to the target_sources(), add_executable(), add_library(),
297 /// add_custom_target(), or other command invocation that added this source to the target is available.
298 /// The value is an unsigned integer 0-based index into the backtraceGraph member's nodes array.
299 pub backtrace: Option<usize>,
300}
301
302#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
303#[serde(rename_all = "camelCase")]
304#[non_exhaustive]
305pub struct SourceGroup {
306 /// A string specifying the name of the source group.
307 pub name: String,
308
309 /// Indices to sources belonging to the group.
310 /// Each entry is an unsigned integer 0-based index into the main sources array for the target.
311 pub source_indexes: Vec<usize>,
312}
313
314#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
315#[serde(rename_all = "camelCase")]
316#[non_exhaustive]
317pub struct CompileGroup {
318 /// Indices to sources belonging to the compile-group.
319 pub source_indexes: Vec<usize>,
320
321 /// A string specifying the language (e.g. C, CXX, Fortran) of the toolchain is used to compile the source file.
322 pub language: String,
323
324 /// Optional member that is present when the language standard is set explicitly (e.g. via CXX_STANDARD) or
325 /// implicitly by compile features.
326 /// This field was added in codemodel version 2.2.
327 pub language_standard: Option<LanguageStandard>,
328
329 /// Optional member that is present when fragments of the compiler command line invocation are available.
330 #[serde(default)]
331 pub compile_command_fragments: Vec<CompileCommandFragment>,
332
333 /// include directories.
334 #[serde(default)]
335 pub includes: Vec<Include>,
336
337 /// available frameworks (Apple)
338 /// This field was added in codemodel version 2.6.
339 #[serde(default)]
340 pub frameworks: Vec<Framework>,
341
342 /// precompiled headers
343 #[serde(default)]
344 pub precompile_headers: Vec<PrecompileHeader>,
345
346 /// defines
347 #[serde(default)]
348 pub defines: Vec<Define>,
349
350 /// Optional member that is present when the `CMAKE_SYSROOT_COMPILE` or `CMAKE_SYSROOT` variable is defined.
351 pub sysroot: Option<SysRootPath>,
352}
353
354#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
355#[serde(rename_all = "camelCase")]
356#[non_exhaustive]
357pub struct LanguageStandard {
358 /// Optional member that is present when a CMake language backtrace to the `<LANG>_STANDARD` setting is available.
359 /// If the language standard was set implicitly by compile features those are used as the backtrace(s).
360 /// It's possible for multiple compile features to require the same language standard so there could be multiple backtraces.
361 /// Each entry being an unsigned integer 0-based index into the backtraceGraph member's nodes array.
362 #[serde(default)]
363 pub backtraces: Vec<usize>,
364
365 /// String representing the language standard.
366 pub standard: String,
367}
368
369#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
370#[serde(rename_all = "camelCase")]
371#[non_exhaustive]
372pub struct CompileCommandFragment {
373 /// A string specifying a fragment of the compile command line invocation.
374 /// The value is encoded in the build system's native shell format.
375 pub fragment: String,
376}
377
378#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
379#[serde(rename_all = "camelCase")]
380#[non_exhaustive]
381pub struct Include {
382 /// Path to the include directory, represented with forward slashes.
383 pub path: PathBuf,
384
385 /// True if the include directory is marked as a system include directory.
386 #[serde(default)]
387 pub is_system: bool,
388
389 /// Optional member that is present when a CMake language backtrace to the target_include_directories() or
390 /// other command invocation that added this include directory is available.
391 /// The value is an unsigned integer 0-based index into the backtraceGraph member's nodes array.
392 pub backtrace: Option<usize>,
393}
394#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
395#[serde(rename_all = "camelCase")]
396#[non_exhaustive]
397pub struct Framework {
398 /// Path to the framework directory, represented with forward slashes.
399 pub path: PathBuf,
400
401 /// True if the framework is marked as a system one.
402 #[serde(default)]
403 pub is_system: bool,
404
405 /// Optional member that is present when a CMake language backtrace to the target_link_libraries() or
406 /// other command invocation that added this framework is available.
407 /// The value is an unsigned integer 0-based index into the backtraceGraph member's nodes array.
408 pub backtrace: Option<usize>,
409}
410
411#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
412#[serde(rename_all = "camelCase")]
413#[non_exhaustive]
414pub struct PrecompileHeader {
415 /// Full path to the precompile header file.
416 pub header: PathBuf,
417
418 /// Optional member that is present when a CMake language backtrace to the target_precompile_headers() or
419 /// other command invocation that added this precompiled header is available.
420 /// The value is an unsigned integer 0-based index into the backtraceGraph member's nodes array.
421 pub backtrace: Option<usize>,
422}
423
424#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
425#[serde(rename_all = "camelCase")]
426#[non_exhaustive]
427pub struct Define {
428 /// A string specifying the preprocessor definition in the format `<name>[=<value>]`, e.g. `DEF` or `DEF=1`.
429 pub define: String,
430
431 /// Optional member that is present when a CMake language backtrace to the target_compile_definitions() or
432 /// other command invocation that added this preprocessor definition is available.
433 /// The value is an unsigned integer 0-based index into the backtraceGraph member's nodes array.
434 pub backtrace: Option<usize>,
435}
436
437impl CompileGroup {
438 /// Returns a list of defines for the compile group
439 ///
440 /// Compile command fragments can contain defines as well (/D or -D).
441 #[must_use]
442 pub fn defines(&self) -> Vec<String> {
443 let mut defines: Vec<String> = self
444 .defines
445 .iter()
446 .map(|define| define.define.clone())
447 .collect();
448 defines.extend(self.compile_fragments().iter().filter_map(|flag| {
449 if Self::is_define(flag) {
450 flag.get(2..).map(|define| define.to_owned())
451 } else {
452 None
453 }
454 }));
455 defines
456 }
457
458 /// Returns a list of compile flags for the compile group
459 ///
460 /// Compile command fragments are split into single flags and defines (/D or -D) are filtered out.
461 #[must_use]
462 pub fn flags(&self) -> Vec<String> {
463 self.compile_fragments()
464 .iter()
465 .filter(|&flag| !Self::is_define(flag))
466 .cloned()
467 .collect()
468 }
469
470 fn is_define(flag: &str) -> bool {
471 flag.starts_with("/D") || flag.starts_with("-D")
472 }
473
474 #[must_use]
475 /// Compile command fragments are split into single flags.
476 pub fn compile_fragments(&self) -> Vec<String> {
477 self.compile_command_fragments
478 .iter()
479 .filter_map(|frag| shlex::split(&frag.fragment))
480 .flatten()
481 .collect()
482 }
483}
484
485#[cfg(test)]
486mod tests {
487 use crate::objects::codemodel_v2::target::*;
488 use crate::objects::codemodel_v2::Node;
489 use serde_json::json;
490
491 #[test]
492 fn test_target() {
493 let json = json!({
494 "backtrace" : 0,
495 "backtraceGraph" :
496 {
497 "commands" : [],
498 "files" :
499 [
500 "CMakeLists.txt"
501 ],
502 "nodes" :
503 [
504 {
505 "file" : 0
506 }
507 ]
508 },
509 "dependencies" :
510 [
511 {
512 "id" : "ZERO_CHECK::@6890427a1f51a3e7e1df"
513 },
514 {
515 "id" : "subbinary::@6890427a1f51a3e7e1df"
516 }
517 ],
518 "id" : "ALL_BUILD::@6890427a1f51a3e7e1df",
519 "isGeneratorProvided" : true,
520 "name" : "ALL_BUILD",
521 "paths" :
522 {
523 "build" : ".",
524 "source" : "."
525 },
526 "sources" : [],
527 "type" : "UTILITY"
528 }
529 );
530
531 let target = serde_json::from_value::<Target>(json).unwrap();
532 assert_eq!(
533 target,
534 Target {
535 backtrace: Some(0),
536 backtrace_graph: BacktraceGraph {
537 commands: vec![],
538 files: vec!["CMakeLists.txt".into()],
539 nodes: vec![Node {
540 file: 0,
541 ..Default::default()
542 }]
543 },
544 dependencies: vec![
545 Dependency {
546 id: "ZERO_CHECK::@6890427a1f51a3e7e1df".to_string(),
547 ..Default::default()
548 },
549 Dependency {
550 id: "subbinary::@6890427a1f51a3e7e1df".to_string(),
551 ..Default::default()
552 }
553 ],
554 id: "ALL_BUILD::@6890427a1f51a3e7e1df".to_string(),
555 is_generator_provided: true,
556 name: "ALL_BUILD".to_string(),
557 paths: TargetPaths {
558 build: ".".into(),
559 source: ".".into()
560 },
561 sources: vec![],
562 type_name: "UTILITY".to_string(),
563 ..Default::default()
564 }
565 );
566 }
567}