1 # Copyright (c) 2012 Google Inc. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
8 This contains class definitions and supporting functions for generating
9 pieces of SCons files for the different types of GYP targets.
15 def WriteList(fp, list, prefix='',
19 fp.write(preamble or '')
20 fp.write((separator or ' ').join([prefix + l for l in list]))
21 fp.write(postamble or '')
24 class TargetBase(object):
26 Base class for a SCons representation of a GYP target.
31 def __init__(self, spec):
33 def full_product_name(self):
35 Returns the full name of the product being built:
37 * Uses 'product_name' if it's set, else prefix + 'target_name'.
38 * Prepends 'product_dir' if set.
39 * Appends SCons suffix variables for the target type (or
42 suffix = self.target_suffix
43 product_extension = self.spec.get('product_extension')
45 suffix = '.' + product_extension
46 prefix = self.spec.get('product_prefix', self.target_prefix)
47 name = self.spec['target_name']
48 name = prefix + self.spec.get('product_name', name) + suffix
49 product_dir = self.spec.get('product_dir')
51 name = os.path.join(product_dir, name)
53 name = os.path.join(self.out_dir, name)
56 def write_input_files(self, fp):
58 Writes the definition of the input files (sources).
60 sources = self.spec.get('sources')
62 fp.write('\ninput_files = []\n')
64 preamble = '\ninput_files = [\n '
66 WriteList(fp, map(repr, sources), preamble=preamble, postamble=postamble)
68 def builder_call(self):
70 Returns the actual SCons builder call to build this target.
72 name = self.full_product_name()
73 return 'env.%s(env.File(%r), input_files)' % (self.builder_name, name)
74 def write_target(self, fp, src_dir='', pre=''):
76 Writes the lines necessary to build this target.
79 fp.write('_outputs = %s\n' % self.builder_call())
80 fp.write('target_files.extend(_outputs)\n')
83 class NoneTarget(TargetBase):
85 A GYP target type of 'none', implicitly or explicitly.
87 def write_target(self, fp, src_dir='', pre=''):
88 fp.write('\ntarget_files.extend(input_files)\n')
91 class SettingsTarget(TargetBase):
93 A GYP target type of 'settings'.
98 compilable_sources_template = """
100 for infile in input_files:
101 if env.compilable(infile):
102 if (type(infile) == type('')
103 and (infile.startswith(%(src_dir)r)
104 or not os.path.isabs(env.subst(infile)))):
105 # Force files below the build directory by replacing all '..'
106 # elements in the path with '__':
107 base, ext = os.path.splitext(os.path.normpath(infile))
108 base = [d == '..' and '__' or d for d in base.split('/')]
109 base = os.path.join(*base)
110 object = '${OBJ_DIR}/${COMPONENT_NAME}/${TARGET_NAME}/' + base
111 if not infile.startswith(%(src_dir)r):
112 infile = %(src_dir)r + infile
113 infile = env.%(name)s(object, infile)[0]
115 infile = env.%(name)s(infile)[0]
116 _result.append(infile)
117 input_files = _result
120 class CompilableSourcesTargetBase(TargetBase):
122 An abstract base class for targets that compile their source files.
124 We explicitly transform compilable files into object files,
125 even though SCons could infer that for us, because we want
126 to control where the object file ends up. (The implicit rules
127 in SCons always put the object file next to the source file.)
129 intermediate_builder_name = None
130 def write_target(self, fp, src_dir='', pre=''):
131 if self.intermediate_builder_name is None:
132 raise NotImplementedError
133 if src_dir and not src_dir.endswith('/'):
137 'name': self.intermediate_builder_name,
139 fp.write(compilable_sources_template % variables)
140 super(CompilableSourcesTargetBase, self).write_target(fp)
143 class ProgramTarget(CompilableSourcesTargetBase):
145 A GYP target type of 'executable'.
147 builder_name = 'GypProgram'
148 intermediate_builder_name = 'StaticObject'
149 target_prefix = '${PROGPREFIX}'
150 target_suffix = '${PROGSUFFIX}'
151 out_dir = '${TOP_BUILDDIR}'
154 class StaticLibraryTarget(CompilableSourcesTargetBase):
156 A GYP target type of 'static_library'.
158 builder_name = 'GypStaticLibrary'
159 intermediate_builder_name = 'StaticObject'
160 target_prefix = '${LIBPREFIX}'
161 target_suffix = '${LIBSUFFIX}'
162 out_dir = '${LIB_DIR}'
165 class SharedLibraryTarget(CompilableSourcesTargetBase):
167 A GYP target type of 'shared_library'.
169 builder_name = 'GypSharedLibrary'
170 intermediate_builder_name = 'SharedObject'
171 target_prefix = '${SHLIBPREFIX}'
172 target_suffix = '${SHLIBSUFFIX}'
173 out_dir = '${LIB_DIR}'
176 class LoadableModuleTarget(CompilableSourcesTargetBase):
178 A GYP target type of 'loadable_module'.
180 builder_name = 'GypLoadableModule'
181 intermediate_builder_name = 'SharedObject'
182 target_prefix = '${SHLIBPREFIX}'
183 target_suffix = '${SHLIBSUFFIX}'
184 out_dir = '${TOP_BUILDDIR}'
190 'settings' : SettingsTarget,
191 'executable' : ProgramTarget,
192 'static_library' : StaticLibraryTarget,
193 'shared_library' : SharedLibraryTarget,
194 'loadable_module' : LoadableModuleTarget,
199 return TargetMap[spec.get('type')](spec)