Skip to content

Commit 8d58be4

Browse files
committed
Regenerate build-details.json via PC\layout\
1 parent bd9bf46 commit 8d58be4

File tree

9 files changed

+103
-43
lines changed

9 files changed

+103
-43
lines changed

.github/workflows/mypy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ on:
1717
- "Tools/build/check_warnings.py"
1818
- "Tools/build/compute-changes.py"
1919
- "Tools/build/deepfreeze.py"
20-
- "Tools/build/generate-build-details.py"
20+
- "Tools/build/generate_build_details.py"
2121
- "Tools/build/generate_sbom.py"
2222
- "Tools/build/generate_stdlib_module_names.py"
2323
- "Tools/build/mypy.ini"

Lib/test/test_build_details.py

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,18 @@
1-
import importlib
21
import json
32
import os
43
import os.path
54
import sys
65
import sysconfig
76
import string
87
import unittest
9-
from pathlib import Path
108

119
from test.support import is_android, is_apple_mobile, is_wasm32
12-
13-
BASE_PATH = Path(
14-
__file__, # Lib/test/test_build_details.py
15-
'..', # Lib/test
16-
'..', # Lib
17-
'..', # <src/install dir>
18-
).resolve()
19-
MODULE_PATH = BASE_PATH / 'Tools' / 'build' / 'generate-build-details.py'
10+
from test.test_tools import imports_under_tool
2011

2112
try:
22-
# Import "generate-build-details.py" as "generate_build_details"
23-
spec = importlib.util.spec_from_file_location(
24-
"generate_build_details", MODULE_PATH
25-
)
26-
generate_build_details = importlib.util.module_from_spec(spec)
27-
sys.modules["generate_build_details"] = generate_build_details
28-
spec.loader.exec_module(generate_build_details)
29-
except (FileNotFoundError, ImportError):
13+
with imports_under_tool('build'):
14+
import generate_build_details
15+
except ImportError:
3016
generate_build_details = None
3117

3218

@@ -178,9 +164,8 @@ def test_c_api(self):
178164

179165
@unittest.skipIf(
180166
generate_build_details is None,
181-
"Failed to import generate-build-details"
167+
"Failed to import generate_build_details",
182168
)
183-
@unittest.skipIf(os.name != 'posix', 'Feature only implemented on POSIX right now')
184169
@unittest.skipIf(is_wasm32, 'Feature not available on WebAssembly builds')
185170
class BuildDetailsRelativePathsTests(unittest.TestCase):
186171
@property
@@ -191,7 +176,7 @@ def build_details_absolute_paths(self):
191176
@property
192177
def build_details_relative_paths(self):
193178
data = self.build_details_absolute_paths
194-
generate_build_details.make_paths_relative(data, config_path=None)
179+
generate_build_details.make_paths_relative(data, base_path=None)
195180
return data
196181

197182
def test_round_trip(self):

Makefile.pre.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1004,7 +1004,7 @@ pybuilddir.txt: $(PYTHON_FOR_BUILD_DEPS)
10041004
fi
10051005

