create_res.py (3406B)
1 # This Source Code Form is subject to the terms of the Mozilla Public 2 # License, v. 2.0. If a copy of the MPL was not distributed with this 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5 import os 6 import subprocess 7 import sys 8 import tempfile 9 from argparse import Action, ArgumentParser 10 11 import buildconfig 12 13 14 class CPPFlag(Action): 15 all_flags = [] 16 17 def __call__(self, parser, namespace, values, option_string=None): 18 if "windres" in buildconfig.substs["RC"].lower(): 19 if option_string == "-U": 20 return 21 if option_string == "-I": 22 option_string = "--include-dir" 23 24 self.all_flags.extend((option_string, values)) 25 26 27 def generate_res(): 28 parser = ArgumentParser() 29 parser.add_argument( 30 "-D", action=CPPFlag, metavar="VAR[=VAL]", help="Define a variable" 31 ) 32 parser.add_argument("-U", action=CPPFlag, metavar="VAR", help="Undefine a variable") 33 parser.add_argument( 34 "-I", action=CPPFlag, metavar="DIR", help="Search path for includes" 35 ) 36 parser.add_argument("-o", dest="output", metavar="OUTPUT", help="Output file") 37 parser.add_argument("input", help="Input file") 38 args = parser.parse_args() 39 40 is_windres = "windres" in buildconfig.substs["RC"].lower() 41 42 verbose = os.environ.get("BUILD_VERBOSE_LOG") 43 44 # llvm-rc doesn't preprocess on its own, so preprocess manually 45 # Theoretically, not windres could be rc.exe, but configure won't use it 46 # unless you really ask for it, and it will still work with preprocessed 47 # output. 48 try: 49 if not is_windres: 50 fd, path = tempfile.mkstemp(suffix=".rc") 51 command = buildconfig.substs["CXXCPP"] + CPPFlag.all_flags 52 command.extend(("-DRC_INVOKED", args.input)) 53 54 cpu_arch_dict = {"x86_64": "_AMD64_", "x86": "_X86_", "aarch64": "_ARM64_"} 55 56 # add a preprocessor #define that specifies the CPU architecture 57 cpu_arch_ppd = cpu_arch_dict[buildconfig.substs["TARGET_CPU"]] 58 59 command.extend(("-D", cpu_arch_ppd)) 60 61 if verbose: 62 print("Executing:", " ".join(command)) 63 with os.fdopen(fd, "wb") as fh: 64 retcode = subprocess.run(command, check=False, stdout=fh).returncode 65 if retcode: 66 # Rely on the subprocess printing out any relevant error 67 return retcode 68 else: 69 path = args.input 70 71 command = [buildconfig.substs["RC"]] 72 if is_windres: 73 command.extend(("-O", "coff")) 74 75 # Even though llvm-rc doesn't preprocess, we still need to pass at least 76 # the -I flags. 77 command.extend(CPPFlag.all_flags) 78 79 if args.output: 80 if is_windres: 81 command.extend(("-o", args.output)) 82 else: 83 # Use win1252 code page for the input. 84 command.extend(("-c", "1252", "-Fo" + args.output)) 85 86 command.append(path) 87 88 if verbose: 89 print("Executing:", " ".join(command)) 90 retcode = subprocess.run(command, check=False).returncode 91 if retcode: 92 # Rely on the subprocess printing out any relevant error 93 return retcode 94 finally: 95 if path != args.input: 96 os.remove(path) 97 98 return 0 99 100 101 if __name__ == "__main__": 102 sys.exit(generate_res())