1 #!/usr/bin/python 2 3 # Copyright 2014 Google Inc. 4 # 5 # Use of this source code is governed by a BSD-style license that can be 6 # found in the LICENSE file. 7 8 """ 9 Functions for creating an Android.mk from already created dictionaries. 10 """ 11 12 import os 13 14 def write_group(f, name, items, append): 15 """Helper function to list all names passed to a variable. 16 17 Args: 18 f: File open for writing (Android.mk) 19 name: Name of the makefile variable (e.g. LOCAL_CFLAGS) 20 items: list of strings to be passed to the variable. 21 append: Whether to append to the variable or overwrite it. 22 """ 23 if not items: 24 return 25 26 # Copy the list so we can prepend it with its name. 27 items_to_write = list(items) 28 29 if append: 30 items_to_write.insert(0, '%s +=' % name) 31 else: 32 items_to_write.insert(0, '%s :=' % name) 33 34 f.write(' \\\n\t'.join(items_to_write)) 35 36 f.write('\n\n') 37 38 39 def write_local_vars(f, var_dict, append, name): 40 """Helper function to write all the members of var_dict to the makefile. 41 42 Args: 43 f: File open for writing (Android.mk) 44 var_dict: VarsDict holding the unique values for one configuration. 45 append: Whether to append to each makefile variable or overwrite it. 46 name: If not None, a string to be appended to each key. 47 """ 48 for key in var_dict.keys(): 49 _key = key 50 _items = var_dict[key] 51 if key == 'LOCAL_CFLAGS': 52 # Always append LOCAL_CFLAGS. This allows us to define some early on in 53 # the makefile and not overwrite them. 54 _append = True 55 elif key == 'DEFINES': 56 # For DEFINES, we want to append to LOCAL_CFLAGS. 57 _append = True 58 _key = 'LOCAL_CFLAGS' 59 _items_with_D = [] 60 for define in _items: 61 _items_with_D.append('-D' + define) 62 _items = _items_with_D 63 elif key == 'KNOWN_TARGETS': 64 # KNOWN_TARGETS are not needed in the final make file. 65 continue 66 else: 67 _append = append 68 if name: 69 _key += '_' + name 70 write_group(f, _key, _items, _append) 71 72 73 AUTOGEN_WARNING = ( 74 """ 75 ############################################################################### 76 # 77 # THIS FILE IS AUTOGENERATED BY GYP_TO_ANDROID.PY. DO NOT EDIT. 78 # 79 # For bugs, please contact scroggo (at] google.com or djsollen (at] google.com 80 # 81 ############################################################################### 82 83 """ 84 ) 85 86 DEBUGGING_HELP = ( 87 """ 88 ############################################################################### 89 # 90 # PROBLEMS WITH SKIA DEBUGGING?? READ THIS... 91 # 92 # The debug build results in changes to the Skia headers. This means that those 93 # using libskia must also be built with the debug version of the Skia headers. 94 # There are a few scenarios where this comes into play: 95 # 96 # (1) You're building debug code that depends on libskia. 97 # (a) If libskia is built in release, then define SK_RELEASE when building 98 # your sources. 99 # (b) If libskia is built with debugging (see step 2), then no changes are 100 # needed since your sources and libskia have been built with SK_DEBUG. 101 # (2) You're building libskia in debug mode. 102 # (a) RECOMMENDED: You can build the entire system in debug mode. Do this by 103 # updating your build/core/config.mk to include -DSK_DEBUG on the line 104 # that defines COMMON_GLOBAL_CFLAGS 105 # (b) You can update all the users of libskia to define SK_DEBUG when they are 106 # building their sources. 107 # 108 # NOTE: If neither SK_DEBUG or SK_RELEASE are defined then Skia checks NDEBUG to 109 # determine which build type to use. 110 ############################################################################### 111 """ 112 ) 113 114 SKIA_TOOLS = ( 115 """ 116 ############################################################# 117 # Build the skia tools 118 # 119 120 # benchmark (timings) 121 include $(BASE_PATH)/bench/Android.mk 122 123 # diamond-master (one test to rule them all) 124 include $(BASE_PATH)/dm/Android.mk 125 """ 126 ) 127 128 STATIC_HEADER = ( 129 """ 130 ############################################################################### 131 # STATIC LIBRARY 132 # 133 # This target is only to be used internally for only one of two purposes... 134 # (1) statically linking into testing frameworks 135 # (2) as an inclusion target for the libskia.so shared library 136 ############################################################################### 137 138 """ 139 ) 140 141 SHARED_HEADER = ( 142 """ 143 ############################################################################### 144 # SHARED LIBRARY 145 ############################################################################### 146 147 """ 148 ) 149 150 STATIC_DEPS_INFO = ( 151 """ 152 ############################################################################### 153 # 154 # This file contains the shared and static dependencies needed by any target 155 # that attempts to statically link Skia (i.e. libskia_static build target). 156 # 157 # This is a workaround for the fact that the build system does not add these 158 # transitive dependencies when it attempts to link libskia_static into another 159 # library. 160 # 161 ############################################################################### 162 """ 163 ) 164 165 CLEAR_VARS = ("""include $(CLEAR_VARS)\n""") 166 LOCAL_PATH = ("""LOCAL_PATH:= $(call my-dir)\n""") 167 168 class VarsDictData(object): 169 """Helper class to keep a VarsDict along with a name and optional condition. 170 """ 171 def __init__(self, vars_dict, name, condition=None): 172 """Create a new VarsDictData. 173 174 Args: 175 vars_dict: A VarsDict. Can be accessed via self.vars_dict. 176 name: Name associated with the VarsDict. Can be accessed via 177 self.name. 178 condition: Optional string representing a condition. If not None, 179 used to create a conditional inside the makefile. 180 """ 181 self.vars_dict = vars_dict 182 self.condition = condition 183 self.name = name 184 185 def write_static_deps_mk(target_dir, common, deviations_from_common): 186 """Given all the variables, write the final make file. 187 188 Args: 189 target_dir: The full path to the directory to write skia_static_includes.mk, 190 or None to use the current working directory. 191 common: VarsDict holding variables definitions common to all 192 configurations. 193 deviations_from_common: List of VarsDictData, one for each possible 194 configuration. VarsDictData.name will be appended to each key before 195 writing it to the makefile. VarsDictData.condition, if not None, will be 196 written to the makefile as a condition to determine whether to include 197 VarsDictData.vars_dict. 198 """ 199 target_file = 'skia_static_deps.mk' 200 if target_dir: 201 target_file = os.path.join(target_dir, target_file) 202 with open(target_file, 'w') as f: 203 f.write(AUTOGEN_WARNING) 204 f.write(STATIC_DEPS_INFO) 205 206 for data in deviations_from_common: 207 var_dict_shared = data.vars_dict['LOCAL_SHARED_LIBRARIES'] 208 var_dict_static = data.vars_dict['LOCAL_STATIC_LIBRARIES'] 209 if data.condition and (var_dict_shared or var_dict_static): 210 f.write('ifeq ($(%s), true)\n' % data.condition) 211 write_group(f, 'LOCAL_SHARED_LIBRARIES', var_dict_shared, True) 212 write_group(f, 'LOCAL_STATIC_LIBRARIES', var_dict_static, True) 213 if data.condition and (var_dict_shared or var_dict_static): 214 f.write('endif\n\n') 215 216 write_group(f, 'LOCAL_SHARED_LIBRARIES', common['LOCAL_SHARED_LIBRARIES'], 217 True) 218 write_group(f, 'LOCAL_STATIC_LIBRARIES', common['LOCAL_STATIC_LIBRARIES'], 219 True) 220 221 222 def write_android_mk(target_dir, common, deviations_from_common): 223 """Given all the variables, write the final make file. 224 225 Args: 226 target_dir: The full path to the directory to write Android.mk, or None 227 to use the current working directory. 228 common: VarsDict holding variables definitions common to all 229 configurations. 230 deviations_from_common: List of VarsDictData, one for each possible 231 configuration. VarsDictData.name will be appended to each key before 232 writing it to the makefile. VarsDictData.condition, if not None, will be 233 written to the makefile as a condition to determine whether to include 234 VarsDictData.vars_dict. 235 """ 236 target_file = 'Android.mk' 237 if target_dir: 238 target_file = os.path.join(target_dir, target_file) 239 with open(target_file, 'w') as f: 240 f.write(AUTOGEN_WARNING) 241 f.write('BASE_PATH := $(call my-dir)\n') 242 f.write(LOCAL_PATH) 243 244 f.write(DEBUGGING_HELP) 245 246 f.write(STATIC_HEADER) 247 f.write(CLEAR_VARS) 248 249 # need flags to enable feedback driven optimization (FDO) when requested 250 # by the build system. 251 f.write('LOCAL_FDO_SUPPORT := true\n') 252 f.write('ifneq ($(strip $(TARGET_FDO_CFLAGS)),)\n') 253 f.write('\t# This should be the last -Oxxx specified in LOCAL_CFLAGS\n') 254 f.write('\tLOCAL_CFLAGS += -O2\n') 255 f.write('endif\n\n') 256 257 f.write('LOCAL_ARM_MODE := thumb\n') 258 259 f.write('# used for testing\n') 260 f.write('#LOCAL_CFLAGS += -g -O0\n\n') 261 262 # update the provided LOCAL_MODULE with a _static suffix 263 local_module = common['LOCAL_MODULE'][0] 264 static_local_module = local_module + '_static' 265 common['LOCAL_MODULE'].reset() 266 common['LOCAL_MODULE'].add(static_local_module) 267 268 write_local_vars(f, common, False, None) 269 270 for data in deviations_from_common: 271 if data.condition: 272 f.write('ifeq ($(%s), true)\n' % data.condition) 273 write_local_vars(f, data.vars_dict, True, data.name) 274 if data.condition: 275 f.write('endif\n\n') 276 277 f.write('LOCAL_MODULE_CLASS := STATIC_LIBRARIES\n') 278 f.write('include $(BUILD_STATIC_LIBRARY)\n\n') 279 280 f.write(SHARED_HEADER) 281 f.write(CLEAR_VARS) 282 f.write('LOCAL_MODULE_CLASS := SHARED_LIBRARIES\n') 283 f.write('LOCAL_MODULE := %s\n' % local_module) 284 f.write('LOCAL_WHOLE_STATIC_LIBRARIES := %s\n' % static_local_module) 285 write_group(f, 'LOCAL_EXPORT_C_INCLUDE_DIRS', 286 common['LOCAL_EXPORT_C_INCLUDE_DIRS'], False) 287 f.write('include $(BASE_PATH)/skia_static_deps.mk\n') 288 f.write('include $(BUILD_SHARED_LIBRARY)\n') 289 290 f.write(SKIA_TOOLS) 291 292