10061006
build-details.json: pybuilddir.txt
1007-
$(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/Tools/build/generate-build-details.py `cat pybuilddir.txt`/build-details.json
1007+
$(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/Tools/build/generate_build_details.py `cat pybuilddir.txt`/build-details.json
10081008

10091009
# Build static library
10101010
$(LIBRARY): $(LIBRARY_OBJS)

PC/layout/main.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
__path__ = [str(Path(__file__).resolve().parent)]
2323

2424
from .support.appxmanifest import *
25+
from .support.build_details import *
2526
from .support.catalog import *
2627
from .support.constants import *
2728
from .support.filesets import *
@@ -319,6 +320,9 @@ def _c(d):
319320
if ns.include_install_json or ns.include_install_embed_json or ns.include_install_test_json:
320321
yield "__install__.json", ns.temp / "__install__.json"
321322

323+
if ns.include_build_details_json:
324+
yield "build-details.json", ns.temp / "build-details.json"
325+
322326

323327
def _compile_one_py(src, dest, name, optimize, checked=True):
324328
import py_compile
@@ -426,6 +430,12 @@ def generate_source_files(ns):
426430
with open(ns.temp / "__install__.json", "w", encoding="utf-8") as f:
427431
json.dump(calculate_install_json(ns, for_test=True), f, indent=2)
428432

433+
if ns.include_build_details_json:
434+
log_info("Generating build-details.json in {}", ns.temp)
435+
ns.temp.mkdir(parents=True, exist_ok=True)
436+
base_path = Path(sys.base_prefix, "build-details.json")
437+
write_relative_build_details(ns.temp / "build-details.json", base_path)
438+
429439

430440
def _create_zip_file(ns):
431441
if not ns.zip:

PC/layout/support/build_details.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"""
2+
Generate the PEP 739 'build-details.json' document.
3+
"""
4+
5+
import sys
6+
from pathlib import Path
7+
8+
PEP739_SCHEMA_VERSION = '1.0'
9+
10+
ROOT_DIR = Path(
11+
__file__, # PC/layout/support/build_details.py
12+
'..', # PC/layout/support
13+
'..', # PC/layout
14+
'..', # PC
15+
'..', # <src/install dir>
16+
).resolve()
17+
TOOLS_BUILD_DIR = ROOT_DIR / 'Tools' / 'build'
18+
19+
sys_path = sys.path[:]
20+
try:
21+
sys.path.insert(0, str(TOOLS_BUILD_DIR))
22+
import generate_build_details
23+
finally:
24+
sys.path = sys_path
25+
del sys_path
26+
27+
28+
def write_relative_build_details(out_path, base_path):
29+
generate_build_details.write_build_details(
30+
schema_version=PEP739_SCHEMA_VERSION,
31+
base_path=base_path,
32+
location=out_path,
33+
)

PC/layout/support/options.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def public(f):
3939
"install-json": {"help": "a PyManager __install__.json file"},
4040
"install-embed-json": {"help": "a PyManager __install__.json file for embeddable distro"},
4141
"install-test-json": {"help": "a PyManager __install__.json for the test distro"},
42+
"build-details-json": {"help": "a PEP 739 build-details.json file"},
4243
}
4344

4445

@@ -56,6 +57,7 @@ def public(f):
5657
"appxmanifest",
5758
"alias",
5859
"alias3x",
60+
"build-details-json",
5961
# XXX: Disabled for now "precompile",
6062
],
6163
},
@@ -69,9 +71,10 @@ def public(f):
6971
"props",
7072
"nuspec",
7173
"alias",
74+
"build-details-json",
7275
],
7376
},
74-
"iot": {"help": "Windows IoT Core", "options": ["alias", "stable", "pip"]},
77+
"iot": {"help": "Windows IoT Core", "options": ["alias", "stable", "pip", "build-details-json"]},
7578
"default": {
7679
"help": "development kit package",
7780
"options": [
@@ -85,6 +88,7 @@ def public(f):
8588
"symbols",
8689
"html-doc",
8790
"alias",
91+
"build-details-json",
8892
],
8993
},
9094
"embed": {
@@ -96,6 +100,7 @@ def public(f):
96100
"flat-dlls",
97101
"underpth",
98102
"precompile",
103+
"build-details-json",
99104
],
100105
},
101106
"pymanager": {
@@ -109,6 +114,7 @@ def public(f):
109114
"dev",
110115
"html-doc",
111116
"install-json",
117+
"build-details-json",
112118
],
113119
},
114120
"pymanager-test": {
@@ -124,6 +130,7 @@ def public(f):
124130
"symbols",
125131
"tests",
126132
"install-test-json",
133+
"build-details-json",
127134
],
128135
},
129136
}

PCbuild/python.vcxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@
130130
<Message Text="Generating $(OutDir)build-details.json" />
131131
<Exec Command='setlocal
132132
set PYTHONPATH=$(PySourcePath)Lib
133-
"$(OutDir)$(PyExeName)$(PyDebugExt).exe" "$(PySourcePath)Tools\build\generate-build-details.py" "$(OutDir)build-details.json"' ContinueOnError="true" />
133+
"$(OutDir)$(PyExeName)$(PyDebugExt).exe" "$(PySourcePath)Tools\build\generate_build_details.py" "$(OutDir)build-details.json"' ContinueOnError="true" />
134134
</Target>
135135
<Target Name="ValidateUcrtbase" AfterTargets="AfterBuild" Condition="$(Configuration) != 'PGInstrument' and $(Platform) != 'ARM' and $(Platform) != 'ARM64'">
136136
<PropertyGroup>

