6 import Task
, Runner
, Utils
, Logs
, Build
, Node
, Options
7 from TaskGen
import extension
, after
, before
9 EXT_VALA
= ['.vala', '.gs']
11 class valac_task(Task
.Task
):
13 vars = ("VALAC", "VALAC_VERSION", "VALAFLAGS")
14 before
= ("cc", "cxx")
18 inputs
= [a
.srcpath(env
) for a
in self
.inputs
]
20 vala_flags
= env
.get_flat('VALAFLAGS')
21 top_src
= self
.generator
.bld
.srcnode
.abspath()
22 top_bld
= self
.generator
.bld
.srcnode
.abspath(env
)
24 if env
['VALAC_VERSION'] > (0, 1, 6):
25 cmd
= [valac
, '-C', '--quiet', vala_flags
]
27 cmd
= [valac
, '-C', vala_flags
]
30 cmd
.append('--thread')
33 cmd
.append('--profile=%s' % self
.profile
)
36 cmd
.append('--target-glib=%s' % self
.target_glib
)
38 features
= self
.generator
.features
40 if 'cshlib' in features
or 'cstaticlib' in features
:
41 output_dir
= self
.outputs
[0].bld_dir(env
)
42 cmd
.append('--library ' + self
.target
)
43 if env
['VALAC_VERSION'] >= (0, 7, 0):
44 for x
in self
.outputs
:
45 if x
.name
.endswith('.h'):
46 cmd
.append('--header ' + x
.bldpath(self
.env
))
47 cmd
.append('--basedir ' + top_src
)
48 cmd
.append('-d ' + top_bld
)
49 if env
['VALAC_VERSION'] > (0, 7, 2) and hasattr(self
, 'gir'):
50 cmd
.append('--gir=%s.gir' % self
.gir
)
53 output_dir
= self
.outputs
[0].bld_dir(env
)
54 cmd
.append('-d %s' % output_dir
)
56 for vapi_dir
in self
.vapi_dirs
:
57 cmd
.append('--vapidir=%s' % vapi_dir
)
59 for package
in self
.packages
:
60 cmd
.append('--pkg %s' % package
)
62 for package
in self
.packages_private
:
63 cmd
.append('--pkg %s' % package
)
65 cmd
.append(" ".join(inputs
))
66 result
= self
.generator
.bld
.exec_command(" ".join(cmd
))
68 if not 'cprogram' in features
:
69 # generate the .deps file
71 filename
= os
.path
.join(self
.generator
.path
.abspath(env
), "%s.deps" % self
.target
)
72 deps
= open(filename
, 'w')
73 for package
in self
.packages
:
74 deps
.write(package
+ '\n')
77 # handle vala 0.1.6 who doesn't honor --directory for the generated .vapi
78 self
._fix
_output
("../%s.vapi" % self
.target
)
79 # handle vala >= 0.1.7 who has a weid definition for --directory
80 self
._fix
_output
("%s.vapi" % self
.target
)
81 # handle vala >= 0.2.0 who doesn't honor --directory for the generated .gidl
82 self
._fix
_output
("%s.gidl" % self
.target
)
83 # handle vala >= 0.3.6 who doesn't honor --directory for the generated .gir
84 self
._fix
_output
("%s.gir" % self
.target
)
85 if hasattr(self
, 'gir'):
86 self
._fix
_output
("%s.gir" % self
.gir
)
89 for node
in self
.outputs
:
93 if first
.parent
.id != node
.parent
.id:
95 if env
['VALAC_VERSION'] < (0, 7, 0):
96 shutil
.move(first
.parent
.abspath(self
.env
) + os
.sep
+ node
.name
, node
.abspath(self
.env
))
100 bld
= self
.generator
.bld
101 features
= self
.generator
.features
103 if self
.attr("install_path") and ("cshlib" in features
or "cstaticlib" in features
):
104 headers_list
= [o
for o
in self
.outputs
if o
.suffix() == ".h"]
105 vapi_list
= [o
for o
in self
.outputs
if (o
.suffix() in (".vapi", ".deps"))]
106 gir_list
= [o
for o
in self
.outputs
if o
.suffix() == ".gir"]
108 for header
in headers_list
:
109 top_src
= self
.generator
.bld
.srcnode
110 package
= self
.env
['PACKAGE']
112 api_version
= Utils
.g_module
.API_VERSION
113 except AttributeError:
114 version
= Utils
.g_module
.VERSION
.split(".")
115 if version
[0] == "0":
116 api_version
= "0." + version
[1]
118 api_version
= version
[0] + ".0"
119 install_path
= '${INCLUDEDIR}/%s-%s/%s' % (package
, api_version
, header
.relpath_gen(top_src
))
120 bld
.install_as(install_path
, header
, self
.env
)
121 bld
.install_files('${DATAROOTDIR}/vala/vapi', vapi_list
, self
.env
)
122 bld
.install_files('${DATAROOTDIR}/gir-1.0', gir_list
, self
.env
)
124 def _fix_output(self
, output
):
125 top_bld
= self
.generator
.bld
.srcnode
.abspath(self
.env
)
127 src
= os
.path
.join(top_bld
, output
)
128 dst
= self
.generator
.path
.abspath (self
.env
)
129 shutil
.move(src
, dst
)
134 def vala_file(self
, node
):
135 valatask
= getattr(self
, "valatask", None)
136 # there is only one vala task and it compiles all vala files .. :-/
138 valatask
= self
.create_task('valac')
139 self
.valatask
= valatask
140 self
.includes
= Utils
.to_list(getattr(self
, 'includes', []))
141 self
.uselib
= self
.to_list(self
.uselib
)
142 valatask
.packages
= []
143 valatask
.packages_private
= Utils
.to_list(getattr(self
, 'packages_private', []))
144 valatask
.vapi_dirs
= []
145 valatask
.target
= self
.target
146 valatask
.threading
= False
147 valatask
.install_path
= self
.install_path
148 valatask
.profile
= getattr (self
, 'profile', 'gobject')
149 valatask
.target_glib
= None #Deprecated
151 packages
= Utils
.to_list(getattr(self
, 'packages', []))
152 vapi_dirs
= Utils
.to_list(getattr(self
, 'vapi_dirs', []))
155 if hasattr(self
, 'uselib_local'):
156 local_packages
= Utils
.to_list(self
.uselib_local
)
158 while len(local_packages
) > 0:
159 package
= local_packages
.pop()
164 # check if the package exists
165 package_obj
= self
.name_to_obj(package
)
167 raise Utils
.WafError("object '%s' was not found in uselib_local (required by '%s')" % (package
, self
.name
))
169 package_name
= package_obj
.target
170 package_node
= package_obj
.path
171 package_dir
= package_node
.relpath_gen(self
.path
)
173 for task
in package_obj
.tasks
:
174 for output
in task
.outputs
:
175 if output
.name
== package_name
+ ".vapi":
176 valatask
.set_run_after(task
)
177 if package_name
not in packages
:
178 packages
.append(package_name
)
179 if package_dir
not in vapi_dirs
:
180 vapi_dirs
.append(package_dir
)
181 if package_dir
not in includes
:
182 includes
.append(package_dir
)
184 if hasattr(package_obj
, 'uselib_local'):
185 lst
= self
.to_list(package_obj
.uselib_local
)
187 local_packages
= [pkg
for pkg
in lst
if pkg
not in seen
] + local_packages
189 valatask
.packages
= packages
190 for vapi_dir
in vapi_dirs
:
192 valatask
.vapi_dirs
.append(self
.path
.find_dir(vapi_dir
).abspath())
193 valatask
.vapi_dirs
.append(self
.path
.find_dir(vapi_dir
).abspath(self
.env
))
194 except AttributeError:
195 Logs
.warn("Unable to locate Vala API directory: '%s'" % vapi_dir
)
197 self
.includes
.append(node
.bld
.srcnode
.abspath())
198 self
.includes
.append(node
.bld
.srcnode
.abspath(self
.env
))
199 for include
in includes
:
201 self
.includes
.append(self
.path
.find_dir(include
).abspath())
202 self
.includes
.append(self
.path
.find_dir(include
).abspath(self
.env
))
203 except AttributeError:
204 Logs
.warn("Unable to locate include directory: '%s'" % include
)
206 if valatask
.profile
== 'gobject':
207 if hasattr(self
, 'target_glib'):
208 Logs
.warn ('target_glib on vala tasks is deprecated --vala-target-glib=MAJOR.MINOR from the vala tool options')
210 if getattr(Options
.options
, 'vala_target_glib', None):
211 valatask
.target_glib
= Options
.options
.vala_target_glib
213 if not 'GOBJECT' in self
.uselib
:
214 self
.uselib
.append('GOBJECT')
216 if hasattr(self
, 'threading'):
217 if valatask
.profile
== 'gobject':
218 valatask
.threading
= self
.threading
219 if not 'GTHREAD' in self
.uselib
:
220 self
.uselib
.append('GTHREAD')
222 #Vala doesn't have threading support for dova nor posix
223 Logs
.warn("Profile %s does not have threading support" % valatask
.profile
)
225 if hasattr(self
, 'gir'):
226 valatask
.gir
= self
.gir
232 c_node
= node
.change_ext('.c')
233 output_nodes
.append(c_node
)
234 self
.allnodes
.append(c_node
)
236 if env
['VALAC_VERSION'] < (0, 7, 0):
237 output_nodes
.append(node
.change_ext('.h'))
239 if not 'cprogram' in self
.features
:
240 output_nodes
.append(self
.path
.find_or_declare('%s.h' % self
.target
))
242 if not 'cprogram' in self
.features
:
243 output_nodes
.append(self
.path
.find_or_declare('%s.vapi' % self
.target
))
244 if env
['VALAC_VERSION'] > (0, 7, 2):
245 if hasattr(self
, 'gir'):
246 output_nodes
.append(self
.path
.find_or_declare('%s.gir' % self
.gir
))
247 elif env
['VALAC_VERSION'] > (0, 3, 5):
248 output_nodes
.append(self
.path
.find_or_declare('%s.gir' % self
.target
))
249 elif env
['VALAC_VERSION'] > (0, 1, 7):
250 output_nodes
.append(self
.path
.find_or_declare('%s.gidl' % self
.target
))
251 if valatask
.packages
:
252 output_nodes
.append(self
.path
.find_or_declare('%s.deps' % self
.target
))
254 valatask
.inputs
.append(node
)
255 valatask
.outputs
.extend(output_nodes
)
258 min_version
= (0, 1, 6)
259 min_version_str
= "%d.%d.%d" % min_version
261 valac
= conf
.find_program('valac', var
='VALAC', mandatory
=True)
263 if not conf
.env
["HAVE_GOBJECT"]:
264 pkg_args
= {'package': 'gobject-2.0',
265 'uselib_store': 'GOBJECT',
266 'args': '--cflags --libs'}
267 if getattr(Options
.options
, 'vala_target_glib', None):
268 pkg_args
['atleast_version'] = Options
.options
.vala_target_glib
270 conf
.check_cfg(**pkg_args
)
272 if not conf
.env
["HAVE_GTHREAD"]:
273 pkg_args
= {'package': 'gthread-2.0',
274 'uselib_store': 'GTHREAD',
275 'args': '--cflags --libs'}
276 if getattr(Options
.options
, 'vala_target_glib', None):
277 pkg_args
['atleast_version'] = Options
.options
.vala_target_glib
279 conf
.check_cfg(**pkg_args
)
282 output
= Utils
.cmd_output(valac
+ " --version", silent
=True)
283 version
= output
.split(' ', 1)[-1].strip().split(".")[0:3]
284 version
= [int(x
) for x
in version
]
285 valac_version
= tuple(version
)
287 valac_version
= (0, 0, 0)
289 conf
.check_message('program version',
290 'valac >= ' + min_version_str
,
291 valac_version
>= min_version
,
292 "%d.%d.%d" % valac_version
)
294 conf
.check_tool('gnu_dirs')
296 if valac_version
< min_version
:
297 conf
.fatal("valac version too old to be used with this tool")
300 conf
.env
['VALAC_VERSION'] = valac_version
301 conf
.env
['VALAFLAGS'] = ''
303 def set_options (opt
):
304 valaopts
= opt
.add_option_group('Vala Compiler Options')
305 valaopts
.add_option ('--vala-target-glib', default
=None,
306 dest
='vala_target_glib', metavar
='MAJOR.MINOR',
307 help='Target version of glib for Vala GObject code generation')