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

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

Issue 571053003: android: Build against NDK prebuilts, not system libraries. (Closed) Base URL: http://gyp.googlecode.com/svn/trunk
Patch Set: Created 6 years, 3 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 # Copyright (c) 2012 Google Inc. All rights reserved. 1 # Copyright (c) 2012 Google Inc. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 # Notes: 5 # Notes:
6 # 6 #
7 # This generates makefiles suitable for inclusion into the Android build system 7 # This generates makefiles suitable for inclusion into the Android build system
8 # via an Android.mk file. It is based on make.py, the standard makefile 8 # via an Android.mk file. It is based on make.py, the standard makefile
9 # generator. 9 # generator.
10 # 10 #
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 class AndroidMkWriter(object): 101 class AndroidMkWriter(object):
102 """AndroidMkWriter packages up the writing of one target-specific Android.mk. 102 """AndroidMkWriter packages up the writing of one target-specific Android.mk.
103 103
104 Its only real entry point is Write(), and is mostly used for namespacing. 104 Its only real entry point is Write(), and is mostly used for namespacing.
105 """ 105 """
106 106
107 def __init__(self, android_top_dir): 107 def __init__(self, android_top_dir):
108 self.android_top_dir = android_top_dir 108 self.android_top_dir = android_top_dir
109 109
110 def Write(self, qualified_target, relative_target, base_path, output_filename, 110 def Write(self, qualified_target, relative_target, base_path, output_filename,
111 spec, configs, part_of_all, write_alias_target): 111 spec, configs, part_of_all, write_alias_target, sdk_version):
112 """The main entry point: writes a .mk file for a single target. 112 """The main entry point: writes a .mk file for a single target.
113 113
114 Arguments: 114 Arguments:
115 qualified_target: target we're generating 115 qualified_target: target we're generating
116 relative_target: qualified target name relative to the root 116 relative_target: qualified target name relative to the root
117 base_path: path relative to source root we're building in, used to resolve 117 base_path: path relative to source root we're building in, used to resolve
118 target-relative paths 118 target-relative paths
119 output_filename: output .mk file name to write 119 output_filename: output .mk file name to write
120 spec, configs: gyp info 120 spec, configs: gyp info
121 part_of_all: flag indicating this target is part of 'all' 121 part_of_all: flag indicating this target is part of 'all'
122 write_alias_target: flag indicating whether to create short aliases for 122 write_alias_target: flag indicating whether to create short aliases for
123 this target 123 this target
124 sdk_version: what to emit for LOCAL_SDK_VERSION in output
124 """ 125 """
125 gyp.common.EnsureDirExists(output_filename) 126 gyp.common.EnsureDirExists(output_filename)
126 127
127 self.fp = open(output_filename, 'w') 128 self.fp = open(output_filename, 'w')
128 129
129 self.fp.write(header) 130 self.fp.write(header)
130 131
131 self.qualified_target = qualified_target 132 self.qualified_target = qualified_target
132 self.relative_target = relative_target 133 self.relative_target = relative_target
133 self.path = base_path 134 self.path = base_path
(...skipping 25 matching lines...) Expand all
159 # makes sure that stem == modulename in these cases. 160 # makes sure that stem == modulename in these cases.
160 if self.android_stem != self.android_module: 161 if self.android_stem != self.android_module:
161 self.WriteLn('LOCAL_MODULE_STEM := ' + self.android_stem) 162 self.WriteLn('LOCAL_MODULE_STEM := ' + self.android_stem)
162 self.WriteLn('LOCAL_MODULE_SUFFIX := ' + self.android_suffix) 163 self.WriteLn('LOCAL_MODULE_SUFFIX := ' + self.android_suffix)
163 if self.toolset == 'host': 164 if self.toolset == 'host':
164 self.WriteLn('LOCAL_IS_HOST_MODULE := true') 165 self.WriteLn('LOCAL_IS_HOST_MODULE := true')
165 self.WriteLn('LOCAL_MULTILIB := $(GYP_HOST_MULTILIB)') 166 self.WriteLn('LOCAL_MULTILIB := $(GYP_HOST_MULTILIB)')
166 else: 167 else:
167 self.WriteLn('LOCAL_MODULE_TARGET_ARCH := ' 168 self.WriteLn('LOCAL_MODULE_TARGET_ARCH := '
168 '$(TARGET_$(GYP_VAR_PREFIX)ARCH)') 169 '$(TARGET_$(GYP_VAR_PREFIX)ARCH)')
170 self.WriteLn('LOCAL_SDK_VERSION := %s' % sdk_version)
169 171
170 # Grab output directories; needed for Actions and Rules. 172 # Grab output directories; needed for Actions and Rules.
171 if self.toolset == 'host': 173 if self.toolset == 'host':
172 self.WriteLn('gyp_intermediate_dir := ' 174 self.WriteLn('gyp_intermediate_dir := '
173 '$(call local-intermediates-dir,,$(GYP_HOST_VAR_PREFIX))') 175 '$(call local-intermediates-dir,,$(GYP_HOST_VAR_PREFIX))')
174 else: 176 else:
175 self.WriteLn('gyp_intermediate_dir := ' 177 self.WriteLn('gyp_intermediate_dir := '
176 '$(call local-intermediates-dir,,$(GYP_VAR_PREFIX))') 178 '$(call local-intermediates-dir,,$(GYP_VAR_PREFIX))')
177 self.WriteLn('gyp_shared_intermediate_dir := ' 179 self.WriteLn('gyp_shared_intermediate_dir := '
178 '$(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))') 180 '$(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))')
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 clean_cflags = [] 714 clean_cflags = []
713 include_paths = [] 715 include_paths = []
714 for flag in cflags: 716 for flag in cflags:
715 if flag.startswith('-I'): 717 if flag.startswith('-I'):
716 include_paths.append(flag[2:]) 718 include_paths.append(flag[2:])
717 else: 719 else:
718 clean_cflags.append(flag) 720 clean_cflags.append(flag)
719 721
720 return (clean_cflags, include_paths) 722 return (clean_cflags, include_paths)
721 723
722 def ComputeAndroidLibraryModuleNames(self, libraries): 724 def FilterLibraries(self, libraries):
723 """Compute the Android module names from libraries, ie spec.get('libraries') 725 """Filter the 'libraries' key to separate things that shouldn't be ldflags.
726
727 Library entries that look like filenames should be converted to android
728 module names instead of being passed to the linker as flags.
724 729
725 Args: 730 Args:
726 libraries: the value of spec.get('libraries') 731 libraries: the value of spec.get('libraries')
727 Returns: 732 Returns:
728 A tuple (static_lib_modules, dynamic_lib_modules) 733 A tuple (static_lib_modules, dynamic_lib_modules, ldflags)
729 """ 734 """
730 static_lib_modules = [] 735 static_lib_modules = []
731 dynamic_lib_modules = [] 736 dynamic_lib_modules = []
737 ldflags = []
732 for libs in libraries: 738 for libs in libraries:
733 # Libs can have multiple words. 739 # Libs can have multiple words.
734 for lib in libs.split(): 740 for lib in libs.split():
735 # Filter the system libraries, which are added by default by the Android 741 # Filter the system libraries, which are added by default by the Android
736 # build system. 742 # build system.
737 if (lib == '-lc' or lib == '-lstdc++' or lib == '-lm' or 743 if (lib == '-lc' or lib == '-lstdc++' or lib == '-lm' or
738 lib.endswith('libgcc.a')): 744 lib.endswith('libgcc.a')):
739 continue 745 continue
740 match = re.search(r'([^/]+)\.a$', lib) 746 match = re.search(r'([^/]+)\.a$', lib)
741 if match: 747 if match:
742 static_lib_modules.append(match.group(1)) 748 static_lib_modules.append(match.group(1))
743 continue 749 continue
744 match = re.search(r'([^/]+)\.so$', lib) 750 match = re.search(r'([^/]+)\.so$', lib)
745 if match: 751 if match:
746 dynamic_lib_modules.append(match.group(1)) 752 dynamic_lib_modules.append(match.group(1))
747 continue 753 continue
748 # "-lstlport" -> libstlport
749 if lib.startswith('-l'): 754 if lib.startswith('-l'):
750 if lib.endswith('_static'): 755 ldflags.append(lib)
751 static_lib_modules.append('lib' + lib[2:]) 756 return (static_lib_modules, dynamic_lib_modules, ldflags)
752 else:
753 dynamic_lib_modules.append('lib' + lib[2:])
754 return (static_lib_modules, dynamic_lib_modules)
755 757
756 758
757 def ComputeDeps(self, spec): 759 def ComputeDeps(self, spec):
758 """Compute the dependencies of a gyp spec. 760 """Compute the dependencies of a gyp spec.
759 761
760 Returns a tuple (deps, link_deps), where each is a list of 762 Returns a tuple (deps, link_deps), where each is a list of
761 filenames that will need to be put in front of make for either 763 filenames that will need to be put in front of make for either
762 building (deps) or linking (link_deps). 764 building (deps) or linking (link_deps).
763 """ 765 """
764 deps = [] 766 deps = []
765 link_deps = [] 767 link_deps = []
766 if 'dependencies' in spec: 768 if 'dependencies' in spec:
767 deps.extend([target_outputs[dep] for dep in spec['dependencies'] 769 deps.extend([target_outputs[dep] for dep in spec['dependencies']
768 if target_outputs[dep]]) 770 if target_outputs[dep]])
769 for dep in spec['dependencies']: 771 for dep in spec['dependencies']:
770 if dep in target_link_deps: 772 if dep in target_link_deps:
771 link_deps.append(target_link_deps[dep]) 773 link_deps.append(target_link_deps[dep])
772 deps.extend(link_deps) 774 deps.extend(link_deps)
773 return (gyp.common.uniquer(deps), gyp.common.uniquer(link_deps)) 775 return (gyp.common.uniquer(deps), gyp.common.uniquer(link_deps))
774 776
775 777
776 def WriteTargetFlags(self, spec, configs, link_deps): 778 def WriteTargetFlags(self, spec, configs, link_deps):
777 """Write Makefile code to specify the link flags and library dependencies. 779 """Write Makefile code to specify the link flags and library dependencies.
778 780
779 spec, configs: input from gyp. 781 spec, configs: input from gyp.
780 link_deps: link dependency list; see ComputeDeps() 782 link_deps: link dependency list; see ComputeDeps()
781 """ 783 """
784 # Libraries (i.e. -lfoo)
785 # These must be included even for static libraries as some of them provide
786 # implicit include paths through the build system.
787 libraries = gyp.common.uniquer(spec.get('libraries', []))
788 static_libs, dynamic_libs, ldflags_libs = self.FilterLibraries(libraries)
789
782 if self.type != 'static_library': 790 if self.type != 'static_library':
783 for configname, config in sorted(configs.iteritems()): 791 for configname, config in sorted(configs.iteritems()):
784 ldflags = list(config.get('ldflags', [])) 792 ldflags = list(config.get('ldflags', []))
785 self.WriteLn('') 793 self.WriteLn('')
786 self.WriteList(ldflags, 'LOCAL_LDFLAGS_%s' % configname) 794 self.WriteList(ldflags, 'LOCAL_LDFLAGS_%s' % configname)
787 self.WriteLn('\nLOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))') 795 self.WriteList(ldflags_libs, 'LOCAL_GYP_LIBS')
788 796 self.WriteLn('LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION)) '
789 # Libraries (i.e. -lfoo) 797 '$(LOCAL_GYP_LIBS)')
790 # These must be included even for static libraries as some of them provide
791 # implicit include paths through the build system.
792 libraries = gyp.common.uniquer(spec.get('libraries', []))
793 static_libs, dynamic_libs = self.ComputeAndroidLibraryModuleNames(
794 libraries)
795 798
796 # Link dependencies (i.e. other gyp targets this target depends on) 799 # Link dependencies (i.e. other gyp targets this target depends on)
797 # These need not be included for static libraries as within the gyp build 800 # These need not be included for static libraries as within the gyp build
798 # we do not use the implicit include path mechanism. 801 # we do not use the implicit include path mechanism.
799 if self.type != 'static_library': 802 if self.type != 'static_library':
800 static_link_deps = [x[1] for x in link_deps if x[0] == 'static'] 803 static_link_deps = [x[1] for x in link_deps if x[0] == 'static']
801 shared_link_deps = [x[1] for x in link_deps if x[0] == 'shared'] 804 shared_link_deps = [x[1] for x in link_deps if x[0] == 'shared']
802 else: 805 else:
803 static_link_deps = [] 806 static_link_deps = []
804 shared_link_deps = [] 807 shared_link_deps = []
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
955 print 'Building: %s' % arguments 958 print 'Building: %s' % arguments
956 subprocess.check_call(arguments, env=env) 959 subprocess.check_call(arguments, env=env)
957 960
958 961
959 def GenerateOutput(target_list, target_dicts, data, params): 962 def GenerateOutput(target_list, target_dicts, data, params):
960 options = params['options'] 963 options = params['options']
961 generator_flags = params.get('generator_flags', {}) 964 generator_flags = params.get('generator_flags', {})
962 builddir_name = generator_flags.get('output_dir', 'out') 965 builddir_name = generator_flags.get('output_dir', 'out')
963 limit_to_target_all = generator_flags.get('limit_to_target_all', False) 966 limit_to_target_all = generator_flags.get('limit_to_target_all', False)
964 write_alias_targets = generator_flags.get('write_alias_targets', True) 967 write_alias_targets = generator_flags.get('write_alias_targets', True)
968 sdk_version = generator_flags.get('aosp_sdk_version', 19)
965 android_top_dir = os.environ.get('ANDROID_BUILD_TOP') 969 android_top_dir = os.environ.get('ANDROID_BUILD_TOP')
966 assert android_top_dir, '$ANDROID_BUILD_TOP not set; you need to run lunch.' 970 assert android_top_dir, '$ANDROID_BUILD_TOP not set; you need to run lunch.'
967 971
968 def CalculateMakefilePath(build_file, base_name): 972 def CalculateMakefilePath(build_file, base_name):
969 """Determine where to write a Makefile for a given gyp file.""" 973 """Determine where to write a Makefile for a given gyp file."""
970 # Paths in gyp files are relative to the .gyp file, but we want 974 # Paths in gyp files are relative to the .gyp file, but we want
971 # paths relative to the source root for the master makefile. Grab 975 # paths relative to the source root for the master makefile. Grab
972 # the path of the .gyp file as the base to relativize against. 976 # the path of the .gyp file as the base to relativize against.
973 # E.g. "foo/bar" when we're constructing targets for "foo/bar/baz.gyp". 977 # E.g. "foo/bar" when we're constructing targets for "foo/bar/baz.gyp".
974 base_path = gyp.common.RelativePath(os.path.dirname(build_file), 978 base_path = gyp.common.RelativePath(os.path.dirname(build_file),
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 not int(spec.get('suppress_wildcard', False))) 1055 not int(spec.get('suppress_wildcard', False)))
1052 if limit_to_target_all and not part_of_all: 1056 if limit_to_target_all and not part_of_all:
1053 continue 1057 continue
1054 1058
1055 relative_target = gyp.common.QualifiedTarget(relative_build_file, target, 1059 relative_target = gyp.common.QualifiedTarget(relative_build_file, target,
1056 toolset) 1060 toolset)
1057 writer = AndroidMkWriter(android_top_dir) 1061 writer = AndroidMkWriter(android_top_dir)
1058 android_module = writer.Write(qualified_target, relative_target, base_path, 1062 android_module = writer.Write(qualified_target, relative_target, base_path,
1059 output_file, spec, configs, 1063 output_file, spec, configs,
1060 part_of_all=part_of_all, 1064 part_of_all=part_of_all,
1061 write_alias_target=write_alias_targets) 1065 write_alias_target=write_alias_targets,
1066 sdk_version=sdk_version)
1062 if android_module in android_modules: 1067 if android_module in android_modules:
1063 print ('ERROR: Android module names must be unique. The following ' 1068 print ('ERROR: Android module names must be unique. The following '
1064 'targets both generate Android module name %s.\n %s\n %s' % 1069 'targets both generate Android module name %s.\n %s\n %s' %
1065 (android_module, android_modules[android_module], 1070 (android_module, android_modules[android_module],
1066 qualified_target)) 1071 qualified_target))
1067 return 1072 return
1068 android_modules[android_module] = qualified_target 1073 android_modules[android_module] = qualified_target
1069 1074
1070 # Our root_makefile lives at the source root. Compute the relative path 1075 # Our root_makefile lives at the source root. Compute the relative path
1071 # from there to the output_file for including. 1076 # from there to the output_file for including.
1072 mkfile_rel_path = gyp.common.RelativePath(output_file, 1077 mkfile_rel_path = gyp.common.RelativePath(output_file,
1073 os.path.dirname(makefile_path)) 1078 os.path.dirname(makefile_path))
1074 include_list.add(mkfile_rel_path) 1079 include_list.add(mkfile_rel_path)
1075 1080
1076 root_makefile.write('GYP_CONFIGURATION ?= %s\n' % default_configuration) 1081 root_makefile.write('GYP_CONFIGURATION ?= %s\n' % default_configuration)
1077 root_makefile.write('GYP_VAR_PREFIX ?=\n') 1082 root_makefile.write('GYP_VAR_PREFIX ?=\n')
1078 root_makefile.write('GYP_HOST_VAR_PREFIX ?=\n') 1083 root_makefile.write('GYP_HOST_VAR_PREFIX ?=\n')
1079 root_makefile.write('GYP_HOST_MULTILIB ?=\n') 1084 root_makefile.write('GYP_HOST_MULTILIB ?=\n')
1080 1085
1081 # Write out the sorted list of includes. 1086 # Write out the sorted list of includes.
1082 root_makefile.write('\n') 1087 root_makefile.write('\n')
1083 for include_file in sorted(include_list): 1088 for include_file in sorted(include_list):
1084 root_makefile.write('include $(LOCAL_PATH)/' + include_file + '\n') 1089 root_makefile.write('include $(LOCAL_PATH)/' + include_file + '\n')
1085 root_makefile.write('\n') 1090 root_makefile.write('\n')
1086 1091
1087 if write_alias_targets: 1092 if write_alias_targets:
1088 root_makefile.write(ALL_MODULES_FOOTER) 1093 root_makefile.write(ALL_MODULES_FOOTER)
1089 1094
1090 root_makefile.close() 1095 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