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 verision of Skia from gyp | 9 Script for generating the Android framework's verision 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 # FIXME: Currently the x86 specific files are not included. Include them. | 20 # FIXME: Currently the x86 specific files are not included. Include them. |
19 INCLUDE_X86_OPTS = False | 21 INCLUDE_X86_OPTS = False |
20 | 22 |
21 def WriteGroup(f, name, items, append): | 23 def WriteGroup(f, name, items, append): |
22 """ | 24 """ |
23 Helper function to list all names passed to a variable. | 25 Helper function to list all names passed to a variable. |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
114 # (b) You can update all the users of libskia to define SK_DEBUG when they are | 116 # (b) You can update all the users of libskia to define SK_DEBUG when they are |
115 # building their sources. | 117 # building their sources. |
116 # | 118 # |
117 # NOTE: If neither SK_DEBUG or SK_RELEASE are defined then Skia checks NDEBUG to | 119 # NOTE: If neither SK_DEBUG or SK_RELEASE are defined then Skia checks NDEBUG to |
118 # determine which build type to use. | 120 # determine which build type to use. |
119 ############################################################################### | 121 ############################################################################### |
120 | 122 |
121 """ | 123 """ |
122 ) | 124 ) |
123 | 125 |
124 def WriteAndroidMk(common, arm, armNeon, x86, default): | 126 def WriteAndroidMk(target_dir, common, arm, armNeon, x86, default): |
125 """ | 127 """ |
126 Given all the variables, write the final make file. | 128 Given all the variables, write the final make file. |
129 @param target_dir The full path to the directory to write Android.mk, or None | |
130 to use the current working directory. | |
127 @param common VarsDict holding variables definitions common to all | 131 @param common VarsDict holding variables definitions common to all |
128 configurations. | 132 configurations. |
129 @param arm VarsDict holding variable definitions unique to arm. Will be | 133 @param arm VarsDict holding variable definitions unique to arm. Will be |
130 written to the makefile inside an 'ifeq ($(TARGET_ARCH), arm)' | 134 written to the makefile inside an 'ifeq ($(TARGET_ARCH), arm)' |
131 block. | 135 block. |
132 @param armNeon VarsDict holding variable definitions unique to arm with neon. | 136 @param armNeon VarsDict holding variable definitions unique to arm with neon. |
133 Will be written inside an 'ifeq ($(ARCH_ARM_HAVE_NEON),true)' | 137 Will be written inside an 'ifeq ($(ARCH_ARM_HAVE_NEON),true)' |
134 block nested inside an 'ifeq ($(TARGET_ARCH), arm)' block. | 138 block nested inside an 'ifeq ($(TARGET_ARCH), arm)' block. |
135 @param x86 VarsDict holding variable definitions unique to x86. Will be | 139 @param x86 VarsDict holding variable definitions unique to x86. Will be |
136 written inside an 'ifeq ($(TARGET_ARCH),x86)' block. | 140 written inside an 'ifeq ($(TARGET_ARCH),x86)' block. |
137 @param default VarsDict holding variable definitions for an architecture | 141 @param default VarsDict holding variable definitions for an architecture |
138 without custom optimizations. | 142 without custom optimizations. |
139 TODO: Add mips. | 143 TODO: Add mips. |
140 """ | 144 """ |
141 with open('Android.mk', 'w') as f: | 145 target_file = 'Android.mk' |
146 if target_dir: | |
147 target_file = os.path.join(target_dir, target_file) | |
148 with open(target_file, 'w') as f: | |
142 f.write('BASE_PATH := $(call my-dir)\n') | 149 f.write('BASE_PATH := $(call my-dir)\n') |
143 f.write('LOCAL_PATH:= $(call my-dir)\n') | 150 f.write('LOCAL_PATH:= $(call my-dir)\n') |
144 | 151 |
145 f.write(DEBUGGING_HELP) | 152 f.write(DEBUGGING_HELP) |
146 | 153 |
147 f.write('include $(CLEAR_VARS)\n') | 154 f.write('include $(CLEAR_VARS)\n') |
148 | 155 |
149 f.write('LOCAL_ARM_MODE := thumb\n') | 156 f.write('LOCAL_ARM_MODE := thumb\n') |
150 | 157 |
151 # need a flag to tell the C side when we're on devices with large memory | 158 # need a flag to tell the C side when we're on devices with large memory |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
333 # set of keys. | 340 # set of keys. |
334 if not item in var_dict[key]: | 341 if not item in var_dict[key]: |
335 in_all_lists = False | 342 in_all_lists = False |
336 break | 343 break |
337 if in_all_lists: | 344 if in_all_lists: |
338 intersection[key].append(item) | 345 intersection[key].append(item) |
339 for var_dict in var_dict_list: | 346 for var_dict in var_dict_list: |
340 var_dict[key].remove(item) | 347 var_dict[key].remove(item) |
341 return intersection | 348 return intersection |
342 | 349 |
343 def CleanGypdFiles(): | 350 def CleanGypdFiles(folder): |
344 """ | 351 """ |
345 Remove the gypd files generated by android_framework_gyp.main(). | 352 Remove the gypd files generated by android_framework_gyp.main(). |
353 @param folder Folder in which to delete all files ending with 'gypd'. | |
346 """ | 354 """ |
347 assert os.path.isdir(GYP_FOLDER) | 355 assert os.path.isdir(folder) |
348 files = os.listdir(GYP_FOLDER) | 356 files = os.listdir(folder) |
349 for f in files: | 357 for f in files: |
350 if f.endswith('gypd'): | 358 if f.endswith('gypd'): |
351 os.remove(os.path.join(GYP_FOLDER, f)) | 359 os.remove(os.path.join(folder, f)) |
352 | 360 |
353 import android_framework_gyp | 361 import android_framework_gyp |
354 | 362 |
355 def main(): | 363 def main(target_dir=None): |
364 """ | |
365 Read gyp files and create Android.mk for the Android framework's | |
366 external/skia. | |
367 @param target_dir Directory in which to place 'Android.mk'. If None, the file | |
368 will be placed in skia's root directory. | |
369 """ | |
356 # Move up to top of trunk | 370 # Move up to top of trunk |
357 script_dir = os.path.dirname(__file__) | 371 script_dir = os.path.dirname(__file__) |
358 skia_dir = os.path.normpath(os.path.join(script_dir, os.pardir, os.pardir, | 372 skia_dir = os.path.normpath(os.path.join(script_dir, os.pardir, os.pardir, |
359 os.pardir)) | 373 os.pardir)) |
360 os.chdir(skia_dir) | 374 os.chdir(skia_dir) |
361 | 375 |
362 main_gypd_file = os.path.join(GYP_FOLDER, 'android_framework_lib.gypd') | 376 # Create a temporary folder to hold gyp and gypd files. Create it in skia_dir |
377 # so that it is a sibling of gyp/, so the relationships between gyp files and | |
378 # other files (e.g. platform_tools/android/gyp/dependencies.gypi, referenced | |
379 # by android_deps.gyp as a relative path) is unchanged. | |
380 # Use mkdtemp to find an unused folder name, but then delete it so copytree | |
381 # can be called with a non-existent directory. | |
382 tmp_folder = tempfile.mkdtemp(dir=os.getcwd()) | |
epoger
2014/01/22 21:35:03
This will work, but maybe set dir=skia_dir so that
scroggo
2014/01/22 23:33:08
Done.
| |
383 os.rmdir(tmp_folder) | |
384 shutil.copytree(GYP_FOLDER, tmp_folder) | |
363 | 385 |
364 print 'Creating Android.mk', | 386 try: |
387 main_gyp_file = 'android_framework_lib.gyp' | |
388 main_gypd_file = os.path.join(tmp_folder, main_gyp_file + 'd') | |
365 | 389 |
366 # Call the script to generate gypd files, first using a non-existant archtype. | 390 print 'Creating Android.mk', |
367 android_framework_gyp.main('other', False) | |
368 # And store its variables in the default dict | |
369 default_var_dict = VarsDict() | |
370 ParseGypd(default_var_dict, main_gypd_file) | |
371 CleanGypdFiles() | |
372 | 391 |
373 print '.', | 392 # Call the script to generate gypd files, first using a non-existant |
393 # archtype. | |
394 android_framework_gyp.main(tmp_folder, main_gyp_file, 'other', False) | |
395 # And store its variables in the default dict | |
396 default_var_dict = VarsDict() | |
397 ParseGypd(default_var_dict, main_gypd_file) | |
398 CleanGypdFiles(tmp_folder) | |
374 | 399 |
375 # Now do the same for Arm. arm_var_dict will contain all the variable | 400 print '.', |
376 # definitions needed to build with arm (meaning that it will share most | |
377 # with default_var_dict). | |
378 android_framework_gyp.main('arm', False) | |
379 arm_var_dict = VarsDict() | |
380 ParseGypd(arm_var_dict, main_gypd_file) | |
381 CleanGypdFiles() | |
382 | 401 |
383 print '.', | 402 # Now do the same for Arm. arm_var_dict will contain all the variable |
403 # definitions needed to build with arm (meaning that it will share most | |
404 # with default_var_dict). | |
405 android_framework_gyp.main(tmp_folder, main_gyp_file, 'arm', False) | |
406 arm_var_dict = VarsDict() | |
407 ParseGypd(arm_var_dict, main_gypd_file) | |
408 CleanGypdFiles(tmp_folder) | |
384 | 409 |
385 # Now do the same for Arm/Neon. | 410 print '.', |
386 android_framework_gyp.main('arm', True) | |
387 arm_neon_var_dict = VarsDict() | |
388 ParseGypd(arm_neon_var_dict, main_gypd_file) | |
389 CleanGypdFiles() | |
390 | 411 |
391 print '.' | 412 # Now do the same for Arm/Neon. |
413 android_framework_gyp.main(tmp_folder, main_gyp_file, 'arm', True) | |
414 arm_neon_var_dict = VarsDict() | |
415 ParseGypd(arm_neon_var_dict, main_gypd_file) | |
416 CleanGypdFiles(tmp_folder) | |
392 | 417 |
393 # Now do the same for x86. | 418 print '.' |
394 x86_var_dict = VarsDict() | |
395 if INCLUDE_X86_OPTS: | |
396 android_framework_gyp.main('x86', False) | |
397 ParseGypd(x86_var_dict, main_gypd_file) | |
398 CleanGypdFiles() | |
399 | 419 |
400 # Compute the intersection of all targets. All the files in the intersection | 420 # Now do the same for x86. |
401 # should be part of the makefile always. Each dict will now contain trimmed | 421 x86_var_dict = VarsDict() |
402 # lists containing only variable definitions specific to that configuration. | 422 if INCLUDE_X86_OPTS: |
403 var_dict_list = [default_var_dict, arm_var_dict, arm_neon_var_dict] | 423 android_framework_gyp.main(tmp_folder, main_gyp_file, 'x86', False) |
404 if INCLUDE_X86_OPTS: | 424 ParseGypd(x86_var_dict, main_gypd_file) |
405 var_dict_list.append(x86_var_dict) | 425 CleanGypdFiles(tmp_folder) |
406 common = Intersect(var_dict_list) | |
407 | 426 |
408 # Further trim arm_neon_var_dict with arm_var_dict. After this call, | 427 # Compute the intersection of all targets. All the files in the intersection |
409 # arm_var_dict (which will now be the intersection) includes all definitions | 428 # should be part of the makefile always. Each dict will now contain trimmed |
410 # used by both arm and arm + neon, and arm_neon_var_dict will only contain | 429 # lists containing only variable definitions specific to that configuration. |
411 # those specific to arm + neon. | 430 var_dict_list = [default_var_dict, arm_var_dict, arm_neon_var_dict] |
412 arm_var_dict = Intersect([arm_var_dict, arm_neon_var_dict]) | 431 if INCLUDE_X86_OPTS: |
432 var_dict_list.append(x86_var_dict) | |
433 common = Intersect(var_dict_list) | |
413 | 434 |
414 WriteAndroidMk(common, arm_var_dict, arm_neon_var_dict, x86_var_dict, | 435 # Further trim arm_neon_var_dict with arm_var_dict. After this call, |
415 default_var_dict) | 436 # arm_var_dict (which will now be the intersection) includes all definitions |
437 # used by both arm and arm + neon, and arm_neon_var_dict will only contain | |
438 # those specific to arm + neon. | |
439 arm_var_dict = Intersect([arm_var_dict, arm_neon_var_dict]) | |
440 | |
441 WriteAndroidMk(target_dir, common, arm_var_dict, arm_neon_var_dict, | |
442 x86_var_dict, default_var_dict) | |
443 | |
444 finally: | |
445 shutil.rmtree(tmp_folder) | |
416 | 446 |
417 if __name__ == '__main__': | 447 if __name__ == '__main__': |
418 main() | 448 main() |
OLD | NEW |