Skip to content

Commit bed56f7

Browse files
committed
GH-107956: install a static description file
Signed-off-by: Filipe Laíns <[email protected]>
1 parent 20cc90c commit bed56f7

File tree

3 files changed

+77
-2
lines changed

3 files changed

+77
-2
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ Tools/unicode/data/
124124
/config.status.lineno
125125
# hendrikmuhs/ccache-action@v1
126126
/.ccache
127+
/install-details.toml
127128
/platform
128129
/profile-clean-stamp
129130
/profile-run-stamp

Makefile.pre.in

+11-2
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ all: @DEF_MAKE_ALL_RULE@
615615

616616
.PHONY: build_all
617617
build_all: check-clean-src $(BUILDPYTHON) platform sharedmods \
618-
gdbhooks Programs/_testembed scripts checksharedmods rundsymutil
618+
gdbhooks Programs/_testembed scripts checksharedmods rundsymutil install-details.toml
619619

620620
.PHONY: build_wasm
621621
build_wasm: check-clean-src $(BUILDPYTHON) platform sharedmods \
@@ -790,6 +790,9 @@ $(BUILDPYTHON): Programs/python.o $(LINK_PYTHON_DEPS)
790790
platform: $(PYTHON_FOR_BUILD_DEPS) pybuilddir.txt
791791
$(RUNSHARED) $(PYTHON_FOR_BUILD) -c 'import sys ; from sysconfig import get_platform ; print("%s-%d.%d" % (get_platform(), *sys.version_info[:2]))' >platform
792792

793+
install-details.toml: $(PYTHON_FOR_BUILD_DEPS) pybuilddir.txt $(srcdir)/Tools/build/generate_install_details_file.py
794+
$(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/Tools/build/generate_install_details_file.py ./install-details.toml
795+
793796
# Create build directory and generate the sysconfig build-time data there.
794797
# pybuilddir.txt contains the name of the build dir and is used for
795798
# sys.path fixup -- see Modules/getpath.c.
@@ -1948,7 +1951,7 @@ altinstall: commoninstall
19481951
.PHONY: commoninstall
19491952
commoninstall: check-clean-src @FRAMEWORKALTINSTALLFIRST@ \
19501953
altbininstall libinstall inclinstall libainstall \
1951-
sharedinstall altmaninstall @FRAMEWORKALTINSTALLLAST@
1954+
sharedinstall altmaninstall descfileinstall @FRAMEWORKALTINSTALLLAST@
19521955

19531956
# Install shared libraries enabled by Setup
19541957
DESTDIRS= $(exec_prefix) $(LIBDIR) $(BINLIBDEST) $(DESTSHARED)
@@ -2552,6 +2555,11 @@ frameworkaltinstallunixtools:
25522555
frameworkinstallextras:
25532556
cd Mac && $(MAKE) installextras DESTDIR="$(DESTDIR)"
25542557

2558+
# Install the
2559+
.PHONY: descfileinstall
2560+
descfileinstall:
2561+
$(INSTALL) -d -m $(FILEMODE) ./install-details.toml $(DESTDIR)$(LIBDEST)/install-details.toml
2562+
25552563
# Build the toplevel Makefile
25562564
Makefile.pre: $(srcdir)/Makefile.pre.in config.status
25572565
CONFIG_FILES=Makefile.pre CONFIG_HEADERS= ./config.status
@@ -2652,6 +2660,7 @@ clean-retain-profile: pycremoval
26522660
find build -name '*.py' -exec rm -f {} ';' || true
26532661
find build -name '*.py[co]' -exec rm -f {} ';' || true
26542662
-rm -f pybuilddir.txt
2663+
-rm -f install-details.toml
26552664
-rm -f _bootstrap_python
26562665
-rm -f python.html python*.js python.data python*.symbols python*.map
26572666
-rm -f $(WASM_STDLIB)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import argparse
2+
import io
3+
import os
4+
import sys
5+
import sysconfig
6+
import tomllib
7+
8+
from typing import Any, Callable
9+
10+
11+
ConfigItem = str | int | list[str | int]
12+
ConfigData = dict[str, dict[str, ConfigItem]]
13+
14+
15+
def generic_info() -> ConfigData:
16+
return {
17+
'python': {
18+
'version': sys.version.split(' ')[0],
19+
'version_parts': {
20+
field: getattr(sys.version_info, field)
21+
for field in ('major', 'minor', 'micro', 'releaselevel', 'serial')
22+
},
23+
'executable': os.path.join(
24+
sysconfig.get_path('scripts'),
25+
os.path.basename(sys.executable),
26+
),
27+
'stdlib': sysconfig.get_path('stdlib'),
28+
},
29+
}
30+
31+
32+
def toml_dump(fd: io.TextIOBase, data: ConfigData) -> None:
33+
"""**Very** basic TOML writer. It only implements what is necessary for this use-case."""
34+
def toml_repr(obj: object) -> str:
35+
if isinstance(obj, dict):
36+
return '{ ' + ', '.join(f'{k} = {toml_repr(v)}' for k, v in obj.items()) + ' }'
37+
else:
38+
return repr(obj)
39+
40+
for section, entries in data.items():
41+
print(f'[{section}]', file=fd)
42+
for name, value in entries.items():
43+
print(f'{name} = {toml_repr(value)}', file=fd)
44+
fd.write('\n')
45+
46+
47+
def main() -> None:
48+
parser = argparse.ArgumentParser()
49+
parser.add_argument('output_path', metavar='FILE')
50+
51+
args = parser.parse_args()
52+
53+
config = generic_info()
54+
55+
# write TOML with our very basic writer
56+
with open(args.output_path, 'w') as f:
57+
toml_dump(f, config)
58+
59+
# try to load the data as a sanity check to verify our writer outputed, at least, valid TOML
60+
with open(args.output_path, 'rb') as f:
61+
parsed = tomllib.load(f)
62+
63+
64+
if __name__ == '__main__':
65+
main()

0 commit comments

Comments
 (0)