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