• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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"""
9Functions for creating an Android.mk from already created dictionaries.
10"""
11
12import os
13
14def 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
39def 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
73AUTOGEN_WARNING = (
74"""
75###############################################################################
76#
77# THIS FILE IS AUTOGENERATED BY GYP_TO_ANDROID.PY. DO NOT EDIT.
78#
79# For bugs, please contact scroggo@google.com or djsollen@google.com
80#
81###############################################################################
82
83"""
84)
85
86DEBUGGING_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
114SKIA_TOOLS = (
115"""
116#############################################################
117# Build the skia tools
118#
119
120# benchmark (timings)
121include $(BASE_PATH)/bench/Android.mk
122
123# diamond-master (one test to rule them all)
124include $(BASE_PATH)/dm/Android.mk
125"""
126)
127
128STATIC_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
141SHARED_HEADER = (
142"""
143###############################################################################
144# SHARED LIBRARY
145###############################################################################
146
147"""
148)
149
150STATIC_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
165CLEAR_VARS = ("""include $(CLEAR_VARS)\n""")
166LOCAL_PATH = ("""LOCAL_PATH:= $(call my-dir)\n""")
167
168class 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
185def 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
222def 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