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 |