1
0
mirror of https://git.yoctoproject.org/poky synced 2026-05-30 12:29:55 +00:00

bitbake-dev: Sync with upstream

Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
This commit is contained in:
Richard Purdie
2010-01-14 17:36:31 +00:00
parent a7740492af
commit f00e5cf964
12 changed files with 237 additions and 48 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ Tim Ansell <mithro@mithis.net>
Phil Blundell <pb@handhelds.org> Phil Blundell <pb@handhelds.org>
Seb Frankengul <seb@frankengul.org> Seb Frankengul <seb@frankengul.org>
Holger Freyther <zecke@handhelds.org> Holger Freyther <zecke@handhelds.org>
Marcin Juszkiewicz <marcin@haerwu.biz> Marcin Juszkiewicz <marcin@juszkiewicz.com.pl>
Chris Larson <kergoth@handhelds.org> Chris Larson <kergoth@handhelds.org>
Ulrich Luckas <luckas@musoft.de> Ulrich Luckas <luckas@musoft.de>
Mickey Lauer <mickey@Vanille.de> Mickey Lauer <mickey@Vanille.de>
+2
View File
@@ -176,6 +176,8 @@ Changes in Bitbake 1.9.x:
- Set HOME environmental variable when running fetcher commands (from Poky) - Set HOME environmental variable when running fetcher commands (from Poky)
- Make sure allowed variables inherited from the environment are exported again (from Poky) - Make sure allowed variables inherited from the environment are exported again (from Poky)
- When running a stage task in bbshell, run populate_staging, not the stage task (from Poky) - When running a stage task in bbshell, run populate_staging, not the stage task (from Poky)
- Fix + character escaping from PACKAGES_DYNAMIC (thanks Otavio Salvador)
- Addition of BBCLASSEXTEND support for allowing one recipe to provide multiple targets (from Poky)
Changes in Bitbake 1.8.0: Changes in Bitbake 1.8.0:
- Release 1.7.x as a stable series - Release 1.7.x as a stable series
+9 -5
View File
@@ -144,7 +144,11 @@ Default BBFILES are the .bb files in the current directory.""" )
configuration.pkgs_to_build = [] configuration.pkgs_to_build = []
configuration.pkgs_to_build.extend(args[1:]) configuration.pkgs_to_build.extend(args[1:])
cooker = bb.cooker.BBCooker(configuration) # Save a logfile for cooker into the current working directory. When the
# server is daemonized this logfile will be truncated.
cooker_logfile = os.path.join (os.getcwd(), "cooker.log")
cooker = bb.cooker.BBCooker(configuration, bb.server.xmlrpc)
# Clear away any spurious environment variables. But don't wipe the # Clear away any spurious environment variables. But don't wipe the
# environment totally. This is necessary to ensure the correct operation # environment totally. This is necessary to ensure the correct operation
@@ -152,13 +156,13 @@ Default BBFILES are the .bb files in the current directory.""" )
bb.utils.clean_environment() bb.utils.clean_environment()
cooker.parseCommandLine() cooker.parseCommandLine()
host = cooker.server.host host = cooker.server.host
port = cooker.server.port port = cooker.server.port
# Save a logfile for cooker into the current working directory. When the
# server is daemonized this logfile will be truncated.
cooker_logfile = os.path.join (os.getcwd(), "cooker.log")
daemonize.createDaemon(cooker.serve, cooker_logfile) daemonize.createDaemon(cooker.serve, cooker_logfile)
del cooker del cooker
-1
View File
@@ -57,7 +57,6 @@ class Command:
async_cmds[command] = (method) async_cmds[command] = (method)
def runCommand(self, commandline): def runCommand(self, commandline):
bb.debug("Running command %s" % commandline)
try: try:
command = commandline.pop(0) command = commandline.pop(0)
if command in CommandsSync.__dict__: if command in CommandsSync.__dict__:
+5 -5
View File
@@ -25,7 +25,8 @@
import sys, os, getopt, glob, copy, os.path, re, time import sys, os, getopt, glob, copy, os.path, re, time
import bb import bb
from bb import utils, data, parse, event, cache, providers, taskdata, runqueue from bb import utils, data, parse, event, cache, providers, taskdata, runqueue
from bb import xmlrpcserver, command from bb import command
import bb.server.xmlrpc
import itertools, sre_constants import itertools, sre_constants
class MultipleMatches(Exception): class MultipleMatches(Exception):
@@ -62,14 +63,13 @@ class BBCooker:
Manages one bitbake build run Manages one bitbake build run
""" """
def __init__(self, configuration): def __init__(self, configuration, server):
self.status = None self.status = None
self.cache = None self.cache = None
self.bb_cache = None self.bb_cache = None
self.server = bb.xmlrpcserver.BitBakeXMLRPCServer(self) self.server = server.BitBakeServer(self)
#self.server.register_function(self.showEnvironment)
self.configuration = configuration self.configuration = configuration
@@ -680,7 +680,7 @@ class BBCooker:
retval = False retval = False
if not retval: if not retval:
self.command.finishAsyncCommand() self.command.finishAsyncCommand()
bb.event.fire(bb.event.BuildCompleted(buildname, targets, self.configuration.event_data, failures)) bb.event.fire(bb.event.BuildCompleted(buildname, item, self.configuration.event_data, failures))
return False return False
return 0.5 return 0.5
+40 -10
View File
@@ -99,6 +99,11 @@ def fetcher_init(d):
pd.delDomain("BB_URI_HEADREVS") pd.delDomain("BB_URI_HEADREVS")
else: else:
bb.msg.fatal(bb.msg.domain.Fetcher, "Invalid SRCREV cache policy of: %s" % srcrev_policy) bb.msg.fatal(bb.msg.domain.Fetcher, "Invalid SRCREV cache policy of: %s" % srcrev_policy)
for m in methods:
if hasattr(m, "init"):
m.init(d)
# Make sure our domains exist # Make sure our domains exist
pd.addDomain("BB_URI_HEADREVS") pd.addDomain("BB_URI_HEADREVS")
pd.addDomain("BB_URI_LOCALCOUNT") pd.addDomain("BB_URI_LOCALCOUNT")
@@ -147,14 +152,16 @@ def init(urls, d, setup = True):
urldata_cache[fn] = urldata urldata_cache[fn] = urldata
return urldata return urldata
def go(d): def go(d, urls = None):
""" """
Fetch all urls Fetch all urls
init must have previously been called init must have previously been called
""" """
urldata = init([], d, True) if not urls:
urls = d.getVar("SRC_URI", 1).split()
urldata = init(urls, d, True)
for u in urldata: for u in urls:
ud = urldata[u] ud = urldata[u]
m = ud.method m = ud.method
if ud.localfile: if ud.localfile:
@@ -465,6 +472,23 @@ class Fetch(object):
srcrev_internal_helper = staticmethod(srcrev_internal_helper) srcrev_internal_helper = staticmethod(srcrev_internal_helper)
def localcount_internal_helper(ud, d):
"""
Return:
a) a locked localcount if specified
b) None otherwise
"""
localcount= None
if 'name' in ud.parm:
pn = data.getVar("PN", d, 1)
localcount = data.getVar("LOCALCOUNT_" + ud.parm['name'], d, 1)
if not localcount:
localcount = data.getVar("LOCALCOUNT", d, 1)
return localcount
localcount_internal_helper = staticmethod(localcount_internal_helper)
def try_mirror(d, tarfn): def try_mirror(d, tarfn):
""" """
Try to use a mirrored version of the sources. We do this Try to use a mirrored version of the sources. We do this
@@ -553,12 +577,7 @@ class Fetch(object):
""" """
""" """
has_sortable_valid = hasattr(self, "_sortable_revision_valid") if hasattr(self, "_sortable_revision"):
has_sortable = hasattr(self, "_sortable_revision")
if has_sortable and not has_sortable_valid:
return self._sortable_revision(url, ud, d)
elif has_sortable and self._sortable_revision_valid(url, ud, d):
return self._sortable_revision(url, ud, d) return self._sortable_revision(url, ud, d)
pd = persist_data.PersistData(d) pd = persist_data.PersistData(d)
@@ -566,13 +585,24 @@ class Fetch(object):
latest_rev = self._build_revision(url, ud, d) latest_rev = self._build_revision(url, ud, d)
last_rev = pd.getValue("BB_URI_LOCALCOUNT", key + "_rev") last_rev = pd.getValue("BB_URI_LOCALCOUNT", key + "_rev")
count = pd.getValue("BB_URI_LOCALCOUNT", key + "_count") uselocalcount = bb.data.getVar("BB_LOCALCOUNT_OVERRIDE", d, True) or False
count = None
if uselocalcount:
count = Fetch.localcount_internal_helper(ud, d)
if count is None:
count = pd.getValue("BB_URI_LOCALCOUNT", key + "_count")
if last_rev == latest_rev: if last_rev == latest_rev:
return str(count + "+" + latest_rev) return str(count + "+" + latest_rev)
buildindex_provided = hasattr(self, "_sortable_buildindex")
if buildindex_provided:
count = self._sortable_buildindex(url, ud, d, latest_rev)
if count is None: if count is None:
count = "0" count = "0"
elif uselocalcount or buildindex_provided:
count = str(count)
else: else:
count = str(int(count) + 1) count = str(int(count) + 1)
+18 -24
View File
@@ -28,6 +28,12 @@ from bb.fetch import runfetchcmd
class Git(Fetch): class Git(Fetch):
"""Class to fetch a module or modules from git repositories""" """Class to fetch a module or modules from git repositories"""
def init(self, d):
#
# Only enable _sortable revision if the key is set
#
if bb.data.getVar("BB_GIT_CLONE_FOR_SRCREV", d, True):
self._sortable_buildindex = self._sortable_buildindex_disabled
def supports(self, url, ud, d): def supports(self, url, ud, d):
""" """
Check to see if a given url can be fetched with git. Check to see if a given url can be fetched with git.
@@ -145,44 +151,32 @@ class Git(Fetch):
def _build_revision(self, url, ud, d): def _build_revision(self, url, ud, d):
return ud.tag return ud.tag
def _sortable_revision_valid(self, url, ud, d): def _sortable_buildindex_disabled(self, url, ud, d, rev):
return bb.data.getVar("BB_GIT_CLONE_FOR_SRCREV", d, True) or False
def _sortable_revision(self, url, ud, d):
""" """
This is only called when _sortable_revision_valid called true Return a suitable buildindex for the revision specified. This is done by counting revisions
using "git rev-list" which may or may not work in different circumstances.
We will have to get the updated revision.
""" """
gitsrcname = '%s%s' % (ud.host, ud.path.replace('/', '.')) gitsrcname = '%s%s' % (ud.host, ud.path.replace('/', '.'))
repodir = os.path.join(data.expand('${GITDIR}', d), gitsrcname) repodir = os.path.join(data.expand('${GITDIR}', d), gitsrcname)
key = "GIT_CACHED_REVISION-%s-%s" % (gitsrcname, ud.tag)
if bb.data.getVar(key, d):
return bb.data.getVar(key, d)
# Runtime warning on wrongly configured sources
if ud.tag == "1":
bb.msg.error(1, bb.msg.domain.Fetcher, "SRCREV is '1'. This indicates a configuration error of %s" % url)
return "0+1"
cwd = os.getcwd() cwd = os.getcwd()
# Check if we have the rev already # Check if we have the rev already
if not os.path.exists(repodir): if not os.path.exists(repodir):
print "no repo"
self.go(None, ud, d) self.go(None, ud, d)
if not os.path.exists(repodir):
bb.msg.error(bb.msg.domain.Fetcher, "GIT repository for %s doesn't exist in %s, cannot get sortable buildnumber, using old value" % (url, repodir))
return None
os.chdir(repodir) os.chdir(repodir)
if not self._contains_ref(ud.tag, d): if not self._contains_ref(rev, d):
self.go(None, ud, d) self.go(None, ud, d)
output = runfetchcmd("git rev-list %s -- 2> /dev/null | wc -l" % ud.tag, d, quiet=True) output = runfetchcmd("git rev-list %s -- 2> /dev/null | wc -l" % rev, d, quiet=True)
os.chdir(cwd) os.chdir(cwd)
sortable_revision = "%s+%s" % (output.split()[0], ud.tag) buildindex = "%s" % output.split()[0]
bb.data.setVar(key, sortable_revision, d) bb.msg.debug(1, bb.msg.domain.Fetcher, "GIT repository for %s in %s is returning %s revisions in rev-list before %s" % (url, repodir, buildindex, rev))
return sortable_revision return buildindex
+1 -1
View File
@@ -191,7 +191,7 @@ def _filterProviders(providers, item, cfgData, dataCache):
eligible.append(preferred_versions[pn][1]) eligible.append(preferred_versions[pn][1])
# Now add latest verisons # Now add latest verisons
for pn in pkg_pn.keys(): for pn in sortpkg_pn.keys():
if pn in preferred_versions and preferred_versions[pn][1]: if pn in preferred_versions and preferred_versions[pn][1]:
continue continue
preferred_versions[pn] = findLatestProvider(pn, cfgData, dataCache, sortpkg_pn[pn][0]) preferred_versions[pn] = findLatestProvider(pn, cfgData, dataCache, sortpkg_pn[pn][0])
+1
View File
@@ -0,0 +1 @@
import xmlrpc
+145
View File
@@ -0,0 +1,145 @@
#
# BitBake XMLRPC Server
#
# Copyright (C) 2006 - 2007 Michael 'Mickey' Lauer
# Copyright (C) 2006 - 2008 Richard Purdie
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""
This module implements an xmlrpc server for BitBake.
Use this by deriving a class from BitBakeXMLRPCServer and then adding
methods which you want to "export" via XMLRPC. If the methods have the
prefix xmlrpc_, then registering those function will happen automatically,
if not, you need to call register_function.
Use register_idle_function() to add a function which the xmlrpc server
calls from within server_forever when no requests are pending. Make sure
that those functions are non-blocking or else you will introduce latency
in the server's main loop.
"""
import bb
import xmlrpclib
DEBUG = False
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
import inspect, select
class BitBakeServerCommands():
def __init__(self, server, cooker):
self.cooker = cooker
self.server = server
def registerEventHandler(self, host, port):
"""
Register a remote UI Event Handler
"""
s = xmlrpclib.Server("http://%s:%d" % (host, port), allow_none=True)
return bb.event.register_UIHhandler(s)
def unregisterEventHandler(self, handlerNum):
"""
Unregister a remote UI Event Handler
"""
return bb.event.unregister_UIHhandler(handlerNum)
def runCommand(self, command):
"""
Run a cooker command on the server
"""
return self.cooker.command.runCommand(command)
def terminateServer(self):
"""
Trigger the server to quit
"""
self.server.quit = True
print "Server (cooker) exitting"
return
def ping(self):
"""
Dummy method which can be used to check the server is still alive
"""
return True
class BitBakeServer(SimpleXMLRPCServer):
# remove this when you're done with debugging
# allow_reuse_address = True
def __init__(self, cooker, interface = ("localhost", 0)):
"""
Constructor
"""
SimpleXMLRPCServer.__init__(self, interface,
requestHandler=SimpleXMLRPCRequestHandler,
logRequests=False, allow_none=True)
self._idlefuns = {}
self.host, self.port = self.socket.getsockname()
#self.register_introspection_functions()
commands = BitBakeServerCommands(self, cooker)
self.autoregister_all_functions(commands, "")
def autoregister_all_functions(self, context, prefix):
"""
Convenience method for registering all functions in the scope
of this class that start with a common prefix
"""
methodlist = inspect.getmembers(context, inspect.ismethod)
for name, method in methodlist:
if name.startswith(prefix):
self.register_function(method, name[len(prefix):])
def register_idle_function(self, function, data):
"""Register a function to be called while the server is idle"""
assert callable(function)
self._idlefuns[function] = data
def serve_forever(self):
"""
Serve Requests. Overloaded to honor a quit command
"""
self.quit = False
while not self.quit:
#print "Idle queue length %s" % len(self._idlefuns)
if len(self._idlefuns) == 0:
self.timeout = None
else:
self.timeout = 0
self.handle_request()
#print "Idle timeout, running idle functions"
for function, data in self._idlefuns.items():
try:
retval = function(self, data, False)
if not retval:
del self._idlefuns[function]
except SystemExit:
raise
except:
import traceback
traceback.print_exc()
pass
# Tell idle functions we're exiting
for function, data in self._idlefuns.items():
try:
retval = function(self, data, True)
except:
pass
self.server_close()
return
+15 -1
View File
@@ -21,8 +21,9 @@ BitBake Utility Functions
digits = "0123456789" digits = "0123456789"
ascii_letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ascii_letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
separators = ".-"
import re, fcntl, os import re, fcntl, os, types
def explode_version(s): def explode_version(s):
r = [] r = []
@@ -39,12 +40,15 @@ def explode_version(s):
r.append(m.group(1)) r.append(m.group(1))
s = m.group(2) s = m.group(2)
continue continue
r.append(s[0])
s = s[1:] s = s[1:]
return r return r
def vercmp_part(a, b): def vercmp_part(a, b):
va = explode_version(a) va = explode_version(a)
vb = explode_version(b) vb = explode_version(b)
sa = False
sb = False
while True: while True:
if va == []: if va == []:
ca = None ca = None
@@ -56,6 +60,16 @@ def vercmp_part(a, b):
cb = vb.pop(0) cb = vb.pop(0)
if ca == None and cb == None: if ca == None and cb == None:
return 0 return 0
if type(ca) is types.StringType:
sa = ca in separators
if type(cb) is types.StringType:
sb = cb in separators
if sa and not sb:
return -1
if not sa and sb:
return 1
if ca > cb: if ca > cb:
return 1 return 1
if ca < cb: if ca < cb: