1// Copyright 2022 Gregory Szorc.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
89/*! Functionality for building a library containing Python */
1011use {
12crate::licensing::LicensedComponents,
13 simple_file_manifest::FileData,
14 std::{
15 collections::{BTreeMap, BTreeSet},
16 path::PathBuf,
17 },
18};
1920/// Holds state necessary to build and link a libpython.
21///
22/// Note that this context is only for producing libpython: it is very
23/// linker centric and doesn't track state like Python resources.
24#[derive(Clone, Debug, Default, PartialEq)]
25pub struct LibPythonBuildContext {
26/// Compiled flags to use when compiling the object containing Py_inittab.
27pub inittab_cflags: Option<Vec<String>>,
2829/// Include files defining Python headers.
30 ///
31 /// These are necessary to compile code that references Python types.
32pub includes: BTreeMap<PathBuf, FileData>,
3334/// Object files that will be linked together.
35pub object_files: Vec<FileData>,
3637/// Filesystem paths to add to linker search path.
38pub library_search_paths: BTreeSet<PathBuf>,
3940/// System libraries that will be linked against.
41pub system_libraries: BTreeSet<String>,
4243/// Dynamic libraries that will be linked against.
44pub dynamic_libraries: BTreeSet<String>,
4546/// Static libraries that will be linked against.
47pub static_libraries: BTreeSet<String>,
4849/// Frameworks that will be linked against.
50 ///
51 /// Used on Apple platforms.
52pub frameworks: BTreeSet<String>,
5354/// Builtin extension module initialization functions.
55 ///
56 /// Key is extension name. Value is initialization function. The
57 /// function can have the special value `NULL`.
58pub init_functions: BTreeMap<String, String>,
5960/// Holds licensing info for things being linked together.
61pub licensed_components: LicensedComponents,
62}
6364impl LibPythonBuildContext {
65/// Merge multiple `LinkingContext` together to produce an aggregate instance.
66pub fn merge(contexts: &[&Self]) -> Self {
67let mut inittab_cflags = None;
68let mut includes = BTreeMap::new();
69let mut object_files = Vec::new();
70let mut library_search_paths = BTreeSet::new();
71let mut system_libraries = BTreeSet::new();
72let mut dynamic_libraries = BTreeSet::new();
73let mut static_libraries = BTreeSet::new();
74let mut frameworks = BTreeSet::new();
75let mut init_functions = BTreeMap::new();
76let mut licensed_components = LicensedComponents::default();
7778for context in contexts {
79// Last write wins.
80if let Some(flags) = &context.inittab_cflags {
81 inittab_cflags = Some(flags.clone());
82 }
83for (k, v) in &context.includes {
84 includes.insert(k.clone(), v.clone());
85 }
86for o in &context.object_files {
87 object_files.push(o.clone());
88 }
89for p in &context.library_search_paths {
90 library_search_paths.insert(p.clone());
91 }
92for l in &context.system_libraries {
93 system_libraries.insert(l.clone());
94 }
95for l in &context.dynamic_libraries {
96 dynamic_libraries.insert(l.clone());
97 }
98for l in &context.static_libraries {
99 static_libraries.insert(l.clone());
100 }
101for f in &context.frameworks {
102 frameworks.insert(f.clone());
103 }
104for (k, v) in &context.init_functions {
105 init_functions.insert(k.clone(), v.clone());
106 }
107for c in context.licensed_components.iter_components() {
108 licensed_components.add_component(c.clone());
109 }
110 }
111112Self {
113 inittab_cflags,
114 includes,
115 object_files,
116 library_search_paths,
117 system_libraries,
118 dynamic_libraries,
119 static_libraries,
120 frameworks,
121 init_functions,
122 licensed_components,
123 }
124 }
125}