| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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() |
| OLD | NEW |