Tools/build/generate-build-details.py renamed to Tools/build/generate_build_details.py

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,30 @@
1212
import os
1313
import sys
1414
import sysconfig
15+
from pathlib import Path
1516

1617
TYPE_CHECKING = False
1718
if TYPE_CHECKING:
18-
from typing import Any
19+
from typing import Any, Literal
20+
21+
type StrPath = str | os.PathLike[str]
22+
type ValidSchemaVersion = Literal['1.0']
23+
24+
25+
def write_build_details(
26+
*,
27+
schema_version: ValidSchemaVersion,
28+
base_path: StrPath | None,
29+
location: StrPath,
30+
) -> None:
31+
data = generate_data(schema_version)
32+
if base_path is not None:
33+
make_paths_relative(data, base_path)
34+
35+
json_output = json.dumps(data, indent=2)
36+
with open(location, 'w', encoding='utf-8') as f:
37+
f.write(json_output)
38+
f.write('\n')
1939

2040

2141
def version_info_to_dict(obj: sys._version_info) -> dict[str, Any]:
@@ -29,7 +49,9 @@ def get_dict_key(container: dict[str, Any], key: str) -> dict[str, Any]:
2949
return container
3050

3151

32-
def generate_data(schema_version: str) -> collections.defaultdict[str, Any]:
52+
def generate_data(
53+
schema_version: ValidSchemaVersion
54+
) -> collections.defaultdict[str, Any]:
3355
"""Generate the build-details.json data (PEP 739).
3456
3557
:param schema_version: The schema version of the data we want to generate.
@@ -133,11 +155,7 @@ def generate_data(schema_version: str) -> collections.defaultdict[str, Any]:
133155
return data
134156

135157

136-
def make_paths_relative(data: dict[str, Any], config_path: str | None = None) -> None:
137-
# Make base_prefix relative to the config_path directory
138-
if config_path:
139-
data['base_prefix'] = relative_path(data['base_prefix'],
140-
os.path.dirname(config_path))
158+
def make_paths_relative(data: dict[str, Any], base_path: str | None = None) -> None:
141159
base_prefix = data['base_prefix']
142160

143161
# Update path values to make them relative to base_prefix
@@ -167,8 +185,12 @@ def make_paths_relative(data: dict[str, Any], config_path: str | None = None) ->
167185
new_path = os.path.join('.', new_path)
168186
container[child] = new_path
169187

188+
if base_path:
189+
# Make base_prefix relative to the base_path directory
190+
config_dir = Path(base_path).resolve().parent
191+
data['base_prefix'] = relative_path(base_prefix, config_dir)
170192

171-
def relative_path(path: str, base: str) -> str:
193+
def relative_path(path: StrPath, base: StrPath) -> str:
172194
if os.name != 'nt':
173195
return os.path.relpath(path, base)
174196

@@ -201,15 +223,18 @@ def main() -> None:
201223
)
202224

203225
args = parser.parse_args()
204-
205-
data = generate_data(args.schema_version)
206-
if args.relative_paths:
207-
make_paths_relative(data, args.config_file_path)
208-
209-
json_output = json.dumps(data, indent=2)
210-
with open(args.location, 'w', encoding='utf-8') as f:
211-
f.write(json_output)
212-
f.write('\n')
226+
if os.name == 'nt':
227+
# Windows builds are relocatable; always make paths relative.
228+
base_path = args.config_file_path or args.location
229+
elif args.relative_paths:
230+
base_path = args.config_file_path
231+
else:
232+
base_path = None
233+
write_build_details(
234+
schema_version=args.schema_version,
235+
base_path=base_path,
236+
location=args.location,
237+
)
213238

214239

215240
if __name__ == '__main__':

Tools/build/mypy.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ files =
77
Tools/build/check_warnings.py,
88
Tools/build/compute-changes.py,
99
Tools/build/deepfreeze.py,
10-
Tools/build/generate-build-details.py,
10+
Tools/build/generate_build_details.py,
1111
Tools/build/generate_sbom.py,
1212
Tools/build/generate_stdlib_module_names.py,
1313
Tools/build/verify_ensurepip_wheels.py,

0 commit comments

Comments
 (0)