tor-browser

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

makefile.py (9625B)


      1 # Copyright (C) 2018 and later: Unicode, Inc. and others.
      2 # License & terms of use: http://www.unicode.org/copyright.html
      3 
      4 # Python 2/3 Compatibility (ICU-20299)
      5 # TODO(ICU-20301): Remove this.
      6 from __future__ import print_function
      7 
      8 from . import *
      9 from .. import *
     10 from .. import utils
     11 from ..request_types import *
     12 
     13 import platform
     14 
     15 def get_gnumake_rules(build_dirs, requests, makefile_vars, **kwargs):
     16    makefile_string = ""
     17 
     18    # Common Variables
     19    common_vars = kwargs["common_vars"]
     20    for key, value in sorted(makefile_vars.items()):
     21        makefile_string += "{KEY} = {VALUE}\n".format(
     22            KEY = key,
     23            VALUE = value
     24        )
     25    makefile_string += "\n"
     26 
     27    # Directories
     28    dirs_timestamp_file = "{TMP_DIR}/dirs.timestamp".format(**common_vars)
     29    makefile_string += "DIRS = {TIMESTAMP_FILE}\n\n".format(
     30        TIMESTAMP_FILE = dirs_timestamp_file
     31    )
     32    makefile_string += "{TIMESTAMP_FILE}:\n\t$(MKINSTALLDIRS) {ALL_DIRS}\n\techo timestamp > {TIMESTAMP_FILE}\n\n".format(
     33        TIMESTAMP_FILE = dirs_timestamp_file,
     34        ALL_DIRS = " ".join(build_dirs).format(**common_vars)
     35    )
     36 
     37    # Generate Rules
     38    make_rules = []
     39    for request in requests:
     40        make_rules += get_gnumake_rules_helper(request, **kwargs)
     41 
     42    # Main Commands
     43    for rule in make_rules:
     44        if isinstance(rule, MakeFilesVar):
     45            makefile_string += "{NAME} = {FILE_LIST}\n\n".format(
     46                NAME = rule.name,
     47                FILE_LIST = files_to_makefile(rule.files, wrap = True, **kwargs),
     48            )
     49            continue
     50 
     51        if isinstance(rule, MakeStringVar):
     52            makefile_string += "define {NAME}\n{CONTENT}\nendef\nexport {NAME}\n\n".format(
     53                NAME = rule.name,
     54                CONTENT = rule.content
     55            )
     56            continue
     57 
     58        assert isinstance(rule, MakeRule)
     59        header_line = "{OUT_FILE}: {DEP_FILES} {DEP_LITERALS} | $(DIRS)".format(
     60            OUT_FILE = files_to_makefile([rule.output_file], **kwargs),
     61            DEP_FILES = files_to_makefile(rule.dep_files, wrap = True, **kwargs),
     62            DEP_LITERALS = " ".join(rule.dep_literals)
     63        )
     64 
     65        if len(rule.cmds) == 0:
     66            makefile_string += "%s\n\n" % header_line
     67            continue
     68 
     69        makefile_string += "{HEADER_LINE}\n{RULE_LINES}\n\n".format(
     70            HEADER_LINE = header_line,
     71            RULE_LINES = "\n".join("\t%s" % cmd for cmd in rule.cmds)
     72        )
     73 
     74    return makefile_string
     75 
     76 def files_to_makefile(files, common_vars, wrap = False, **kwargs):
     77    if len(files) == 0:
     78        return ""
     79    dirnames = [utils.dir_for(file).format(**common_vars) for file in files]
     80    join_str = " \\\n\t\t" if wrap and len(files) > 2 else " "
     81    if len(files) == 1:
     82        return "%s/%s" % (dirnames[0], files[0].filename)
     83    elif len(set(dirnames)) == 1:
     84        return "$(addprefix %s/,%s)" % (dirnames[0], join_str.join(file.filename for file in files))
     85    else:
     86        return join_str.join("%s/%s" % (d, f.filename) for d,f in zip(dirnames, files))
     87 
     88 def get_gnumake_rules_helper(request, common_vars, **kwargs):
     89 
     90    if isinstance(request, PrintFileRequest):
     91        var_name = "%s_CONTENT" % request.name.upper()
     92        platform_os = platform.system()
     93        cmds = []
     94        if platform_os in ["OS390", "OS/390", "zos"] and request.shall_be_utf8:
     95            cmds.append(
     96                    '''echo "$${VAR_NAME}" | iconv -f IBM-1047 -T -t UTF-8 > {MAKEFILENAME}'''.format(
     97                        VAR_NAME = var_name,
     98                        MAKEFILENAME = files_to_makefile([request.output_file], common_vars),
     99                        **common_vars
    100                    ))
    101            cmds.append(
    102                    '''sed -i '1s/^/\\xef\\xbb\\xbf/' {MAKEFILENAME}'''.format(
    103                        MAKEFILENAME = files_to_makefile([request.output_file], common_vars),
    104                        **common_vars
    105                    ))
    106        else:
    107            cmds.append("echo \"$${VAR_NAME}\" > {MAKEFILENAME}".format(
    108                        VAR_NAME = var_name,
    109                        MAKEFILENAME = files_to_makefile([request.output_file], common_vars),
    110                        **common_vars
    111                    ))
    112        return [
    113            MakeStringVar(
    114                name = var_name,
    115                content = request.content
    116            ),
    117            MakeRule(
    118                name = request.name,
    119                dep_literals = [],
    120                dep_files = [],
    121                output_file = request.output_file,
    122                cmds = cmds
    123            )
    124        ]
    125 
    126 
    127    if isinstance(request, CopyRequest):
    128        return [
    129            MakeRule(
    130                name = request.name,
    131                dep_literals = [],
    132                dep_files = [request.input_file],
    133                output_file = request.output_file,
    134                cmds = ["cp %s %s" % (
    135                    files_to_makefile([request.input_file], common_vars),
    136                    files_to_makefile([request.output_file], common_vars))
    137                ]
    138            )
    139        ]
    140 
    141    if isinstance(request, VariableRequest):
    142        return [
    143            MakeFilesVar(
    144                name = request.name.upper(),
    145                files = request.input_files
    146            )
    147        ]
    148 
    149    if request.tool.name == "make":
    150        cmd_template = "$(MAKE) {ARGS}"
    151    elif request.tool.name == "gentest":
    152        cmd_template = "$(INVOKE) $(GENTEST) {ARGS}"
    153    else:
    154        assert isinstance(request.tool, IcuTool)
    155        cmd_template = "$(INVOKE) $(TOOLBINDIR)/{TOOL} {{ARGS}}".format(
    156            TOOL = request.tool.name
    157        )
    158 
    159    if isinstance(request, SingleExecutionRequest):
    160        cmd = utils.format_single_request_command(request, cmd_template, common_vars)
    161        dep_files = request.all_input_files()
    162 
    163        if len(request.output_files) > 1:
    164            # Special case for multiple output files: Makefile rules should have only one
    165            # output file apiece. More information:
    166            # https://www.gnu.org/software/automake/manual/html_node/Multiple-Outputs.html
    167            timestamp_var_name = "%s_ALL" % request.name.upper()
    168            timestamp_file = TmpFile("%s.timestamp" % request.name)
    169            rules = [
    170                MakeFilesVar(
    171                    name = timestamp_var_name,
    172                    files = [timestamp_file]
    173                ),
    174                MakeRule(
    175                    name = "%s_all" % request.name,
    176                    dep_literals = [],
    177                    dep_files = dep_files,
    178                    output_file = timestamp_file,
    179                    cmds = [
    180                        cmd,
    181                        "echo timestamp > {MAKEFILENAME}".format(
    182                            MAKEFILENAME = files_to_makefile([timestamp_file], common_vars)
    183                        )
    184                    ]
    185                )
    186            ]
    187            for i, file in enumerate(request.output_files):
    188                rules += [
    189                    MakeRule(
    190                        name = "%s_%d" % (request.name, i),
    191                        dep_literals = ["$(%s)" % timestamp_var_name],
    192                        dep_files = [],
    193                        output_file = file,
    194                        cmds = []
    195                    )
    196                ]
    197            return rules
    198 
    199        elif len(dep_files) > 5:
    200            # For nicer printing, for long input lists, use a helper variable.
    201            dep_var_name = "%s_DEPS" % request.name.upper()
    202            return [
    203                MakeFilesVar(
    204                    name = dep_var_name,
    205                    files = dep_files
    206                ),
    207                MakeRule(
    208                    name = request.name,
    209                    dep_literals = ["$(%s)" % dep_var_name],
    210                    dep_files = [],
    211                    output_file = request.output_files[0],
    212                    cmds = [cmd]
    213                )
    214            ]
    215 
    216        else:
    217            return [
    218                MakeRule(
    219                    name = request.name,
    220                    dep_literals = [],
    221                    dep_files = dep_files,
    222                    output_file = request.output_files[0],
    223                    cmds = [cmd]
    224                )
    225            ]
    226 
    227    if isinstance(request, RepeatedExecutionRequest):
    228        rules = []
    229        dep_literals = []
    230        # To keep from repeating the same dep files many times, make a variable.
    231        if len(request.common_dep_files) > 0:
    232            dep_var_name = "%s_DEPS" % request.name.upper()
    233            dep_literals = ["$(%s)" % dep_var_name]
    234            rules += [
    235                MakeFilesVar(
    236                    name = dep_var_name,
    237                    files = request.common_dep_files
    238                )
    239            ]
    240        # Add a rule for each individual file.
    241        for loop_vars in utils.repeated_execution_request_looper(request):
    242            (_, specific_dep_files, input_file, output_file) = loop_vars
    243            name_suffix = input_file[input_file.filename.rfind("/")+1:input_file.filename.rfind(".")]
    244            cmd = utils.format_repeated_request_command(
    245                request,
    246                cmd_template,
    247                loop_vars,
    248                common_vars
    249            )
    250            rules += [
    251                MakeRule(
    252                    name = "%s_%s" % (request.name, name_suffix),
    253                    dep_literals = dep_literals,
    254                    dep_files = specific_dep_files + [input_file],
    255                    output_file = output_file,
    256                    cmds = [cmd]
    257                )
    258            ]
    259        return rules
    260 
    261    assert False