tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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())