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("--krita-install-dir", action='store',
0047                           help="Specify Krita install dir")
0048 path_options.add_argument(
0049     "--krita-build-dir", action="store", help="Specify Krita build dir")
0050 args = parser.parse_args()
0051 
0052 KRITA_BUILD_DIR = None
0053 
0054 if args.krita_build_dir is not None:
0055     KRITA_BUILD_DIR = args.krita_build_dir
0056 if KRITA_BUILD_DIR is None:
0057     KRITA_BUILD_DIR = f"{os.getcwd()}\\b_msvc"
0058     print(f"Using default Krita build dir: {KRITA_BUILD_DIR}")
0059     if not args.no_interactive:
0060         status = choice()
0061         if not status:
0062             KRITA_BUILD_DIR = prompt_for_dir(
0063                 "Provide path of Krita build dir")
0064     if KRITA_BUILD_DIR is None:
0065         warnings.warn("ERROR: Krita build dir not set!")
0066         exit(102)
0067 print(f"Krita build dir: {KRITA_BUILD_DIR}")
0068 
0069 KRITA_INSTALL_DIR = None
0070 
0071 if args.krita_install_dir is not None:
0072     KRITA_INSTALL_DIR = args.krita_install_dir
0073 if KRITA_INSTALL_DIR is None:
0074     KRITA_INSTALL_DIR = f"{os.getcwd()}\\i_msvc"
0075     print(f"Using default Krita install dir: {KRITA_INSTALL_DIR}")
0076     if not args.no_interactive:
0077         status = choice()
0078         if not status:
0079             KRITA_INSTALL_DIR = prompt_for_dir(
0080                 "Provide path of Krita install dir")
0081     if KRITA_INSTALL_DIR is None:
0082         warnings.warn("ERROR: Krita install dir not set!")
0083         exit(102)
0084 print(f"Krita install dir: {KRITA_INSTALL_DIR}")
0085 
0086 # Simple checking
0087 if not os.path.isdir(KRITA_INSTALL_DIR):
0088     warnings.warn("ERROR: Cannot find the selected install folder!")
0089     exit(1)
0090 if not os.path.isdir(KRITA_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 # try and figure out what configuration was used
0104 # the latter covers the case where Ninja was used to build
0105 configurations = ["MinSizeRel", "RelWithDebInfo", "Release", "Debug", ""]
0106 
0107 configuration = None
0108 
0109 for c in configurations:
0110     if os.path.isfile(f"{KRITA_BUILD_DIR}\\bin\\{c}\\krita.pdb"):
0111         configuration = c
0112         break
0113 
0114 if configuration is None:
0115     warnings.warn("ERROR: No compatible configuration was built!")
0116     exit(102)
0117 
0118 
0119 print("Listing all available PDB files...")
0120 
0121 pdb = glob.glob(
0122     f"{KRITA_BUILD_DIR}\\bin\\{configuration}\\*.pdb", recursive=False)
0123 
0124 print("{} PDB files found in {}.".format(len(pdb), KRITA_BUILD_DIR))
0125 
0126 # Glob all binaries; we'll need to match pairs
0127 
0128 print("Listing all available Krita binaries...")
0129 
0130 bin_exe = glob.glob(
0131     f"{KRITA_INSTALL_DIR}\\bin\\*.exe", recursive=False)
0132 
0133 bin_dll = glob.glob(
0134     f"{KRITA_INSTALL_DIR}\\bin\\**\\*.dll", recursive=True)
0135 
0136 lib_dll = glob.glob(
0137     f"{KRITA_INSTALL_DIR}\\lib\\**\\*.dll", recursive=True)
0138 
0139 print(f"{len(bin_exe) + len(bin_dll) + len(lib_dll)} executable code files found.")
0140 
0141 krita_binaries = {os.path.splitext(os.path.basename(f))[0]: os.path.dirname(
0142     f) for f in itertools.chain(bin_exe, bin_dll, lib_dll)}
0143 
0144 print("Matching up...")
0145 
0146 for src in pdb:
0147     key = os.path.splitext(os.path.basename(src))[0]
0148     if key == "PyKrita.krita":
0149        # This one is manually installed, continue.
0150        continue
0151     dst = krita_binaries.get(key)
0152     if not dst:
0153         continue
0154     if os.path.isfile(f"{dst}\\{os.path.basename(src)}"):
0155         print(f"{src} => {dst} ")
0156         continue
0157     else:
0158         print(f"{src} => {dst}")
0159         shutil.copy(src, dst)