summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/build.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/build.py')
-rw-r--r--bitbake/lib/bb/build.py193
1 files changed, 100 insertions, 93 deletions
diff --git a/bitbake/lib/bb/build.py b/bitbake/lib/bb/build.py
index 942bdc1a39..bf6b612f32 100644
--- a/bitbake/lib/bb/build.py
+++ b/bitbake/lib/bb/build.py
@@ -1,29 +1,29 @@
1#!/usr/bin/env python
2# ex:ts=4:sw=4:sts=4:et 1# ex:ts=4:sw=4:sts=4:et
3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- 2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4""" 3#
5BitBake 'Build' implementation 4# BitBake 'Build' implementation
6 5#
7Core code for function execution and task handling in the 6# Core code for function execution and task handling in the
8BitBake build tools. 7# BitBake build tools.
9 8#
10Copyright (C) 2003, 2004 Chris Larson 9# Copyright (C) 2003, 2004 Chris Larson
11 10#
12Based on Gentoo's portage.py. 11# Based on Gentoo's portage.py.
13 12#
14This program is free software; you can redistribute it and/or modify it under 13# This program is free software; you can redistribute it and/or modify
15the terms of the GNU General Public License as published by the Free Software 14# it under the terms of the GNU General Public License version 2 as
16Foundation; either version 2 of the License, or (at your option) any later 15# published by the Free Software Foundation.
17version. 16#
18 17# This program is distributed in the hope that it will be useful,
19This program is distributed in the hope that it will be useful, but WITHOUT 18# but WITHOUT ANY WARRANTY; without even the implied warranty of
20ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 20# GNU General Public License for more details.
22 21#
23You should have received a copy of the GNU General Public License along with 22# You should have received a copy of the GNU General Public License along
24 23# with this program; if not, write to the Free Software Foundation, Inc.,
25Based on functions from the base bb module, Copyright 2003 Holger Schurig 24# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26""" 25#
26#Based on functions from the base bb module, Copyright 2003 Holger Schurig
27 27
28from bb import data, fetch, event, mkdirhier, utils 28from bb import data, fetch, event, mkdirhier, utils
29import bb, os 29import bb, os
@@ -219,14 +219,18 @@ def exec_func_shell(func, d):
219 bb.msg.error(bb.msg.domain.Build, "function %s failed" % func) 219 bb.msg.error(bb.msg.domain.Build, "function %s failed" % func)
220 if data.getVar("BBINCLUDELOGS", d): 220 if data.getVar("BBINCLUDELOGS", d):
221 bb.msg.error(bb.msg.domain.Build, "log data follows (%s)" % logfile) 221 bb.msg.error(bb.msg.domain.Build, "log data follows (%s)" % logfile)
222 f = open(logfile, "r") 222 number_of_lines = data.getVar("BBINCLUDELOGS_LINES", d)
223 while True: 223 if number_of_lines:
224 l = f.readline() 224 os.system('tail -n%s %s' % (number_of_lines, logfile))
225 if l == '': 225 else:
226 break 226 f = open(logfile, "r")
227 l = l.rstrip() 227 while True:
228 print '| %s' % l 228 l = f.readline()
229 f.close() 229 if l == '':
230 break
231 l = l.rstrip()
232 print '| %s' % l
233 f.close()
230 else: 234 else:
231 bb.msg.error(bb.msg.domain.Build, "see log in %s" % logfile) 235 bb.msg.error(bb.msg.domain.Build, "see log in %s" % logfile)
232 raise FuncFailed( logfile ) 236 raise FuncFailed( logfile )
@@ -252,9 +256,8 @@ def exec_task(task, d):
252 raise EventException("Missing node in task graph", InvalidTask(task, d)) 256 raise EventException("Missing node in task graph", InvalidTask(task, d))
253 257
254 # check whether this task needs executing.. 258 # check whether this task needs executing..
255 if not data.getVarFlag(task, 'force', d): 259 if stamp_is_current(task, d):
256 if stamp_is_current(task, d): 260 return 1
257 return 1
258 261
259 # follow digraph path up, then execute our way back down 262 # follow digraph path up, then execute our way back down
260 def execute(graph, item): 263 def execute(graph, item):
@@ -291,59 +294,43 @@ def exec_task(task, d):
291 294
292 # make stamp, or cause event and raise exception 295 # make stamp, or cause event and raise exception
293 if not data.getVarFlag(task, 'nostamp', d): 296 if not data.getVarFlag(task, 'nostamp', d):
294 mkstamp(task, d) 297 make_stamp(task, d)
295 298
296def stamp_is_current_cache(dataCache, file_name, task, checkdeps = 1): 299def extract_stamp_data(d, fn):
297 """ 300 """
298 Check status of a given task's stamp. 301 Extracts stamp data from d which is either a data dictonary (fn unset)
299 Returns 0 if it is not current and needs updating. 302 or a dataCache entry (fn set).
300 Same as stamp_is_current but works against the dataCache instead of d
301 """ 303 """
302 task_graph = dataCache.task_queues[file_name] 304 if fn:
303 305 return (d.task_queues[fn], d.stamp[fn], d.task_deps[fn])
304 if not dataCache.stamp[file_name]: 306 task_graph = data.getVar('_task_graph', d)
305 return 0 307 if not task_graph:
306 308 task_graph = bb.digraph()
307 stampfile = "%s.%s" % (dataCache.stamp[file_name], task) 309 data.setVar('_task_graph', task_graph, d)
308 if not os.access(stampfile, os.F_OK): 310 return (task_graph, data.getVar('STAMP', d, 1), None)
309 return 0
310
311 if checkdeps == 0:
312 return 1
313
314 import stat
315 tasktime = os.stat(stampfile)[stat.ST_MTIME]
316
317 _deps = []
318 def checkStamp(graph, task):
319 # check for existance
320 if 'nostamp' in dataCache.task_deps[file_name] and task in dataCache.task_deps[file_name]['nostamp']:
321 return 1
322
323 if not stamp_is_current_cache(dataCache, file_name, task, 0):
324 return 0
325
326 depfile = "%s.%s" % (dataCache.stamp[file_name], task)
327 deptime = os.stat(depfile)[stat.ST_MTIME]
328 if deptime > tasktime:
329 return 0
330 return 1
331 311
332 return task_graph.walkdown(task, checkStamp) 312def extract_stamp(d, fn):
313 """
314 Extracts stamp format which is either a data dictonary (fn unset)
315 or a dataCache entry (fn set).
316 """
317 if fn:
318 return d.stamp[fn]
319 return data.getVar('STAMP', d, 1)
333 320
334def stamp_is_current(task, d, checkdeps = 1): 321def stamp_is_current(task, d, file_name = None, checkdeps = 1):
335 """ 322 """
336 Check status of a given task's stamp. 323 Check status of a given task's stamp.
337 Returns 0 if it is not current and needs updating. 324 Returns 0 if it is not current and needs updating.
325 (d can be a data dict or dataCache)
338 """ 326 """
339 task_graph = data.getVar('_task_graph', d) 327
340 if not task_graph: 328 (task_graph, stampfn, taskdep) = extract_stamp_data(d, file_name)
341 task_graph = bb.digraph() 329
342 data.setVar('_task_graph', task_graph, d) 330 if not stampfn:
343 stamp = data.getVar('STAMP', d)
344 if not stamp:
345 return 0 331 return 0
346 stampfile = "%s.%s" % (data.expand(stamp, d), task) 332
333 stampfile = "%s.%s" % (stampfn, task)
347 if not os.access(stampfile, os.F_OK): 334 if not os.access(stampfile, os.F_OK):
348 return 0 335 return 0
349 336
@@ -356,13 +343,17 @@ def stamp_is_current(task, d, checkdeps = 1):
356 _deps = [] 343 _deps = []
357 def checkStamp(graph, task): 344 def checkStamp(graph, task):
358 # check for existance 345 # check for existance
359 if data.getVarFlag(task, 'nostamp', d): 346 if file_name:
360 return 1 347 if 'nostamp' in taskdep and task in taskdep['nostamp']:
348 return 1
349 else:
350 if data.getVarFlag(task, 'nostamp', d):
351 return 1
361 352
362 if not stamp_is_current(task, d, 0): 353 if not stamp_is_current(task, d, file_name, 0 ):
363 return 0 354 return 0
364 355
365 depfile = "%s.%s" % (data.expand(stamp, d), task) 356 depfile = "%s.%s" % (stampfn, task)
366 deptime = os.stat(depfile)[stat.ST_MTIME] 357 deptime = os.stat(depfile)[stat.ST_MTIME]
367 if deptime > tasktime: 358 if deptime > tasktime:
368 return 0 359 return 0
@@ -370,24 +361,40 @@ def stamp_is_current(task, d, checkdeps = 1):
370 361
371 return task_graph.walkdown(task, checkStamp) 362 return task_graph.walkdown(task, checkStamp)
372 363
373 364def stamp_internal(task, d, file_name):
374def md5_is_current(task): 365 """
375 """Check if a md5 file for a given task is current""" 366 Internal stamp helper function
376 367 Removes any stamp for the given task
377 368 Makes sure the stamp directory exists
378def mkstamp(task, d): 369 Returns the stamp path+filename
379 """Creates/updates a stamp for a given task""" 370 """
380 stamp = data.getVar('STAMP', d) 371 stamp = extract_stamp(d, file_name)
381 if not stamp: 372 if not stamp:
382 return 373 return
383 stamp = "%s.%s" % (data.expand(stamp, d), task) 374 stamp = "%s.%s" % (stamp, task)
384 mkdirhier(os.path.dirname(stamp)) 375 mkdirhier(os.path.dirname(stamp))
385 # Remove the file and recreate to force timestamp 376 # Remove the file and recreate to force timestamp
386 # change on broken NFS filesystems 377 # change on broken NFS filesystems
387 if os.access(stamp, os.F_OK): 378 if os.access(stamp, os.F_OK):
388 os.remove(stamp) 379 os.remove(stamp)
389 f = open(stamp, "w") 380 return stamp
390 f.close() 381
382def make_stamp(task, d, file_name = None):
383 """
384 Creates/updates a stamp for a given task
385 (d can be a data dict or dataCache)
386 """
387 stamp = stamp_internal(task, d, file_name)
388 if stamp:
389 f = open(stamp, "w")
390 f.close()
391
392def del_stamp(task, d, file_name = None):
393 """
394 Removes a stamp for a given task
395 (d can be a data dict or dataCache)
396 """
397 stamp_internal(task, d, file_name)
391 398
392def add_task(task, deps, d): 399def add_task(task, deps, d):
393 task_graph = data.getVar('_task_graph', d) 400 task_graph = data.getVar('_task_graph', d)