X Tutup
Skip to content

Commit 5030b89

Browse files
committed
Include C++ extension dependencies (msvcpxx.dll) with binaries (cztomczak#359)
1 parent ef76811 commit 5030b89

File tree

3 files changed

+115
-8
lines changed

3 files changed

+115
-8
lines changed

tools/build_distrib.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,22 +131,22 @@ def main():
131131
run_automate_prebuilt_cef(pythons_32bit[0])
132132
pack_prebuilt_cef("32bit")
133133
if LINUX:
134-
reduce_package_size_issue_262("32bit")
134+
reduce_package_size_issue262("32bit")
135135
remove_unnecessary_package_files("32bit")
136136
if pythons_64bit:
137137
if not NO_AUTOMATE:
138138
run_automate_prebuilt_cef(pythons_64bit[0])
139139
pack_prebuilt_cef("64bit")
140140
if LINUX:
141-
reduce_package_size_issue_262("64bit")
141+
reduce_package_size_issue262("64bit")
142142
remove_unnecessary_package_files("64bit")
143143
if not NO_REBUILD:
144144
build_cefpython_modules(pythons_32bit, "32bit")
145145
build_cefpython_modules(pythons_64bit, "64bit")
146146
if pythons_32bit:
147-
make_packages(pythons_32bit[0], "32bit")
147+
make_packages(pythons_32bit[0], "32bit", pythons_32bit)
148148
if pythons_64bit:
149-
make_packages(pythons_64bit[0], "64bit")
149+
make_packages(pythons_64bit[0], "64bit", pythons_64bit)
150150
test_wheel_packages(pythons_32bit + pythons_64bit)
151151
show_summary(pythons_32bit, pythons_64bit)
152152

@@ -432,7 +432,7 @@ def zip_directory(path, base_path, archive):
432432
os.chdir(original_dir)
433433

434434

435-
def reduce_package_size_issue_262(arch):
435+
def reduce_package_size_issue262(arch):
436436
"""Linux only: libcef.so is huge (500 MB) in Chrome v54+. Issue #262."""
437437
print("[build_distrib.py] Reduce package size for {arch} (Issue #262)"
438438
.format(arch=arch))
@@ -533,7 +533,7 @@ def restore_subprocess_executable_issue342(arch):
533533
shutil.copy(src, dst)
534534

535535

536-
def make_packages(python, arch):
536+
def make_packages(python, arch, all_pythons):
537537
"""Make setup and wheel packages."""
538538
print("[build_distrib.py] Make setup package for {arch}..."
539539
.format(arch=arch))
@@ -556,6 +556,7 @@ def make_packages(python, arch):
556556
setup_basename = get_setup_installer_basename(
557557
VERSION, get_os_postfix2_for_arch(arch))
558558
setup_dir = os.path.join(BUILD_DIR, setup_basename)
559+
check_cpp_extension_dependencies_issue359(setup_dir, all_pythons)
559560
archive = pack_directory(setup_dir, BUILD_DIR)
560561
shutil.move(archive, DISTRIB_DIR)
561562

@@ -583,6 +584,28 @@ def make_packages(python, arch):
583584
shutil.rmtree(setup_dir)
584585

585586

587+
def check_cpp_extension_dependencies_issue359(setup_dir, all_pythons):
588+
"""Windows only: check if msvcpXX.dll exist for all Python versions.
589+
Issue #359."""
590+
if not WINDOWS:
591+
return
592+
checked_any = False
593+
for python in all_pythons:
594+
if python["version2"] in ((3, 5), (3, 6), (3, 7)):
595+
checked_any = True
596+
if not os.path.exists(os.path.join(setup_dir, "msvcp140.dll")):
597+
raise Exception("C++ ext dependency missing: msvcp140.dll")
598+
elif python["version2"] == (3, 4):
599+
checked_any = True
600+
if not os.path.exists(os.path.join(setup_dir, "msvcp100.dll")):
601+
raise Exception("C++ ext dependency missing: msvcp100.dll")
602+
elif python["version2"] == (2, 7):
603+
if not os.path.exists(os.path.join(setup_dir, "msvcp90.dll")):
604+
raise Exception("C++ ext dependency missing: msvcp100.dll")
605+
checked_any = True
606+
assert checked_any
607+
608+
586609
def test_wheel_packages(pythons):
587610
"""Test wheel packages installation and run unit tests."""
588611
uninstall_cefpython3_packages(pythons)

tools/common.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# These sample apps will be deleted when creating setup/wheel packages
1616
CEF_SAMPLE_APPS = ["cefclient", "cefsimple", "ceftests", "chrome-sandbox"]
1717

18-
# Architecture and OS postfixes
18+
# Python architecture and OS postfixes
1919
ARCH32 = (8 * struct.calcsize('P') == 32)
2020
ARCH64 = (8 * struct.calcsize('P') == 64)
2121
# Make sure platform.architecture()[0] shows correctly 32bit when
@@ -26,6 +26,10 @@
2626
assert platform.architecture()[0] == "64bit"
2727
ARCH_STR = platform.architecture()[0]
2828

29+
# Operating system architecture
30+
SYSTEM64 = platform.machine().endswith('64')
31+
SYSTEM32 = not SYSTEM64
32+
2933
# OS_POSTFIX is for directories/files names in cefpython sources
3034
# and doesn't include architecture type, just OS name.
3135

tools/make_installer.py

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ def main():
102102
create_empty_log_file(os.path.join(PKG_DIR, "debug.log"))
103103
create_empty_log_file(os.path.join(PKG_DIR, "examples/debug.log"))
104104

105+
copy_cpp_extension_dependencies_issue359(PKG_DIR)
106+
105107
print("[make_installer.py] Done. Installer package created: {setup_dir}"
106108
.format(setup_dir=SETUP_DIR))
107109

@@ -184,7 +186,7 @@ def replace_template_vars(string, dictionary):
184186
string = string.replace("{{"+key+"}}", value)
185187
if string == orig_string:
186188
raise Exception("Nothing to format")
187-
if re.search(r"\{\{[a-zA-Z0-9_]+\}\}", string):
189+
if re.search(r"{{[a-zA-Z0-9_]+}}", string):
188190
raise Exception("Not all strings were formatted")
189191
return string
190192

@@ -334,6 +336,84 @@ def create_empty_log_file(log_file):
334336
subprocess.check_call(command, shell=True)
335337

336338

339+
def copy_cpp_extension_dependencies_issue359(pkg_dir):
340+
"""CEF Python module is written in Cython and is a Python C++
341+
extension and depends on msvcpXX.dll. For Python 3.5 / 3.6 / 3.7
342+
msvcp140.dll is required. See Issue #359. For Python 2.7
343+
msvcp90.dll is required. Etc. These dependencies are not included
344+
with Python binaries from Python.org."""
345+
if not WINDOWS:
346+
return
347+
348+
windows_dir = os.environ["SYSTEMROOT"]
349+
if SYSTEM64:
350+
system32 = os.path.join(windows_dir, "SysWOW64")
351+
system64 = os.path.join(windows_dir, "System32")
352+
else:
353+
system32 = os.path.join(windows_dir, "")
354+
system64 = None
355+
if ARCH64:
356+
system = system64
357+
else:
358+
system = system32
359+
360+
root_search_paths = []
361+
362+
# Need to check for .pyd files for all Python version, because
363+
# the builder/installer work in a way that previous cefpython
364+
# module builds for other Python versions are also included
365+
# in the package. Thus if included, msvcpxx.dll dependency is
366+
# required as well.
367+
368+
# Python 3.5 / 3.6 / 3.7
369+
if os.path.exists(os.path.join(pkg_dir, "cefpython_py35.pyd")) \
370+
or os.path.exists(os.path.join(pkg_dir, "cefpython_py36.pyd")) \
371+
or os.path.exists(os.path.join(pkg_dir, "cefpython_py37.pyd")):
372+
search_paths = [
373+
# This is where Microsoft Visual C++ 2015 Update 3 installs
374+
# (14.00.24212).
375+
os.path.join(system, "msvcp140.dll"),
376+
]
377+
root_search_paths.append(search_paths)
378+
379+
# Python 3.4
380+
if os.path.exists(os.path.join(pkg_dir, "cefpython_py34.pyd")):
381+
search_paths = [
382+
# 10.00.40219.325 installs here on my system.
383+
os.path.join(system, "msvcp100.dll"),
384+
]
385+
root_search_paths.append(search_paths)
386+
387+
# Python 2.7
388+
if os.path.exists(os.path.join(pkg_dir, "cefpython_py27.pyd")):
389+
if ARCH32:
390+
search_paths = [
391+
# This runtime version is shipped with Python 2.7.14
392+
r"c:\Windows\winsxs\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b"
393+
r"_9.0.30729.1_none_e163563597edeada\msvcp90.dll",
394+
]
395+
else:
396+
search_paths = [
397+
# This runtime version is shipped with Python 2.7.14
398+
r"c:\Windows\winsxs\amd64_microsoft.vc90.crt_1fc8b3b9a1e18e3b"
399+
r"_9.0.30729.1_none_99b61f5e8371c1d4\msvcp90.dll",
400+
]
401+
root_search_paths.append(search_paths)
402+
403+
assert len(root_search_paths)
404+
405+
for search_paths in root_search_paths:
406+
found = False
407+
for path in search_paths:
408+
if os.path.exists(path):
409+
shutil.copy(path, pkg_dir)
410+
found = True
411+
if not found:
412+
raise Exception("C++ extension dll dependency not found."
413+
" Search paths: {0}"
414+
.format(", ".join(search_paths)))
415+
416+
337417
def short_src_path(path):
338418
# Very long: \build\cef55_3.2883.1553.g80bd606_win32\
339419
find = os.path.basename(CEF_BINARIES_LIBRARIES)

0 commit comments

Comments
 (0)
X Tutup