| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 #!/usr/bin/env python | 
|  | 2 # coding: utf-8 | 
|  | 3 """This script fixes the support of manually compiled static libraries for | 
|  | 4 android NDK build system. | 
|  | 5 | 
|  | 6 Issue: | 
|  | 7 Let's say there are some manually compiled libraries specified in | 
|  | 8 link_settings.libraries or in ldflags of a gyp file. In this case ndk-build | 
|  | 9 passes them to a linker after system libraries, like c++_static, and | 
|  | 10 as the result linker cannot find functions from system libraries. | 
|  | 11 | 
|  | 12 Desire: | 
|  | 13 Pass manually compiled libraries after regular dependencies. | 
|  | 14 | 
|  | 15 How it works: | 
|  | 16 The recommended way to do it is to use LOCAL_STATIC_LIBRARIES. However, to | 
|  | 17 simply add libraries to the list is not enough because here ndk-build is trying | 
|  | 18 to be too smart and removes any libraries which are not defined in Makefiles. | 
|  | 19 | 
|  | 20 So, the idea is to monkey patch gyp to inject definition of static libraries | 
|  | 21 and add them to LOCAL_STATIC_LIBRARIES. The former is to prevent them from | 
|  | 22 being removed. | 
|  | 23 | 
|  | 24 Firstly some excerpts from gyp codebase: | 
|  | 25 source: gyp/pylib/gyp/generator/make.py | 
|  | 26 | 
|  | 27 MakefileWriter(object): | 
|  | 28     def Write(self, qualified_target, base_path, output_filename, spec, configs, | 
|  | 29             part_of_all): | 
|  | 30     // The main entry point: writes a .mk file for a single target. | 
|  | 31         ... | 
|  | 32         if android: | 
|  | 33            self.WriteAndroidNdkModuleRule(...) | 
|  | 34 | 
|  | 35     def WriteAndroidNdkModuleRule(self, module_name, all_sources, link_deps): | 
|  | 36     /* Write a set of LOCAL_XXX definitions for Android NDK. | 
|  | 37 | 
|  | 38     These variable definitions will be used by Android NDK but do nothing for | 
|  | 39     non-Android applications. | 
|  | 40 | 
|  | 41     Arguments: | 
|  | 42       module_name: Android NDK module name, which must be unique among all | 
|  | 43           module names. | 
|  | 44       all_sources: A list of source files (will be filtered by Compilable). | 
|  | 45       link_deps: A list of link dependencies, which must be sorted in | 
|  | 46           the order from dependencies to dependents. | 
|  | 47     */ | 
|  | 48         ... | 
|  | 49         self.WriteList( | 
|  | 50                 DepsToModules(link_deps, | 
|  | 51                               generator_default_variables['STATIC_LIB_PREFIX'], | 
|  | 52                               generator_default_variables['STATIC_LIB_SUFFIX']), | 
|  | 53                 'LOCAL_STATIC_LIBRARIES') | 
|  | 54         .... | 
|  | 55 | 
|  | 56     def WriteList(self, value_list, variable=None, prefix='', | 
|  | 57                 quoter=QuoteIfNecessary): | 
|  | 58     // Write a variable definition that is a list of values. | 
|  | 59 | 
|  | 60 The only class which is writing Makefiles is MakefileWriter and the "entry | 
|  | 61 point" is MakefileWriter.Write. To write LOCAL_STATIC_LIBRARIES it uses | 
|  | 62 MakefileWriter.WriteList, so one could simply override | 
|  | 63 - Write method to store all required information and to define (CLEAR_VARS, | 
|  | 64   LOCAL_MODULE, etc) libraries. | 
|  | 65 - WriteList to change the value of LOCAL_STATIC_LIBRARIES. | 
|  | 66 However merely to reduce any potential influence we override | 
|  | 67 MakefileWriter.WriteAndroidNdkModuleRule to define manually compiled libraries | 
|  | 68 and override WriteList only while we are in the WriteAndroidNdkModuleRule method
     . | 
|  | 69 The aim of the latter method is exactly to write Rules for ndk-build and it is | 
|  | 70 called at the end of Write. However, since WriteAndroidNdkModuleRule lacks | 
|  | 71 required information, we override method Write to store configurations as | 
|  | 72 _abp_configs attribute of instance of MakefileWriter. | 
|  | 73 """ | 
|  | 74 | 
|  | 75 import os | 
|  | 76 import sys | 
|  | 77 import types | 
|  | 78 | 
|  | 79 base_dir = os.path.abspath(os.path.dirname(__file__)) | 
|  | 80 sys.path.append(os.path.join(base_dir, 'third_party', 'gyp', 'pylib')) | 
|  | 81 import gyp | 
|  | 82 from gyp.generator.make import MakefileWriter, QuoteIfNecessary | 
|  | 83 | 
|  | 84 | 
|  | 85 orig_MakefileWriter_Write = MakefileWriter.Write | 
|  | 86 orig_MakefileWriter_WriteAndroidNdkModuleRule = MakefileWriter.WriteAndroidNdkMo
     duleRule | 
