Skip to content

Commit b047365

Browse files
ben-ednaspoorcc
authored andcommitted
add bzl
1 parent 665940f commit b047365

1 file changed

Lines changed: 340 additions & 0 deletions

File tree

bin/pyoxidizer.bzl

Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
# This file defines how PyOxidizer application building and packaging is
2+
# performed. See PyOxidizer's documentation at
3+
# https://gregoryszorc.com/docs/pyoxidizer/stable/pyoxidizer.html for details
4+
# of this configuration file format.
5+
6+
7+
# Configuration files consist of functions which define build "targets."
8+
# This function creates a Python executable and installs it in a destination
9+
# directory.
10+
def make_exe():
11+
# Obtain the default PythonDistribution for our build target. We link
12+
# this distribution into our produced executable and extract the Python
13+
# standard library from it.
14+
dist = default_python_distribution()
15+
16+
# This function creates a `PythonPackagingPolicy` instance, which
17+
# influences how executables are built and how resources are added to
18+
# the executable. You can customize the default behavior by assigning
19+
# to attributes and calling functions.
20+
policy = dist.make_python_packaging_policy()
21+
22+
# Enable support for non-classified "file" resources to be added to
23+
# resource collections.
24+
# policy.allow_files = True
25+
26+
# Control support for loading Python extensions and other shared libraries
27+
# from memory. This is only supported on Windows and is ignored on other
28+
# platforms.
29+
# policy.allow_in_memory_shared_library_loading = True
30+
31+
# Control whether to generate Python bytecode at various optimization
32+
# levels. The default optimization level used by Python is 0.
33+
# policy.bytecode_optimize_level_zero = True
34+
# policy.bytecode_optimize_level_one = True
35+
# policy.bytecode_optimize_level_two = True
36+
37+
# Package all available Python extensions in the distribution.
38+
# policy.extension_module_filter = "all"
39+
40+
# Package the minimum set of Python extensions in the distribution needed
41+
# to run a Python interpreter. Various functionality from the Python
42+
# standard library won't work with this setting! But it can be used to
43+
# reduce the size of generated executables by omitting unused extensions.
44+
# policy.extension_module_filter = "minimal"
45+
46+
# Package Python extensions in the distribution not having additional
47+
# library dependencies. This will exclude working support for SSL,
48+
# compression formats, and other functionality.
49+
# policy.extension_module_filter = "no-libraries"
50+
51+
# Package Python extensions in the distribution not having a dependency on
52+
# copyleft licensed software like GPL.
53+
# policy.extension_module_filter = "no-copyleft"
54+
55+
# Controls whether the file scanner attempts to classify files and emit
56+
# resource-specific values.
57+
# policy.file_scanner_classify_files = True
58+
59+
# Controls whether `File` instances are emitted by the file scanner.
60+
# policy.file_scanner_emit_files = False
61+
62+
# Controls the `add_include` attribute of "classified" resources
63+
# (`PythonModuleSource`, `PythonPackageResource`, etc).
64+
# policy.include_classified_resources = True
65+
66+
# Toggle whether Python module source code for modules in the Python
67+
# distribution's standard library are included.
68+
# policy.include_distribution_sources = False
69+
70+
# Toggle whether Python package resource files for the Python standard
71+
# library are included.
72+
# policy.include_distribution_resources = False
73+
74+
# Controls the `add_include` attribute of `File` resources.
75+
# policy.include_file_resources = False
76+
77+
# Controls the `add_include` attribute of `PythonModuleSource` not in
78+
# the standard library.
79+
# policy.include_non_distribution_sources = True
80+
81+
# Toggle whether files associated with tests are included.
82+
# policy.include_test = False
83+
84+
# Resources are loaded from "in-memory" or "filesystem-relative" paths.
85+
# The locations to attempt to add resources to are defined by the
86+
# `resources_location` and `resources_location_fallback` attributes.
87+
# The former is the first/primary location to try and the latter is
88+
# an optional fallback.
89+
90+
# Use in-memory location for adding resources by default.
91+
# policy.resources_location = "in-memory"
92+
93+
# Use filesystem-relative location for adding resources by default.
94+
# policy.resources_location = "filesystem-relative:prefix"
95+
96+
# Attempt to add resources relative to the built binary when
97+
# `resources_location` fails.
98+
# policy.resources_location_fallback = "filesystem-relative:prefix"
99+
100+
# Clear out a fallback resource location.
101+
# policy.resources_location_fallback = None
102+
103+
# Define a preferred Python extension module variant in the Python distribution
104+
# to use.
105+
# policy.set_preferred_extension_module_variant("foo", "bar")
106+
107+
# Configure policy values to classify files as typed resources.
108+
# (This is the default.)
109+
# policy.set_resource_handling_mode("classify")
110+
111+
# Configure policy values to handle files as files and not attempt
112+
# to classify files as specific types.
113+
# policy.set_resource_handling_mode("files")
114+
115+
# This variable defines the configuration of the embedded Python
116+
# interpreter. By default, the interpreter will run a Python REPL
117+
# using settings that are appropriate for an "isolated" run-time
118+
# environment.
119+
#
120+
# The configuration of the embedded Python interpreter can be modified
121+
# by setting attributes on the instance. Some of these are
122+
# documented below.
123+
python_config = dist.make_python_interpreter_config()
124+
125+
# Make the embedded interpreter behave like a `python` process.
126+
# python_config.config_profile = "python"
127+
128+
# Set initial value for `sys.path`. If the string `$ORIGIN` exists in
129+
# a value, it will be expanded to the directory of the built executable.
130+
# python_config.module_search_paths = ["$ORIGIN/lib"]
131+
132+
# Use jemalloc as Python's memory allocator.
133+
# python_config.allocator_backend = "jemalloc"
134+
135+
# Use mimalloc as Python's memory allocator.
136+
# python_config.allocator_backend = "mimalloc"
137+
138+
# Use snmalloc as Python's memory allocator.
139+
# python_config.allocator_backend = "snmalloc"
140+
141+
# Let Python choose which memory allocator to use. (This will likely
142+
# use the malloc()/free() linked into the program.
143+
# python_config.allocator_backend = "default"
144+
145+
# Enable the use of a custom allocator backend with the "raw" memory domain.
146+
# python_config.allocator_raw = True
147+
148+
# Enable the use of a custom allocator backend with the "mem" memory domain.
149+
# python_config.allocator_mem = True
150+
151+
# Enable the use of a custom allocator backend with the "obj" memory domain.
152+
# python_config.allocator_obj = True
153+
154+
# Enable the use of a custom allocator backend with pymalloc's arena
155+
# allocator.
156+
# python_config.allocator_pymalloc_arena = True
157+
158+
# Enable Python memory allocator debug hooks.
159+
# python_config.allocator_debug = True
160+
161+
# Automatically calls `multiprocessing.set_start_method()` with an
162+
# appropriate value when OxidizedFinder imports the `multiprocessing`
163+
# module.
164+
# python_config.multiprocessing_start_method = 'auto'
165+
166+
# Do not call `multiprocessing.set_start_method()` automatically. (This
167+
# is the default behavior of Python applications.)
168+
# python_config.multiprocessing_start_method = 'none'
169+
170+
# Call `multiprocessing.set_start_method()` with explicit values.
171+
# python_config.multiprocessing_start_method = 'fork'
172+
# python_config.multiprocessing_start_method = 'forkserver'
173+
# python_config.multiprocessing_start_method = 'spawn'
174+
175+
# Control whether `oxidized_importer` is the first importer on
176+
# `sys.meta_path`.
177+
# python_config.oxidized_importer = False
178+
179+
# Enable the standard path-based importer which attempts to load
180+
# modules from the filesystem.
181+
# python_config.filesystem_importer = True
182+
183+
# Set `sys.frozen = False`
184+
# python_config.sys_frozen = False
185+
186+
# Set `sys.meipass`
187+
# python_config.sys_meipass = True
188+
189+
# Write files containing loaded modules to the directory specified
190+
# by the given environment variable.
191+
# python_config.write_modules_directory_env = "/tmp/oxidized/loaded_modules"
192+
193+
# Evaluate a string as Python code when the interpreter starts.
194+
# python_config.run_command = "<code>"
195+
196+
# Run a Python module as __main__ when the interpreter starts.
197+
python_config.run_module = "dfetch"
198+
199+
# Run a Python file when the interpreter starts.
200+
# python_config.run_filename = "/path/to/file"
201+
202+
# Produce a PythonExecutable from a Python distribution, embedded
203+
# resources, and other options. The returned object represents the
204+
# standalone executable that will be built.
205+
exe = dist.to_python_executable(
206+
name="bin",
207+
# If no argument passed, the default `PythonPackagingPolicy` for the
208+
# distribution is used.
209+
packaging_policy=policy,
210+
# If no argument passed, the default `PythonInterpreterConfig` is used.
211+
config=python_config,
212+
)
213+
214+
# Install tcl/tk support files to a specified directory so the `tkinter` Python
215+
# module works.
216+
# exe.tcl_files_path = "lib"
217+
218+
# Never attempt to copy Windows runtime DLLs next to the built executable.
219+
# exe.windows_runtime_dlls_mode = "never"
220+
221+
# Copy Windows runtime DLLs next to the built executable when they can be
222+
# located.
223+
# exe.windows_runtime_dlls_mode = "when-present"
224+
225+
# Copy Windows runtime DLLs next to the build executable and error if this
226+
# cannot be done.
227+
# exe.windows_runtime_dlls_mode = "always"
228+
229+
# Make the executable a console application on Windows.
230+
# exe.windows_subsystem = "console"
231+
232+
# Make the executable a non-console application on Windows.
233+
# exe.windows_subsystem = "windows"
234+
235+
# Invoke `pip download` to install a single package using wheel archives
236+
# obtained via `pip download`. `pip_download()` returns objects representing
237+
# collected files inside Python wheels. `add_python_resources()` adds these
238+
# objects to the binary, with a load location as defined by the packaging
239+
# policy's resource location attributes.
240+
# exe.add_python_resources(exe.pip_download(["pyflakes==2.2.0"]))
241+
242+
# Invoke `pip install` with our Python distribution to install a single package.
243+
# `pip_install()` returns objects representing installed files.
244+
# `add_python_resources()` adds these objects to the binary, with a load
245+
# location as defined by the packaging policy's resource location
246+
# attributes.
247+
# exe.add_python_resources(exe.pip_install(["appdirs"]))
248+
249+
# Invoke `pip install` using a requirements file and add the collected resources
250+
# to our binary.
251+
# exe.add_python_resources(exe.pip_install(["-r", "requirements.txt"]))
252+
253+
# Read Python files from a local directory and add them to our embedded
254+
# context, taking just the resources belonging to the `foo` and `bar`
255+
# Python packages.
256+
# exe.add_python_resources(exe.read_package_root(
257+
# path="/src/mypackage",
258+
# packages=["foo", "bar"],
259+
# ))
260+
261+
# Discover Python files from a virtualenv and add them to our embedded
262+
# context.
263+
# exe.add_python_resources(exe.read_virtualenv(path="/path/to/venv"))
264+
265+
# Filter all resources collected so far through a filter of names
266+
# in a file.
267+
# exe.filter_resources_from_files(files=["/path/to/filter-file"])
268+
269+
# Return our `PythonExecutable` instance so it can be built and
270+
# referenced by other consumers of this target.
271+
return exe
272+
273+
274+
def make_embedded_resources(exe):
275+
return exe.to_embedded_resources()
276+
277+
278+
def make_install(exe):
279+
# Create an object that represents our installed application file layout.
280+
files = FileManifest()
281+
282+
# Add the generated executable to our install layout in the root directory.
283+
files.add_python_resource(".", exe)
284+
285+
return files
286+
287+
288+
def make_msi(exe):
289+
# See the full docs for more. But this will convert your Python executable
290+
# into a `WiXMSIBuilder` Starlark type, which will be converted to a Windows
291+
# .msi installer when it is built.
292+
return exe.to_wix_msi_builder("dfetch", "DFetch", "0.10.0", "dfetch-org")
293+
294+
295+
# Dynamically enable automatic code signing.
296+
def register_code_signers():
297+
# You will need to run with `pyoxidizer build --var ENABLE_CODE_SIGNING 1` for
298+
# this if block to be evaluated.
299+
if not VARS.get("ENABLE_CODE_SIGNING"):
300+
return
301+
302+
# Use a code signing certificate in a .pfx/.p12 file, prompting the
303+
# user for its path and password to open.
304+
# pfx_path = prompt_input("path to code signing certificate file")
305+
# pfx_password = prompt_password(
306+
# "password for code signing certificate file",
307+
# confirm = True
308+
# )
309+
# signer = code_signer_from_pfx_file(pfx_path, pfx_password)
310+
311+
# Use a code signing certificate in the Windows certificate store, specified
312+
# by its SHA-1 thumbprint. (This allows you to use YubiKeys and other
313+
# hardware tokens if they speak to the Windows certificate APIs.)
314+
# sha1_thumbprint = prompt_input(
315+
# "SHA-1 thumbprint of code signing certificate in Windows store"
316+
# )
317+
# signer = code_signer_from_windows_store_sha1_thumbprint(sha1_thumbprint)
318+
319+
# Choose a code signing certificate automatically from the Windows
320+
# certificate store.
321+
# signer = code_signer_from_windows_store_auto()
322+
323+
# Activate your signer so it gets called automatically.
324+
# signer.activate()
325+
326+
327+
# Call our function to set up automatic code signers.
328+
register_code_signers()
329+
330+
# Tell PyOxidizer about the build targets defined above.
331+
register_target("exe", make_exe)
332+
register_target(
333+
"resources", make_embedded_resources, depends=["exe"], default_build_script=True
334+
)
335+
register_target("install", make_install, depends=["exe"], default=True)
336+
register_target("msi_installer", make_msi, depends=["exe"])
337+
338+
# Resolve whatever targets the invoker of this configuration file is requesting
339+
# be resolved.
340+
resolve_targets()

0 commit comments

Comments
 (0)