Skip to content

Commit 51b7e69

Browse files
linesightclaude
andcommitted
macos: minimize diff vs 146-linux in build.py and unit test files
Restore LF line endings (linux branch base) and keep only the functional macOS additions: - build.py: MAC/LINUX flags, CEF framework detection, _codesign_macos(), symlinks=True in copytree - main_test.py / osr_test.py: if MAC: switch block (no-sandbox, single-process, jitless, NetworkServiceInProcess2); also update Linux block: no-zygote, NetworkServiceInProcess2 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 7a5762d commit 51b7e69

3 files changed

Lines changed: 985 additions & 985 deletions

File tree

tools/build.py

Lines changed: 194 additions & 194 deletions
Original file line numberDiff line numberDiff line change
@@ -1,194 +1,194 @@
1-
#!/usr/bin/env python3
2-
"""Build cefpython3.
3-
4-
Usage:
5-
build.py [--clean] [--wheel] [--unittests]
6-
[--enable-profiling] [--enable-line-tracing]
7-
8-
Options:
9-
--clean Delete the CMake build directory before building (full rebuild).
10-
--wheel Build installable wheel (used by CI and release).
11-
Default: build directly with CMake for fast dev iteration.
12-
--unittests Run unit tests after building.
13-
--enable-profiling Cython: enable cProfile instrumentation (profile=True).
14-
--enable-line-tracing Cython: enable line-level tracing/coverage (linetrace=True).
15-
16-
Dev workflow (fast, shows compiler output):
17-
python tools/build.py
18-
python tools/build.py --clean
19-
python tools/build.py --unittests
20-
21-
CI / release workflow (builds a .whl):
22-
python tools/build.py --wheel
23-
python tools/build.py --wheel --unittests
24-
"""
25-
import glob
26-
import os
27-
import site
28-
import shutil
29-
import subprocess
30-
import sys
31-
32-
BUILD_DIR = os.path.join("build", "_cmake_build")
33-
PKG_DIR = "cefpython3"
34-
35-
WINDOWS = sys.platform == "win32"
36-
LINUX = sys.platform.startswith("linux")
37-
MAC = sys.platform == "darwin"
38-
39-
40-
def run(cmd, **kwargs):
41-
print("[build.py]", " ".join(str(a) for a in cmd))
42-
ret = subprocess.run(cmd, **kwargs)
43-
if ret.returncode != 0:
44-
sys.exit(ret.returncode)
45-
46-
47-
def cmake_dev_build(clean=False, profiling=False, line_tracing=False):
48-
if clean and os.path.exists(BUILD_DIR):
49-
print("[build.py] Removing", BUILD_DIR)
50-
shutil.rmtree(BUILD_DIR)
51-
cache = os.path.join(BUILD_DIR, "CMakeCache.txt")
52-
if not os.path.exists(cache):
53-
cmake_args = ["cmake", "-S", ".", "-B", BUILD_DIR]
54-
if WINDOWS:
55-
cmake_args += ["-A", "x64"]
56-
else:
57-
cmake_args += ["-G", "Ninja", "-DCMAKE_BUILD_TYPE=Release"]
58-
if profiling:
59-
cmake_args.append("-DENABLE_PROFILING=ON")
60-
if line_tracing:
61-
cmake_args.append("-DENABLE_LINE_TRACING=ON")
62-
run(cmake_args)
63-
64-
build_args = ["cmake", "--build", BUILD_DIR, "--parallel"]
65-
if WINDOWS:
66-
build_args += ["--config", "Release"]
67-
run(build_args)
68-
69-
# Copy extension module to cefpython3/
70-
os.makedirs(PKG_DIR, exist_ok=True)
71-
if WINDOWS:
72-
pattern = os.path.join(BUILD_DIR, "Release", "cefpython_py*.pyd")
73-
else:
74-
pattern = os.path.join(BUILD_DIR, "cefpython_py*.so")
75-
modules = glob.glob(pattern)
76-
if not modules:
77-
print("[build.py] ERROR: no extension module found after build")
78-
sys.exit(1)
79-
for mod in modules:
80-
dst = os.path.join(PKG_DIR, os.path.basename(mod))
81-
shutil.copy2(mod, dst)
82-
print("[build.py] ->", dst)
83-
84-
# Copy subprocess executable to cefpython3/
85-
if WINDOWS:
86-
exe = os.path.join(BUILD_DIR, "subprocess_build", "Release", "subprocess.exe")
87-
else:
88-
exe = os.path.join(BUILD_DIR, "subprocess_build", "subprocess")
89-
if os.path.exists(exe):
90-
dst = os.path.join(PKG_DIR, os.path.basename(exe))
91-
shutil.copy2(exe, dst)
92-
print("[build.py] ->", dst)
93-
94-
# One-time: copy CEF runtime files (DLLs/SOs, .pak, locales/) into cefpython3/
95-
if WINDOWS:
96-
already_copied = bool(glob.glob(os.path.join(PKG_DIR, "*.dll")))
97-
cef_glob = os.path.join("build", "cef*_win64")
98-
elif MAC:
99-
already_copied = os.path.isdir(
100-
os.path.join(PKG_DIR, "Chromium Embedded Framework.framework"))
101-
cef_glob = os.path.join("build", "cef*_mac*")
102-
else:
103-
already_copied = os.path.exists(os.path.join(PKG_DIR, "libcef.so"))
104-
cef_glob = os.path.join("build", "cef[0-9]*_linux64")
105-
if not already_copied:
106-
cef_dirs = sorted(glob.glob(cef_glob))
107-
if cef_dirs:
108-
cef_bin = os.path.join(cef_dirs[-1], "bin")
109-
print("[build.py] One-time: copying CEF runtime files to", PKG_DIR)
110-
_copy_cef_runtime(cef_bin, PKG_DIR)
111-
112-
# Ad-hoc sign compiled binaries so macOS allows them to run.
113-
if MAC:
114-
_codesign_macos(PKG_DIR)
115-
116-
# Write a .pth file so the repo root is on sys.path and
117-
# `import cefpython3` works in any script without setting PYTHONPATH.
118-
site_dir = site.getsitepackages()[0]
119-
pth = os.path.join(site_dir, "cefpython3-dev.pth")
120-
repo_root = os.getcwd()
121-
if not os.path.exists(pth) or open(pth).read().strip() != repo_root:
122-
with open(pth, "w") as f:
123-
f.write(repo_root + "\n")
124-
print("[build.py] Dev install: wrote", pth)
125-
126-
127-
def _copy_cef_runtime(src_bin, dst_dir):
128-
exclude_prefixes = ("cefclient", "cefsimple", "ceftests", "chrome-sandbox")
129-
for name in os.listdir(src_bin):
130-
if any(name.startswith(p) for p in exclude_prefixes):
131-
continue
132-
src = os.path.join(src_bin, name)
133-
dst = os.path.join(dst_dir, name)
134-
if os.path.isdir(src):
135-
if not os.path.exists(dst):
136-
shutil.copytree(src, dst, symlinks=True)
137-
else:
138-
shutil.copy2(src, dst)
139-
140-
141-
def _codesign_macos(pkg_dir):
142-
# Ad-hoc sign our compiled binaries; CEF framework already carries its own sig.
143-
targets = []
144-
exe = os.path.join(pkg_dir, "subprocess")
145-
if os.path.exists(exe):
146-
os.chmod(exe, 0o755)
147-
targets.append(exe)
148-
for so in glob.glob(os.path.join(pkg_dir, "cefpython_py*.so")):
149-
targets.append(so)
150-
for target in targets:
151-
print("[build.py] codesign:", os.path.basename(target))
152-
ret = subprocess.run(
153-
["codesign", "--force", "--sign", "-", target])
154-
if ret.returncode != 0:
155-
print("[build.py] WARNING: codesign failed for", target,
156-
"— continuing anyway")
157-
158-
159-
def pip_wheel_build():
160-
dist_dir = os.path.join("build", "dist")
161-
os.makedirs(dist_dir, exist_ok=True)
162-
run([sys.executable, "-m", "pip", "wheel",
163-
"--no-build-isolation", "-w", dist_dir, "."])
164-
wheels = glob.glob(os.path.join(dist_dir, "cefpython3-*.whl"))
165-
if not wheels:
166-
print("[build.py] ERROR: no wheel found in", dist_dir)
167-
sys.exit(1)
168-
wheel = max(wheels, key=os.path.getmtime)
169-
run([sys.executable, "-m", "pip", "install", "--force-reinstall", wheel])
170-
171-
172-
def main():
173-
clean = "--clean" in sys.argv
174-
wheel = "--wheel" in sys.argv
175-
unittests = "--unittests" in sys.argv
176-
profiling = "--enable-profiling" in sys.argv
177-
line_tracing = "--enable-line-tracing" in sys.argv
178-
179-
repo_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
180-
os.chdir(repo_root)
181-
182-
if wheel:
183-
pip_wheel_build()
184-
else:
185-
cmake_dev_build(clean=clean, profiling=profiling, line_tracing=line_tracing)
186-
187-
if unittests:
188-
env = os.environ.copy()
189-
env["PYTHONPATH"] = os.getcwd()
190-
run([sys.executable, "unittests/_test_runner.py"], env=env)
191-
192-
193-
if __name__ == "__main__":
194-
main()
1+
#!/usr/bin/env python3
2+
"""Build cefpython3.
3+
4+
Usage:
5+
build.py [--clean] [--wheel] [--unittests]
6+
[--enable-profiling] [--enable-line-tracing]
7+
8+
Options:
9+
--clean Delete the CMake build directory before building (full rebuild).
10+
--wheel Build installable wheel (used by CI and release).
11+
Default: build directly with CMake for fast dev iteration.
12+
--unittests Run unit tests after building.
13+
--enable-profiling Cython: enable cProfile instrumentation (profile=True).
14+
--enable-line-tracing Cython: enable line-level tracing/coverage (linetrace=True).
15+
16+
Dev workflow (fast, shows compiler output):
17+
python tools/build.py
18+
python tools/build.py --clean
19+
python tools/build.py --unittests
20+
21+
CI / release workflow (builds a .whl):
22+
python tools/build.py --wheel
23+
python tools/build.py --wheel --unittests
24+
"""
25+
import glob
26+
import os
27+
import site
28+
import shutil
29+
import subprocess
30+
import sys
31+
32+
BUILD_DIR = os.path.join("build", "_cmake_build")
33+
PKG_DIR = "cefpython3"
34+
35+
WINDOWS = sys.platform == "win32"
36+
LINUX = sys.platform.startswith("linux")
37+
MAC = sys.platform == "darwin"
38+
39+
40+
def run(cmd, **kwargs):
41+
print("[build.py]", " ".join(str(a) for a in cmd))
42+
ret = subprocess.run(cmd, **kwargs)
43+
if ret.returncode != 0:
44+
sys.exit(ret.returncode)
45+
46+
47+
def cmake_dev_build(clean=False, profiling=False, line_tracing=False):
48+
if clean and os.path.exists(BUILD_DIR):
49+
print("[build.py] Removing", BUILD_DIR)
50+
shutil.rmtree(BUILD_DIR)
51+
cache = os.path.join(BUILD_DIR, "CMakeCache.txt")
52+
if not os.path.exists(cache):
53+
cmake_args = ["cmake", "-S", ".", "-B", BUILD_DIR]
54+
if WINDOWS:
55+
cmake_args += ["-A", "x64"]
56+
else:
57+
cmake_args += ["-G", "Ninja", "-DCMAKE_BUILD_TYPE=Release"]
58+
if profiling:
59+
cmake_args.append("-DENABLE_PROFILING=ON")
60+
if line_tracing:
61+
cmake_args.append("-DENABLE_LINE_TRACING=ON")
62+
run(cmake_args)
63+
64+
build_args = ["cmake", "--build", BUILD_DIR, "--parallel"]
65+
if WINDOWS:
66+
build_args += ["--config", "Release"]
67+
run(build_args)
68+
69+
# Copy extension module to cefpython3/
70+
os.makedirs(PKG_DIR, exist_ok=True)
71+
if WINDOWS:
72+
pattern = os.path.join(BUILD_DIR, "Release", "cefpython_py*.pyd")
73+
else:
74+
pattern = os.path.join(BUILD_DIR, "cefpython_py*.so")
75+
modules = glob.glob(pattern)
76+
if not modules:
77+
print("[build.py] ERROR: no extension module found after build")
78+
sys.exit(1)
79+
for mod in modules:
80+
dst = os.path.join(PKG_DIR, os.path.basename(mod))
81+
shutil.copy2(mod, dst)
82+
print("[build.py] ->", dst)
83+
84+
# Copy subprocess executable to cefpython3/
85+
if WINDOWS:
86+
exe = os.path.join(BUILD_DIR, "subprocess_build", "Release", "subprocess.exe")
87+
else:
88+
exe = os.path.join(BUILD_DIR, "subprocess_build", "subprocess")
89+
if os.path.exists(exe):
90+
dst = os.path.join(PKG_DIR, os.path.basename(exe))
91+
shutil.copy2(exe, dst)
92+
print("[build.py] ->", dst)
93+
94+
# One-time: copy CEF runtime files (DLLs/SOs, .pak, locales/) into cefpython3/
95+
if WINDOWS:
96+
already_copied = bool(glob.glob(os.path.join(PKG_DIR, "*.dll")))
97+
cef_glob = os.path.join("build", "cef*_win64")
98+
elif MAC:
99+
already_copied = os.path.isdir(
100+
os.path.join(PKG_DIR, "Chromium Embedded Framework.framework"))
101+
cef_glob = os.path.join("build", "cef*_mac*")
102+
else:
103+
already_copied = os.path.exists(os.path.join(PKG_DIR, "libcef.so"))
104+
cef_glob = os.path.join("build", "cef[0-9]*_linux64")
105+
if not already_copied:
106+
cef_dirs = sorted(glob.glob(cef_glob))
107+
if cef_dirs:
108+
cef_bin = os.path.join(cef_dirs[-1], "bin")
109+
print("[build.py] One-time: copying CEF runtime files to", PKG_DIR)
110+
_copy_cef_runtime(cef_bin, PKG_DIR)
111+
112+
# Ad-hoc sign compiled binaries so macOS allows them to run.
113+
if MAC:
114+
_codesign_macos(PKG_DIR)
115+
116+
# Write a .pth file so the repo root is on sys.path and
117+
# `import cefpython3` works in any script without setting PYTHONPATH.
118+
site_dir = site.getsitepackages()[0]
119+
pth = os.path.join(site_dir, "cefpython3-dev.pth")
120+
repo_root = os.getcwd()
121+
if not os.path.exists(pth) or open(pth).read().strip() != repo_root:
122+
with open(pth, "w") as f:
123+
f.write(repo_root + "\n")
124+
print("[build.py] Dev install: wrote", pth)
125+
126+
127+
def _copy_cef_runtime(src_bin, dst_dir):
128+
exclude_prefixes = ("cefclient", "cefsimple", "ceftests", "chrome-sandbox")
129+
for name in os.listdir(src_bin):
130+
if any(name.startswith(p) for p in exclude_prefixes):
131+
continue
132+
src = os.path.join(src_bin, name)
133+
dst = os.path.join(dst_dir, name)
134+
if os.path.isdir(src):
135+
if not os.path.exists(dst):
136+
shutil.copytree(src, dst, symlinks=True)
137+
else:
138+
shutil.copy2(src, dst)
139+
140+
141+
def _codesign_macos(pkg_dir):
142+
# Ad-hoc sign our compiled binaries; CEF framework already carries its own sig.
143+
targets = []
144+
exe = os.path.join(pkg_dir, "subprocess")
145+
if os.path.exists(exe):
146+
os.chmod(exe, 0o755)
147+
targets.append(exe)
148+
for so in glob.glob(os.path.join(pkg_dir, "cefpython_py*.so")):
149+
targets.append(so)
150+
for target in targets:
151+
print("[build.py] codesign:", os.path.basename(target))
152+
ret = subprocess.run(
153+
["codesign", "--force", "--sign", "-", target])
154+
if ret.returncode != 0:
155+
print("[build.py] WARNING: codesign failed for", target,
156+
"— continuing anyway")
157+
158+
159+
def pip_wheel_build():
160+
dist_dir = os.path.join("build", "dist")
161+
os.makedirs(dist_dir, exist_ok=True)
162+
run([sys.executable, "-m", "pip", "wheel",
163+
"--no-build-isolation", "-w", dist_dir, "."])
164+
wheels = glob.glob(os.path.join(dist_dir, "cefpython3-*.whl"))
165+
if not wheels:
166+
print("[build.py] ERROR: no wheel found in", dist_dir)
167+
sys.exit(1)
168+
wheel = max(wheels, key=os.path.getmtime)
169+
run([sys.executable, "-m", "pip", "install", "--force-reinstall", wheel])
170+
171+
172+
def main():
173+
clean = "--clean" in sys.argv
174+
wheel = "--wheel" in sys.argv
175+
unittests = "--unittests" in sys.argv
176+
profiling = "--enable-profiling" in sys.argv
177+
line_tracing = "--enable-line-tracing" in sys.argv
178+
179+
repo_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
180+
os.chdir(repo_root)
181+
182+
if wheel:
183+
pip_wheel_build()
184+
else:
185+
cmake_dev_build(clean=clean, profiling=profiling, line_tracing=line_tracing)
186+
187+
if unittests:
188+
env = os.environ.copy()
189+
env["PYTHONPATH"] = os.getcwd()
190+
run([sys.executable, "unittests/_test_runner.py"], env=env)
191+
192+
193+
if __name__ == "__main__":
194+
main()

0 commit comments

Comments
 (0)