OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 | 2 |
3 # Copyright 2014 Google Inc. | 3 # Copyright 2014 Google Inc. |
4 # | 4 # |
5 # Use of this source code is governed by a BSD-style license that can be | 5 # Use of this source code is governed by a BSD-style license that can be |
6 # found in the LICENSE file. | 6 # found in the LICENSE file. |
7 | 7 |
8 """ | 8 """ |
9 Script for generating the Android framework's version of Skia from gyp | 9 Script for generating the Android framework's version of Skia from gyp |
10 files. | 10 files. |
11 """ | 11 """ |
12 | 12 |
13 import os | 13 import os |
| 14 import shutil |
| 15 import tempfile |
14 | 16 |
15 # Folder containing all gyp files and generated gypd files. | 17 # Folder containing all gyp files and generated gypd files. |
16 GYP_FOLDER = 'gyp' | 18 GYP_FOLDER = 'gyp' |
17 | 19 |
18 # TODO (scroggo): Currently the x86 specific files are not included. Include | 20 # TODO (scroggo): Currently the x86 specific files are not included. Include |
19 # them. | 21 # them. |
20 INCLUDE_X86_OPTS = False | 22 INCLUDE_X86_OPTS = False |
21 | 23 |
22 # TODO (scroggo): Use lower_case_function_names. | 24 # TODO (scroggo): Use lower_case_function_names. |
23 def WriteGroup(f, name, items, append): | 25 def WriteGroup(f, name, items, append): |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 # (b) You can update all the users of libskia to define SK_DEBUG when they are | 136 # (b) You can update all the users of libskia to define SK_DEBUG when they are |
135 # building their sources. | 137 # building their sources. |
136 # | 138 # |
137 # NOTE: If neither SK_DEBUG or SK_RELEASE are defined then Skia checks NDEBUG to | 139 # NOTE: If neither SK_DEBUG or SK_RELEASE are defined then Skia checks NDEBUG to |
138 # determine which build type to use. | 140 # determine which build type to use. |
139 ############################################################################### | 141 ############################################################################### |
140 | 142 |
141 """ | 143 """ |
142 ) | 144 ) |
143 | 145 |
144 def WriteAndroidMk(common, arm, armNeon, x86, default): | 146 def WriteAndroidMk(target_dir, common, arm, armNeon, x86, default): |
145 """ | 147 """ |
146 Given all the variables, write the final make file. | 148 Given all the variables, write the final make file. |
| 149 @param target_dir The full path to the directory to write Android.mk, or None |
| 150 to use the current working directory. |
147 @param common VarsDict holding variables definitions common to all | 151 @param common VarsDict holding variables definitions common to all |
148 configurations. | 152 configurations. |
149 @param arm VarsDict holding variable definitions unique to arm. Will be | 153 @param arm VarsDict holding variable definitions unique to arm. Will be |
150 written to the makefile inside an 'ifeq ($(TARGET_ARCH), arm)' | 154 written to the makefile inside an 'ifeq ($(TARGET_ARCH), arm)' |
151 block. | 155 block. |
152 @param armNeon VarsDict holding variable definitions unique to arm with neon. | 156 @param armNeon VarsDict holding variable definitions unique to arm with neon. |
153 Will be written inside an 'ifeq ($(ARCH_ARM_HAVE_NEON),true)' | 157 Will be written inside an 'ifeq ($(ARCH_ARM_HAVE_NEON),true)' |
154 block nested inside an 'ifeq ($(TARGET_ARCH), arm)' block. | 158 block nested inside an 'ifeq ($(TARGET_ARCH), arm)' block. |
155 @param x86 VarsDict holding variable definitions unique to x86. Will be | 159 @param x86 VarsDict holding variable definitions unique to x86. Will be |
156 written inside an 'ifeq ($(TARGET_ARCH),x86)' block. | 160 written inside an 'ifeq ($(TARGET_ARCH),x86)' block. |
157 @param default VarsDict holding variable definitions for an architecture | 161 @param default VarsDict holding variable definitions for an architecture |
158 without custom optimizations. | 162 without custom optimizations. |
159 TODO: Add mips. | 163 TODO: Add mips. |
160 """ | 164 """ |
161 with open('Android.mk', 'w') as f: | 165 target_file = 'Android.mk' |
| 166 if target_dir: |
| 167 target_file = os.path.join(target_dir, target_file) |
| 168 with open(target_file, 'w') as f: |
162 f.write(AUTOGEN_WARNING) | 169 f.write(AUTOGEN_WARNING) |
163 f.write('BASE_PATH := $(call my-dir)\n') | 170 f.write('BASE_PATH := $(call my-dir)\n') |
164 f.write('LOCAL_PATH:= $(call my-dir)\n') | 171 f.write('LOCAL_PATH:= $(call my-dir)\n') |
165 | 172 |
166 f.write(DEBUGGING_HELP) | 173 f.write(DEBUGGING_HELP) |
167 | 174 |
168 f.write('include $(CLEAR_VARS)\n') | 175 f.write('include $(CLEAR_VARS)\n') |
169 | 176 |
170 f.write('LOCAL_ARM_MODE := thumb\n') | 177 f.write('LOCAL_ARM_MODE := thumb\n') |
171 | 178 |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 # set of keys. | 354 # set of keys. |
348 if not item in var_dict[key]: | 355 if not item in var_dict[key]: |
349 in_all_lists = False | 356 in_all_lists = False |
350 break | 357 break |
351 if in_all_lists: | 358 if in_all_lists: |
352 intersection[key].append(item) | 359 intersection[key].append(item) |
353 for var_dict in var_dict_list: | 360 for var_dict in var_dict_list: |
354 var_dict[key].remove(item) | 361 var_dict[key].remove(item) |
355 return intersection | 362 return intersection |
356 | 363 |
357 def CleanGypdFiles(): | 364 def CleanGypdFiles(folder): |
358 """ | 365 """ |
359 Remove the gypd files generated by android_framework_gyp.main(). | 366 Remove the gypd files generated by android_framework_gyp.main(). |
| 367 @param folder Folder in which to delete all files ending with 'gypd'. |
360 """ | 368 """ |
361 assert os.path.isdir(GYP_FOLDER) | 369 assert os.path.isdir(folder) |
362 files = os.listdir(GYP_FOLDER) | 370 files = os.listdir(folder) |
363 for f in files: | 371 for f in files: |
364 if f.endswith('gypd'): | 372 if f.endswith('gypd'): |
365 os.remove(os.path.join(GYP_FOLDER, f)) | 373 os.remove(os.path.join(folder, f)) |
366 | 374 |
367 import android_framework_gyp | 375 import android_framework_gyp |
368 | 376 |
369 def main(): | 377 def main(target_dir=None): |
| 378 """ |
| 379 Read gyp files and create Android.mk for the Android framework's |
| 380 external/skia. |
| 381 @param target_dir Directory in which to place 'Android.mk'. If None, the file |
| 382 will be placed in skia's root directory. |
| 383 """ |
370 # Move up to top of trunk | 384 # Move up to top of trunk |
371 script_dir = os.path.dirname(__file__) | 385 script_dir = os.path.abspath(os.path.dirname(__file__)) |
372 skia_dir = os.path.normpath(os.path.join(script_dir, os.pardir, os.pardir, | 386 skia_dir = os.path.normpath(os.path.join(script_dir, os.pardir, os.pardir, |
373 os.pardir)) | 387 os.pardir)) |
374 os.chdir(skia_dir) | 388 # Create a temporary folder to hold gyp and gypd files. Create it in skia_dir |
| 389 # so that it is a sibling of gyp/, so the relationships between gyp files and |
| 390 # other files (e.g. platform_tools/android/gyp/dependencies.gypi, referenced |
| 391 # by android_deps.gyp as a relative path) is unchanged. |
| 392 # Use mkdtemp to find an unused folder name, but then delete it so copytree |
| 393 # can be called with a non-existent directory. |
| 394 tmp_folder = tempfile.mkdtemp(dir=skia_dir) |
| 395 os.rmdir(tmp_folder) |
| 396 shutil.copytree(os.path.join(skia_dir, GYP_FOLDER), tmp_folder) |
375 | 397 |
376 main_gypd_file = os.path.join(GYP_FOLDER, 'android_framework_lib.gypd') | 398 try: |
| 399 main_gyp_file = 'android_framework_lib.gyp' |
| 400 main_gypd_file = os.path.join(tmp_folder, main_gyp_file + 'd') |
377 | 401 |
378 print 'Creating Android.mk', | 402 print 'Creating Android.mk', |
379 | 403 |
380 # Call the script to generate gypd files, first using a non-existant archtype. | 404 # Call the script to generate gypd files, first using a non-existant |
381 android_framework_gyp.main('other', False) | 405 # archtype. |
382 # And store its variables in the default dict | 406 android_framework_gyp.main(tmp_folder, main_gyp_file, 'other', False) |
383 default_var_dict = VarsDict() | 407 # And store its variables in the default dict |
384 ParseGypd(default_var_dict, main_gypd_file) | 408 default_var_dict = VarsDict() |
385 CleanGypdFiles() | 409 ParseGypd(default_var_dict, main_gypd_file) |
| 410 CleanGypdFiles(tmp_folder) |
386 | 411 |
387 print '.', | 412 print '.', |
388 | 413 |
389 # Now do the same for Arm. arm_var_dict will contain all the variable | 414 # Now do the same for Arm. arm_var_dict will contain all the variable |
390 # definitions needed to build with arm (meaning that it will share most | 415 # definitions needed to build with arm (meaning that it will share most |
391 # with default_var_dict). | 416 # with default_var_dict). |
392 android_framework_gyp.main('arm', False) | 417 android_framework_gyp.main(tmp_folder, main_gyp_file, 'arm', False) |
393 arm_var_dict = VarsDict() | 418 arm_var_dict = VarsDict() |
394 ParseGypd(arm_var_dict, main_gypd_file) | 419 ParseGypd(arm_var_dict, main_gypd_file) |
395 CleanGypdFiles() | 420 CleanGypdFiles(tmp_folder) |
396 | 421 |
397 print '.', | 422 print '.', |
398 | 423 |
399 # Now do the same for Arm/Neon. | 424 # Now do the same for Arm/Neon. |
400 android_framework_gyp.main('arm', True) | 425 android_framework_gyp.main(tmp_folder, main_gyp_file, 'arm', True) |
401 arm_neon_var_dict = VarsDict() | 426 arm_neon_var_dict = VarsDict() |
402 ParseGypd(arm_neon_var_dict, main_gypd_file) | 427 ParseGypd(arm_neon_var_dict, main_gypd_file) |
403 CleanGypdFiles() | 428 CleanGypdFiles(tmp_folder) |
404 | 429 |
405 print '.' | 430 print '.' |
406 | 431 |
407 # Now do the same for x86. | 432 # Now do the same for x86. |
408 x86_var_dict = VarsDict() | 433 x86_var_dict = VarsDict() |
409 if INCLUDE_X86_OPTS: | 434 if INCLUDE_X86_OPTS: |
410 android_framework_gyp.main('x86', False) | 435 android_framework_gyp.main(tmp_folder, main_gyp_file, 'x86', False) |
411 ParseGypd(x86_var_dict, main_gypd_file) | 436 ParseGypd(x86_var_dict, main_gypd_file) |
412 CleanGypdFiles() | 437 CleanGypdFiles(tmp_folder) |
413 | 438 |
414 # Compute the intersection of all targets. All the files in the intersection | 439 # Compute the intersection of all targets. All the files in the intersection |
415 # should be part of the makefile always. Each dict will now contain trimmed | 440 # should be part of the makefile always. Each dict will now contain trimmed |
416 # lists containing only variable definitions specific to that configuration. | 441 # lists containing only variable definitions specific to that configuration. |
417 var_dict_list = [default_var_dict, arm_var_dict, arm_neon_var_dict] | 442 var_dict_list = [default_var_dict, arm_var_dict, arm_neon_var_dict] |
418 if INCLUDE_X86_OPTS: | 443 if INCLUDE_X86_OPTS: |
419 var_dict_list.append(x86_var_dict) | 444 var_dict_list.append(x86_var_dict) |
420 common = Intersect(var_dict_list) | 445 common = Intersect(var_dict_list) |
421 | 446 |
422 # Further trim arm_neon_var_dict with arm_var_dict. After this call, | 447 # Further trim arm_neon_var_dict with arm_var_dict. After this call, |
423 # arm_var_dict (which will now be the intersection) includes all definitions | 448 # arm_var_dict (which will now be the intersection) includes all definitions |
424 # used by both arm and arm + neon, and arm_neon_var_dict will only contain | 449 # used by both arm and arm + neon, and arm_neon_var_dict will only contain |
425 # those specific to arm + neon. | 450 # those specific to arm + neon. |
426 arm_var_dict = Intersect([arm_var_dict, arm_neon_var_dict]) | 451 arm_var_dict = Intersect([arm_var_dict, arm_neon_var_dict]) |
427 | 452 |
428 WriteAndroidMk(common, arm_var_dict, arm_neon_var_dict, x86_var_dict, | 453 WriteAndroidMk(target_dir, common, arm_var_dict, arm_neon_var_dict, |
429 default_var_dict) | 454 x86_var_dict, default_var_dict) |
| 455 |
| 456 finally: |
| 457 shutil.rmtree(tmp_folder) |
430 | 458 |
431 if __name__ == '__main__': | 459 if __name__ == '__main__': |
432 main() | 460 main() |
OLD | NEW |