-
Notifications
You must be signed in to change notification settings - Fork 27
/
_hook_copy_pdbs_to_package.py
49 lines (46 loc) · 2.32 KB
/
_hook_copy_pdbs_to_package.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
from conan.tools.files import copy
import glob
import json
import os
import re
from io import StringIO
from conan.errors import ConanException
def post_package(conanfile):
if conanfile.settings.get_safe("os") != "Windows" or conanfile.settings.get_safe("compiler") != "msvc":
return
conanfile.output.info("PDBs post package hook running")
search_package_dll = os.path.join(conanfile.package_folder, "**/*.dll")
package_dll = glob.glob(search_package_dll, recursive=True)
if len(package_dll) == 0:
return
# Find dumpbin path
output = StringIO()
try:
program_files = os.environ.get("ProgramFiles(x86)") or os.environ.get("ProgramFiles") # fallback for 32-bit windows
conanfile.run(
rf'"{program_files}\Microsoft Visual Studio\Installer\vswhere.exe" -find "**\dumpbin.exe" -format json',
stdout=output, scope="")
match = re.search(r'\[(.*?)\]', str(output.getvalue()), re.DOTALL)
dumpbin_path = json.loads(f'[{match.group(1)}]')[0]
except ConanException:
raise ConanException(
"Failed to locate dumpbin.exe which is needed to locate the PDBs and copy them to package folder.")
for dll_path in package_dll:
# Use dumpbin to get the pdb path from each dll
dumpbin_output = StringIO()
pdbpath_flag = "-PDBPATH" if conanfile.win_bash else "/PDBPATH"
conanfile.run(rf'"{dumpbin_path}" {pdbpath_flag} "{dll_path}"', stdout=dumpbin_output)
dumpbin = str(dumpbin_output.getvalue())
pdb_path = re.search(r"[“'\"].*\.pdb[”'\"]", dumpbin)
if pdb_path:
pdb_path = pdb_path.group()[1:-1]
pdb_file = os.path.basename(pdb_path)
src_path = os.path.dirname(pdb_path)
dst_path = os.path.dirname(dll_path)
if src_path != dst_path: # if pdb is not allready in the package folder, then copy
# Copy the corresponding pdb file from the build to the package folder
conanfile.output.info(
f"copying {pdb_file} from {src_path} to {dst_path}")
copy(conanfile, os.path.basename(pdb_path), os.path.dirname(pdb_path), os.path.dirname(dll_path))
else:
conanfile.output.info(f"PDB file {pdb_file} already in destination folder {dst_path}, skipping copy")