|  | 87 | 
|  | 88 def overridden_Write(self, qualified_target, base_path, output_filename, spec, c
     onfigs, part_of_all): | 
|  | 89     if hasattr(self, "_abp_configs"): | 
|  | 90       sys.exit("MakefileWriter already has property _abp_configs") | 
|  | 91     self._abp_configs = configs | 
|  | 92     orig_MakefileWriter_Write(self, qualified_target, base_path, output_filename
     , spec, configs, part_of_all) | 
|  | 93     delattr(self, "_abp_configs") | 
|  | 94 | 
|  | 95 def overridden_WriteAndroidNdkModuleRule(self, module_name, all_sources, link_de
     ps): | 
|  | 96     for config in self._abp_configs: | 
|  | 97         libs = self._abp_configs[config].get("user_libraries") | 
|  | 98         if not libs: | 
|  | 99             continue | 
|  | 100         self.WriteLn("ifeq (${{BUILDTYPE}}, {})".format(config)) | 
|  | 101         for lib in libs: | 
|  | 102             self.WriteLn("include $(CLEAR_VARS)") | 
|  | 103             self.WriteLn("LOCAL_MODULE := {}".format(lib)) | 
|  | 104             self.WriteLn("LOCAL_SRC_FILES := {}".format(lib)) | 
|  | 105             self.WriteLn("include $(PREBUILT_STATIC_LIBRARY)") | 
|  | 106             self.WriteLn("ABP_STATIC_LIBRARIES_${{BUILDTYPE}} += {}".format(lib)
     ) | 
|  | 107         self.WriteLn("endif") | 
|  | 108     orig_WriteList = self.WriteList | 
|  | 109     def overridden_WriteList(self, orig_value_list, variable=None, prefix='', qu
     oter=QuoteIfNecessary): | 
|  | 110         value_list = orig_value_list[:] | 
|  | 111         if variable == "LOCAL_STATIC_LIBRARIES": | 
|  | 112             value_list.append("${ABP_STATIC_LIBRARIES_${BUILDTYPE}}") | 
|  | 113         orig_WriteList(value_list, variable, prefix, quoter) | 
|  | 114     self.WriteList = types.MethodType(overridden_WriteList, self) | 
|  | 115     orig_MakefileWriter_WriteAndroidNdkModuleRule(self, module_name, all_sources
     , link_deps) | 
|  | 116     self.WriteList = orig_WriteList | 
|  | 117 | 
|  | 118 MakefileWriter.Write = overridden_Write | 
|  | 119 MakefileWriter.WriteAndroidNdkModuleRule = overridden_WriteAndroidNdkModuleRule | 
|  | 120 | 
|  | 121 if __name__ == '__main__': | 
|  | 122     gyp.main(sys.argv[1:]) | 
| OLD | NEW | 
|---|