File indexing completed on 2024-05-12 16:02:32

0001 #!/usr/bin/env python
0002 
0003 # SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
0004 # SPDX-License-Identifier: GPL-2.0-or-later
0005 
0006 # This Python script tries to retrieve all missing PDBs for
0007 # existing EXEs or DLLs from their build folders
0008 
0009 import argparse
0010 import glob
0011 import itertools
0012 import os
0013 import shutil
0014 import warnings
0015 
0016 # Subroutines
0017 
0018 
0019 def choice(prompt="Is this ok?"):
0020     c = input(f"{prompt} [y/n] ")
0021     if c == "y":
0022         return True
0023     else:
0024         return False
0025 
0026 
0027 def prompt_for_dir(prompt):
0028     user_input = input(f"{prompt}: ")
0029     if not len(user_input):
0030         return None
0031     result = os.path.exists(user_input)
0032     if result is None:
0033         print("Input does not point to valid dir!")
0034         return prompt_for_dir(prompt)
0035     else:
0036         return os.path.realpath(user_input)
0037 
0038 
0039 # command-line args parsing
0040 parser = argparse.ArgumentParser()
0041 
0042 basic_options = parser.add_argument_group("Basic options")
0043 basic_options.add_argument("--no-interactive", action='store_true',
0044                            help="Run without interactive prompts. When not specified, the script will prompt for some of the parameters.")
0045 path_options = parser.add_argument_group("Path options")
0046 path_options.add_argument("--deps-install-dir", action='store',
0047                           help="Specify deps install dir")
0048 path_options.add_argument("--deps-build-dir", action='store',
0049                           help="Specify deps build dir")
0050 args = parser.parse_args()
0051 
0052 DEPS_BUILD_DIR = None
0053 
0054 if args.deps_build_dir is not None:
0055     DEPS_BUILD_DIR = args.deps_build_dir
0056 if DEPS_BUILD_DIR is None:
0057     DEPS_BUILD_DIR = f"{os.getcwd()}\\b_deps_msvc"
0058     print(f"Using default deps build dir: {DEPS_BUILD_DIR}")
0059     if not args.no_interactive:
0060         status = choice()
0061         if not status:
0062             DEPS_BUILD_DIR = prompt_for_dir(
0063                 "Provide path of deps build dir")
0064     if DEPS_BUILD_DIR is None:
0065         warnings.warn("ERROR: Deps build dir not set!")
0066         exit(102)
0067 print(f"Deps build dir: {DEPS_BUILD_DIR}")
0068 
0069 DEPS_INSTALL_DIR = None
0070 
0071 if args.deps_install_dir is not None:
0072     DEPS_INSTALL_DIR = args.deps_install_dir
0073 if DEPS_INSTALL_DIR is None:
0074     DEPS_INSTALL_DIR = f"{os.getcwd()}\\i_deps_msvc"
0075     print(f"Using default deps install dir: {DEPS_INSTALL_DIR}")
0076     if not args.no_interactive:
0077         status = choice()
0078         if not status:
0079             DEPS_INSTALL_DIR = prompt_for_dir(
0080                 "Provide path of deps install dir")
0081     if DEPS_INSTALL_DIR is None:
0082         warnings.warn("ERROR: Deps install dir not set!")
0083         exit(102)
0084 print(f"Deps install dir: {DEPS_INSTALL_DIR}")
0085 
0086 # Simple checking
0087 if not os.path.isdir(DEPS_INSTALL_DIR):
0088     warnings.warn("ERROR: Cannot find the selected install folder!")
0089     exit(1)
0090 if not os.path.isdir(DEPS_BUILD_DIR):
0091     warnings.warn("ERROR: Cannot find the selected build folder!")
0092     exit(1)
0093 # Amyspark: paths with spaces are automagically handled by Python!
0094 
0095 if not args.no_interactive:
0096     status = choice()
0097     if not status:
0098         exit(255)
0099     print("")
0100 
0101 # Glob all PDBs for Krita binaries
0102 
0103 print("Listing all available PDB files...")
0104 
0105 deps_pdb = glob.glob(
0106     f"{DEPS_BUILD_DIR}\\**\\*.pdb", recursive=True)
0107 
0108 print("{} PDB files found in {}.".format(len(deps_pdb), DEPS_BUILD_DIR))
0109 
0110 # Glob all binaries; we'll need to match pairs
0111 
0112 print("Listing all available dependencies binaries...")
0113 
0114 bin_exe = glob.glob(
0115     f"{DEPS_INSTALL_DIR}\\bin\\**\\*.exe", recursive=True)
0116 
0117 bin_dll = glob.glob(
0118     f"{DEPS_INSTALL_DIR}\\bin\\**\\*.dll", recursive=True)
0119 
0120 lib_dll = glob.glob(
0121     f"{DEPS_INSTALL_DIR}\\lib\\**\\*.dll", recursive=True)
0122 
0123 lib_pyd = glob.glob(
0124     f"{DEPS_INSTALL_DIR}\\lib\\**\\*.pyd", recursive=True)
0125 
0126 print(f"{len(bin_exe) + len(bin_dll) + len(lib_dll) + len(lib_pyd)} executable code files found.")
0127 
0128 deps_binaries = {os.path.splitext(os.path.basename(f))[0]: os.path.dirname(
0129     f) for f in itertools.chain(bin_exe, bin_dll, lib_dll, lib_pyd)}
0130 
0131 print("Matching up...")
0132 
0133 for src in deps_pdb:
0134     key = os.path.splitext(os.path.basename(src))[0]
0135     dst = deps_binaries.get(key)
0136     if not dst:
0137         continue
0138     print(f"{src} => {dst}")
0139     shutil.copy(src, dst)