[SyncFS] Build indexes from FileTracker entries on disk.
[chromium-blink-merge.git] / native_client_sdk / src / build_tools / make_simple.py
blob90f8d33b168c618d4c749b99494988d2f9652fb7
1 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
5 """This is a simplified Makefile generator for single-target gyp files.
6 It was originally designed for generating readable Makefiles for the
7 the NaCl examples.
8 """
10 # pylint: disable=C0301
12 import os
13 import gyp.common
14 from gyp.common import GetEnvironFallback
15 from gyp.generator.make import QuoteIfNecessary
17 generator_default_variables = {
18 'EXECUTABLE_PREFIX': '',
19 'EXECUTABLE_SUFFIX': '',
20 'STATIC_LIB_PREFIX': 'lib',
21 'SHARED_LIB_PREFIX': 'lib',
22 'STATIC_LIB_SUFFIX': '.a',
23 'INTERMEDIATE_DIR': '$(BUILDDIR)/$(BUILDTYPE)/obj',
24 'SHARED_INTERMEDIATE_DIR': '$(obj)/gen',
25 'PRODUCT_DIR': '$(BUILDDIR)/$(BUILDTYPE)',
26 'CONFIGURATION_NAME': '$(BUILDTYPE)',
30 generator_additional_non_configuration_keys = [
31 'make_valid_configurations',
35 preamble = """\
37 # GNU Make based build file. For details on GNU Make see:
38 # http://www.gnu.org/software/make/manual/make.html
40 # This file was generated by gyp (http://code.google.com/p/gyp/)
42 # Default build configuration
43 BUILDTYPE = %(default_config)s
45 # All possible build configurations
46 BUILDTYPES = %(all_configs)s
48 # Check for valid build configuration
49 ifeq (,$(findstring $(BUILDTYPE),$(BUILDTYPES)))
50 $(warning Possible build configurations are: $(BUILDTYPES))
51 $(warning Cannot use BUILDTYPE=$(BUILDTYPE) with this Makefile.)
52 all:
53 else
55 # Target toolchain
56 CC.target ?= %(CC.target)s
57 CFLAGS.target ?= $(CFLAGS)
58 CXX.target ?= %(CXX.target)s
59 CXXFLAGS.target ?= $(CXXFLAGS)
60 LINK.target ?= %(LINK.target)s
61 LDFLAGS.target ?= $(LDFLAGS)
62 AR.target ?= %(AR.target)s
63 ARFLAGS.target ?= %(ARFLAGS.target)s
65 # Host toolchain
66 CC.host ?= gcc
67 CFLAGS.host ?=
68 CXX.host ?= g++
69 CXXFLAGS.host ?=
70 LINK.host ?= g++
71 LDFLAGS.host ?=
72 AR.host ?= ar
73 ARFLAGS.host := %(ARFLAGS.host)s
75 BUILDDIR = build
77 DEPFLAGS = -MMD
79 DEPFILES :=
81 .PHONY: all clean
83 all:
85 clean:
86 \trm -rf $(BUILDDIR)
87 """
89 none_section = """
90 TARGET = $(BUILDDIR)/$(BUILDTYPE)/%(target)s.stamp
91 all: $(TARGET)
93 INPUTS = %(inputs)s
95 $(TARGET): $(INPUTS)
96 """
99 target_section = """
100 TARGET = %(product)s
101 all: $(TARGET)
103 SOURCES = %(sources)s
105 LIBS_%(target_name_var)s_$(BUILDTYPE) = %(libs)s
107 OBJS = %(objs)s
109 DEPFILES += $(OBJS:%%.o=%%.d)
111 # Suffix rules, putting all outputs into build folder.
112 $(BUILDDIR)/$(BUILDTYPE)/obj_%(target)s/%%.o: %%.c
113 \t@mkdir -p $(dir $@)
114 \t$(CC.%(toolset)s) $(CFLAGS_%(target_name_var)s_$(BUILDTYPE)) -c -o $@ $<
116 $(BUILDDIR)/$(BUILDTYPE)/obj_%(target)s/%%.o: %%.cc
117 \t@mkdir -p $(dir $@)
118 \t$(CXX.%(toolset)s) $(CXXFLAGS_%(target_name_var)s_$(BUILDTYPE)) -c -o $@ $<
122 lib_section = """
123 $(TARGET): $(OBJS)
124 \t@mkdir -p $(dir $@)
125 \t$(AR.%(toolset)s) $(ARFLAGS.%(toolset)s) $(ARFLAGS_%(target_name_var)s_$(BUILDTYPE)) $@ $^
129 link_section = """
130 $(TARGET): $(OBJS)
131 \t@mkdir -p $(dir $@)
132 \t$(LINK.%(toolset)s) $(LDFLAGS_%(target_name_var)s_$(BUILDTYPE)) $(LDFLAGS.%(toolset)s) -o $@ -Wl,--start-group $^ $(LIBS_%(target_name_var)s_$(BUILDTYPE)) -Wl,--end-group
136 def MakeList(value_list, prefix='', quoter=QuoteIfNecessary, initial_indent=0):
137 """Construct from a list of values a string that can be assigned to a make
138 variable. This uses line continuations and limits line length to 80 chars.
140 if not value_list:
141 return ''
143 value_list = [quoter(prefix + l) for l in value_list]
144 lines = []
145 line = ' ' * initial_indent
146 for value in value_list:
147 if len(line) + len(value) >= 79:
148 lines.append(line)
149 line = ''
150 elif line:
151 line += ' '
152 line += value
153 lines.append(line)
154 rtn = ' \\\n\t'.join(lines)
155 return rtn.lstrip()
158 def WriteList(makefile, value_list, variable, prefix='', quoter=QuoteIfNecessary):
159 values = MakeList(value_list, prefix, quoter, initial_indent=len(variable)+4)
160 makefile.write("\n%s := %s\n" % (variable, values))
163 def WriteConfig(makefile, name, config, target_type):
164 WriteList(makefile, config.get('defines', []), 'DEFS_%s' % name, '-D')
165 WriteList(makefile, config.get('cflags', []), 'CPPFLAGS_%s' % name)
166 WriteList(makefile, config.get('arflags', []), 'ARFLAGS_%s' % name)
167 ldflags = config.get('ldflags', [])
168 if target_type == 'shared_library':
169 ldflags.insert(0, '-shared')
170 WriteList(makefile, ldflags, 'LDFLAGS_%s' % name)
172 include_dirs = config.get('include_dirs', [])
173 include_dirs = ["-I%s" % i for i in include_dirs]
174 common_flags = ['$(CPPFLAGS_%s)' % name, '$(DEFS_%s)' % name, '$(DEPFLAGS)']
175 common_flags += include_dirs
176 WriteList(makefile, common_flags + config.get('cflags_c', []), 'CFLAGS_%s' % name)
177 WriteList(makefile, common_flags + config.get('cflags_cc', []), 'CXXFLAGS_%s' % name)
180 def WriteActions(makefile, actions, target_type):
181 for action in actions:
182 cmd = gyp.common.EncodePOSIXShellList(action['action'])
183 makefile.write("\t%s\n" % cmd)
184 if target_type == 'none':
185 makefile.write("\ttouch $@\n")
186 makefile.write("\n")
189 def WriteTarget(makefile, target_info):
190 valid_conf = ' '.join(target_info.get('make_valid_configurations', []))
191 if valid_conf:
192 makefile.write("\nifneq (,$(findstring $(BUILDTYPE),%s))\n" % valid_conf)
194 makefile.write('''
196 # Settings for the '%(target_name)s'
198 ''' % target_info)
200 sources = target_info.get('sources', [])
201 exts = ['.cc', '.c', '.cxx', '.cpp']
202 sources = [s for s in sources if os.path.splitext(s)[1] in exts]
203 objects = [os.path.splitext(src)[0] for src in sources]
204 objects = [obj + '.o' for obj in objects]
206 target_name_var = target_info['target_name']
207 target_name_var = target_name_var.replace('.', '_')
209 for name, config in target_info['configurations'].items():
210 name = target_name_var + '_' + name
211 WriteConfig(makefile, name, config, target_info['type'])
213 actions = target_info.get('actions', [])
215 params = {
216 'target': target_info['target_name'],
217 'product': target_info['target_name'],
218 'target_name_var': target_name_var,
221 if 'product_name' in target_info:
222 params['product'] = target_info['product_name']
224 if target_info['type'] == 'static_library':
225 prefix = 'lib'
226 elif target_info['type'] == 'shared_library':
227 prefix = 'lib'
228 else:
229 prefix = ''
231 if prefix and not params['product'].startswith(prefix):
232 params['product'] = prefix + params['product']
234 dirname = target_info.get('product_dir', '$(BUILDDIR)/$(BUILDTYPE)')
235 params['product'] = os.path.join(dirname, params['product'])
237 if target_info['type'] == 'none':
238 params.update({
239 'inputs': MakeList(actions[0]['inputs'])
241 makefile.write(none_section % params)
242 else:
243 builddir = '$(BUILDDIR)/$(BUILDTYPE)/obj_%s' % target_info['target_name']
244 params.update({
245 'sources': MakeList(sources),
246 'libs': MakeList(target_info['libraries']),
247 'objs': MakeList(["%s/%s" % (builddir, obj) for obj in objects]),
248 'toolset': target_info['toolset']
251 makefile.write(target_section % params)
252 if target_info['type'] == 'static_library':
253 makefile.write(lib_section % params)
254 else:
255 makefile.write(link_section % params)
257 WriteActions(makefile, actions, target_info['type'])
258 if valid_conf:
259 makefile.write('endif\n')
262 def GenerateOutput(target_list, target_dicts, data, params):
263 """Main entry point for this generator.
265 gyp will call this function.
267 options = params['options']
268 makefilename = os.path.join(options.toplevel_dir, 'Makefile')
269 makefile = open(makefilename, 'w')
271 build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0])
272 make_global_settings = data[build_file].get('make_global_settings', [])
273 settings_map = dict((key, value) for key, value in make_global_settings)
275 target_info = target_dicts[target_list[0]]
277 params = {
278 'CC.target': GetEnvironFallback(['CC_target'], '$(CC)'),
279 'AR.target': GetEnvironFallback(['AR_target'], '$(AR)'),
280 'ARFLAGS.target': GetEnvironFallback(['ARFLAGS_target'], 'crs'),
281 'CXX.target': GetEnvironFallback(['CXX_target'], '$(CXX)'),
282 'LINK.target': GetEnvironFallback(['LINK_target'], '$(LINK)') ,
284 'ARFLAGS.host': GetEnvironFallback(['ARFLAGS_host'], 'crs'),
286 'default_config': target_info['default_configuration'],
287 'all_configs': ' '.join(target_info['configurations'].keys()),
290 params.update(settings_map)
291 makefile.write(preamble % params)
293 for target_info in target_dicts.values():
294 WriteTarget(makefile, target_info)
296 makefile.write('''
297 # include (if they exists) the .d dependency files that the compiler generates
298 -include $(DEPFILES)
300 endif
301 ''')
303 makefile.close()