Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(216)

Side by Side Diff: pylib/gyp/generator/make.py

Issue 6901022: This change supports Android NDK. (Closed) Base URL: http://gyp.googlecode.com/svn/trunk/
Patch Set: '' Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 # Copyright (c) 2009 Google Inc. All rights reserved. 3 # Copyright (c) 2009 Google Inc. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 # Notes: 7 # Notes:
8 # 8 #
9 # This is all roughly based on the Makefile system used by the Linux 9 # This is all roughly based on the Makefile system used by the Linux
10 # kernel, but is a non-recursive make -- we put the entire dependency 10 # kernel, but is a non-recursive make -- we put the entire dependency
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 # Used in building shared-library-based executables. 496 # Used in building shared-library-based executables.
497 target_link_deps = {} 497 target_link_deps = {}
498 498
499 499
500 class MakefileWriter: 500 class MakefileWriter:
501 """MakefileWriter packages up the writing of one target-specific foobar.mk. 501 """MakefileWriter packages up the writing of one target-specific foobar.mk.
502 502
503 Its only real entry point is Write(), and is mostly used for namespacing. 503 Its only real entry point is Write(), and is mostly used for namespacing.
504 """ 504 """
505 505
506 def __init__(self): 506 def __init__(self, generator_flags):
507 self.generator_flags = generator_flags
507 # Keep track of the total number of outputs for this makefile. 508 # Keep track of the total number of outputs for this makefile.
508 self._num_outputs = 0 509 self._num_outputs = 0
509 510
510 511
511 def NumOutputs(self): 512 def NumOutputs(self):
512 return self._num_outputs 513 return self._num_outputs
513 514
514 515
515 def Write(self, qualified_target, base_path, output_filename, spec, configs, 516 def Write(self, qualified_target, base_path, output_filename, spec, configs,
516 part_of_all): 517 part_of_all):
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 target_outputs[qualified_target] = install_path 598 target_outputs[qualified_target] = install_path
598 599
599 # Update global list of link dependencies. 600 # Update global list of link dependencies.
600 if self.type == 'static_library': 601 if self.type == 'static_library':
601 target_link_deps[qualified_target] = [self.output] 602 target_link_deps[qualified_target] = [self.output]
602 elif self.type == 'shared_library': 603 elif self.type == 'shared_library':
603 # Anyone that uses us transitively depend on all of our link 604 # Anyone that uses us transitively depend on all of our link
604 # dependencies. 605 # dependencies.
605 target_link_deps[qualified_target] = [self.output] + link_deps 606 target_link_deps[qualified_target] = [self.output] + link_deps
606 607
608 # Currently any versions have the same effect, but in future the behavior
609 # could be different.
610 if self.generator_flags.get('android_ndk_version', None):
611 self.WriteAndroidNdkModuleRule(self.target, all_sources, link_deps)
612
607 self.fp.close() 613 self.fp.close()
608 614
609 615
610 def WriteSubMake(self, output_filename, makefile_path, targets, build_dir): 616 def WriteSubMake(self, output_filename, makefile_path, targets, build_dir):
611 """Write a "sub-project" Makefile. 617 """Write a "sub-project" Makefile.
612 618
613 This is a small, wrapper Makefile that calls the top-level Makefile to build 619 This is a small, wrapper Makefile that calls the top-level Makefile to build
614 the targets from a single gyp file (i.e. a sub-project). 620 the targets from a single gyp file (i.e. a sub-project).
615 621
616 Arguments: 622 Arguments:
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
1139 # we'll have generated all the outputs and we're done. 1145 # we'll have generated all the outputs and we're done.
1140 self.WriteLn('%s: %s' % (' '.join(outputs[1:]), outputs[0])) 1146 self.WriteLn('%s: %s' % (' '.join(outputs[1:]), outputs[0]))
1141 # Add a dummy command to the "extra outputs" rule, otherwise make seems to 1147 # Add a dummy command to the "extra outputs" rule, otherwise make seems to
1142 # think these outputs haven't (couldn't have?) changed, and thus doesn't 1148 # think these outputs haven't (couldn't have?) changed, and thus doesn't
1143 # flag them as changed (i.e. include in '$?') when evaluating dependent 1149 # flag them as changed (i.e. include in '$?') when evaluating dependent
1144 # rules, which in turn causes do_cmd() to skip running dependent commands. 1150 # rules, which in turn causes do_cmd() to skip running dependent commands.
1145 self.WriteLn('%s: ;' % (' '.join(outputs[1:]))) 1151 self.WriteLn('%s: ;' % (' '.join(outputs[1:])))
1146 self.WriteLn() 1152 self.WriteLn()
1147 1153
1148 1154
1155 def WriteAndroidNdkModuleRule(self, module_name, all_sources, link_deps):
1156 """Write a set of LOCAL_XXX definitions for Android NDK.
1157
1158 These variable definitions will be used by Android NDK but do nothing for
1159 non-Android applications.
1160
1161 Arguments:
1162 module_name: Android NDK module name, which must be unique among all
1163 module names.
1164 all_sources: A list of source files (will be filtered by Compilable).
1165 link_deps: A list of link dependencies, which must be sorted in
1166 the order from dependencies to dependents.
1167 """
1168 if self.type not in ('executable', 'shared_library', 'static_library'):
1169 return
1170
1171 self.WriteLn('# Variable definitions for Android applications')
1172 self.WriteLn('include $(CLEAR_VARS)')
1173 self.WriteLn('LOCAL_MODULE := ' + module_name)
1174 self.WriteLn('LOCAL_CFLAGS := $(CFLAGS_$(BUILDTYPE)) '
1175 '$(DEFS_$(BUILDTYPE)) '
1176 # LOCAL_CFLAGS is applied to both of C and C++. There is
1177 # no way to specify $(CFLAGS_C_$(BUILDTYPE)) only for C
1178 # sources.
1179 '$(CFLAGS_C_$(BUILDTYPE)) '
1180 # $(INCS_$(BUILDTYPE)) includes the prefix '-I' while
1181 # LOCAL_C_INCLUDES does not expect it. So put it in
1182 # LOCAL_CFLAGS.
1183 '$(INCS_$(BUILDTYPE))')
1184 # LOCAL_CXXFLAGS is obsolete and LOCAL_CPPFLAGS is preferred.
1185 self.WriteLn('LOCAL_CPPFLAGS := $(CFLAGS_CC_$(BUILDTYPE))')
1186 self.WriteLn('LOCAL_C_INCLUDES :=')
1187 self.WriteLn('LOCAL_LDLIBS := $(LDFLAGS_$(BUILDTYPE)) $(LIBS)')
1188
1189 # Detect the C++ extension.
1190 cpp_ext = {'.cc': 0, '.cpp': 0, '.cxx': 0}
1191 default_cpp_ext = '.cpp'
1192 for filename in all_sources:
1193 ext = os.path.splitext(filename)[1]
1194 if ext in cpp_ext:
1195 cpp_ext[ext] += 1
1196 if cpp_ext[ext] > cpp_ext[default_cpp_ext]:
1197 default_cpp_ext = ext
1198 self.WriteLn('LOCAL_CPP_EXTENSION := ' + default_cpp_ext)
1199
1200 self.WriteList(map(self.Absolutify, filter(Compilable, all_sources)),
1201 'LOCAL_SRC_FILES')
1202
1203 # Filter out those which do not match prefix and suffix and produce
1204 # the resulting list without prefix and suffix.
1205 def DepsToModules(deps, prefix, suffix):
1206 modules = []
1207 for filepath in deps:
1208 filename = os.path.basename(filepath)
1209 if filename.startswith(prefix) and filename.endswith(suffix):
1210 modules.append(filename[len(prefix):-len(suffix)])
1211 return modules
1212
1213 self.WriteList(
1214 DepsToModules(link_deps,
1215 generator_default_variables['SHARED_LIB_PREFIX'],
1216 generator_default_variables['SHARED_LIB_SUFFIX']),
1217 'LOCAL_SHARED_LIBRARIES')
1218 self.WriteList(
1219 DepsToModules(link_deps,
1220 generator_default_variables['STATIC_LIB_PREFIX'],
1221 generator_default_variables['STATIC_LIB_SUFFIX']),
1222 'LOCAL_STATIC_LIBRARIES')
1223
1224 if self.type == 'executable':
1225 self.WriteLn('include $(BUILD_EXECUTABLE)')
1226 elif self.type == 'shared_library':
1227 self.WriteLn('include $(BUILD_SHARED_LIBRARY)')
1228 elif self.type == 'static_library':
1229 self.WriteLn('include $(BUILD_STATIC_LIBRARY)')
1230 self.WriteLn()
1231
1232
1149 def WriteLn(self, text=''): 1233 def WriteLn(self, text=''):
1150 self.fp.write(text + '\n') 1234 self.fp.write(text + '\n')
1151 1235
1152 1236
1153 def Objectify(self, path): 1237 def Objectify(self, path):
1154 """Convert a path to its output directory form.""" 1238 """Convert a path to its output directory form."""
1155 if '$(' in path: 1239 if '$(' in path:
1156 path = path.replace('$(obj)/', '$(obj).%s/$(TARGET)/' % self.toolset) 1240 path = path.replace('$(obj)/', '$(obj).%s/$(TARGET)/' % self.toolset)
1157 return path 1241 return path
1158 return '$(obj).%s/$(TARGET)/%s' % (self.toolset, path) 1242 return '$(obj).%s/$(TARGET)/%s' % (self.toolset, path)
1159 1243
1244
1160 def Absolutify(self, path): 1245 def Absolutify(self, path):
1161 """Convert a subdirectory-relative path into a base-relative path. 1246 """Convert a subdirectory-relative path into a base-relative path.
1162 Skips over paths that contain variables.""" 1247 Skips over paths that contain variables."""
1163 if '$(' in path: 1248 if '$(' in path:
1164 return path 1249 return path
1165 return os.path.normpath(os.path.join(self.path, path)) 1250 return os.path.normpath(os.path.join(self.path, path))
1166 1251
1167 1252
1168 def FixupArgPath(self, arg): 1253 def FixupArgPath(self, arg):
1169 if '/' in arg or '.h.' in arg: 1254 if '/' in arg or '.h.' in arg:
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 """Calculate additional variables for use in the build (called by gyp).""" 1348 """Calculate additional variables for use in the build (called by gyp)."""
1264 cc_target = os.environ.get('CC.target', os.environ.get('CC', 'cc')) 1349 cc_target = os.environ.get('CC.target', os.environ.get('CC', 'cc'))
1265 default_variables['LINKER_SUPPORTS_ICF'] = \ 1350 default_variables['LINKER_SUPPORTS_ICF'] = \
1266 gyp.system_test.TestLinkerSupportsICF(cc_command=cc_target) 1351 gyp.system_test.TestLinkerSupportsICF(cc_command=cc_target)
1267 1352
1268 1353
1269 def GenerateOutput(target_list, target_dicts, data, params): 1354 def GenerateOutput(target_list, target_dicts, data, params):
1270 options = params['options'] 1355 options = params['options']
1271 generator_flags = params.get('generator_flags', {}) 1356 generator_flags = params.get('generator_flags', {})
1272 builddir_name = generator_flags.get('output_dir', 'out') 1357 builddir_name = generator_flags.get('output_dir', 'out')
1358 android_ndk_version = generator_flags.get('android_ndk_version', None)
1273 1359
1274 def CalculateMakefilePath(build_file, base_name): 1360 def CalculateMakefilePath(build_file, base_name):
1275 """Determine where to write a Makefile for a given gyp file.""" 1361 """Determine where to write a Makefile for a given gyp file."""
1276 # Paths in gyp files are relative to the .gyp file, but we want 1362 # Paths in gyp files are relative to the .gyp file, but we want
1277 # paths relative to the source root for the master makefile. Grab 1363 # paths relative to the source root for the master makefile. Grab
1278 # the path of the .gyp file as the base to relativize against. 1364 # the path of the .gyp file as the base to relativize against.
1279 # E.g. "foo/bar" when we're constructing targets for "foo/bar/baz.gyp". 1365 # E.g. "foo/bar" when we're constructing targets for "foo/bar/baz.gyp".
1280 base_path = gyp.common.RelativePath(os.path.dirname(build_file), 1366 base_path = gyp.common.RelativePath(os.path.dirname(build_file),
1281 options.depth) 1367 options.depth)
1282 # We write the file in the base_path directory. 1368 # We write the file in the base_path directory.
(...skipping 29 matching lines...) Expand all
1312 header_params = { 1398 header_params = {
1313 'srcdir': srcdir, 1399 'srcdir': srcdir,
1314 'builddir': builddir_name, 1400 'builddir': builddir_name,
1315 'default_configuration': default_configuration, 1401 'default_configuration': default_configuration,
1316 } 1402 }
1317 header_params.update(RunSystemTests()) 1403 header_params.update(RunSystemTests())
1318 1404
1319 ensure_directory_exists(makefile_path) 1405 ensure_directory_exists(makefile_path)
1320 root_makefile = open(makefile_path, 'w') 1406 root_makefile = open(makefile_path, 'w')
1321 root_makefile.write(SHARED_HEADER % header_params) 1407 root_makefile.write(SHARED_HEADER % header_params)
1408 # Currently any versions have the same effect, but in future the behavior
1409 # could be different.
1410 if android_ndk_version:
1411 root_makefile.write(
1412 '# Define LOCAL_PATH for build of Android applications.\n'
1413 'LOCAL_PATH := $(call my-dir)\n'
1414 '\n')
1322 for toolset in toolsets: 1415 for toolset in toolsets:
1323 root_makefile.write('TOOLSET := %s\n' % toolset) 1416 root_makefile.write('TOOLSET := %s\n' % toolset)
1324 root_makefile.write(ROOT_HEADER_SUFFIX_RULES) 1417 root_makefile.write(ROOT_HEADER_SUFFIX_RULES)
1325 1418
1326 # Find the list of targets that derive from the gyp file(s) being built. 1419 # Find the list of targets that derive from the gyp file(s) being built.
1327 needed_targets = set() 1420 needed_targets = set()
1328 for build_file in params['build_files']: 1421 for build_file in params['build_files']:
1329 for target in gyp.common.AllTargets(target_list, target_dicts, build_file): 1422 for target in gyp.common.AllTargets(target_list, target_dicts, build_file):
1330 needed_targets.add(target) 1423 needed_targets.add(target)
1331 1424
(...skipping 20 matching lines...) Expand all
1352 build_files.add(abs_include_file) 1445 build_files.add(abs_include_file)
1353 else: 1446 else:
1354 build_files.add(relative_include_file) 1447 build_files.add(relative_include_file)
1355 1448
1356 base_path, output_file = CalculateMakefilePath(build_file, 1449 base_path, output_file = CalculateMakefilePath(build_file,
1357 target + '.' + toolset + options.suffix + '.mk') 1450 target + '.' + toolset + options.suffix + '.mk')
1358 1451
1359 spec = target_dicts[qualified_target] 1452 spec = target_dicts[qualified_target]
1360 configs = spec['configurations'] 1453 configs = spec['configurations']
1361 1454
1362 writer = MakefileWriter() 1455 writer = MakefileWriter(generator_flags)
1363 writer.Write(qualified_target, base_path, output_file, spec, configs, 1456 writer.Write(qualified_target, base_path, output_file, spec, configs,
1364 part_of_all=qualified_target in needed_targets) 1457 part_of_all=qualified_target in needed_targets)
1365 num_outputs += writer.NumOutputs() 1458 num_outputs += writer.NumOutputs()
1366 1459
1367 # Our root_makefile lives at the source root. Compute the relative path 1460 # Our root_makefile lives at the source root. Compute the relative path
1368 # from there to the output_file for including. 1461 # from there to the output_file for including.
1369 mkfile_rel_path = gyp.common.RelativePath(output_file, 1462 mkfile_rel_path = gyp.common.RelativePath(output_file,
1370 os.path.dirname(makefile_path)) 1463 os.path.dirname(makefile_path))
1371 include_list.add(mkfile_rel_path) 1464 include_list.add(mkfile_rel_path)
1372 1465
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1421 # Add a check to make sure we tried to process all the .d files. 1514 # Add a check to make sure we tried to process all the .d files.
1422 all_deps += """ 1515 all_deps += """
1423 ifneq ($(word %(last)d,$(d_files)),) 1516 ifneq ($(word %(last)d,$(d_files)),)
1424 $(error Found unprocessed dependency files (gyp didn't generate enough rules !)) 1517 $(error Found unprocessed dependency files (gyp didn't generate enough rules !))
1425 endif 1518 endif
1426 """ % { 'last': ((num_outputs / 1000) + 1) * 1000 + 1 } 1519 """ % { 'last': ((num_outputs / 1000) + 1) * 1000 + 1 }
1427 1520
1428 root_makefile.write(SHARED_FOOTER % { 'generate_all_deps': all_deps }) 1521 root_makefile.write(SHARED_FOOTER % { 'generate_all_deps': all_deps })
1429 1522
1430 root_makefile.close() 1523 root_makefile.close()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698