Compare commits

..

3 Commits

Author SHA1 Message Date
Richard Purdie
0e392026ff build-appliance-image: Update to warrior head revision
(From OE-Core rev: f571b188177788d8ed0a7f3efe3569f153b1b0d3)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2019-04-14 21:29:15 +01:00
Richard Purdie
41136dd0cf Revert "nettle: fix ptest failure"
This reverts commit 83faaf7b2a5f4fc4ae504b300134409e90389770.

This should never have merged as the change was rejected upstream and adding a library
to the ptest package resulted in it providing that SONAME which led to being
included in images like core-image-sato.

This in turn led to a ton of ptest failures in the 2.7 r1 QA report.

(From OE-Core rev: 039e7b25f0018e6923d14b40c35252f99e1d3ea3)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2019-04-12 23:01:22 +01:00
Scott Rifenbark
80baa2d1fb bitbake: poky.ent: Removed "ECLIPSE" entity variables.
These have never been used in the BB manual and were an
artifact from copy-and-pasting the poky.ent file from
the main yocto-docs repo to this bb repo when the BB
manual was origially created.  They are useless.  I have
removed them.

(Bitbake rev: cb185efe9e88cfb12b7a3fd08f3086ca0b69c8e2)

Signed-off-by: Scott Rifenbark <srifenbark@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2019-04-12 22:44:16 +01:00
2438 changed files with 59007 additions and 55163 deletions

24
LICENSE
View File

@@ -1,20 +1,14 @@
Different components of OpenEmbedded are under different licenses (a mix
of MIT and GPLv2). See LICENSE.GPL-2.0-only and LICENSE.MIT for further
details of the individual licenses.
of MIT and GPLv2). Please see:
meta/COPYING.GPLv2 (GPLv2)
meta/COPYING.MIT (MIT)
meta-selftest/COPYING.MIT (MIT)
meta-skeleton/COPYING.MIT (MIT)
All metadata is MIT licensed unless otherwise stated. Source code
included in tree for individual recipes (e.g. patches) are under
the LICENSE stated in the associated recipe (.bb file) unless
otherwise stated.
included in tree for individual recipes is under the LICENSE stated in
the associated recipe (.bb file) unless otherwise stated.
License information for any other files is either explicitly stated
or defaults to GPL version 2 only.
Individual files contain the following style tags instead of the full license
text to identify their license:
SPDX-License-Identifier: GPL-2.0-only
SPDX-License-Identifier: MIT
This enables machine processing of license information based on the SPDX
License Identifiers that are here available: http://spdx.org/licenses/
or defaults to GPL version 2.

26
README.LSB Normal file
View File

@@ -0,0 +1,26 @@
OE-Core aims to be able to provide basic LSB compatible images. There
are some challenges for OE as LSB isn't always 100% relevant to its
target embedded and IoT audiences.
One challenge is that the LSB spec is no longer being actively
developed [https://github.com/LinuxStandardBase/lsb] and has
components which are end of life or significantly dated. OE
therefore provides compatibility with the following caveats:
* Qt4 is provided by the separate meta-qt4 layer. Its noted that Qt4
is end of life and this isn't something the core project regularly
tests any longer. Users are recommended to group together to support
maintenance of that layer. [http://git.yoctoproject.org/cgit/cgit.cgi/meta-qt4/]
* mailx has been dropped since its no longer being developed upstream
and there are better, more modern replacements such as s-nail
(http://sdaoden.eu/code.html) or mailutils (http://mailutils.org/).
* A few perl modules that were required by LSB 4.x aren't provided:
libclass-isa, libenv, libdumpvalue, libfile-checktree,
libi18n-collate, libpod-plainer.
* libpng 1.2 isn't provided; oe-core includes the latest release of libpng
instead.
* pax (POSIX standard archive) tool is not provided.

View File

@@ -279,10 +279,61 @@ POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Note:
Individual files contain the following tag instead of the full license text.
How to Apply These Terms to Your New Programs
SPDX-License-Identifier: GPL-2.0-only
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
This enables machine processing of license information based on the SPDX
License Identifiers that are here available: http://spdx.org/licenses/
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

19
bitbake/HEADER Normal file
View File

@@ -0,0 +1,19 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# <one line to give the program's name and a brief idea of what it does.>
# Copyright (C) <year> <name of author>
#
# 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.

View File

@@ -1,13 +1,4 @@
BitBake is licensed under the GNU General Public License version 2.0. See
LICENSE.GPL-2.0-only for further details.
Individual files contain the following style tags instead of the full license text:
SPDX-License-Identifier: GPL-2.0-only
This enables machine processing of license information based on the SPDX
License Identifiers that are here available: http://spdx.org/licenses/
BitBake is licensed under the GNU General Public License version 2.0. See COPYING for further details.
The following external components are distributed with this software:
@@ -26,4 +17,3 @@ Foundation and individual contributors.
* Font Awesome fonts redistributed under the SIL Open Font License 1.1
* simplediff is distributed under the zlib license.

View File

@@ -1,4 +1,6 @@
#!/usr/bin/env python3
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# Copyright (C) 2003, 2004 Chris Larson
# Copyright (C) 2003, 2004 Phil Blundell
@@ -7,8 +9,18 @@
# Copyright (C) 2005 ROAD GmbH
# Copyright (C) 2006 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import os
import sys
@@ -26,7 +38,7 @@ from bb.main import bitbake_main, BitBakeConfigParameters, BBMainException
if sys.getfilesystemencoding() != "utf-8":
sys.exit("Please use a locale setting which supports UTF-8 (such as LANG=en_US.UTF-8).\nPython can't change the filesystem locale after loading so we need a UTF-8 when Python starts or things won't work.")
__version__ = "1.44.0"
__version__ = "1.42.0"
if __name__ == "__main__":
if __version__ != bb.__version__:

View File

@@ -5,8 +5,18 @@
#
# Copyright (C) 2012-2013, 2017 Intel Corporation
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import os
import sys
@@ -95,7 +105,7 @@ def recursecb(key, hash1, hash2):
out2 = bb.siggen.compare_sigfiles(hashfiles[hash1], hashfiles[hash2], recursecb, color=color)
for change in out2:
for line in change.splitlines():
recout.append(' ' + line)
recout.append(' ' + line)
return recout

View File

@@ -1,170 +0,0 @@
#! /usr/bin/env python3
#
# Copyright (C) 2019 Garmin Ltd.
#
# SPDX-License-Identifier: GPL-2.0-only
#
import argparse
import hashlib
import logging
import os
import pprint
import sys
import threading
import time
try:
import tqdm
ProgressBar = tqdm.tqdm
except ImportError:
class ProgressBar(object):
def __init__(self, *args, **kwargs):
pass
def __enter__(self):
return self
def __exit__(self, *args, **kwargs):
pass
def update(self):
pass
sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(__file__)), 'lib'))
import hashserv
DEFAULT_ADDRESS = 'unix://./hashserve.sock'
METHOD = 'stress.test.method'
def main():
def handle_stats(args, client):
if args.reset:
s = client.reset_stats()
else:
s = client.get_stats()
pprint.pprint(s)
return 0
def handle_stress(args, client):
def thread_main(pbar, lock):
nonlocal found_hashes
nonlocal missed_hashes
nonlocal max_time
client = hashserv.create_client(args.address)
for i in range(args.requests):
taskhash = hashlib.sha256()
taskhash.update(args.taskhash_seed.encode('utf-8'))
taskhash.update(str(i).encode('utf-8'))
start_time = time.perf_counter()
l = client.get_unihash(METHOD, taskhash.hexdigest())
elapsed = time.perf_counter() - start_time
with lock:
if l:
found_hashes += 1
else:
missed_hashes += 1
max_time = max(elapsed, max_time)
pbar.update()
max_time = 0
found_hashes = 0
missed_hashes = 0
lock = threading.Lock()
total_requests = args.clients * args.requests
start_time = time.perf_counter()
with ProgressBar(total=total_requests) as pbar:
threads = [threading.Thread(target=thread_main, args=(pbar, lock), daemon=False) for _ in range(args.clients)]
for t in threads:
t.start()
for t in threads:
t.join()
elapsed = time.perf_counter() - start_time
with lock:
print("%d requests in %.1fs. %.1f requests per second" % (total_requests, elapsed, total_requests / elapsed))
print("Average request time %.8fs" % (elapsed / total_requests))
print("Max request time was %.8fs" % max_time)
print("Found %d hashes, missed %d" % (found_hashes, missed_hashes))
if args.report:
with ProgressBar(total=args.requests) as pbar:
for i in range(args.requests):
taskhash = hashlib.sha256()
taskhash.update(args.taskhash_seed.encode('utf-8'))
taskhash.update(str(i).encode('utf-8'))
outhash = hashlib.sha256()
outhash.update(args.outhash_seed.encode('utf-8'))
outhash.update(str(i).encode('utf-8'))
client.report_unihash(taskhash.hexdigest(), METHOD, outhash.hexdigest(), taskhash.hexdigest())
with lock:
pbar.update()
parser = argparse.ArgumentParser(description='Hash Equivalence Client')
parser.add_argument('--address', default=DEFAULT_ADDRESS, help='Server address (default "%(default)s")')
parser.add_argument('--log', default='WARNING', help='Set logging level')
subparsers = parser.add_subparsers()
stats_parser = subparsers.add_parser('stats', help='Show server stats')
stats_parser.add_argument('--reset', action='store_true',
help='Reset server stats')
stats_parser.set_defaults(func=handle_stats)
stress_parser = subparsers.add_parser('stress', help='Run stress test')
stress_parser.add_argument('--clients', type=int, default=10,
help='Number of simultaneous clients')
stress_parser.add_argument('--requests', type=int, default=1000,
help='Number of requests each client will perform')
stress_parser.add_argument('--report', action='store_true',
help='Report new hashes')
stress_parser.add_argument('--taskhash-seed', default='',
help='Include string in taskhash')
stress_parser.add_argument('--outhash-seed', default='',
help='Include string in outhash')
stress_parser.set_defaults(func=handle_stress)
args = parser.parse_args()
logger = logging.getLogger('hashserv')
level = getattr(logging, args.log.upper(), None)
if not isinstance(level, int):
raise ValueError('Invalid log level: %s' % args.log)
logger.setLevel(level)
console = logging.StreamHandler()
console.setLevel(level)
logger.addHandler(console)
func = getattr(args, 'func', None)
if func:
client = hashserv.create_client(args.address)
# Try to establish a connection to the server now to detect failures
# early
client.connect()
return func(args, client)
return 0
if __name__ == '__main__':
try:
ret = main()
except Exception:
ret = 1
import traceback
traceback.print_exc()
sys.exit(ret)

View File

@@ -2,35 +2,38 @@
#
# Copyright (C) 2018 Garmin Ltd.
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import os
import sys
import logging
import argparse
import sqlite3
sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(__file__)), 'lib'))
sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(__file__)),'lib'))
import hashserv
VERSION = "1.0.0"
DEFAULT_BIND = 'unix://./hashserve.sock'
DEFAULT_HOST = ''
DEFAULT_PORT = 8686
def main():
parser = argparse.ArgumentParser(description='Hash Equivalence Reference Server. Version=%s' % VERSION,
epilog='''The bind address is the path to a unix domain socket if it is
prefixed with "unix://". Otherwise, it is an IP address
and port in form ADDRESS:PORT. To bind to all addresses, leave
the ADDRESS empty, e.g. "--bind :8686". To bind to a specific
IPv6 address, enclose the address in "[]", e.g.
"--bind [::1]:8686"'''
)
parser.add_argument('--bind', default=DEFAULT_BIND, help='Bind address (default "%(default)s")')
parser = argparse.ArgumentParser(description='HTTP Equivalence Reference Server. Version=%s' % VERSION)
parser.add_argument('--address', default=DEFAULT_HOST, help='Bind address (default "%(default)s")')
parser.add_argument('--port', type=int, default=DEFAULT_PORT, help='Bind port (default %(default)d)')
parser.add_argument('--prefix', default='', help='HTTP path prefix (default "%(default)s")')
parser.add_argument('--database', default='./hashserv.db', help='Database file (default "%(default)s")')
parser.add_argument('--log', default='WARNING', help='Set logging level')
@@ -47,11 +50,12 @@ def main():
console.setLevel(level)
logger.addHandler(console)
server = hashserv.create_server(args.bind, args.database)
db = sqlite3.connect(args.database)
server = hashserv.create_server((args.address, args.port), db, args.prefix)
server.serve_forever()
return 0
if __name__ == '__main__':
try:
ret = main()
@@ -60,3 +64,4 @@ if __name__ == '__main__':
import traceback
traceback.print_exc()
sys.exit(ret)

View File

@@ -7,8 +7,18 @@
# Copyright (C) 2011 Mentor Graphics Corporation
# Copyright (C) 2011-2015 Intel Corporation
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import logging
import os

View File

@@ -1,8 +1,4 @@
#!/usr/bin/env python3
#
# SPDX-License-Identifier: GPL-2.0-only
#
import os
import sys,logging
import optparse

View File

@@ -2,8 +2,18 @@
#
# Copyright (C) 2012 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import os
import sys, logging
@@ -25,7 +35,6 @@ tests = ["bb.tests.codeparser",
"bb.tests.fetch",
"bb.tests.parse",
"bb.tests.persist_data",
"bb.tests.runqueue",
"bb.tests.utils",
"hashserv.tests",
"layerindexlib.tests.layerindexobj",

View File

@@ -1,7 +1,4 @@
#!/usr/bin/env python3
#
# SPDX-License-Identifier: GPL-2.0-only
#
import os
import sys
@@ -195,6 +192,9 @@ def fork_off_task(cfg, data, databuilder, workerdata, fn, task, taskname, taskha
global worker_pipe_lock
pipein.close()
signal.signal(signal.SIGTERM, sigterm_handler)
# Let SIGHUP exit as SIGTERM
signal.signal(signal.SIGHUP, sigterm_handler)
bb.utils.signal_on_parent_exit("SIGTERM")
# Save out the PID so that the event can include it the
@@ -209,11 +209,6 @@ def fork_off_task(cfg, data, databuilder, workerdata, fn, task, taskname, taskha
# This ensures signals sent to the controlling terminal like Ctrl+C
# don't stop the child processes.
os.setsid()
signal.signal(signal.SIGTERM, sigterm_handler)
# Let SIGHUP exit as SIGTERM
signal.signal(signal.SIGHUP, sigterm_handler)
# No stdin
newsi = os.open(os.devnull, os.O_RDWR)
os.dup2(newsi, sys.stdin.fileno())
@@ -236,8 +231,6 @@ def fork_off_task(cfg, data, databuilder, workerdata, fn, task, taskname, taskha
the_data.setVar(varname, value)
bb.parse.siggen.set_taskdata(workerdata["sigdata"])
if "newhashes" in workerdata:
bb.parse.siggen.set_taskhashes(workerdata["newhashes"])
ret = 0
the_data = bb_cache.loadDataFull(fn, appends)
@@ -381,7 +374,6 @@ class BitbakeWorker(object):
self.handle_item(b"cookerconfig", self.handle_cookercfg)
self.handle_item(b"extraconfigdata", self.handle_extraconfigdata)
self.handle_item(b"workerdata", self.handle_workerdata)
self.handle_item(b"newtaskhashes", self.handle_newtaskhashes)
self.handle_item(b"runtask", self.handle_runtask)
self.handle_item(b"finishnow", self.handle_finishnow)
self.handle_item(b"ping", self.handle_ping)
@@ -420,10 +412,6 @@ class BitbakeWorker(object):
bb.msg.loggerDefaultDomains = self.workerdata["logdefaultdomain"]
for mc in self.databuilder.mcdata:
self.databuilder.mcdata[mc].setVar("PRSERV_HOST", self.workerdata["prhost"])
self.databuilder.mcdata[mc].setVar("BB_HASHSERVE", self.workerdata["hashservaddr"])
def handle_newtaskhashes(self, data):
self.workerdata["newhashes"] = pickle.loads(data)
def handle_ping(self, _):
workerlog_write("Handling ping\n")

View File

@@ -1,9 +1,21 @@
#!/usr/bin/env python3
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# Copyright (C) 2005 Holger Hans Peter Freyther
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import optparse, os, sys

View File

@@ -1,8 +1,4 @@
#!/usr/bin/env python3
#
# SPDX-License-Identifier: GPL-2.0-only
#
"""git-make-shallow: make the current git repository shallow
Remove the history of the specified revisions, then optionally filter the

View File

@@ -3,9 +3,19 @@
# toaster - shell script to start Toaster
# Copyright (C) 2013-2015 Intel Corp.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# SPDX-License-Identifier: GPL-2.0-or-later
# 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, see http://www.gnu.org/licenses/.
HELP="
Usage: source toaster start|stop [webport=<address:port>] [noweb] [nobuild] [toasterdir]

View File

@@ -1,12 +1,25 @@
#!/usr/bin/env python3
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# Copyright (C) 2014 Alex Damian
#
# SPDX-License-Identifier: GPL-2.0-only
#
# This file re-uses code spread throughout other Bitbake source files.
# As such, all other copyrights belong to their own right holders.
#
#
# 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 command takes a filename as a single parameter. The filename is read

View File

@@ -1,4 +1,6 @@
#!/usr/bin/env python3
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# Copyright (C) 2012, 2018 Wind River Systems, Inc.
#

View File

@@ -832,13 +832,7 @@
Bazaar (<filename>bzr://</filename>)
</para></listitem>
<listitem><para>
Mercurial (<filename>hg://</filename>)
</para></listitem>
<listitem><para>
npm (<filename>npm://</filename>)
</para></listitem>
<listitem><para>
OSC (<filename>osc://</filename>)
Trees using Git Annex (<filename>gitannex://</filename>)
</para></listitem>
<listitem><para>
Secure FTP (<filename>sftp://</filename>)
@@ -847,7 +841,10 @@
Secure Shell (<filename>ssh://</filename>)
</para></listitem>
<listitem><para>
Trees using Git Annex (<filename>gitannex://</filename>)
OSC (<filename>osc://</filename>)
</para></listitem>
<listitem><para>
Mercurial (<filename>hg://</filename>)
</para></listitem>
</itemizedlist>
No documentation currently exists for these lesser used

View File

@@ -791,7 +791,7 @@
The following statement in the
<filename>local.conf</filename> file both enables
BitBake to perform multiple configuration builds and
specifies the two extra multiconfigs:
specifies the two multiconfigs:
<literallayout class='monospaced'>
BBMULTICONFIG = "target1 target2"
</literallayout>
@@ -803,13 +803,13 @@
builds, use the following command form to start the
builds:
<literallayout class='monospaced'>
$ bitbake [mc:<replaceable>multiconfigname</replaceable>:]<replaceable>target</replaceable> [[[mc:<replaceable>multiconfigname</replaceable>:]<replaceable>target</replaceable>] ... ]
$ bitbake [multiconfig:<replaceable>multiconfigname</replaceable>:]<replaceable>target</replaceable> [[[multiconfig:<replaceable>multiconfigname</replaceable>:]<replaceable>target</replaceable>] ... ]
</literallayout>
Here is an example for two extra multiconfigs:
Here is an example for two multiconfigs:
<filename>target1</filename> and
<filename>target2</filename>:
<literallayout class='monospaced'>
$ bitbake mc::<replaceable>target</replaceable> mc:target1:<replaceable>target</replaceable> mc:target2:<replaceable>target</replaceable>
$ bitbake multiconfig:target1:<replaceable>target</replaceable> multiconfig:target2:<replaceable>target</replaceable>
</literallayout>
</para>
</section>
@@ -837,13 +837,13 @@
build, you must declare the dependencies in the recipe
using the following statement form:
<literallayout class='monospaced'>
<replaceable>task_or_package</replaceable>[mcdepends] = "mc:<replaceable>from_multiconfig</replaceable>:<replaceable>to_multiconfig</replaceable>:<replaceable>recipe_name</replaceable>:<replaceable>task_on_which_to_depend</replaceable>"
<replaceable>task_or_package</replaceable>[mcdepends] = "multiconfig:<replaceable>from_multiconfig</replaceable>:<replaceable>to_multiconfig</replaceable>:<replaceable>recipe_name</replaceable>:<replaceable>task_on_which_to_depend</replaceable>"
</literallayout>
To better show how to use this statement, consider an
example with two multiconfigs: <filename>target1</filename>
and <filename>target2</filename>:
<literallayout class='monospaced'>
<replaceable>image_task</replaceable>[mcdepends] = "mc:target1:target2:<replaceable>image2</replaceable>:<replaceable>rootfs_task</replaceable>"
<replaceable>image_task</replaceable>[mcdepends] = "multiconfig:target1:target2:<replaceable>image2</replaceable>:<replaceable>rootfs_task</replaceable>"
</literallayout>
In this example, the
<replaceable>from_multiconfig</replaceable> is "target1" and
@@ -859,7 +859,7 @@
Once you set up this dependency, you can build the
"target1" multiconfig using a BitBake command as follows:
<literallayout class='monospaced'>
$ bitbake mc:target1:<replaceable>image1</replaceable>
$ bitbake multiconfig:target1:<replaceable>image1</replaceable>
</literallayout>
This command executes all the tasks needed to create
<replaceable>image1</replaceable> for the "target1"
@@ -875,7 +875,7 @@
Consider this change to the statement in the
<replaceable>image1</replaceable> recipe:
<literallayout class='monospaced'>
<replaceable>image_task</replaceable>[mcdepends] = "mc:target1:target2:<replaceable>image2</replaceable>:<replaceable>image_task</replaceable>"
<replaceable>image_task</replaceable>[mcdepends] = "multiconfig:target1:target2:<replaceable>image2</replaceable>:<replaceable>image_task</replaceable>"
</literallayout>
In this case, BitBake must create
<replaceable>image2</replaceable> for the "target2"

View File

@@ -61,78 +61,6 @@
</para>
</section>
<section id='modifying-existing-variables'>
<title>Modifying Existing Variables</title>
<para>
Sometimes you need to modify existing variables.
Following are some cases where you might find you want to
modify an existing variable:
<itemizedlist>
<listitem><para>
Customize a recipe that uses the variable.
</para></listitem>
<listitem><para>
Change a variable's default value used in a
<filename>*.bbclass</filename> file.
</para></listitem>
<listitem><para>
Change the variable in a <filename>*.bbappend</filename>
file to override the variable in the original recipe.
</para></listitem>
<listitem><para>
Change the variable in a configuration file so that the
value overrides an existing configuration.
</para></listitem>
</itemizedlist>
</para>
<para>
Changing a variable value can sometimes depend on how the
value was originally assigned and also on the desired
intent of the change.
In particular, when you append a value to a variable that
has a default value, the resulting value might not be what
you expect.
In this case, the value you provide might replace the value
rather than append to the default value.
</para>
<para>
If after you have changed a variable's value and something
unexplained occurs, you can use BitBake to check the actual
value of the suspect variable.
You can make these checks for both configuration and recipe
level changes:
<itemizedlist>
<listitem><para>
For configuration changes, use the following:
<literallayout class='monospaced'>
$ bitbake -e
</literallayout>
This command displays variable values after the
configuration files (i.e. <filename>local.conf</filename>,
<filename>bblayers.conf</filename>,
<filename>bitbake.conf</filename> and so forth) have
been parsed.
<note>
Variables that are exported to the environment are
preceded by the string "export" in the command's
output.
</note>
</para></listitem>
<listitem><para>
For recipe changes, use the following:
<literallayout class='monospaced'>
$ bitbake <replaceable>recipe</replaceable> -e | grep VARIABLE="
</literallayout>
This command checks to see if the variable actually
makes it into a specific recipe.
</para></listitem>
</itemizedlist>
</para>
</section>
<section id='line-joining'>
<title>Line Joining</title>
@@ -369,8 +297,9 @@
<para>
These operators differ from the ":=", ".=", "=.", "+=", and "=+"
operators in that their effects are applied at variable
expansion time rather than being immediately applied.
operators in that their effects are deferred
until after parsing completes rather than being immediately
applied.
Here are some examples:
<literallayout class='monospaced'>
B = "bval"
@@ -419,22 +348,18 @@
FOO = "123 456 789 123456 123 456 123 456"
FOO_remove = "123"
FOO_remove = "456"
FOO2 = " abc def ghi abcdef abc def abc def def"
FOO2_remove = " \
def \
abc \
ghi \
"
FOO2 = "abc def ghi abcdef abc def abc def"
FOO2_remove = "abc def"
</literallayout>
The variable <filename>FOO</filename> becomes
"&nbsp;&nbsp;789&nbsp;123456&nbsp;&nbsp;&nbsp;&nbsp;"
"&nbsp;&nbsp;789 123456&nbsp;&nbsp;&nbsp;&nbsp;"
and <filename>FOO2</filename> becomes
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jkl&nbsp;&nbsp;abcdef&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;".
"&nbsp;&nbsp;ghi abcdef&nbsp;&nbsp;&nbsp;&nbsp;".
</para>
<para>
Like "_append" and "_prepend", "_remove"
is applied at variable expansion time.
is deferred until after parsing completes.
</para>
</section>
@@ -799,15 +724,17 @@
<title>Key Expansion</title>
<para>
Key expansion happens when the BitBake datastore is finalized.
Key expansion happens when the BitBake datastore is finalized
just before BitBake expands overrides.
To better understand this, consider the following example:
<literallayout class='monospaced'>
A${B} = "X"
B = "2"
A2 = "Y"
</literallayout>
In this case, after all the parsing is complete,
BitBake expands <filename>${B}</filename> into "2".
In this case, after all the parsing is complete, and
before any overrides are handled, BitBake expands
<filename>${B}</filename> into "2".
This expansion causes <filename>A2</filename>, which was
set to "Y" before the expansion, to become "X".
</para>

View File

@@ -1,8 +1,23 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# This is a copy on write dictionary and set which abuses classes to try and be nice and fast.
#
# Copyright (C) 2006 Tim Ansell
#
# 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.
#
#Please Note:
# Be careful when using mutable types (ie Dict and Lists) - operations involving these are SLOW.
# Assign a file to __warn__ to get warnings about slow operations.

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# BitBake Build System Python Library
#
@@ -6,10 +8,20 @@
#
# Based on Gentoo's portage.py.
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
__version__ = "1.44.0"
__version__ = "1.42.0"
import sys
if sys.version_info < (3, 4, 0):
@@ -43,11 +55,6 @@ class BBLogger(Logger):
Logger.__init__(self, name)
def bbdebug(self, level, msg, *args, **kwargs):
if not bb.event.worker_pid:
if self.name in bb.msg.loggerDefaultDomains and level > (bb.msg.loggerDefaultDomains[self.name]):
return
if level > (bb.msg.loggerDefaultDebugLevel):
return
return self.log(logging.DEBUG - level + 1, msg, *args, **kwargs)
def plain(self, msg, *args, **kwargs):

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# BitBake 'Build' implementation
#
@@ -8,7 +10,18 @@
#
# Based on Gentoo's portage.py.
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
# Based on functions from the base bb module, Copyright 2003 Holger Schurig
@@ -54,12 +67,28 @@ else:
builtins['bb'] = bb
builtins['os'] = os
class FuncFailed(Exception):
def __init__(self, name = None, logfile = None):
self.logfile = logfile
self.name = name
if name:
self.msg = 'Function failed: %s' % name
else:
self.msg = "Function failed"
def __str__(self):
if self.logfile and os.path.exists(self.logfile):
msg = ("%s (log file is located at %s)" %
(self.msg, self.logfile))
else:
msg = self.msg
return msg
class TaskBase(event.Event):
"""Base class for task events"""
def __init__(self, t, fn, logfile, d):
def __init__(self, t, logfile, d):
self._task = t
self._fn = fn
self._package = d.getVar("PF")
self._mc = d.getVar("BB_CURRENT_MC")
self.taskfile = d.getVar("FILE")
@@ -82,8 +111,8 @@ class TaskBase(event.Event):
class TaskStarted(TaskBase):
"""Task execution started"""
def __init__(self, t, fn, logfile, taskflags, d):
super(TaskStarted, self).__init__(t, fn, logfile, d)
def __init__(self, t, logfile, taskflags, d):
super(TaskStarted, self).__init__(t, logfile, d)
self.taskflags = taskflags
class TaskSucceeded(TaskBase):
@@ -92,9 +121,9 @@ class TaskSucceeded(TaskBase):
class TaskFailed(TaskBase):
"""Task execution failed"""
def __init__(self, task, fn, logfile, metadata, errprinted = False):
def __init__(self, task, logfile, metadata, errprinted = False):
self.errprinted = errprinted
super(TaskFailed, self).__init__(task, fn, logfile, metadata)
super(TaskFailed, self).__init__(task, logfile, metadata)
class TaskFailedSilent(TaskBase):
"""Task execution failed (silently)"""
@@ -104,8 +133,8 @@ class TaskFailedSilent(TaskBase):
class TaskInvalid(TaskBase):
def __init__(self, task, fn, metadata):
super(TaskInvalid, self).__init__(task, fn, None, metadata)
def __init__(self, task, metadata):
super(TaskInvalid, self).__init__(task, None, metadata)
self._message = "No such task '%s'" % task
class TaskProgress(event.Event):
@@ -147,33 +176,15 @@ class LogTee(object):
def __repr__(self):
return '<LogTee {0}>'.format(self.name)
def flush(self):
self.outfile.flush()
class StdoutNoopContextManager:
"""
This class acts like sys.stdout, but adds noop __enter__ and __exit__ methods.
"""
def __enter__(self):
return sys.stdout
def __exit__(self, *exc_info):
pass
def write(self, string):
return sys.stdout.write(string)
def flush(self):
sys.stdout.flush()
@property
def name(self):
return sys.stdout.name
def exec_func(func, d, dirs = None):
#
# pythonexception allows the python exceptions generated to be raised
# as the real exceptions (not FuncFailed) and without a backtrace at the
# origin of the failure.
#
def exec_func(func, d, dirs = None, pythonexception=False):
"""Execute a BB 'function'"""
try:
@@ -245,7 +256,7 @@ def exec_func(func, d, dirs = None):
with bb.utils.fileslocked(lockfiles):
if ispython:
exec_func_python(func, d, runfile, cwd=adir)
exec_func_python(func, d, runfile, cwd=adir, pythonexception=pythonexception)
else:
exec_func_shell(func, d, runfile, cwd=adir)
@@ -265,7 +276,7 @@ _functionfmt = """
{function}(d)
"""
logformatter = bb.msg.BBLogFormatter("%(levelname)s: %(message)s")
def exec_func_python(func, d, runfile, cwd=None):
def exec_func_python(func, d, runfile, cwd=None, pythonexception=False):
"""Execute a python BB 'function'"""
code = _functionfmt.format(function=func)
@@ -290,7 +301,14 @@ def exec_func_python(func, d, runfile, cwd=None):
bb.methodpool.insert_method(func, text, fn, lineno - 1)
comp = utils.better_compile(code, func, "exec_python_func() autogenerated")
utils.better_exec(comp, {"d": d}, code, "exec_python_func() autogenerated")
utils.better_exec(comp, {"d": d}, code, "exec_python_func() autogenerated", pythonexception=pythonexception)
except (bb.parse.SkipRecipe, bb.build.FuncFailed):
raise
except Exception as e:
if pythonexception:
raise
logger.error(str(e))
raise FuncFailed(func, None)
finally:
bb.debug(2, "Python function %s finished" % func)
@@ -318,42 +336,6 @@ trap 'bb_exit_handler' 0
set -e
'''
def create_progress_handler(func, progress, logfile, d):
if progress == 'percent':
# Use default regex
return bb.progress.BasicProgressHandler(d, outfile=logfile)
elif progress.startswith('percent:'):
# Use specified regex
return bb.progress.BasicProgressHandler(d, regex=progress.split(':', 1)[1], outfile=logfile)
elif progress.startswith('outof:'):
# Use specified regex
return bb.progress.OutOfProgressHandler(d, regex=progress.split(':', 1)[1], outfile=logfile)
elif progress.startswith("custom:"):
# Use a custom progress handler that was injected via OE_EXTRA_IMPORTS or __builtins__
import functools
from types import ModuleType
parts = progress.split(":", 2)
_, cls, otherargs = parts[0], parts[1], (parts[2] or None) if parts[2:] else None
if cls:
def resolve(x, y):
if not x:
return None
if isinstance(x, ModuleType):
return getattr(x, y, None)
return x.get(y)
cls_obj = functools.reduce(resolve, cls.split("."), bb.utils._context)
if not cls_obj:
# Fall-back on __builtins__
cls_obj = functools.reduce(lambda x, y: x.get(y), cls.split("."), __builtins__)
if cls_obj:
return cls_obj(d, outfile=logfile, otherargs=otherargs)
bb.warn('%s: unknown custom progress handler in task progress varflag value "%s", ignoring' % (func, cls))
else:
bb.warn('%s: invalid task progress varflag value "%s", ignoring' % (func, progress))
return logfile
def exec_func_shell(func, d, runfile, cwd=None):
"""Execute a shell function from the metadata
@@ -391,13 +373,23 @@ exit $ret
cmd = [fakerootcmd, runfile]
if bb.msg.loggerDefaultVerbose:
logfile = LogTee(logger, StdoutNoopContextManager())
logfile = LogTee(logger, sys.stdout)
else:
logfile = StdoutNoopContextManager()
logfile = sys.stdout
progress = d.getVarFlag(func, 'progress')
if progress:
logfile = create_progress_handler(func, progress, logfile, d)
if progress == 'percent':
# Use default regex
logfile = bb.progress.BasicProgressHandler(d, outfile=logfile)
elif progress.startswith('percent:'):
# Use specified regex
logfile = bb.progress.BasicProgressHandler(d, regex=progress.split(':', 1)[1], outfile=logfile)
elif progress.startswith('outof:'):
# Use specified regex
logfile = bb.progress.OutOfProgressHandler(d, regex=progress.split(':', 1)[1], outfile=logfile)
else:
bb.warn('%s: invalid task progress varflag value "%s", ignoring' % (func, progress))
fifobuffer = bytearray()
def readfifo(data):
@@ -416,8 +408,6 @@ exit $ret
bb.plain(value)
elif cmd == 'bbnote':
bb.note(value)
elif cmd == 'bbverbnote':
bb.verbnote(value)
elif cmd == 'bbwarn':
bb.warn(value)
elif cmd == 'bberror':
@@ -447,8 +437,13 @@ exit $ret
with open(fifopath, 'r+b', buffering=0) as fifo:
try:
bb.debug(2, "Executing shell function %s" % func)
with open(os.devnull, 'r+') as stdin, logfile:
bb.process.run(cmd, shell=False, stdin=stdin, log=logfile, extrafiles=[(fifo,readfifo)])
try:
with open(os.devnull, 'r+') as stdin:
bb.process.run(cmd, shell=False, stdin=stdin, log=logfile, extrafiles=[(fifo,readfifo)])
except bb.process.CmdError:
logfn = d.getVar('BB_LOGFILE')
raise FuncFailed(func, logfn)
finally:
os.unlink(fifopath)
@@ -573,9 +568,12 @@ def _exec_task(fn, task, d, quieterr):
try:
try:
event.fire(TaskStarted(task, fn, logfn, flags, localdata), localdata)
event.fire(TaskStarted(task, logfn, flags, localdata), localdata)
except (bb.BBHandledException, SystemExit):
return 1
except FuncFailed as exc:
logger.error(str(exc))
return 1
try:
for func in (prefuncs or '').split():
@@ -583,16 +581,16 @@ def _exec_task(fn, task, d, quieterr):
exec_func(task, localdata)
for func in (postfuncs or '').split():
exec_func(func, localdata)
except bb.BBHandledException:
event.fire(TaskFailed(task, fn, logfn, localdata, True), localdata)
return 1
except Exception as exc:
except FuncFailed as exc:
if quieterr:
event.fire(TaskFailedSilent(task, fn, logfn, localdata), localdata)
event.fire(TaskFailedSilent(task, logfn, localdata), localdata)
else:
errprinted = errchk.triggered
logger.error(str(exc))
event.fire(TaskFailed(task, fn, logfn, localdata, errprinted), localdata)
event.fire(TaskFailed(task, logfn, localdata, errprinted), localdata)
return 1
except bb.BBHandledException:
event.fire(TaskFailed(task, logfn, localdata, True), localdata)
return 1
finally:
sys.stdout.flush()
@@ -615,7 +613,7 @@ def _exec_task(fn, task, d, quieterr):
logger.debug(2, "Zero size logfn %s, removing", logfn)
bb.utils.remove(logfn)
bb.utils.remove(loglink)
event.fire(TaskSucceeded(task, fn, logfn, localdata), localdata)
event.fire(TaskSucceeded(task, logfn, localdata), localdata)
if not localdata.getVarFlag(task, 'nostamp', False) and not localdata.getVarFlag(task, 'selfstamp', False):
make_stamp(task, localdata)
@@ -817,9 +815,6 @@ def add_tasks(tasklist, d):
task_deps['parents'][task] = []
if 'deps' in flags:
for dep in flags['deps']:
# Check and warn for "addtask task after foo" while foo does not exist
#if not dep in tasklist:
# bb.warn('%s: dependent task %s for %s does not exist' % (d.getVar('PN'), dep, task))
dep = d.expand(dep)
task_deps['parents'][task].append(dep)

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# BitBake Cache implementation
#
@@ -13,8 +15,18 @@
# Copyright (C) 2005 Holger Hans Peter Freyther
# Copyright (C) 2005 ROAD GmbH
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import os
import sys
@@ -83,21 +95,21 @@ class CoreRecipeInfo(RecipeInfoCommon):
self.appends = self.listvar('__BBAPPEND', metadata)
self.nocache = self.getvar('BB_DONT_CACHE', metadata)
self.provides = self.depvar('PROVIDES', metadata)
self.rprovides = self.depvar('RPROVIDES', metadata)
self.pn = self.getvar('PN', metadata) or bb.parse.vars_from_file(filename,metadata)[0]
self.packages = self.listvar('PACKAGES', metadata)
if not self.packages:
self.packages.append(self.pn)
self.packages_dynamic = self.listvar('PACKAGES_DYNAMIC', metadata)
self.skipreason = self.getvar('__SKIPPED', metadata)
if self.skipreason:
self.pn = self.getvar('PN', metadata) or bb.parse.vars_from_file(filename,metadata)[0]
self.skipped = True
self.provides = self.depvar('PROVIDES', metadata)
self.rprovides = self.depvar('RPROVIDES', metadata)
return
self.tasks = metadata.getVar('__BBTASKS', False)
self.pn = self.getvar('PN', metadata)
self.packages = self.listvar('PACKAGES', metadata)
if not self.packages:
self.packages.append(self.pn)
self.basetaskhashes = self.taskvar('BB_BASEHASH', self.tasks, metadata)
self.hashfilename = self.getvar('BB_HASHFILENAME', metadata)
@@ -113,8 +125,11 @@ class CoreRecipeInfo(RecipeInfoCommon):
self.stampclean = self.getvar('STAMPCLEAN', metadata)
self.stamp_extrainfo = self.flaglist('stamp-extra-info', self.tasks, metadata)
self.file_checksums = self.flaglist('file-checksums', self.tasks, metadata, True)
self.packages_dynamic = self.listvar('PACKAGES_DYNAMIC', metadata)
self.depends = self.depvar('DEPENDS', metadata)
self.provides = self.depvar('PROVIDES', metadata)
self.rdepends = self.depvar('RDEPENDS', metadata)
self.rprovides = self.depvar('RPROVIDES', metadata)
self.rrecommends = self.depvar('RRECOMMENDS', metadata)
self.rprovides_pkg = self.pkgvar('RPROVIDES', self.packages, metadata)
self.rdepends_pkg = self.pkgvar('RDEPENDS', self.packages, metadata)
@@ -208,10 +223,10 @@ class CoreRecipeInfo(RecipeInfoCommon):
# Collect files we may need for possible world-dep
# calculations
if not self.not_world:
if self.not_world:
logger.debug(1, "EXCLUDE FROM WORLD: %s", fn)
else:
cachedata.possible_world.append(fn)
#else:
# logger.debug(2, "EXCLUDE FROM WORLD: %s", fn)
# create a collection of all targets for sanity checking
# tasks, such as upstream versions, license, and tools for
@@ -220,7 +235,7 @@ class CoreRecipeInfo(RecipeInfoCommon):
cachedata.hashfn[fn] = self.hashfilename
for task, taskhash in self.basetaskhashes.items():
identifier = '%s:%s' % (fn, task)
identifier = '%s.%s' % (fn, task)
cachedata.basetaskhash[identifier] = taskhash
cachedata.inherits[fn] = self.inherits
@@ -234,7 +249,7 @@ def virtualfn2realfn(virtualfn):
Convert a virtual file name to a real one + the associated subclass keyword
"""
mc = ""
if virtualfn.startswith('mc:'):
if virtualfn.startswith('multiconfig:'):
elems = virtualfn.split(':')
mc = elems[1]
virtualfn = ":".join(elems[2:])
@@ -255,7 +270,7 @@ def realfn2virtual(realfn, cls, mc):
if cls:
realfn = "virtual:" + cls + ":" + realfn
if mc:
realfn = "mc:" + mc + ":" + realfn
realfn = "multiconfig:" + mc + ":" + realfn
return realfn
def variant2virtual(realfn, variant):
@@ -264,11 +279,11 @@ def variant2virtual(realfn, variant):
"""
if variant == "":
return realfn
if variant.startswith("mc:"):
if variant.startswith("multiconfig:"):
elems = variant.split(":")
if elems[2]:
return "mc:" + elems[1] + ":virtual:" + ":".join(elems[2:]) + ":" + realfn
return "mc:" + elems[1] + ":" + realfn
return "multiconfig:" + elems[1] + ":virtual:" + ":".join(elems[2:]) + ":" + realfn
return "multiconfig:" + elems[1] + ":" + realfn
return "virtual:" + variant + ":" + realfn
def parse_recipe(bb_data, bbfile, appends, mc=''):
@@ -346,7 +361,7 @@ class NoCache(object):
bb_data = self.databuilder.mcdata[mc].createCopy()
newstores = parse_recipe(bb_data, bbfile, appends, mc)
for ns in newstores:
datastores["mc:%s:%s" % (mc, ns)] = newstores[ns]
datastores["multiconfig:%s:%s" % (mc, ns)] = newstores[ns]
return datastores
@@ -396,15 +411,6 @@ class Cache(NoCache):
else:
logger.debug(1, "Cache file %s not found, building..." % self.cachefile)
# We don't use the symlink, its just for debugging convinience
symlink = os.path.join(self.cachedir, "bb_cache.dat")
if os.path.exists(symlink):
bb.utils.remove(symlink)
try:
os.symlink(os.path.basename(self.cachefile), symlink)
except OSError:
pass
def load_cachefile(self):
cachesize = 0
previous_progress = 0
@@ -883,56 +889,3 @@ class MultiProcessCache(object):
p.dump([data, self.__class__.CACHE_VERSION])
bb.utils.unlockfile(glf)
class SimpleCache(object):
"""
BitBake multi-process cache implementation
Used by the codeparser & file checksum caches
"""
def __init__(self, version):
self.cachefile = None
self.cachedata = None
self.cacheversion = version
def init_cache(self, d, cache_file_name=None, defaultdata=None):
cachedir = (d.getVar("PERSISTENT_DIR") or
d.getVar("CACHE"))
if not cachedir:
return defaultdata
bb.utils.mkdirhier(cachedir)
self.cachefile = os.path.join(cachedir,
cache_file_name or self.__class__.cache_file_name)
logger.debug(1, "Using cache in '%s'", self.cachefile)
glf = bb.utils.lockfile(self.cachefile + ".lock")
try:
with open(self.cachefile, "rb") as f:
p = pickle.Unpickler(f)
data, version = p.load()
except:
bb.utils.unlockfile(glf)
return defaultdata
bb.utils.unlockfile(glf)
if version != self.cacheversion:
return defaultdata
return data
def save(self, data):
if not self.cachefile:
return
glf = bb.utils.lockfile(self.cachefile + ".lock")
with open(self.cachefile, "wb") as f:
p = pickle.Pickler(f, -1)
p.dump([data, self.cacheversion])
bb.utils.unlockfile(glf)

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# Extra RecipeInfo will be all defined in this file. Currently,
# Only Hob (Image Creator) Requests some extra fields. So
@@ -10,8 +12,18 @@
# Copyright (C) 2011, Intel Corporation. All rights reserved.
# SPDX-License-Identifier: GPL-2.0-only
# 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.
from bb.cache import RecipeInfoCommon

View File

@@ -2,8 +2,18 @@
#
# Copyright (C) 2012 Intel Corporation
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import glob
import operator
@@ -74,7 +84,7 @@ class FileChecksumCache(MultiProcessCache):
else:
dest[0][h] = source[0][h]
def get_checksums(self, filelist, pn, localdirsexclude):
def get_checksums(self, filelist, pn):
"""Get checksums for a list of files"""
def checksum_file(f):
@@ -90,8 +100,7 @@ class FileChecksumCache(MultiProcessCache):
if pth == "/":
bb.fatal("Refusing to checksum /")
dirchecksums = []
for root, dirs, files in os.walk(pth, topdown=True):
[dirs.remove(d) for d in list(dirs) if d in localdirsexclude]
for root, dirs, files in os.walk(pth):
for name in files:
fullpth = os.path.join(root, name)
checksum = checksum_file(fullpth)

View File

@@ -1,7 +1,3 @@
#
# SPDX-License-Identifier: GPL-2.0-only
#
"""
BitBake code parser

View File

@@ -6,8 +6,18 @@ Provide an interface to interact with the bitbake server through 'commands'
# Copyright (C) 2006-2007 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
"""
The bitbake server takes 'commands' from its UI/commandline.

View File

@@ -1,7 +1,3 @@
#
# SPDX-License-Identifier: GPL-2.0-only
#
"""Code pulled from future python versions, here for compatibility"""
from collections import MutableMapping, KeysView, ValuesView, ItemsView, OrderedDict

View File

@@ -1,3 +1,6 @@
#!/usr/bin/env python
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# Copyright (C) 2003, 2004 Chris Larson
# Copyright (C) 2003, 2004 Phil Blundell
@@ -6,8 +9,19 @@
# Copyright (C) 2005 ROAD GmbH
# Copyright (C) 2006 - 2007 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import sys, os, glob, os.path, re, time
import atexit
@@ -31,7 +45,6 @@ import pyinotify
import json
import pickle
import codecs
import hashserv
logger = logging.getLogger("BitBake")
collectlog = logging.getLogger("BitBake.Collection")
@@ -169,8 +182,8 @@ class BBCooker:
bb.debug(1, "BBCooker pyinotify1 %s" % time.time())
sys.stdout.flush()
self.configwatcher.bbseen = set()
self.configwatcher.bbwatchedfiles = set()
self.configwatcher.bbseen = []
self.configwatcher.bbwatchedfiles = []
self.confignotifier = pyinotify.Notifier(self.configwatcher, self.config_notifications)
bb.debug(1, "BBCooker pyinotify2 %s" % time.time())
sys.stdout.flush()
@@ -180,8 +193,8 @@ class BBCooker:
self.watcher = pyinotify.WatchManager()
bb.debug(1, "BBCooker pyinotify3 %s" % time.time())
sys.stdout.flush()
self.watcher.bbseen = set()
self.watcher.bbwatchedfiles = set()
self.watcher.bbseen = []
self.watcher.bbwatchedfiles = []
self.notifier = pyinotify.Notifier(self.watcher, self.notifications)
bb.debug(1, "BBCooker pyinotify complete %s" % time.time())
@@ -193,8 +206,6 @@ class BBCooker:
bb.parse.BBHandler.cached_statements = {}
self.ui_cmdline = None
self.hashserv = None
self.hashservaddr = None
self.initConfigurationData()
@@ -278,14 +289,14 @@ class BBCooker:
if not watcher:
watcher = self.watcher
for i in deps:
watcher.bbwatchedfiles.add(i[0])
watcher.bbwatchedfiles.append(i[0])
if dirs:
f = i[0]
else:
f = os.path.dirname(i[0])
if f in watcher.bbseen:
continue
watcher.bbseen.add(f)
watcher.bbseen.append(f)
watchtarget = None
while True:
# We try and add watches for files that don't exist but if they did, would influence
@@ -294,7 +305,7 @@ class BBCooker:
try:
watcher.add_watch(f, self.watchmask, quiet=False)
if watchtarget:
watcher.bbwatchedfiles.add(watchtarget)
watcher.bbwatchedfiles.append(watchtarget)
break
except pyinotify.WatchManagerError as e:
if 'ENOENT' in str(e):
@@ -302,7 +313,7 @@ class BBCooker:
f = os.path.dirname(f)
if f in watcher.bbseen:
break
watcher.bbseen.add(f)
watcher.bbseen.append(f)
continue
if 'ENOSPC' in str(e):
providerlog.error("No space left on device or exceeds fs.inotify.max_user_watches?")
@@ -371,12 +382,17 @@ class BBCooker:
self.data.setVar('BB_CMDLINE', self.ui_cmdline)
#
# Copy of the data store which has been expanded.
# Used for firing events and accessing variables where expansion needs to be accounted for
#
bb.parse.init_parser(self.data)
if CookerFeatures.BASEDATASTORE_TRACKING in self.featureset:
self.disableDataTracking()
for mc in self.databuilder.mcdata.values():
mc.renameVar("__depends", "__base_depends")
self.add_filewatch(mc.getVar("__base_depends", False), self.configwatcher)
self.data.renameVar("__depends", "__base_depends")
self.add_filewatch(self.data.getVar("__base_depends", False), self.configwatcher)
self.baseconfig_valid = True
self.parsecache_valid = False
@@ -388,22 +404,6 @@ class BBCooker:
except prserv.serv.PRServiceConfigError as e:
bb.fatal("Unable to start PR Server, exitting")
if self.data.getVar("BB_HASHSERVE") == "auto":
# Create a new hash server bound to a unix domain socket
if not self.hashserv:
dbfile = (self.data.getVar("PERSISTENT_DIR") or self.data.getVar("CACHE")) + "/hashserv.db"
self.hashservaddr = "unix://%s/hashserve.sock" % self.data.getVar("TOPDIR")
self.hashserv = hashserv.create_server(self.hashservaddr, dbfile, sync=False)
self.hashserv.process = multiprocessing.Process(target=self.hashserv.serve_forever)
self.hashserv.process.start()
self.data.setVar("BB_HASHSERVE", self.hashservaddr)
self.databuilder.origdata.setVar("BB_HASHSERVE", self.hashservaddr)
self.databuilder.data.setVar("BB_HASHSERVE", self.hashservaddr)
for mc in self.databuilder.mcdata:
self.databuilder.mcdata[mc].setVar("BB_HASHSERVE", self.hashservaddr)
bb.parse.init_parser(self.data)
def enableDataTracking(self):
self.configuration.tracking = True
if hasattr(self, "data"):
@@ -507,7 +507,6 @@ class BBCooker:
"""
fn = None
envdata = None
mc = ''
if not pkgs_to_build:
pkgs_to_build = []
@@ -516,12 +515,6 @@ class BBCooker:
self.enableDataTracking()
self.reset()
def mc_base(p):
if p.startswith('mc:'):
s = p.split(':')
if len(s) == 2:
return s[1]
return None
if buildfile:
# Parse the configuration here. We need to do it explicitly here since
@@ -532,16 +525,18 @@ class BBCooker:
fn = self.matchFile(fn)
fn = bb.cache.realfn2virtual(fn, cls, mc)
elif len(pkgs_to_build) == 1:
mc = mc_base(pkgs_to_build[0])
if not mc:
ignore = self.data.getVar("ASSUME_PROVIDED") or ""
if pkgs_to_build[0] in set(ignore.split()):
bb.fatal("%s is in ASSUME_PROVIDED" % pkgs_to_build[0])
ignore = self.data.getVar("ASSUME_PROVIDED") or ""
if pkgs_to_build[0] in set(ignore.split()):
bb.fatal("%s is in ASSUME_PROVIDED" % pkgs_to_build[0])
taskdata, runlist = self.buildTaskData(pkgs_to_build, None, self.configuration.abort, allowincomplete=True)
taskdata, runlist = self.buildTaskData(pkgs_to_build, None, self.configuration.abort, allowincomplete=True)
mc = runlist[0][0]
fn = runlist[0][3]
mc = runlist[0][0]
fn = runlist[0][3]
else:
envdata = self.data
data.expandKeys(envdata)
parse.ast.runAnonFuncs(envdata)
if fn:
try:
@@ -550,12 +545,6 @@ class BBCooker:
except Exception as e:
parselog.exception("Unable to read %s", fn)
raise
else:
if not mc in self.databuilder.mcdata:
bb.fatal('Not multiconfig named "%s" found' % mc)
envdata = self.databuilder.mcdata[mc]
data.expandKeys(envdata)
parse.ast.runAnonFuncs(envdata)
# Display history
with closing(StringIO()) as env:
@@ -595,10 +584,10 @@ class BBCooker:
wildcard = False
# Wild card expansion:
# Replace string such as "mc:*:bash"
# into "mc:A:bash mc:B:bash bash"
# Replace string such as "multiconfig:*:bash"
# into "multiconfig:A:bash multiconfig:B:bash bash"
for k in targetlist:
if k.startswith("mc:"):
if k.startswith("multiconfig:"):
if wildcard:
bb.fatal('multiconfig conflict')
if k.split(":")[1] == "*":
@@ -631,7 +620,7 @@ class BBCooker:
runlist = []
for k in fulltargetlist:
mc = ""
if k.startswith("mc:"):
if k.startswith("multiconfig:"):
mc = k.split(":")[1]
k = ":".join(k.split(":")[2:])
ktask = task
@@ -650,13 +639,9 @@ class BBCooker:
runlist.append([mc, k, ktask, fn])
bb.event.fire(bb.event.TreeDataPreparationProgress(current, len(fulltargetlist)), self.data)
havemc = False
for mc in self.multiconfigs:
if taskdata[mc].get_mcdepends():
havemc = True
# No need to do check providers if there are no mcdeps or not an mc build
if havemc or len(self.multiconfigs) > 1:
if len(self.multiconfigs) > 1:
seen = set()
new = True
# Make sure we can provide the multiconfig dependency
@@ -716,7 +701,7 @@ class BBCooker:
@staticmethod
def add_mc_prefix(mc, pn):
if mc:
return "mc:%s:%s" % (mc, pn)
return "multiconfig:%s:%s" % (mc, pn)
return pn
def buildDependTree(self, rq, taskdata):
@@ -915,10 +900,6 @@ class BBCooker:
os.unlink('package-depends.dot')
except FileNotFoundError:
pass
try:
os.unlink('recipe-depends.dot')
except FileNotFoundError:
pass
with open('task-depends.dot', 'w') as f:
f.write("digraph depends {\n")
@@ -932,6 +913,27 @@ class BBCooker:
f.write("}\n")
logger.info("Task dependencies saved to 'task-depends.dot'")
with open('recipe-depends.dot', 'w') as f:
f.write("digraph depends {\n")
pndeps = {}
for task in sorted(depgraph["tdepends"]):
(pn, taskname) = task.rsplit(".", 1)
if pn not in pndeps:
pndeps[pn] = set()
for dep in sorted(depgraph["tdepends"][task]):
(deppn, deptaskname) = dep.rsplit(".", 1)
pndeps[pn].add(deppn)
for pn in sorted(pndeps):
fn = depgraph["pn"][pn]["filename"]
version = depgraph["pn"][pn]["version"]
f.write('"%s" [label="%s\\n%s\\n%s"]\n' % (pn, pn, version, fn))
for dep in sorted(pndeps[pn]):
if dep == pn:
continue
f.write('"%s" -> "%s"\n' % (pn, dep))
f.write("}\n")
logger.info("Flattened recipe dependencies saved to 'recipe-depends.dot'")
def show_appends_with_no_recipes(self):
# Determine which bbappends haven't been applied
@@ -1476,7 +1478,7 @@ class BBCooker:
ntargets = []
for target in runlist:
if target[0]:
ntargets.append("mc:%s:%s:%s" % (target[0], target[1], target[2]))
ntargets.append("multiconfig:%s:%s:%s" % (target[0], target[1], target[2]))
ntargets.append("%s:%s" % (target[1], target[2]))
for mc in self.multiconfigs:
@@ -1599,9 +1601,6 @@ class BBCooker:
for pkg in pkgs_to_build:
if pkg in ignore:
parselog.warning("Explicit target \"%s\" is in ASSUME_PROVIDED, ignoring" % pkg)
if pkg.startswith("multiconfig:"):
pkgs_to_build.remove(pkg)
pkgs_to_build.append(pkg.replace("multiconfig:", "mc:"))
if 'world' in pkgs_to_build:
pkgs_to_build.remove('world')
@@ -1609,7 +1608,7 @@ class BBCooker:
bb.providers.buildWorldTargetList(self.recipecaches[mc], task)
for t in self.recipecaches[mc].world_target:
if mc:
t = "mc:" + mc + ":" + t
t = "multiconfig:" + mc + ":" + t
pkgs_to_build.append(t)
if 'universe' in pkgs_to_build:
@@ -1628,7 +1627,7 @@ class BBCooker:
bb.debug(1, "Skipping %s for universe tasks as task %s doesn't exist" % (t, task))
continue
if mc:
t = "mc:" + mc + ":" + t
t = "multiconfig:" + mc + ":" + t
pkgs_to_build.append(t)
return pkgs_to_build
@@ -1641,11 +1640,9 @@ class BBCooker:
def post_serve(self):
prserv.serv.auto_shutdown()
if self.hashserv:
self.hashserv.process.terminate()
self.hashserv.process.join()
bb.event.fire(CookerExit(), self.data)
def shutdown(self, force = False):
if force:
self.state = state.forceshutdown
@@ -1660,7 +1657,6 @@ class BBCooker:
def reset(self):
self.initConfigurationData()
self.handlePRServ()
def clientComplete(self):
"""Called when the client is done using the server"""
@@ -1788,7 +1784,7 @@ class CookerCollectFiles(object):
# When constructing an older style single regex, it's possible for BBMASK
# to end up beginning with '|', which matches and masks _everything_.
if mask.startswith("|"):
collectlog.warning("BBMASK contains regular expression beginning with '|', fixing: %s" % mask)
collectlog.warn("BBMASK contains regular expression beginning with '|', fixing: %s" % mask)
mask = mask[1:]
try:
re.compile(mask)
@@ -1944,8 +1940,7 @@ class Parser(multiprocessing.Process):
except IndexError:
break
result = self.parse(*job)
# Clear the siggen cache after parsing to control memory usage, its huge
bb.parse.siggen.postparsing_clean_cache()
try:
self.results.put(result, timeout=0.25)
except queue.Full:
@@ -2062,14 +2057,6 @@ class CookerParser(object):
for process in self.processes:
self.parser_quit.put(None)
# Cleanup the queue before call process.join(), otherwise there might be
# deadlocks.
while True:
try:
self.result_queue.get(timeout=0.25)
except queue.Empty:
break
for process in self.processes:
if force:
process.join(.1)

View File

@@ -1,3 +1,6 @@
#!/usr/bin/env python
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# Copyright (C) 2003, 2004 Chris Larson
# Copyright (C) 2003, 2004 Phil Blundell
@@ -6,14 +9,23 @@
# Copyright (C) 2005 ROAD GmbH
# Copyright (C) 2006 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import logging
import os
import re
import sys
import hashlib
from functools import wraps
import bb
from bb import data
@@ -122,7 +134,6 @@ class CookerConfiguration(object):
self.profile = False
self.nosetscene = False
self.setsceneonly = False
self.skipsetscene = False
self.invalidate_stamp = False
self.dump_signatures = []
self.dry_run = False
@@ -268,13 +279,12 @@ class CookerDataBuilder(object):
self.mcdata = {}
def parseBaseConfiguration(self):
data_hash = hashlib.sha256()
try:
bb.parse.init_parser(self.basedata)
self.data = self.parseConfigurationFiles(self.prefiles, self.postfiles)
if self.data.getVar("BB_WORKERCONTEXT", False) is None:
bb.fetch.fetcher_init(self.data)
bb.parse.init_parser(self.data)
bb.codeparser.parser_cache_init(self.data)
bb.event.fire(bb.event.ConfigParsed(), self.data)
@@ -292,7 +302,7 @@ class CookerDataBuilder(object):
bb.event.fire(bb.event.ConfigParsed(), self.data)
bb.parse.init_parser(self.data)
data_hash.update(self.data.get_hash().encode('utf-8'))
self.data_hash = self.data.get_hash()
self.mcdata[''] = self.data
multiconfig = (self.data.getVar("BBMULTICONFIG") or "").split()
@@ -300,11 +310,9 @@ class CookerDataBuilder(object):
mcdata = self.parseConfigurationFiles(self.prefiles, self.postfiles, config)
bb.event.fire(bb.event.ConfigParsed(), mcdata)
self.mcdata[config] = mcdata
data_hash.update(mcdata.get_hash().encode('utf-8'))
if multiconfig:
bb.event.fire(bb.event.MultiConfigParsed(self.mcdata), self.data)
self.data_hash = data_hash.hexdigest()
except (SyntaxError, bb.BBHandledException):
raise bb.BBHandledException
except bb.data_smart.ExpansionError as e:
@@ -346,24 +354,14 @@ class CookerDataBuilder(object):
data = parse_config_file(layerconf, data)
layers = (data.getVar('BBLAYERS') or "").split()
broken_layers = []
data = bb.data.createCopy(data)
approved = bb.utils.approved_variables()
# Check whether present layer directories exist
for layer in layers:
if not os.path.isdir(layer):
broken_layers.append(layer)
if broken_layers:
parselog.critical("The following layer directories do not exist:")
for layer in broken_layers:
parselog.critical(" %s", layer)
parselog.critical("Please check BBLAYERS in %s" % (layerconf))
sys.exit(1)
for layer in layers:
parselog.critical("Layer directory '%s' does not exist! "
"Please check BBLAYERS in %s" % (layer, layerconf))
sys.exit(1)
parselog.debug(2, "Adding layer %s", layer)
if 'HOME' in approved and '~' in layer:
layer = os.path.expanduser(layer)

View File

@@ -1,7 +1,3 @@
#
# SPDX-License-Identifier: GPL-2.0-only
#
"""
Python Daemonizing helper

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake 'Data' implementations
@@ -20,7 +22,18 @@ the speed is more critical here.
# Copyright (C) 2003, 2004 Chris Larson
# Copyright (C) 2005 Holger Hans Peter Freyther
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
# Based on functions from the base bb module, Copyright 2003 Holger Schurig
@@ -130,7 +143,7 @@ def emit_var(var, o=sys.__stdout__, d = init(), all=False):
if all:
oval = d.getVar(var, False)
val = d.getVar(var)
except (KeyboardInterrupt):
except (KeyboardInterrupt, bb.build.FuncFailed):
raise
except Exception as exc:
o.write('# expansion of %s threw %s: %s\n' % (var, exc.__class__.__name__, str(exc)))
@@ -422,7 +435,7 @@ def generate_dependency_hash(tasklist, gendeps, lookupcache, whitelist, fn):
var = lookupcache[dep]
if var is not None:
data = data + str(var)
k = fn + ":" + task
k = fn + "." + task
basehash[k] = hashlib.sha256(data.encode("utf-8")).hexdigest()
taskdeps[task] = alldeps

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake Smart Dictionary Implementation
@@ -12,8 +14,18 @@ BitBake build tools.
# Copyright (C) 2005 Uli Luckas
# Copyright (C) 2005 ROAD GmbH
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
# Based on functions from the base bb module, Copyright 2003 Holger Schurig
import copy, re, sys, traceback

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake 'Event' implementation
@@ -7,8 +9,18 @@ BitBake build tools.
# Copyright (C) 2003, 2004 Chris Larson
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import os, sys
import warnings
@@ -124,7 +136,6 @@ def fire_class_handlers(event, d):
ui_queue = []
@atexit.register
def print_ui_queue():
global ui_queue
"""If we're exiting before a UI has been spawned, display any queued
LogRecords to the console."""
logger = logging.getLogger("BitBake")
@@ -169,7 +180,6 @@ def print_ui_queue():
logger.removeHandler(stderr)
else:
logger.removeHandler(stdout)
ui_queue = []
def fire_ui_handlers(event, d):
global _thread_lock
@@ -404,6 +414,23 @@ class RecipeTaskPreProcess(RecipeEvent):
class RecipeParsed(RecipeEvent):
""" Recipe Parsing Complete """
class StampUpdate(Event):
"""Trigger for any adjustment of the stamp files to happen"""
def __init__(self, targets, stampfns):
self._targets = targets
self._stampfns = stampfns
Event.__init__(self)
def getStampPrefix(self):
return self._stampfns
def getTargets(self):
return self._targets
stampPrefix = property(getStampPrefix)
targets = property(getTargets)
class BuildBase(Event):
"""Base class for bitbake build events"""

View File

@@ -1,6 +1,3 @@
#
# SPDX-License-Identifier: GPL-2.0-only
#
import inspect
import traceback

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake 'Fetch' implementations
@@ -8,7 +10,18 @@ BitBake build tools.
# Copyright (C) 2003, 2004 Chris Larson
# Copyright (C) 2012 Intel Corporation
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
# Based on functions from the base bb module, Copyright 2003 Holger Schurig
@@ -843,11 +856,6 @@ def runfetchcmd(cmd, d, quiet=False, cleanup=None, log=None, workdir=None):
if val:
cmd = 'export ' + var + '=\"%s\"; %s' % (val, cmd)
# Ensure that a _PYTHON_SYSCONFIGDATA_NAME value set by a recipe
# (for example via python3native.bbclass since warrior) is not set for
# host Python (otherwise tools like git-make-shallow will fail)
cmd = 'unset _PYTHON_SYSCONFIGDATA_NAME; ' + cmd
# Disable pseudo as it may affect ssh, potentially causing it to hang.
cmd = 'export PSEUDO_DISABLED=1; ' + cmd
@@ -962,8 +970,7 @@ def rename_bad_checksum(ud, suffix):
new_localpath = "%s_bad-checksum_%s" % (ud.localpath, suffix)
bb.warn("Renaming %s to %s" % (ud.localpath, new_localpath))
if not bb.utils.movefile(ud.localpath, new_localpath):
bb.warn("Renaming %s to %s failed, grep movefile in log.do_fetch to see why" % (ud.localpath, new_localpath))
bb.utils.movefile(ud.localpath, new_localpath)
def try_mirror_url(fetch, origud, ud, ld, check = False):
@@ -1197,14 +1204,14 @@ def get_checksum_file_list(d):
return " ".join(filelist)
def get_file_checksums(filelist, pn, localdirsexclude):
def get_file_checksums(filelist, pn):
"""Get a list of the checksums for a list of local files
Returns the checksums for a list of local files, caching the results as
it proceeds
"""
return _checksum_cache.get_checksums(filelist, pn, localdirsexclude)
return _checksum_cache.get_checksums(filelist, pn)
class FetchData(object):
@@ -1567,7 +1574,8 @@ class FetchMethod(object):
return True, str(latest_rev)
def generate_revision_key(self, ud, d, name):
return self._revision_key(ud, d, name)
key = self._revision_key(ud, d, name)
return "%s-%s" % (key, d.getVar("PN") or "")
def latest_versionstring(self, ud, d):
"""
@@ -1592,7 +1600,7 @@ class Fetch(object):
fn = d.getVar('FILE')
mc = d.getVar('__BBMULTICONFIG') or ""
if cache and fn and mc + fn in urldata_cache:
self.ud = urldata_cache[mc + fn + str(id(d))]
self.ud = urldata_cache[mc + fn]
for url in urls:
if url not in self.ud:
@@ -1604,7 +1612,7 @@ class Fetch(object):
pass
if fn and cache:
urldata_cache[mc + fn + str(id(d))] = self.ud
urldata_cache[mc + fn] = self.ud
def localpath(self, url):
if url not in self.urls:

View File

@@ -10,8 +10,18 @@ BitBake 'Fetch' implementation for bzr.
# BitBake build tools.
# Copyright (C) 2003, 2004 Chris Larson
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import os
import sys

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake 'Fetch' clearcase implementation
@@ -45,7 +47,18 @@ User credentials:
"""
# Copyright (C) 2014 Siemens AG
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
import os
@@ -54,8 +67,6 @@ import shutil
import bb
from bb.fetch2 import FetchMethod
from bb.fetch2 import FetchError
from bb.fetch2 import MissingParameterError
from bb.fetch2 import ParameterError
from bb.fetch2 import runfetchcmd
from bb.fetch2 import logger
@@ -81,7 +92,7 @@ class ClearCase(FetchMethod):
if 'protocol' in ud.parm:
ud.proto = ud.parm['protocol']
if not ud.proto in ('http', 'https'):
raise ParameterError("Invalid protocol type", ud.url)
raise fetch2.ParameterError("Invalid protocol type", ud.url)
ud.vob = ''
if 'vob' in ud.parm:
@@ -145,18 +156,18 @@ class ClearCase(FetchMethod):
basecmd = "%s %s" % (ud.basecmd, command)
if command == 'mkview':
if command is 'mkview':
if not "rcleartool" in ud.basecmd:
# Cleartool needs a -snapshot view
options.append("-snapshot")
options.append("-tag %s" % ud.viewname)
options.append(ud.viewdir)
elif command == 'rmview':
elif command is 'rmview':
options.append("-force")
options.append("%s" % ud.viewdir)
elif command == 'setcs':
elif command is 'setcs':
options.append("-overwrite")
options.append(ud.configspecfile)

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake 'Fetch' implementations
@@ -8,9 +10,20 @@ BitBake build tools.
# Copyright (C) 2003, 2004 Chris Larson
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
# Based on functions from the base bb module, Copyright 2003 Holger Schurig
# 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.
#
#Based on functions from the base bb module, Copyright 2003 Holger Schurig
#
import os

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake 'Fetch' git implementation
@@ -53,10 +55,20 @@ Supported SRC_URI options are:
"""
# Copyright (C) 2005 Richard Purdie
#Copyright (C) 2005 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import collections
import errno
@@ -292,21 +304,11 @@ class Git(FetchMethod):
def clonedir_need_update(self, ud, d):
if not os.path.exists(ud.clonedir):
return True
if ud.shallow and ud.write_shallow_tarballs and self.clonedir_need_shallow_revs(ud, d):
return True
for name in ud.names:
if not self._contains_ref(ud, d, name, ud.clonedir):
return True
return False
def clonedir_need_shallow_revs(self, ud, d):
for rev in ud.shallow_revs:
try:
runfetchcmd('%s rev-parse -q --verify %s' % (ud.basecmd, rev), d, quiet=True, workdir=ud.clonedir)
except bb.fetch2.FetchError:
return rev
return None
def shallow_tarball_need_update(self, ud):
return ud.shallow and ud.write_shallow_tarballs and not os.path.exists(ud.fullshallow)
@@ -349,7 +351,13 @@ class Git(FetchMethod):
runfetchcmd(clone_cmd, d, log=progresshandler)
# Update the checkout if needed
if self.clonedir_need_update(ud, d):
needupdate = False
for name in ud.names:
if not self._contains_ref(ud, d, name, ud.clonedir):
needupdate = True
break
if needupdate:
output = runfetchcmd("%s remote" % ud.basecmd, d, quiet=True, workdir=ud.clonedir)
if "origin" in output:
runfetchcmd("%s remote rm origin" % ud.basecmd, d, workdir=ud.clonedir)
@@ -373,11 +381,6 @@ class Git(FetchMethod):
if not self._contains_ref(ud, d, name, ud.clonedir):
raise bb.fetch2.FetchError("Unable to find revision %s in branch %s even from upstream" % (ud.revisions[name], ud.branches[name]))
if ud.shallow and ud.write_shallow_tarballs:
missing_rev = self.clonedir_need_shallow_revs(ud, d)
if missing_rev:
raise bb.fetch2.FetchError("Unable to find revision %s even from upstream" % missing_rev)
def build_mirror_data(self, ud, d):
if ud.shallow and ud.write_shallow_tarballs:
if not os.path.exists(ud.fullshallow):
@@ -473,8 +476,6 @@ class Git(FetchMethod):
if os.path.exists(destdir):
bb.utils.prunedir(destdir)
need_lfs = ud.parm.get("lfs", "1") == "1"
source_found = False
source_error = []
@@ -502,13 +503,6 @@ class Git(FetchMethod):
repourl = self._get_repo_url(ud)
runfetchcmd("%s remote set-url origin %s" % (ud.basecmd, repourl), d, workdir=destdir)
if self._contains_lfs(ud, d, destdir):
if need_lfs and not self._find_git_lfs(d):
raise bb.fetch2.FetchError("Repository %s has LFS content, install git-lfs on host to download (or set lfs=0 to ignore it)" % (repourl))
else:
bb.note("Repository %s has LFS content but it is not being fetched" % (repourl))
if not ud.nocheckout:
if subdir != "":
runfetchcmd("%s read-tree %s%s" % (ud.basecmd, ud.revisions[ud.names[0]], readpathspec), d,
@@ -559,27 +553,6 @@ class Git(FetchMethod):
raise bb.fetch2.FetchError("The command '%s' gave output with more then 1 line unexpectedly, output: '%s'" % (cmd, output))
return output.split()[0] != "0"
def _contains_lfs(self, ud, d, wd):
"""
Check if the repository has 'lfs' (large file) content
"""
cmd = "%s grep lfs HEAD:.gitattributes | wc -l" % (
ud.basecmd)
try:
output = runfetchcmd(cmd, d, quiet=True, workdir=wd)
if int(output) > 0:
return True
except (bb.fetch2.FetchError,ValueError):
pass
return False
def _find_git_lfs(self, d):
"""
Return True if git-lfs can be found, False otherwise.
"""
import shutil
return shutil.which("git-lfs", path=d.getVar('PATH')) is not None
def _get_repo_url(self, ud):
"""
Return the repository URL
@@ -594,9 +567,7 @@ class Git(FetchMethod):
"""
Return a unique key for the url
"""
# Collapse adjacent slashes
slash_re = re.compile(r"/+")
return "git:" + ud.host + slash_re.sub(".", ud.path) + ud.unresolvedrev[name]
return "git:" + ud.host + ud.path.replace('/', '.') + ud.unresolvedrev[name]
def _lsremote(self, ud, d, search):
"""

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake 'Fetch' git annex implementation
"""
@@ -5,8 +7,18 @@ BitBake 'Fetch' git annex implementation
# Copyright (C) 2014 Otavio Salvador
# Copyright (C) 2014 O.S. Systems Software LTDA.
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import os
import bb

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake 'Fetch' git submodules implementation
@@ -14,8 +16,18 @@ NOTE: Switching a SRC_URI from "git://" to "gitsm://" requires a clean of your r
# Copyright (C) 2013 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import os
import bb
@@ -117,7 +129,7 @@ class GitSM(Git):
url += ';protocol=%s' % proto
url += ";name=%s" % module
url += ";subpath=%s" % module
url += ";subpath=%s" % paths[module]
ld = d.createCopy()
# Not necessary to set SRC_URI, since we're passing the URI to
@@ -184,7 +196,7 @@ class GitSM(Git):
try:
newfetch = Fetch([url], d, cache=False)
newfetch.unpack(root=os.path.dirname(os.path.join(repo_conf, 'modules', module)))
newfetch.unpack(root=os.path.dirname(os.path.join(repo_conf, 'modules', modpath)))
except Exception as e:
logger.error('gitsm: submodule unpack failed: %s %s' % (type(e).__name__, str(e)))
raise
@@ -199,9 +211,9 @@ class GitSM(Git):
# Ensure the submodule repository is NOT set to bare, since we're checking it out...
try:
runfetchcmd("%s config core.bare false" % (ud.basecmd), d, quiet=True, workdir=os.path.join(repo_conf, 'modules', module))
runfetchcmd("%s config core.bare false" % (ud.basecmd), d, quiet=True, workdir=os.path.join(repo_conf, 'modules', modpath))
except:
logger.error("Unable to set git config core.bare to false for %s" % os.path.join(repo_conf, 'modules', module))
logger.error("Unable to set git config core.bare to false for %s" % os.path.join(repo_conf, 'modules', modpath))
raise
Git.unpack(self, ud, destdir, d)
@@ -209,7 +221,5 @@ class GitSM(Git):
ret = self.process_submodules(ud, ud.destdir, unpack_submodules, d)
if not ud.bareclone and ret:
# All submodules should already be downloaded and configured in the tree. This simply sets
# up the configuration and checks out the files. The main project config should remain
# unmodified, and no download from the internet should occur.
# Run submodule update, this sets up the directories -- without touching the config
runfetchcmd("%s submodule update --recursive --no-fetch" % (ud.basecmd), d, quiet=True, workdir=ud.destdir)

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake 'Fetch' implementation for mercurial DRCS (hg).
@@ -7,10 +9,20 @@ BitBake 'Fetch' implementation for mercurial DRCS (hg).
# Copyright (C) 2004 Marcin Juszkiewicz
# Copyright (C) 2007 Robert Schuster
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
# Based on functions from the base bb module, Copyright 2003 Holger Schurig
#
import os
import sys
@@ -54,6 +66,13 @@ class Hg(FetchMethod):
else:
ud.proto = "hg"
ud.setup_revisions(d)
if 'rev' in ud.parm:
ud.revision = ud.parm['rev']
elif not ud.revision:
ud.revision = self.latest_revision(ud, d)
# Create paths to mercurial checkouts
hgsrcname = '%s_%s_%s' % (ud.module.replace('/', '.'), \
ud.host, ud.path.replace('/', '.'))
@@ -67,13 +86,6 @@ class Hg(FetchMethod):
ud.localfile = ud.moddir
ud.basecmd = d.getVar("FETCHCMD_hg") or "/usr/bin/env hg"
ud.setup_revisions(d)
if 'rev' in ud.parm:
ud.revision = ud.parm['rev']
elif not ud.revision:
ud.revision = self.latest_revision(ud, d)
ud.write_tarballs = d.getVar("BB_GENERATE_MIRROR_TARBALLS")
def need_update(self, ud, d):
@@ -139,7 +151,7 @@ class Hg(FetchMethod):
cmd = "%s --config auth.default.prefix=* --config auth.default.username=%s --config auth.default.password=%s --config \"auth.default.schemes=%s\" pull" % (ud.basecmd, ud.user, ud.pswd, proto)
else:
cmd = "%s pull" % (ud.basecmd)
elif command == "update" or command == "up":
elif command == "update":
if ud.user and ud.pswd:
cmd = "%s --config auth.default.prefix=* --config auth.default.username=%s --config auth.default.password=%s --config \"auth.default.schemes=%s\" update -C %s" % (ud.basecmd, ud.user, ud.pswd, proto, " ".join(options))
else:
@@ -247,19 +259,12 @@ class Hg(FetchMethod):
scmdata = ud.parm.get("scmdata", "")
if scmdata != "nokeep":
proto = ud.parm.get('protocol', 'http')
if not os.access(os.path.join(codir, '.hg'), os.R_OK):
logger.debug(2, "Unpack: creating new hg repository in '" + codir + "'")
runfetchcmd("%s init %s" % (ud.basecmd, codir), d)
logger.debug(2, "Unpack: updating source in '" + codir + "'")
if ud.user and ud.pswd:
runfetchcmd("%s --config auth.default.prefix=* --config auth.default.username=%s --config auth.default.password=%s --config \"auth.default.schemes=%s\" pull %s" % (ud.basecmd, ud.user, ud.pswd, proto, ud.moddir), d, workdir=codir)
else:
runfetchcmd("%s pull %s" % (ud.basecmd, ud.moddir), d, workdir=codir)
if ud.user and ud.pswd:
runfetchcmd("%s --config auth.default.prefix=* --config auth.default.username=%s --config auth.default.password=%s --config \"auth.default.schemes=%s\" up -C %s" % (ud.basecmd, ud.user, ud.pswd, proto, revflag), d, workdir=codir)
else:
runfetchcmd("%s up -C %s" % (ud.basecmd, revflag), d, workdir=codir)
runfetchcmd("%s pull %s" % (ud.basecmd, ud.moddir), d, workdir=codir)
runfetchcmd("%s up -C %s" % (ud.basecmd, revflag), d, workdir=codir)
else:
logger.debug(2, "Unpack: extracting source to '" + codir + "'")
runfetchcmd("%s archive -t files %s %s" % (ud.basecmd, revflag, codir), d, workdir=ud.moddir)

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake 'Fetch' implementations
@@ -8,10 +10,20 @@ BitBake build tools.
# Copyright (C) 2003, 2004 Chris Larson
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
# Based on functions from the base bb module, Copyright 2003 Holger Schurig
#
import os
import urllib.request, urllib.parse, urllib.error

View File

@@ -1,6 +1,5 @@
#
# SPDX-License-Identifier: GPL-2.0-only
#
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake 'Fetch' NPM implementation
@@ -101,19 +100,11 @@ class Npm(FetchMethod):
return False
return True
def _runpack(self, ud, d, pkgfullname: str, quiet=False) -> str:
"""
Runs npm pack on a full package name.
Returns the filename of the downloaded package
"""
bb.fetch2.check_network_access(d, pkgfullname, ud.registry)
def _runwget(self, ud, d, command, quiet):
logger.debug(2, "Fetching %s using command '%s'" % (ud.url, command))
bb.fetch2.check_network_access(d, command, ud.url)
dldir = d.getVar("DL_DIR")
dldir = os.path.join(dldir, ud.prefixdir)
command = "npm pack {} --registry {}".format(pkgfullname, ud.registry)
logger.debug(2, "Fetching {} using command '{}' in {}".format(pkgfullname, command, dldir))
filename = runfetchcmd(command, d, quiet, workdir=dldir)
return filename.rstrip()
runfetchcmd(command, d, quiet, workdir=dldir)
def _unpackdep(self, ud, pkg, data, destdir, dldir, d):
file = data[pkg]['tgz']
@@ -159,11 +150,20 @@ class Npm(FetchMethod):
Parse the output of npm view --json; the last JSON result
is assumed to be the one that we're interested in.
'''
pdata = json.loads(output);
try:
return pdata[-1]
except:
return pdata
pdata = None
outdeps = {}
datalines = []
bracelevel = 0
for line in output.splitlines():
if bracelevel:
datalines.append(line)
elif '{' in line:
datalines = []
datalines.append(line)
bracelevel = bracelevel + line.count('{') - line.count('}')
if datalines:
pdata = json.loads('\n'.join(datalines))
return pdata
def _getdependencies(self, pkg, data, version, d, ud, optional=False, fetchedlist=None):
if fetchedlist is None:
@@ -171,9 +171,6 @@ class Npm(FetchMethod):
pkgfullname = pkg
if version != '*' and not '/' in version:
pkgfullname += "@'%s'" % version
if pkgfullname in fetchedlist:
return
logger.debug(2, "Calling getdeps on %s" % pkg)
fetchcmd = "npm view %s --json --registry %s" % (pkgfullname, ud.registry)
output = runfetchcmd(fetchcmd, d, True)
@@ -193,10 +190,15 @@ class Npm(FetchMethod):
if (not blacklist and 'linux' not in pkg_os) or '!linux' in pkg_os:
logger.debug(2, "Skipping %s since it's incompatible with Linux" % pkg)
return
filename = self._runpack(ud, d, pkgfullname)
#logger.debug(2, "Output URL is %s - %s - %s" % (ud.basepath, ud.basename, ud.localfile))
outputurl = pdata['dist']['tarball']
data[pkg] = {}
data[pkg]['tgz'] = filename
fetchedlist.append(pkgfullname)
data[pkg]['tgz'] = os.path.basename(outputurl)
if outputurl in fetchedlist:
return
self._runwget(ud, d, "%s --directory-prefix=%s %s" % (self.basecmd, ud.prefixdir, outputurl), False)
fetchedlist.append(outputurl)
dependencies = pdata.get('dependencies', {})
optionalDependencies = pdata.get('optionalDependencies', {})
@@ -223,12 +225,17 @@ class Npm(FetchMethod):
if obj == pkg:
self._getshrinkeddependencies(obj, data['dependencies'][obj], data['dependencies'][obj]['version'], d, ud, lockdown, manifest, False)
return
pkgnameWithVersion = "{}@{}".format(pkg, version)
logger.debug(2, "Get dependencies for {}".format(pkgnameWithVersion))
filename = self._runpack(ud, d, pkgnameWithVersion)
outputurl = "invalid"
if ('resolved' not in data) or (not data['resolved'].startswith('http://') and not data['resolved'].startswith('https://')):
# will be the case for ${PN}
fetchcmd = "npm view %s@%s dist.tarball --registry %s" % (pkg, version, ud.registry)
logger.debug(2, "Found this matching URL: %s" % str(fetchcmd))
outputurl = runfetchcmd(fetchcmd, d, True)
else:
outputurl = data['resolved']
self._runwget(ud, d, "%s --directory-prefix=%s %s" % (self.basecmd, ud.prefixdir, outputurl), False)
manifest[pkg] = {}
manifest[pkg]['tgz'] = filename
manifest[pkg]['tgz'] = os.path.basename(outputurl).rstrip()
manifest[pkg]['deps'] = {}
if pkg in lockdown:

View File

@@ -1,6 +1,5 @@
#
# SPDX-License-Identifier: GPL-2.0-only
#
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
Bitbake "Fetch" implementation for osc (Opensuse build service client).
Based on the svn "Fetch" implementation.

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake 'Fetch' implementation for perforce
@@ -6,7 +8,18 @@ BitBake 'Fetch' implementation for perforce
# Copyright (C) 2003, 2004 Chris Larson
# Copyright (C) 2016 Kodak Alaris, Inc.
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
# Based on functions from the base bb module, Copyright 2003 Holger Schurig

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake "Fetch" repo (git) implementation
@@ -6,10 +8,20 @@ BitBake "Fetch" repo (git) implementation
# Copyright (C) 2009 Tom Rini <trini@embeddedalley.com>
#
# Based on git.py which is:
# Copyright (C) 2005 Richard Purdie
#Copyright (C) 2005 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import os
import bb

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake 'Fetch' implementation for Amazon AWS S3.
@@ -11,7 +13,18 @@ The aws tool must be correctly installed and configured prior to use.
# Based in part on bb.fetch2.wget:
# Copyright (C) 2003, 2004 Chris Larson
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
# Based on functions from the base bb module, Copyright 2003 Holger Schurig

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake SFTP Fetch implementation
@@ -42,7 +44,18 @@ SRC_URI = "sftp://user@host.example.com/dir/path.file.txt"
# Based in part on bb.fetch2.wget:
# Copyright (C) 2003, 2004 Chris Larson
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
# Based on functions from the base bb module, Copyright 2003 Holger Schurig

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
'''
BitBake 'Fetch' implementations
@@ -27,8 +29,18 @@ IETF secsh internet draft:
# Copyright 2003 Holger Schurig
#
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import re, os
from bb.fetch2 import FetchMethod

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake 'Fetch' implementation for svn.
@@ -6,7 +8,18 @@ BitBake 'Fetch' implementation for svn.
# Copyright (C) 2003, 2004 Chris Larson
# Copyright (C) 2004 Marcin Juszkiewicz
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
# Based on functions from the base bb module, Copyright 2003 Holger Schurig
@@ -91,13 +104,6 @@ class Svn(FetchMethod):
svncmd = "%s log --limit 1 %s %s://%s/%s/" % (ud.basecmd, " ".join(options), proto, svnroot, ud.module)
else:
suffix = ""
# externals may be either 'allowed' or 'nowarn', but not both. Allowed
# will not issue a warning, but will log to the debug buffer what has likely
# been downloaded by SVN.
if not ("externals" in ud.parm and ud.parm["externals"] == "allowed"):
options.append("--ignore-externals")
if ud.revision:
options.append("-r %s" % ud.revision)
suffix = "@%s" % (ud.revision)
@@ -143,18 +149,6 @@ class Svn(FetchMethod):
bb.fetch2.check_network_access(d, svnfetchcmd, ud.url)
runfetchcmd(svnfetchcmd, d, workdir=ud.pkgdir)
if not ("externals" in ud.parm and ud.parm["externals"] == "nowarn"):
# Warn the user if this had externals (won't catch them all)
output = runfetchcmd("svn propget svn:externals || true", d, workdir=ud.moddir)
if output:
if "--ignore-externals" in svnfetchcmd.split():
bb.warn("%s contains svn:externals." % ud.url)
bb.warn("These should be added to the recipe SRC_URI as necessary.")
bb.warn("svn fetch has ignored externals:\n%s" % output)
bb.warn("To disable this warning add ';externals=nowarn' to the url.")
else:
bb.debug(1, "svn repository has externals:\n%s" % output)
scmdata = ud.parm.get("scmdata", "")
if scmdata == "keep":
tar_flags = ""

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake 'Fetch' implementations
@@ -8,7 +10,18 @@ BitBake build tools.
# Copyright (C) 2003, 2004 Chris Larson
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
# Based on functions from the base bb module, Copyright 2003 Holger Schurig
@@ -257,15 +270,13 @@ class Wget(FetchMethod):
fp.read()
fp.close()
if req.get_method() != 'GET':
newheaders = dict((k, v) for k, v in list(req.headers.items())
if k.lower() not in ("content-length", "content-type"))
return self.parent.open(urllib.request.Request(req.get_full_url(),
headers=newheaders,
origin_req_host=req.origin_req_host,
unverifiable=True))
newheaders = dict((k, v) for k, v in list(req.headers.items())
if k.lower() not in ("content-length", "content-type"))
return self.parent.open(urllib.request.Request(req.get_full_url(),
headers=newheaders,
origin_req_host=req.origin_req_host,
unverifiable=True))
raise urllib.request.HTTPError(req, code, msg, headers, None)
# Some servers (e.g. GitHub archives, hosted on Amazon S3) return 403
# Forbidden when they actually mean 405 Method Not Allowed.

View File

@@ -1,3 +1,6 @@
#!/usr/bin/env python
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# Copyright (C) 2003, 2004 Chris Larson
# Copyright (C) 2003, 2004 Phil Blundell
@@ -6,8 +9,18 @@
# Copyright (C) 2005 ROAD GmbH
# Copyright (C) 2006 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import os
import sys
@@ -254,11 +267,6 @@ class BitBakeConfigParameters(cookerdata.ConfigParameters):
help="Do not run any setscene tasks. sstate will be ignored and "
"everything needed, built.")
parser.add_option("", "--skip-setscene", action="store_true",
dest="skipsetscene", default=False,
help="Skip setscene tasks if they would be executed. Tasks previously "
"restored from sstate will be kept, unlike --no-setscene")
parser.add_option("", "--setscene-only", action="store_true",
dest="setsceneonly", default=False,
help="Only run setscene tasks, don't run any real tasks.")
@@ -452,7 +460,12 @@ def setup_bitbake(configParams, configuration, extrafeatures=None):
bb.utils.unlockfile(lock)
raise bb.server.process.ProcessTimeout("Bitbake still shutting down as socket exists but no lock?")
if not configParams.server_only:
server_connection = bb.server.process.connectProcessServer(sockname, featureset)
try:
server_connection = bb.server.process.connectProcessServer(sockname, featureset)
except EOFError:
# The server may have been shutting down but not closed the socket yet. If that happened,
# ignore it.
pass
if server_connection or configParams.server_only:
break
@@ -463,13 +476,12 @@ def setup_bitbake(configParams, configuration, extrafeatures=None):
raise
retries -= 1
tryno = 8 - retries
if isinstance(e, (bb.server.process.ProcessTimeout, BrokenPipeError, EOFError)):
if isinstance(e, (bb.server.process.ProcessTimeout, BrokenPipeError)):
logger.info("Retrying server connection (#%d)..." % tryno)
else:
logger.info("Retrying server connection (#%d)... (%s)" % (tryno, traceback.format_exc()))
if not retries:
bb.fatal("Unable to connect to bitbake server, or start one (server startup failures would be in bitbake-cookerdaemon.log).")
bb.event.print_ui_queue()
bb.fatal("Unable to connect to bitbake server, or start one")
if retries < 5:
time.sleep(5)
@@ -491,7 +503,7 @@ def setup_bitbake(configParams, configuration, extrafeatures=None):
def lockBitbake():
topdir = bb.cookerdata.findTopdir()
if not topdir:
bb.error("Unable to find conf/bblayers.conf or conf/bitbake.conf. BBPATH is unset and/or not in a build directory?")
bb.error("Unable to find conf/bblayers.conf or conf/bitbake.conf. BBAPTH is unset and/or not in a build directory?")
raise BBMainFatal
lockfile = topdir + "/bitbake.lock"
return topdir, bb.utils.lockfile(lockfile, False, False)

View File

@@ -1,8 +1,21 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
#
# Copyright (C) 2006 Holger Hans Peter Freyther
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
from bb.utils import better_compile, better_exec

View File

@@ -1,8 +1,21 @@
#!/usr/bin/env python
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# Copyright (C) 2012 Robert Yang
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import os, logging, re, sys
import bb

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake 'msg' implementation
@@ -7,8 +9,18 @@ Message handling infrastructure for bitbake
# Copyright (C) 2006 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import sys
import copy

View File

@@ -1,8 +1,6 @@
# http://code.activestate.com/recipes/577629-namedtupleabc-abstract-base-class-mix-in-for-named/
#!/usr/bin/env python
# Copyright (c) 2011 Jan Kaliszewski (zuo). Available under the MIT License.
#
# SPDX-License-Identifier: MIT
#
"""
namedtuple_with_abc.py:

View File

@@ -9,10 +9,20 @@ File parsers for the BitBake build tools.
# Copyright (C) 2003, 2004 Chris Larson
# Copyright (C) 2003, 2004 Phil Blundell
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
# Based on functions from the base bb module, Copyright 2003 Holger Schurig
#
handlers = []

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
AbstractSyntaxTree classes for the Bitbake language
"""
@@ -6,8 +8,19 @@
# Copyright (C) 2003, 2004 Phil Blundell
# Copyright (C) 2009 Holger Hans Peter Freyther
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import re
import string

View File

@@ -1,3 +1,6 @@
#!/usr/bin/env python
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
class for handling .bb files
@@ -9,8 +12,19 @@
# Copyright (C) 2003, 2004 Chris Larson
# Copyright (C) 2003, 2004 Phil Blundell
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import re, bb, os
import logging
@@ -28,7 +42,7 @@ __func_start_regexp__ = re.compile(r"(((?P<py>python)|(?P<fr>fakeroot))\s*)*(
__inherit_regexp__ = re.compile(r"inherit\s+(.+)" )
__export_func_regexp__ = re.compile(r"EXPORT_FUNCTIONS\s+(.+)" )
__addtask_regexp__ = re.compile(r"addtask\s+(?P<func>\w+)\s*((before\s*(?P<before>((.*(?=after))|(.*))))|(after\s*(?P<after>((.*(?=before))|(.*)))))*")
__deltask_regexp__ = re.compile(r"deltask\s+(?P<func>\w+)(?P<ignores>.*)")
__deltask_regexp__ = re.compile(r"deltask\s+(?P<func>\w+)")
__addhandler_regexp__ = re.compile(r"addhandler\s+(.+)" )
__def_regexp__ = re.compile(r"def\s+(\w+).*:" )
__python_func_regexp__ = re.compile(r"(\s+.*)|(^$)|(^#)" )
@@ -222,27 +236,11 @@ def feeder(lineno, s, fn, root, statements, eof=False):
m = __addtask_regexp__.match(s)
if m:
if len(m.group().split()) == 2:
# Check and warn for "addtask task1 task2"
m2 = re.match(r"addtask\s+(?P<func>\w+)(?P<ignores>.*)", s)
if m2 and m2.group('ignores'):
logger.warning('addtask ignored: "%s"' % m2.group('ignores'))
# Check and warn for "addtask task1 before task2 before task3", the
# similar to "after"
taskexpression = s.split()
for word in ('before', 'after'):
if taskexpression.count(word) > 1:
logger.warning("addtask contained multiple '%s' keywords, only one is supported" % word)
ast.handleAddTask(statements, fn, lineno, m)
return
m = __deltask_regexp__.match(s)
if m:
# Check and warn "for deltask task1 task2"
if m.group('ignores'):
logger.warning('deltask ignored: "%s"' % m.group('ignores'))
ast.handleDelTask(statements, fn, lineno, m)
return

View File

@@ -1,3 +1,6 @@
#!/usr/bin/env python
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
class for handling configuration data files
@@ -8,8 +11,18 @@
# Copyright (C) 2003, 2004 Chris Larson
# Copyright (C) 2003, 2004 Phil Blundell
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import errno
import re

View File

@@ -1,3 +1,6 @@
#!/usr/bin/env python
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake Parsers
@@ -8,10 +11,20 @@ File parsers for the BitBake build tools.
# Copyright (C) 2003, 2004 Chris Larson
# Copyright (C) 2003, 2004 Phil Blundell
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
# Based on functions from the base bb module, Copyright 2003 Holger Schurig
#
from __future__ import absolute_import
from . import ConfHandler

View File

@@ -8,8 +8,18 @@ currently, providing a key/value store accessed by 'domain'.
# Copyright (C) 2007 Richard Purdie
# Copyright (C) 2010 Chris Larson <chris_larson@mentor.com>
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import collections
import logging
@@ -179,9 +189,6 @@ class SQLTable(collections.MutableMapping):
elif not isinstance(value, str):
raise TypeError('Only string values are supported')
# Ensure the entire transaction (including SELECT) executes under write lock
cursor.execute("BEGIN EXCLUSIVE")
cursor.execute("SELECT * from %s where key=?;" % self.table, [key])
row = cursor.fetchone()
if row is not None:

View File

@@ -1,7 +1,3 @@
#
# SPDX-License-Identifier: GPL-2.0-only
#
import logging
import signal
import subprocess

View File

@@ -4,8 +4,18 @@ BitBake progress handling code
# Copyright (C) 2016 Intel Corporation
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import sys
import re
@@ -13,7 +23,6 @@ import time
import inspect
import bb.event
import bb.build
from bb.build import StdoutNoopContextManager
class ProgressHandler(object):
"""
@@ -28,14 +37,7 @@ class ProgressHandler(object):
if outfile:
self._outfile = outfile
else:
self._outfile = StdoutNoopContextManager()
def __enter__(self):
self._outfile.__enter__()
return self
def __exit__(self, *excinfo):
self._outfile.__exit__(*excinfo)
self._outfile = sys.stdout
def _fire_progress(self, taskprogress, rate=None):
"""Internal function to fire the progress event"""
@@ -155,12 +157,6 @@ class MultiStageProgressReporter(object):
self._stage_total = None
self._callers = []
def __enter__(self):
return self
def __exit__(self, *excinfo):
pass
def _fire_progress(self, taskprogress):
bb.event.fire(bb.build.TaskProgress(taskprogress), self._data)

View File

@@ -1,3 +1,5 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# Copyright (C) 2003, 2004 Chris Larson
# Copyright (C) 2003, 2004 Phil Blundell
@@ -6,8 +8,18 @@
# Copyright (C) 2005 ROAD GmbH
# Copyright (C) 2006 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import re
import logging

View File

@@ -6,8 +6,18 @@ Provides support for using a datastore from the bitbake client
# Copyright (C) 2016 Intel Corporation
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import bb.data

File diff suppressed because it is too large Load Diff

View File

@@ -5,5 +5,17 @@
# Copyright (C) 2006 - 2008 Richard Purdie
# Copyright (C) 2013 Alexandru Damian
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.

View File

@@ -3,8 +3,18 @@
#
# Copyright (C) 2010 Bob Foerster <robert@erafx.com>
#
# SPDX-License-Identifier: GPL-2.0-only
# 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 a multiprocessing.Process based server for bitbake.
@@ -456,10 +466,7 @@ class BitBakeServer(object):
self.configuration.setServerRegIdleCallback(server.register_idle_function)
os.close(self.readypipe)
writer = ConnectionWriter(self.readypipein)
try:
self.cooker = bb.cooker.BBCooker(self.configuration, self.featureset)
except bb.BBHandledException:
return None
self.cooker = bb.cooker.BBCooker(self.configuration, self.featureset)
writer.send("r")
writer.close()
server.cooker = self.cooker

View File

@@ -4,8 +4,18 @@
# Copyright (C) 2006 - 2007 Michael 'Mickey' Lauer
# Copyright (C) 2006 - 2008 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import os
import sys

View File

@@ -4,8 +4,18 @@
# Copyright (C) 2006 - 2007 Michael 'Mickey' Lauer
# Copyright (C) 2006 - 2008 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import os
import sys

View File

@@ -1,7 +1,3 @@
#
# SPDX-License-Identifier: GPL-2.0-only
#
import hashlib
import logging
import os
@@ -12,8 +8,6 @@ import bb.data
import difflib
import simplediff
from bb.checksum import FileChecksumCache
from bb import runqueue
import hashserv
logger = logging.getLogger('BitBake.SigGen')
@@ -40,29 +34,18 @@ class SignatureGenerator(object):
def __init__(self, data):
self.basehash = {}
self.taskhash = {}
self.unihash = {}
self.runtaskdeps = {}
self.file_checksum_values = {}
self.taints = {}
self.unitaskhashes = {}
self.tidtopn = {}
self.setscenetasks = set()
def finalise(self, fn, d, varient):
return
def postparsing_clean_cache(self):
return
def get_unihash(self, task):
return self.taskhash[task]
def get_unihash(self, tid):
return self.taskhash[tid]
def prep_taskhash(self, tid, deps, dataCache):
return
def get_taskhash(self, tid, deps, dataCache):
self.taskhash[tid] = hashlib.sha256(tid.encode("utf-8")).hexdigest()
return self.taskhash[tid]
def get_taskhash(self, fn, task, deps, dataCache):
return "0"
def writeout_file_checksum_cache(self):
"""Write/update the file checksum cache onto disk"""
@@ -84,25 +67,14 @@ class SignatureGenerator(object):
return
def get_taskdata(self):
return (self.runtaskdeps, self.taskhash, self.unihash, self.file_checksum_values, self.taints, self.basehash, self.unitaskhashes, self.tidtopn, self.setscenetasks)
return (self.runtaskdeps, self.taskhash, self.file_checksum_values, self.taints, self.basehash)
def set_taskdata(self, data):
self.runtaskdeps, self.taskhash, self.unihash, self.file_checksum_values, self.taints, self.basehash, self.unitaskhashes, self.tidtopn, self.setscenetasks = data
self.runtaskdeps, self.taskhash, self.file_checksum_values, self.taints, self.basehash = data
def reset(self, data):
self.__init__(data)
def get_taskhashes(self):
return self.taskhash, self.unihash, self.unitaskhashes, self.tidtopn
def set_taskhashes(self, hashes):
self.taskhash, self.unihash, self.unitaskhashes, self.tidtopn = hashes
def save_unitaskhashes(self):
return
def set_setscene_tasks(self, setscene_tasks):
return
class SignatureGeneratorBasic(SignatureGenerator):
"""
@@ -112,14 +84,13 @@ class SignatureGeneratorBasic(SignatureGenerator):
def __init__(self, data):
self.basehash = {}
self.taskhash = {}
self.unihash = {}
self.taskdeps = {}
self.runtaskdeps = {}
self.file_checksum_values = {}
self.taints = {}
self.gendeps = {}
self.lookupcache = {}
self.setscenetasks = set()
self.pkgnameextract = re.compile(r"(?P<fn>.*)\..*")
self.basewhitelist = set((data.getVar("BB_HASHBASE_WHITELIST") or "").split())
self.taskwhitelist = None
self.init_rundepcheck(data)
@@ -130,11 +101,6 @@ class SignatureGeneratorBasic(SignatureGenerator):
else:
self.checksum_cache = None
self.unihash_cache = bb.cache.SimpleCache("3")
self.unitaskhashes = self.unihash_cache.init_cache(data, "bb_unihashes.dat", {})
self.localdirsexclude = (data.getVar("BB_SIGNATURE_LOCAL_DIRS_EXCLUDE") or "CVS .bzr .git .hg .osc .p4 .repo .svn").split()
self.tidtopn = {}
def init_rundepcheck(self, data):
self.taskwhitelist = data.getVar("BB_HASHTASK_WHITELIST") or None
if self.taskwhitelist:
@@ -150,16 +116,10 @@ class SignatureGeneratorBasic(SignatureGenerator):
taskdeps, basehash = bb.data.generate_dependency_hash(tasklist, gendeps, lookupcache, self.basewhitelist, fn)
for task in tasklist:
tid = fn + ":" + task
if not ignore_mismatch and tid in self.basehash and self.basehash[tid] != basehash[tid]:
bb.error("When reparsing %s, the basehash value changed from %s to %s. The metadata is not deterministic and this needs to be fixed." % (tid, self.basehash[tid], basehash[tid]))
bb.error("The following commands may help:")
cmd = "$ bitbake %s -c%s" % (d.getVar('PN'), task)
# Make sure sigdata is dumped before run printdiff
bb.error("%s -Snone" % cmd)
bb.error("Then:")
bb.error("%s -Sprintdiff\n" % cmd)
self.basehash[tid] = basehash[tid]
k = fn + "." + task
if not ignore_mismatch and k in self.basehash and self.basehash[k] != basehash[k]:
bb.error("When reparsing %s, the basehash value changed from %s to %s. The metadata is not deterministic and this needs to be fixed." % (k, self.basehash[k], basehash[k]))
self.basehash[k] = basehash[k]
self.taskdeps[fn] = taskdeps
self.gendeps[fn] = gendeps
@@ -167,9 +127,6 @@ class SignatureGeneratorBasic(SignatureGenerator):
return taskdeps
def set_setscene_tasks(self, setscene_tasks):
self.setscenetasks = set(setscene_tasks)
def finalise(self, fn, d, variant):
mc = d.getVar("__BBMULTICONFIG", False) or ""
@@ -189,15 +146,7 @@ class SignatureGeneratorBasic(SignatureGenerator):
# self.dump_sigtask(fn, task, d.getVar("STAMP"), False)
for task in taskdeps:
d.setVar("BB_BASEHASH_task-%s" % task, self.basehash[fn + ":" + task])
def postparsing_clean_cache(self):
#
# After parsing we can remove some things from memory to reduce our memory footprint
#
self.gendeps = {}
self.lookupcache = {}
self.taskdeps = {}
d.setVar("BB_BASEHASH_task-%s" % task, self.basehash[fn + "." + task])
def rundep_check(self, fn, recipename, task, dep, depname, dataCache):
# Return True if we should keep the dependency, False to drop it
@@ -217,78 +166,60 @@ class SignatureGeneratorBasic(SignatureGenerator):
pass
return taint
def prep_taskhash(self, tid, deps, dataCache):
def get_taskhash(self, fn, task, deps, dataCache):
(mc, _, task, fn) = bb.runqueue.split_tid_mcfn(tid)
mc = ''
if fn.startswith('multiconfig:'):
mc = fn.split(':')[1]
k = fn + "." + task
self.basehash[tid] = dataCache.basetaskhash[tid]
self.runtaskdeps[tid] = []
self.file_checksum_values[tid] = []
data = dataCache.basetaskhash[k]
self.basehash[k] = data
self.runtaskdeps[k] = []
self.file_checksum_values[k] = []
recipename = dataCache.pkg_fn[fn]
self.tidtopn[tid] = recipename
for dep in sorted(deps, key=clean_basepath):
(depmc, _, deptaskname, depfn) = bb.runqueue.split_tid_mcfn(dep)
if mc != depmc:
pkgname = self.pkgnameextract.search(dep).group('fn')
if mc:
depmc = pkgname.split(':')[1]
if mc != depmc:
continue
if dep.startswith("multiconfig:") and not mc:
continue
depname = dataCache.pkg_fn[depfn]
depname = dataCache.pkg_fn[pkgname]
if not self.rundep_check(fn, recipename, task, dep, depname, dataCache):
continue
if dep not in self.taskhash:
bb.fatal("%s is not in taskhash, caller isn't calling in dependency order?" % dep)
self.runtaskdeps[tid].append(dep)
data = data + self.get_unihash(dep)
self.runtaskdeps[k].append(dep)
if task in dataCache.file_checksums[fn]:
if self.checksum_cache:
checksums = self.checksum_cache.get_checksums(dataCache.file_checksums[fn][task], recipename, self.localdirsexclude)
checksums = self.checksum_cache.get_checksums(dataCache.file_checksums[fn][task], recipename)
else:
checksums = bb.fetch2.get_file_checksums(dataCache.file_checksums[fn][task], recipename, self.localdirsexclude)
checksums = bb.fetch2.get_file_checksums(dataCache.file_checksums[fn][task], recipename)
for (f,cs) in checksums:
self.file_checksum_values[tid].append((f,cs))
self.file_checksum_values[k].append((f,cs))
if cs:
data = data + cs
taskdep = dataCache.task_deps[fn]
if 'nostamp' in taskdep and task in taskdep['nostamp']:
# Nostamp tasks need an implicit taint so that they force any dependent tasks to run
if tid in self.taints and self.taints[tid].startswith("nostamp:"):
# Don't reset taint value upon every call
pass
else:
import uuid
taint = str(uuid.uuid4())
self.taints[tid] = "nostamp:" + taint
import uuid
taint = str(uuid.uuid4())
data = data + taint
self.taints[k] = "nostamp:" + taint
taint = self.read_taint(fn, task, dataCache.stamp[fn])
if taint:
self.taints[tid] = taint
logger.warning("%s is tainted from a forced run" % tid)
return
def get_taskhash(self, tid, deps, dataCache):
data = self.basehash[tid]
for dep in self.runtaskdeps[tid]:
if dep in self.unihash:
if self.unihash[dep] is None:
data = data + self.taskhash[dep]
else:
data = data + self.unihash[dep]
else:
data = data + self.get_unihash(dep)
for (f, cs) in self.file_checksum_values[tid]:
if cs:
data = data + cs
if tid in self.taints:
if self.taints[tid].startswith("nostamp:"):
data = data + self.taints[tid][8:]
else:
data = data + self.taints[tid]
data = data + taint
self.taints[k] = taint
logger.warning("%s is tainted from a forced run" % k)
h = hashlib.sha256(data.encode("utf-8")).hexdigest()
self.taskhash[tid] = h
self.taskhash[k] = h
#d.setVar("BB_TASKHASH_task-%s" % task, taskhash[task])
return h
@@ -301,20 +232,17 @@ class SignatureGeneratorBasic(SignatureGenerator):
bb.fetch2.fetcher_parse_save()
bb.fetch2.fetcher_parse_done()
def save_unitaskhashes(self):
self.unihash_cache.save(self.unitaskhashes)
def dump_sigtask(self, fn, task, stampbase, runtime):
tid = fn + ":" + task
k = fn + "." + task
referencestamp = stampbase
if isinstance(runtime, str) and runtime.startswith("customfile"):
sigfile = stampbase
referencestamp = runtime[11:]
elif runtime and tid in self.taskhash:
sigfile = stampbase + "." + task + ".sigdata" + "." + self.get_unihash(tid)
elif runtime and k in self.taskhash:
sigfile = stampbase + "." + task + ".sigdata" + "." + self.taskhash[k]
else:
sigfile = stampbase + "." + task + ".sigbasedata" + "." + self.basehash[tid]
sigfile = stampbase + "." + task + ".sigbasedata" + "." + self.basehash[k]
bb.utils.mkdirhier(os.path.dirname(sigfile))
@@ -323,7 +251,7 @@ class SignatureGeneratorBasic(SignatureGenerator):
data['basewhitelist'] = self.basewhitelist
data['taskwhitelist'] = self.taskwhitelist
data['taskdeps'] = self.taskdeps[fn][task]
data['basehash'] = self.basehash[tid]
data['basehash'] = self.basehash[k]
data['gendeps'] = {}
data['varvals'] = {}
data['varvals'][task] = self.lookupcache[fn][task]
@@ -333,31 +261,30 @@ class SignatureGeneratorBasic(SignatureGenerator):
data['gendeps'][dep] = self.gendeps[fn][dep]
data['varvals'][dep] = self.lookupcache[fn][dep]
if runtime and tid in self.taskhash:
data['runtaskdeps'] = self.runtaskdeps[tid]
data['file_checksum_values'] = [(os.path.basename(f), cs) for f,cs in self.file_checksum_values[tid]]
if runtime and k in self.taskhash:
data['runtaskdeps'] = self.runtaskdeps[k]
data['file_checksum_values'] = [(os.path.basename(f), cs) for f,cs in self.file_checksum_values[k]]
data['runtaskhashes'] = {}
for dep in data['runtaskdeps']:
data['runtaskhashes'][dep] = self.get_unihash(dep)
data['taskhash'] = self.taskhash[tid]
data['unihash'] = self.get_unihash(tid)
data['taskhash'] = self.taskhash[k]
taint = self.read_taint(fn, task, referencestamp)
if taint:
data['taint'] = taint
if runtime and tid in self.taints:
if 'nostamp:' in self.taints[tid]:
data['taint'] = self.taints[tid]
if runtime and k in self.taints:
if 'nostamp:' in self.taints[k]:
data['taint'] = self.taints[k]
computed_basehash = calc_basehash(data)
if computed_basehash != self.basehash[tid]:
bb.error("Basehash mismatch %s versus %s for %s" % (computed_basehash, self.basehash[tid], tid))
if runtime and tid in self.taskhash:
if computed_basehash != self.basehash[k]:
bb.error("Basehash mismatch %s versus %s for %s" % (computed_basehash, self.basehash[k], k))
if runtime and k in self.taskhash:
computed_taskhash = calc_taskhash(data)
if computed_taskhash != self.taskhash[tid]:
bb.error("Taskhash mismatch %s versus %s for %s" % (computed_taskhash, self.taskhash[tid], tid))
sigfile = sigfile.replace(self.taskhash[tid], computed_taskhash)
if computed_taskhash != self.taskhash[k]:
bb.error("Taskhash mismatch %s versus %s for %s" % (computed_taskhash, self.taskhash[k], k))
sigfile = sigfile.replace(self.taskhash[k], computed_taskhash)
fd, tmpfile = tempfile.mkstemp(dir=os.path.dirname(sigfile), prefix="sigtask.")
try:
@@ -377,33 +304,34 @@ class SignatureGeneratorBasic(SignatureGenerator):
if fn in self.taskdeps:
for task in self.taskdeps[fn]:
tid = fn + ":" + task
mc = bb.runqueue.mc_from_tid(tid)
if tid not in self.taskhash:
(mc, _, _) = bb.runqueue.split_tid(tid)
k = fn + "." + task
if k not in self.taskhash:
continue
if dataCaches[mc].basetaskhash[tid] != self.basehash[tid]:
bb.error("Bitbake's cached basehash does not match the one we just generated (%s)!" % tid)
bb.error("The mismatched hashes were %s and %s" % (dataCaches[mc].basetaskhash[tid], self.basehash[tid]))
if dataCaches[mc].basetaskhash[k] != self.basehash[k]:
bb.error("Bitbake's cached basehash does not match the one we just generated (%s)!" % k)
bb.error("The mismatched hashes were %s and %s" % (dataCaches[mc].basetaskhash[k], self.basehash[k]))
self.dump_sigtask(fn, task, dataCaches[mc].stamp[fn], True)
class SignatureGeneratorBasicHash(SignatureGeneratorBasic):
name = "basichash"
def get_stampfile_hash(self, tid):
if tid in self.taskhash:
return self.taskhash[tid]
def get_stampfile_hash(self, task):
if task in self.taskhash:
return self.taskhash[task]
# If task is not in basehash, then error
return self.basehash[tid]
return self.basehash[task]
def stampfile(self, stampbase, fn, taskname, extrainfo, clean=False):
if taskname != "do_setscene" and taskname.endswith("_setscene"):
tid = fn + ":" + taskname[:-9]
k = fn + "." + taskname[:-9]
else:
tid = fn + ":" + taskname
k = fn + "." + taskname
if clean:
h = "*"
else:
h = self.get_stampfile_hash(tid)
h = self.get_stampfile_hash(k)
return ("%s.%s.%s.%s" % (stampbase, taskname, h, extrainfo)).rstrip('.')
@@ -414,232 +342,6 @@ class SignatureGeneratorBasicHash(SignatureGeneratorBasic):
bb.note("Tainting hash to force rebuild of task %s, %s" % (fn, task))
bb.build.write_taint(task, d, fn)
class SignatureGeneratorUniHashMixIn(object):
def __init__(self, data):
self.extramethod = {}
super().__init__(data)
def get_taskdata(self):
return (self.server, self.method, self.extramethod) + super().get_taskdata()
def set_taskdata(self, data):
self.server, self.method, self.extramethod = data[:3]
super().set_taskdata(data[3:])
def client(self):
if getattr(self, '_client', None) is None:
self._client = hashserv.create_client(self.server)
return self._client
def get_stampfile_hash(self, tid):
if tid in self.taskhash:
# If a unique hash is reported, use it as the stampfile hash. This
# ensures that if a task won't be re-run if the taskhash changes,
# but it would result in the same output hash
unihash = self._get_unihash(tid)
if unihash is not None:
return unihash
return super().get_stampfile_hash(tid)
def set_unihash(self, tid, unihash):
(mc, fn, taskname, taskfn) = bb.runqueue.split_tid_mcfn(tid)
key = mc + ":" + self.tidtopn[tid] + ":" + taskname
self.unitaskhashes[key] = (self.taskhash[tid], unihash)
self.unihash[tid] = unihash
def _get_unihash(self, tid, checkkey=None):
if tid not in self.tidtopn:
return None
(mc, fn, taskname, taskfn) = bb.runqueue.split_tid_mcfn(tid)
key = mc + ":" + self.tidtopn[tid] + ":" + taskname
if key not in self.unitaskhashes:
return None
if not checkkey:
checkkey = self.taskhash[tid]
(key, unihash) = self.unitaskhashes[key]
if key != checkkey:
return None
return unihash
def get_unihash(self, tid):
taskhash = self.taskhash[tid]
# If its not a setscene task we can return
if self.setscenetasks and tid not in self.setscenetasks:
self.unihash[tid] = None
return taskhash
# TODO: This cache can grow unbounded. It probably only needs to keep
# for each task
unihash = self._get_unihash(tid)
if unihash is not None:
self.unihash[tid] = unihash
return unihash
# In the absence of being able to discover a unique hash from the
# server, make it be equivalent to the taskhash. The unique "hash" only
# really needs to be a unique string (not even necessarily a hash), but
# making it match the taskhash has a few advantages:
#
# 1) All of the sstate code that assumes hashes can be the same
# 2) It provides maximal compatibility with builders that don't use
# an equivalency server
# 3) The value is easy for multiple independent builders to derive the
# same unique hash from the same input. This means that if the
# independent builders find the same taskhash, but it isn't reported
# to the server, there is a better chance that they will agree on
# the unique hash.
unihash = taskhash
try:
method = self.method
if tid in self.extramethod:
method = method + self.extramethod[tid]
data = self.client().get_unihash(method, self.taskhash[tid])
if data:
unihash = data
# A unique hash equal to the taskhash is not very interesting,
# so it is reported it at debug level 2. If they differ, that
# is much more interesting, so it is reported at debug level 1
bb.debug((1, 2)[unihash == taskhash], 'Found unihash %s in place of %s for %s from %s' % (unihash, taskhash, tid, self.server))
else:
bb.debug(2, 'No reported unihash for %s:%s from %s' % (tid, taskhash, self.server))
except hashserv.client.HashConnectionError as e:
bb.warn('Error contacting Hash Equivalence Server %s: %s' % (self.server, str(e)))
self.set_unihash(tid, unihash)
self.unihash[tid] = unihash
return unihash
def report_unihash(self, path, task, d):
import importlib
taskhash = d.getVar('BB_TASKHASH')
unihash = d.getVar('BB_UNIHASH')
report_taskdata = d.getVar('SSTATE_HASHEQUIV_REPORT_TASKDATA') == '1'
tempdir = d.getVar('T')
fn = d.getVar('BB_FILENAME')
tid = fn + ':do_' + task
key = tid + ':' + taskhash
if self.setscenetasks and tid not in self.setscenetasks:
return
# This can happen if locked sigs are in action. Detect and just abort
if taskhash != self.taskhash[tid]:
return
# Sanity checks
cache_unihash = self._get_unihash(tid, checkkey=taskhash)
if cache_unihash is None:
bb.fatal('%s not in unihash cache. Please report this error' % key)
if cache_unihash != unihash:
bb.fatal("Cache unihash %s doesn't match BB_UNIHASH %s" % (cache_unihash, unihash))
sigfile = None
sigfile_name = "depsig.do_%s.%d" % (task, os.getpid())
sigfile_link = "depsig.do_%s" % task
try:
sigfile = open(os.path.join(tempdir, sigfile_name), 'w+b')
locs = {'path': path, 'sigfile': sigfile, 'task': task, 'd': d}
if "." in self.method:
(module, method) = self.method.rsplit('.', 1)
locs['method'] = getattr(importlib.import_module(module), method)
outhash = bb.utils.better_eval('method(path, sigfile, task, d)', locs)
else:
outhash = bb.utils.better_eval(self.method + '(path, sigfile, task, d)', locs)
try:
extra_data = {}
owner = d.getVar('SSTATE_HASHEQUIV_OWNER')
if owner:
extra_data['owner'] = owner
if report_taskdata:
sigfile.seek(0)
extra_data['PN'] = d.getVar('PN')
extra_data['PV'] = d.getVar('PV')
extra_data['PR'] = d.getVar('PR')
extra_data['task'] = task
extra_data['outhash_siginfo'] = sigfile.read().decode('utf-8')
method = self.method
if tid in self.extramethod:
method = method + self.extramethod[tid]
data = self.client().report_unihash(taskhash, method, outhash, unihash, extra_data)
new_unihash = data['unihash']
if new_unihash != unihash:
bb.debug(1, 'Task %s unihash changed %s -> %s by server %s' % (taskhash, unihash, new_unihash, self.server))
bb.event.fire(bb.runqueue.taskUniHashUpdate(fn + ':do_' + task, new_unihash), d)
self.set_unihash(tid, new_unihash)
d.setVar('BB_UNIHASH', new_unihash)
else:
bb.debug(1, 'Reported task %s as unihash %s to %s' % (taskhash, unihash, self.server))
except hashserv.client.HashConnectionError as e:
bb.warn('Error contacting Hash Equivalence Server %s: %s' % (self.server, str(e)))
finally:
if sigfile:
sigfile.close()
sigfile_link_path = os.path.join(tempdir, sigfile_link)
bb.utils.remove(sigfile_link_path)
try:
os.symlink(sigfile_name, sigfile_link_path)
except OSError:
pass
def report_unihash_equiv(self, tid, taskhash, wanted_unihash, current_unihash, datacaches):
try:
extra_data = {}
method = self.method
if tid in self.extramethod:
method = method + self.extramethod[tid]
data = self.client().report_unihash_equiv(taskhash, method, wanted_unihash, extra_data)
bb.note('Reported task %s as unihash %s to %s (%s)' % (tid, wanted_unihash, self.server, str(data)))
if data is None:
bb.warn("Server unable to handle unihash report")
return False
finalunihash = data['unihash']
if finalunihash == current_unihash:
bb.note('Task %s unihash %s unchanged by server' % (tid, finalunihash))
elif finalunihash == wanted_unihash:
bb.note('Task %s unihash changed %s -> %s as wanted' % (tid, current_unihash, finalunihash))
self.set_unihash(tid, finalunihash)
return True
else:
# TODO: What to do here?
bb.note('Task %s unihash reported as unwanted hash %s' % (tid, finalunihash))
except hashserv.client.HashConnectionError as e:
bb.warn('Error contacting Hash Equivalence Server %s: %s' % (self.server, str(e)))
return False
#
# Dummy class used for bitbake-selftest
#
class SignatureGeneratorTestEquivHash(SignatureGeneratorUniHashMixIn, SignatureGeneratorBasicHash):
name = "TestEquivHash"
def init_rundepcheck(self, data):
super().init_rundepcheck(data)
self.server = data.getVar('BB_HASHSERVE')
self.method = "sstate_output_hash"
def dump_this_task(outfile, d):
import bb.parse
fn = d.getVar("BB_FILENAME")
@@ -700,13 +402,13 @@ def list_inline_diff(oldlist, newlist, colors=None):
def clean_basepath(a):
mc = None
if a.startswith("mc:"):
if a.startswith("multiconfig:"):
_, mc, a = a.split(":", 2)
b = a.rsplit("/", 2)[1] + '/' + a.rsplit("/", 2)[2]
if a.startswith("virtual:"):
b = b + ":" + a.rsplit(":", 1)[0]
if mc:
b = b + ":mc:" + mc
b = b + ":multiconfig:" + mc
return b
def clean_basepaths(a):
@@ -931,10 +633,6 @@ def compare_sigfiles(a, b, recursecb=None, color=False, collapsed=False):
a_taint = a_data.get('taint', None)
b_taint = b_data.get('taint', None)
if a_taint != b_taint:
if a_taint and a_taint.startswith('nostamp:'):
a_taint = a_taint.replace('nostamp:', 'nostamp(uuid4):')
if b_taint and b_taint.startswith('nostamp:'):
b_taint = b_taint.replace('nostamp:', 'nostamp(uuid4):')
output.append(color_format("{color_title}Taint (by forced/invalidated task) changed{color_default} from %s to %s") % (a_taint, b_taint))
return output
@@ -1007,11 +705,7 @@ def dump_sigfile(a):
output.append("Hash for dependent task %s is %s" % (dep, a_data['runtaskhashes'][dep]))
if 'taint' in a_data:
if a_data['taint'].startswith('nostamp:'):
msg = a_data['taint'].replace('nostamp:', 'nostamp(uuid4):')
else:
msg = a_data['taint']
output.append("Tainted (by forced/invalidated task): %s" % msg)
output.append("Tainted (by forced/invalidated task): %s" % a_data['taint'])
if 'task' in a_data:
computed_basehash = calc_basehash(a_data)

View File

@@ -1,3 +1,6 @@
#!/usr/bin/env python
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
"""
BitBake 'TaskData' implementation
@@ -7,8 +10,18 @@ Task data collection and handling
# Copyright (C) 2006 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import logging
import re
@@ -80,7 +93,7 @@ class TaskData:
def add_mcdepends(task):
for dep in task_deps['mcdepends'][task].split():
if len(dep.split(':')) != 5:
bb.msg.fatal("TaskData", "Error for %s:%s[%s], multiconfig dependency %s does not contain exactly four ':' characters.\n Task '%s' should be specified in the form 'mc:fromMC:toMC:packagename:task'" % (fn, task, 'mcdepends', dep, 'mcdepends'))
bb.msg.fatal("TaskData", "Error for %s:%s[%s], multiconfig dependency %s does not contain exactly four ':' characters.\n Task '%s' should be specified in the form 'multiconfig:fromMC:toMC:packagename:task'" % (fn, task, 'mcdepends', dep, 'mcdepends'))
if dep not in self.mcdepends:
self.mcdepends.append(dep)

View File

@@ -1,10 +1,23 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# BitBake Test for codeparser.py
#
# Copyright (C) 2010 Chris Larson
# Copyright (C) 2012 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
import unittest

View File

@@ -1,7 +1,20 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# BitBake Tests for cooker.py
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
import unittest

View File

@@ -1,10 +1,23 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# BitBake Tests for Copy-on-Write (cow.py)
#
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright 2006 Holger Freyther <freyther@handhelds.org>
#
# 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.
#
import unittest
import os

View File

@@ -1,10 +1,23 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# BitBake Tests for the Data Store (data.py/data_smart.py)
#
# Copyright (C) 2010 Chris Larson
# Copyright (C) 2012 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
import unittest
@@ -381,19 +394,6 @@ class TestOverrides(unittest.TestCase):
self.d.setVar("OVERRIDES", "foo:bar:some_val")
self.assertEqual(self.d.getVar("TEST"), " testvalue5")
def test_append_and_override_1(self):
self.d.setVar("TEST_append", "testvalue2")
self.d.setVar("TEST_bar", "testvalue3")
self.assertEqual(self.d.getVar("TEST"), "testvalue3testvalue2")
def test_append_and_override_2(self):
self.d.setVar("TEST_append_bar", "testvalue2")
self.assertEqual(self.d.getVar("TEST"), "testvaluetestvalue2")
def test_append_and_override_3(self):
self.d.setVar("TEST_bar_append", "testvalue2")
self.assertEqual(self.d.getVar("TEST"), "testvalue2")
# Test an override with _<numeric> in it based on a real world OE issue
def test_underscore_override(self):
self.d.setVar("TARGET_ARCH", "x86_64")
@@ -479,7 +479,7 @@ class TaskHash(unittest.TestCase):
tasklist, gendeps, lookupcache = bb.data.generate_dependencies(d)
taskdeps, basehash = bb.data.generate_dependency_hash(tasklist, gendeps, lookupcache, set(), "somefile")
bb.warn(str(lookupcache))
return basehash["somefile:" + taskname]
return basehash["somefile." + taskname]
d = bb.data.init()
d.setVar("__BBTASKS", ["mytask"])

View File

@@ -1,9 +1,22 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# BitBake Tests for the Event implementation (event.py)
#
# Copyright (C) 2017 Intel Corporation
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
import unittest
@@ -561,6 +574,14 @@ class EventClassesTest(unittest.TestCase):
self.assertEqual(event.fn(1), callback(1))
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_StampUpdate(self):
targets = ["foo", "bar"]
stampfns = [lambda:"foobar"]
event = bb.event.StampUpdate(targets, stampfns)
self.assertEqual(event.targets, targets)
self.assertEqual(event.stampPrefix, stampfns)
self.assertEqual(event.pid, EventClassesTest._worker_pid)
def test_BuildBase(self):
""" Test base class for bitbake build events """
name = "foo"

View File

@@ -1,9 +1,22 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# BitBake Tests for the Fetcher (fetch2/)
#
# Copyright (C) 2012 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
import unittest
@@ -899,7 +912,6 @@ class FetcherNetworkTest(FetcherTest):
if os.path.exists(os.path.join(repo_path, 'bitbake-gitsm-test1')):
self.assertTrue(os.path.exists(os.path.join(repo_path, 'bitbake-gitsm-test1', 'bitbake')), msg='submodule of submodule missing')
@skipIfNoNetwork()
def test_git_submodule_dbus_broker(self):
# The following external repositories have show failures in fetch and unpack operations
# We want to avoid regressions!
@@ -917,7 +929,6 @@ class FetcherNetworkTest(FetcherTest):
self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/subprojects/c-sundry/config')), msg='Missing submodule config "subprojects/c-sundry"')
self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/subprojects/c-utf8/config')), msg='Missing submodule config "subprojects/c-utf8"')
@skipIfNoNetwork()
def test_git_submodule_CLI11(self):
url = "gitsm://github.com/CLIUtils/CLI11;protocol=git;rev=bd4dc911847d0cde7a6b41dfa626a85aab213baf"
fetcher = bb.fetch.Fetch([url], self.d)
@@ -931,7 +942,6 @@ class FetcherNetworkTest(FetcherTest):
self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/extern/json/config')), msg='Missing submodule config "extern/json"')
self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/extern/sanitizers/config')), msg='Missing submodule config "extern/sanitizers"')
@skipIfNoNetwork()
def test_git_submodule_update_CLI11(self):
""" Prevent regression on update detection not finding missing submodule, or modules without needed commits """
url = "gitsm://github.com/CLIUtils/CLI11;protocol=git;rev=cf6a99fa69aaefe477cc52e3ef4a7d2d7fa40714"
@@ -951,7 +961,6 @@ class FetcherNetworkTest(FetcherTest):
self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/extern/json/config')), msg='Missing submodule config "extern/json"')
self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/extern/sanitizers/config')), msg='Missing submodule config "extern/sanitizers"')
@skipIfNoNetwork()
def test_git_submodule_aktualizr(self):
url = "gitsm://github.com/advancedtelematic/aktualizr;branch=master;protocol=git;rev=d00d1a04cc2366d1a5f143b84b9f507f8bd32c44"
fetcher = bb.fetch.Fetch([url], self.d)
@@ -968,114 +977,6 @@ class FetcherNetworkTest(FetcherTest):
self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/third_party/googletest/config')), msg='Missing submodule config "third_party/googletest/config"')
self.assertTrue(os.path.exists(os.path.join(repo_path, '.git/modules/third_party/HdrHistogram_c/config')), msg='Missing submodule config "third_party/HdrHistogram_c/config"')
@skipIfNoNetwork()
def test_git_submodule_iotedge(self):
""" Prevent regression on deeply nested submodules not being checked out properly, even though they were fetched. """
# This repository also has submodules where the module (name), path and url do not align
url = "gitsm://github.com/azure/iotedge.git;protocol=git;rev=d76e0316c6f324345d77c48a83ce836d09392699"
fetcher = bb.fetch.Fetch([url], self.d)
fetcher.download()
# Previous cwd has been deleted
os.chdir(os.path.dirname(self.unpackdir))
fetcher.unpack(self.unpackdir)
repo_path = os.path.join(self.tempdir, 'unpacked', 'git')
self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/c-shared/README.md')), msg='Missing submodule checkout')
self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/c-shared/testtools/ctest/README.md')), msg='Missing submodule checkout')
self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/c-shared/testtools/testrunner/readme.md')), msg='Missing submodule checkout')
self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/c-shared/testtools/umock-c/readme.md')), msg='Missing submodule checkout')
self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/c-shared/testtools/umock-c/deps/ctest/README.md')), msg='Missing submodule checkout')
self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/c-shared/testtools/umock-c/deps/testrunner/readme.md')), msg='Missing submodule checkout')
self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/utpm/README.md')), msg='Missing submodule checkout')
self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/utpm/deps/c-utility/README.md')), msg='Missing submodule checkout')
self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/utpm/deps/c-utility/testtools/ctest/README.md')), msg='Missing submodule checkout')
self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/utpm/deps/c-utility/testtools/testrunner/readme.md')), msg='Missing submodule checkout')
self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/utpm/deps/c-utility/testtools/umock-c/readme.md')), msg='Missing submodule checkout')
self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/utpm/deps/c-utility/testtools/umock-c/deps/ctest/README.md')), msg='Missing submodule checkout')
self.assertTrue(os.path.exists(os.path.join(repo_path, 'edgelet/hsm-sys/azure-iot-hsm-c/deps/utpm/deps/c-utility/testtools/umock-c/deps/testrunner/readme.md')), msg='Missing submodule checkout')
class SVNTest(FetcherTest):
def skipIfNoSvn():
import shutil
if not shutil.which("svn"):
return unittest.skip("svn not installed, tests being skipped")
if not shutil.which("svnadmin"):
return unittest.skip("svnadmin not installed, tests being skipped")
return lambda f: f
@skipIfNoSvn()
def setUp(self):
""" Create a local repository """
super(SVNTest, self).setUp()
# Create something we can fetch
src_dir = tempfile.mkdtemp(dir=self.tempdir,
prefix='svnfetch_srcdir_')
src_dir = os.path.abspath(src_dir)
bb.process.run("echo readme > README.md", cwd=src_dir)
# Store it in a local SVN repository
repo_dir = tempfile.mkdtemp(dir=self.tempdir,
prefix='svnfetch_localrepo_')
repo_dir = os.path.abspath(repo_dir)
bb.process.run("svnadmin create project", cwd=repo_dir)
self.repo_url = "file://%s/project" % repo_dir
bb.process.run("svn import --non-interactive -m 'Initial import' %s %s/trunk" % (src_dir, self.repo_url),
cwd=repo_dir)
bb.process.run("svn co %s svnfetch_co" % self.repo_url, cwd=self.tempdir)
# Github will emulate SVN. Use this to check if we're downloding...
bb.process.run("svn propset svn:externals 'bitbake http://github.com/openembedded/bitbake' .",
cwd=os.path.join(self.tempdir, 'svnfetch_co', 'trunk'))
bb.process.run("svn commit --non-interactive -m 'Add external'",
cwd=os.path.join(self.tempdir, 'svnfetch_co', 'trunk'))
self.src_dir = src_dir
self.repo_dir = repo_dir
@skipIfNoSvn()
def tearDown(self):
os.chdir(self.origdir)
if os.environ.get("BB_TMPDIR_NOCLEAN") == "yes":
print("Not cleaning up %s. Please remove manually." % self.tempdir)
else:
bb.utils.prunedir(self.tempdir)
@skipIfNoSvn()
@skipIfNoNetwork()
def test_noexternal_svn(self):
# Always match the rev count from setUp (currently rev 2)
url = "svn://%s;module=trunk;protocol=file;rev=2" % self.repo_url.replace('file://', '')
fetcher = bb.fetch.Fetch([url], self.d)
fetcher.download()
os.chdir(os.path.dirname(self.unpackdir))
fetcher.unpack(self.unpackdir)
self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk')), msg="Missing trunk")
self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk', 'README.md')), msg="Missing contents")
self.assertFalse(os.path.exists(os.path.join(self.unpackdir, 'trunk/bitbake/trunk')), msg="External dir should NOT exist")
self.assertFalse(os.path.exists(os.path.join(self.unpackdir, 'trunk/bitbake/trunk', 'README')), msg="External README should NOT exit")
@skipIfNoSvn()
def test_external_svn(self):
# Always match the rev count from setUp (currently rev 2)
url = "svn://%s;module=trunk;protocol=file;externals=allowed;rev=2" % self.repo_url.replace('file://', '')
fetcher = bb.fetch.Fetch([url], self.d)
fetcher.download()
os.chdir(os.path.dirname(self.unpackdir))
fetcher.unpack(self.unpackdir)
self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk')), msg="Missing trunk")
self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk', 'README.md')), msg="Missing contents")
self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk/bitbake/trunk')), msg="External dir should exist")
self.assertTrue(os.path.exists(os.path.join(self.unpackdir, 'trunk/bitbake/trunk', 'README')), msg="External README should exit")
class TrustedNetworksTest(FetcherTest):
def test_trusted_network(self):
# Ensure trusted_network returns False when the host IS in the list.
@@ -1200,8 +1101,8 @@ class FetchLatestVersionTest(FetcherTest):
# packages with valid UPSTREAM_CHECK_URI and UPSTREAM_CHECK_REGEX
("cups", "http://www.cups.org/software/1.7.2/cups-1.7.2-source.tar.bz2", "https://github.com/apple/cups/releases", "(?P<name>cups\-)(?P<pver>((\d+[\.\-_]*)+))\-source\.tar\.gz")
: "2.0.0",
("db", "http://download.oracle.com/berkeley-db/db-5.3.21.tar.gz", "http://ftp.debian.org/debian/pool/main/d/db5.3/", "(?P<name>db5\.3_)(?P<pver>\d+(\.\d+)+).+\.orig\.tar\.xz")
: "5.3.10",
("db", "http://download.oracle.com/berkeley-db/db-5.3.21.tar.gz", "http://www.oracle.com/technetwork/products/berkeleydb/downloads/index-082944.html", "http://download.oracle.com/otn/berkeley-db/(?P<name>db-)(?P<pver>((\d+[\.\-_]*)+))\.tar\.gz")
: "6.1.19",
}
@skipIfNoNetwork()
@@ -1863,26 +1764,6 @@ class GitShallowTest(FetcherTest):
with self.assertRaises(bb.fetch2.FetchError):
self.fetch()
def test_shallow_fetch_missing_revs(self):
self.add_empty_file('a')
self.add_empty_file('b')
fetcher, ud = self.fetch(self.d.getVar('SRC_URI'))
self.git('tag v0.0 master', cwd=self.srcdir)
self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0')
self.d.setVar('BB_GIT_SHALLOW_REVS', 'v0.0')
self.fetch_shallow()
def test_shallow_fetch_missing_revs_fails(self):
self.add_empty_file('a')
self.add_empty_file('b')
fetcher, ud = self.fetch(self.d.getVar('SRC_URI'))
self.d.setVar('BB_GIT_SHALLOW_DEPTH', '0')
self.d.setVar('BB_GIT_SHALLOW_REVS', 'v0.0')
with self.assertRaises(bb.fetch2.FetchError), self.assertLogs("BitBake.Fetcher", level="ERROR") as cm:
self.fetch_shallow()
self.assertIn("Unable to find revision v0.0 even from upstream", cm.output[0])
@skipIfNoNetwork()
def test_bitbake(self):
self.git('remote add --mirror=fetch origin git://github.com/openembedded/bitbake', cwd=self.srcdir)
@@ -1928,83 +1809,3 @@ class GitShallowTest(FetcherTest):
dir = os.listdir(self.unpackdir + "/git/")
self.assertIn("fstests.doap", dir)
class GitLfsTest(FetcherTest):
def setUp(self):
FetcherTest.setUp(self)
self.gitdir = os.path.join(self.tempdir, 'git')
self.srcdir = os.path.join(self.tempdir, 'gitsource')
self.d.setVar('WORKDIR', self.tempdir)
self.d.setVar('S', self.gitdir)
self.d.delVar('PREMIRRORS')
self.d.delVar('MIRRORS')
self.d.setVar('SRCREV', '${AUTOREV}')
self.d.setVar('AUTOREV', '${@bb.fetch2.get_autorev(d)}')
bb.utils.mkdirhier(self.srcdir)
self.git('init', cwd=self.srcdir)
with open(os.path.join(self.srcdir, '.gitattributes'), 'wt') as attrs:
attrs.write('*.mp3 filter=lfs -text')
self.git(['add', '.gitattributes'], cwd=self.srcdir)
self.git(['commit', '-m', "attributes", '.gitattributes'], cwd=self.srcdir)
def git(self, cmd, cwd=None):
if isinstance(cmd, str):
cmd = 'git ' + cmd
else:
cmd = ['git'] + cmd
if cwd is None:
cwd = self.gitdir
return bb.process.run(cmd, cwd=cwd)[0]
def fetch(self, uri=None):
uris = self.d.getVar('SRC_URI').split()
uri = uris[0]
d = self.d
fetcher = bb.fetch2.Fetch(uris, d)
fetcher.download()
ud = fetcher.ud[uri]
return fetcher, ud
def test_lfs_enabled(self):
import shutil
uri = 'git://%s;protocol=file;subdir=${S};lfs=1' % self.srcdir
self.d.setVar('SRC_URI', uri)
fetcher, ud = self.fetch()
self.assertIsNotNone(ud.method._find_git_lfs)
# If git-lfs can be found, the unpack should be successful
ud.method._find_git_lfs = lambda d: True
shutil.rmtree(self.gitdir, ignore_errors=True)
fetcher.unpack(self.d.getVar('WORKDIR'))
# If git-lfs cannot be found, the unpack should throw an error
with self.assertRaises(bb.fetch2.FetchError):
ud.method._find_git_lfs = lambda d: False
shutil.rmtree(self.gitdir, ignore_errors=True)
fetcher.unpack(self.d.getVar('WORKDIR'))
def test_lfs_disabled(self):
import shutil
uri = 'git://%s;protocol=file;subdir=${S};lfs=0' % self.srcdir
self.d.setVar('SRC_URI', uri)
fetcher, ud = self.fetch()
self.assertIsNotNone(ud.method._find_git_lfs)
# If git-lfs can be found, the unpack should be successful
ud.method._find_git_lfs = lambda d: True
shutil.rmtree(self.gitdir, ignore_errors=True)
fetcher.unpack(self.d.getVar('WORKDIR'))
# If git-lfs cannot be found, the unpack should be successful
ud.method._find_git_lfs = lambda d: False
shutil.rmtree(self.gitdir, ignore_errors=True)
fetcher.unpack(self.d.getVar('WORKDIR'))

View File

@@ -1,9 +1,22 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# BitBake Test for lib/bb/parse/
#
# Copyright (C) 2015 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
import unittest
@@ -174,21 +187,3 @@ python () {
self.assertEqual(d1.getVar("VAR_var"), "B")
self.assertEqual(d2.getVar("VAR_var"), None)
addtask_deltask = """
addtask do_patch after do_foo after do_unpack before do_configure before do_compile
addtask do_fetch do_patch
deltask do_fetch do_patch
"""
def test_parse_addtask_deltask(self):
import sys
f = self.parsehelper(self.addtask_deltask)
d = bb.parse.handle(f.name, self.d)['']
stdout = sys.stdout.getvalue()
self.assertTrue("addtask contained multiple 'before' keywords" in stdout)
self.assertTrue("addtask contained multiple 'after' keywords" in stdout)
self.assertTrue('addtask ignored: " do_patch"' in stdout)
self.assertTrue('deltask ignored: " do_patch"' in stdout)
#self.assertTrue('dependent task do_foo for do_patch does not exist' in stdout)

View File

@@ -1,9 +1,22 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# BitBake Test for lib/bb/persist_data/
#
# Copyright (C) 2018 Garmin Ltd.
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
import unittest

View File

@@ -1,262 +0,0 @@
SLOWTASKS ??= ""
SSTATEVALID ??= ""
def stamptask(d):
import time
thistask = d.expand("${PN}:${BB_CURRENTTASK}")
stampname = d.expand("${TOPDIR}/%s.run" % thistask)
with open(stampname, "a+") as f:
f.write(d.getVar("BB_UNIHASH") + "\n")
if d.getVar("BB_CURRENT_MC") != "default":
thistask = d.expand("${BB_CURRENT_MC}:${PN}:${BB_CURRENTTASK}")
if thistask in d.getVar("SLOWTASKS").split():
bb.note("Slowing task %s" % thistask)
time.sleep(0.5)
if d.getVar("BB_HASHSERVE"):
task = d.getVar("BB_CURRENTTASK")
if task in ['package', 'package_qa', 'packagedata', 'package_write_ipk', 'package_write_rpm', 'populate_lic', 'populate_sysroot']:
bb.parse.siggen.report_unihash(os.getcwd(), d.getVar("BB_CURRENTTASK"), d)
with open(d.expand("${TOPDIR}/task.log"), "a+") as f:
f.write(thistask + "\n")
def sstate_output_hash(path, sigfile, task, d):
import hashlib
h = hashlib.sha256()
h.update(d.expand("${PN}:${BB_CURRENTTASK}").encode('utf-8'))
return h.hexdigest()
python do_fetch() {
# fetch
stamptask(d)
}
python do_unpack() {
# unpack
stamptask(d)
}
python do_patch() {
# patch
stamptask(d)
}
python do_populate_lic() {
# populate_lic
stamptask(d)
}
python do_prepare_recipe_sysroot() {
# prepare_recipe_sysroot
stamptask(d)
}
python do_configure() {
# configure
stamptask(d)
}
python do_compile() {
# compile
stamptask(d)
}
python do_install() {
# install
stamptask(d)
}
python do_populate_sysroot() {
# populate_sysroot
stamptask(d)
}
python do_package() {
# package
stamptask(d)
}
python do_package_write_ipk() {
# package_write_ipk
stamptask(d)
}
python do_package_write_rpm() {
# package_write_rpm
stamptask(d)
}
python do_packagedata() {
# packagedata
stamptask(d)
}
python do_package_qa() {
# package_qa
stamptask(d)
}
python do_build() {
# build
stamptask(d)
}
do_prepare_recipe_sysroot[deptask] = "do_populate_sysroot"
do_package[deptask] += "do_packagedata"
do_build[recrdeptask] += "do_deploy"
do_build[recrdeptask] += "do_package_write_ipk"
do_build[recrdeptask] += "do_package_write_rpm"
do_package_qa[rdeptask] = "do_packagedata"
do_populate_lic_deploy[recrdeptask] += "do_populate_lic do_deploy"
DEBIANRDEP = "do_packagedata"
oo_package_write_ipk[rdeptask] = "${DEBIANRDEP}"
do_package_write_rpm[rdeptask] = "${DEBIANRDEP}"
addtask fetch
addtask unpack after do_fetch
addtask patch after do_unpack
addtask prepare_recipe_sysroot after do_patch
addtask configure after do_prepare_recipe_sysroot
addtask compile after do_configure
addtask install after do_compile
addtask populate_sysroot after do_install
addtask package after do_install
addtask package_write_ipk after do_packagedata do_package
addtask package_write_rpm after do_packagedata do_package
addtask packagedata after do_package
addtask package_qa after do_package
addtask build after do_package_qa do_package_write_rpm do_package_write_ipk do_populate_sysroot
python do_package_setscene() {
stamptask(d)
}
python do_package_qa_setscene() {
stamptask(d)
}
python do_package_write_ipk_setscene() {
stamptask(d)
}
python do_package_write_rpm_setscene() {
stamptask(d)
}
python do_packagedata_setscene() {
stamptask(d)
}
python do_populate_lic_setscene() {
stamptask(d)
}
python do_populate_sysroot_setscene() {
stamptask(d)
}
addtask package_setscene
addtask package_qa_setscene
addtask package_write_ipk_setscene
addtask package_write_rpm_setscene
addtask packagedata_setscene
addtask populate_lic_setscene
addtask populate_sysroot_setscene
BB_SETSCENE_DEPVALID = "setscene_depvalid"
def setscene_depvalid(task, taskdependees, notneeded, d, log=None):
# taskdependees is a dict of tasks which depend on task, each being a 3 item list of [PN, TASKNAME, FILENAME]
# task is included in taskdependees too
# Return - False - We need this dependency
# - True - We can skip this dependency
import re
def logit(msg, log):
if log is not None:
log.append(msg)
else:
bb.debug(2, msg)
logit("Considering setscene task: %s" % (str(taskdependees[task])), log)
def isNativeCross(x):
return x.endswith("-native") or "-cross-" in x or "-crosssdk" in x or x.endswith("-cross")
# We only need to trigger populate_lic through direct dependencies
if taskdependees[task][1] == "do_populate_lic":
return True
# We only need to trigger packagedata through direct dependencies
# but need to preserve packagedata on packagedata links
if taskdependees[task][1] == "do_packagedata":
for dep in taskdependees:
if taskdependees[dep][1] == "do_packagedata":
return False
return True
for dep in taskdependees:
logit(" considering dependency: %s" % (str(taskdependees[dep])), log)
if task == dep:
continue
if dep in notneeded:
continue
# do_package_write_* and do_package doesn't need do_package
if taskdependees[task][1] == "do_package" and taskdependees[dep][1] in ['do_package', 'do_package_write_ipk', 'do_package_write_rpm', 'do_packagedata', 'do_package_qa']:
continue
# do_package_write_* need do_populate_sysroot as they're mainly postinstall dependencies
if taskdependees[task][1] == "do_populate_sysroot" and taskdependees[dep][1] in ['do_package_write_ipk', 'do_package_write_rpm']:
return False
# do_package/packagedata/package_qa don't need do_populate_sysroot
if taskdependees[task][1] == "do_populate_sysroot" and taskdependees[dep][1] in ['do_package', 'do_packagedata', 'do_package_qa']:
continue
# Native/Cross packages don't exist and are noexec anyway
if isNativeCross(taskdependees[dep][0]) and taskdependees[dep][1] in ['do_package_write_ipk', 'do_package_write_rpm', 'do_packagedata', 'do_package', 'do_package_qa']:
continue
# This is due to the [depends] in useradd.bbclass complicating matters
# The logic *is* reversed here due to the way hard setscene dependencies are injected
if (taskdependees[task][1] == 'do_package' or taskdependees[task][1] == 'do_populate_sysroot') and taskdependees[dep][0].endswith(('shadow-native', 'shadow-sysroot', 'base-passwd', 'pseudo-native')) and taskdependees[dep][1] == 'do_populate_sysroot':
continue
# Consider sysroot depending on sysroot tasks
if taskdependees[task][1] == 'do_populate_sysroot' and taskdependees[dep][1] == 'do_populate_sysroot':
# Native/Cross populate_sysroot need their dependencies
if isNativeCross(taskdependees[task][0]) and isNativeCross(taskdependees[dep][0]):
return False
# Target populate_sysroot depended on by cross tools need to be installed
if isNativeCross(taskdependees[dep][0]):
return False
# Native/cross tools depended upon by target sysroot are not needed
# Add an exception for shadow-native as required by useradd.bbclass
if isNativeCross(taskdependees[task][0]) and taskdependees[task][0] != 'shadow-native':
continue
# Target populate_sysroot need their dependencies
return False
if taskdependees[dep][1] == "do_populate_lic":
continue
# Safe fallthrough default
logit(" Default setscene dependency fall through due to dependency: %s" % (str(taskdependees[dep])), log)
return False
return True
BB_HASHCHECK_FUNCTION = "sstate_checkhashes"
def sstate_checkhashes(sq_data, d, siginfo=False, currentcount=0, **kwargs):
found = set()
missed = set()
valid = d.getVar("SSTATEVALID").split()
for tid in sorted(sq_data['hash']):
n = os.path.basename(bb.runqueue.fn_from_tid(tid)).split(".")[0] + ":do_" + bb.runqueue.taskname_from_tid(tid)[3:]
print(n)
stampfile = d.expand("${TOPDIR}/%s.run" % n.replace("do_", ""))
if n in valid:
bb.note("SState: Found valid sstate for %s" % n)
found.add(tid)
elif n + ":" + sq_data['hash'][tid] in valid:
bb.note("SState: Found valid sstate for %s" % n)
found.add(tid)
elif os.path.exists(stampfile):
with open(stampfile, "r") as f:
hash = f.readline().strip()
if hash == sq_data['hash'][tid]:
bb.note("SState: Found valid sstate for %s (already run)" % n)
found.add(tid)
else:
bb.note("SState: sstate hash didn't match previous run for %s (%s vs %s)" % (n, sq_data['hash'][tid], hash))
missed.add(tid)
else:
missed.add(tid)
bb.note("SState: Found no valid sstate for %s (%s)" % (n, sq_data['hash'][tid]))
return found

View File

@@ -1,5 +0,0 @@
do_rootfs[recrdeptask] += "do_package_write_deb do_package_qa"
do_rootfs[recrdeptask] += "do_package_write_ipk do_package_qa"
do_rootfs[recrdeptask] += "do_package_write_rpm do_package_qa
do_rootfs[recrdeptask] += "do_packagedata"
do_rootfs[recrdeptask] += "do_populate_lic"

View File

@@ -1,2 +0,0 @@
RECIPERDEPTASK = "do_populate_sysroot"
do_populate_sysroot[rdeptask] = "${RECIPERDEPTASK}"

View File

@@ -1,16 +0,0 @@
CACHE = "${TOPDIR}/cache"
THISDIR = "${@os.path.dirname(d.getVar('FILE'))}"
COREBASE := "${@os.path.normpath(os.path.dirname(d.getVar('FILE')+'/../../'))}"
BBFILES = "${COREBASE}/recipes/*.bb"
PROVIDES = "${PN}"
PN = "${@bb.parse.vars_from_file(d.getVar('FILE', False),d)[0]}"
PF = "${BB_CURRENT_MC}:${PN}"
export PATH
TMPDIR ??= "${TOPDIR}"
STAMP = "${TMPDIR}/stamps/${PN}"
T = "${TMPDIR}/workdir/${PN}/temp"
BB_NUMBER_THREADS = "4"
BB_HASHBASE_WHITELIST = "BB_CURRENT_MC BB_HASHSERVE TMPDIR TOPDIR SLOWTASKS SSTATEVALID FILE"
include conf/multiconfig/${BB_CURRENT_MC}.conf

View File

@@ -1 +0,0 @@
TMPDIR = "${TOPDIR}/mc1/"

View File

@@ -1 +0,0 @@
TMPDIR = "${TOPDIR}/mc2/"

View File

@@ -1 +0,0 @@
DEPENDS = "a1"

View File

@@ -1,3 +0,0 @@
DEPENDS = "a1"
do_package_setscene[depends] = "a1:do_populate_sysroot_setscene"

View File

@@ -1 +0,0 @@
DEPENDS = "b1"

View File

@@ -1,323 +0,0 @@
#
# BitBake Tests for runqueue task processing
#
# Copyright (C) 2019 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
#
import unittest
import bb
import os
import tempfile
import subprocess
import sys
import time
#
# TODO:
# Add tests on task ordering (X happens before Y after Z)
#
class RunQueueTests(unittest.TestCase):
alltasks = ['package', 'fetch', 'unpack', 'patch', 'prepare_recipe_sysroot', 'configure',
'compile', 'install', 'packagedata', 'package_qa', 'package_write_rpm', 'package_write_ipk',
'populate_sysroot', 'build']
a1_sstatevalid = "a1:do_package a1:do_package_qa a1:do_packagedata a1:do_package_write_ipk a1:do_package_write_rpm a1:do_populate_lic a1:do_populate_sysroot"
b1_sstatevalid = "b1:do_package b1:do_package_qa b1:do_packagedata b1:do_package_write_ipk b1:do_package_write_rpm b1:do_populate_lic b1:do_populate_sysroot"
def run_bitbakecmd(self, cmd, builddir, sstatevalid="", slowtasks="", extraenv=None, cleanup=False):
env = os.environ.copy()
env["BBPATH"] = os.path.realpath(os.path.join(os.path.dirname(__file__), "runqueue-tests"))
env["BB_ENV_EXTRAWHITE"] = "SSTATEVALID SLOWTASKS"
env["SSTATEVALID"] = sstatevalid
env["SLOWTASKS"] = slowtasks
if extraenv:
for k in extraenv:
env[k] = extraenv[k]
env["BB_ENV_EXTRAWHITE"] = env["BB_ENV_EXTRAWHITE"] + " " + k
try:
output = subprocess.check_output(cmd, env=env, stderr=subprocess.STDOUT,universal_newlines=True, cwd=builddir)
print(output)
except subprocess.CalledProcessError as e:
self.fail("Command %s failed with %s" % (cmd, e.output))
tasks = []
tasklog = builddir + "/task.log"
if os.path.exists(tasklog):
with open(tasklog, "r") as f:
tasks = [line.rstrip() for line in f]
if cleanup:
os.remove(tasklog)
return tasks
def test_no_setscenevalid(self):
with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
cmd = ["bitbake", "a1"]
sstatevalid = ""
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
expected = ['a1:' + x for x in self.alltasks]
self.assertEqual(set(tasks), set(expected))
def test_single_setscenevalid(self):
with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
cmd = ["bitbake", "a1"]
sstatevalid = "a1:do_package"
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
expected = ['a1:package_setscene', 'a1:fetch', 'a1:unpack', 'a1:patch', 'a1:prepare_recipe_sysroot', 'a1:configure',
'a1:compile', 'a1:install', 'a1:packagedata', 'a1:package_qa', 'a1:package_write_rpm', 'a1:package_write_ipk',
'a1:populate_sysroot', 'a1:build']
self.assertEqual(set(tasks), set(expected))
def test_intermediate_setscenevalid(self):
with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
cmd = ["bitbake", "a1"]
sstatevalid = "a1:do_package a1:do_populate_sysroot"
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
expected = ['a1:package_setscene', 'a1:packagedata', 'a1:package_qa', 'a1:package_write_rpm', 'a1:package_write_ipk',
'a1:populate_sysroot_setscene', 'a1:build']
self.assertEqual(set(tasks), set(expected))
def test_intermediate_notcovered(self):
with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
cmd = ["bitbake", "a1"]
sstatevalid = "a1:do_package_qa a1:do_packagedata a1:do_package_write_ipk a1:do_package_write_rpm a1:do_populate_lic a1:do_populate_sysroot"
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
expected = ['a1:package_write_ipk_setscene', 'a1:package_write_rpm_setscene', 'a1:packagedata_setscene',
'a1:package_qa_setscene', 'a1:build', 'a1:populate_sysroot_setscene']
self.assertEqual(set(tasks), set(expected))
def test_all_setscenevalid(self):
with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
cmd = ["bitbake", "a1"]
sstatevalid = self.a1_sstatevalid
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
expected = ['a1:package_write_ipk_setscene', 'a1:package_write_rpm_setscene', 'a1:packagedata_setscene',
'a1:package_qa_setscene', 'a1:build', 'a1:populate_sysroot_setscene']
self.assertEqual(set(tasks), set(expected))
def test_no_settasks(self):
with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
cmd = ["bitbake", "a1", "-c", "patch"]
sstatevalid = self.a1_sstatevalid
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
expected = ['a1:fetch', 'a1:unpack', 'a1:patch']
self.assertEqual(set(tasks), set(expected))
def test_mix_covered_notcovered(self):
with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
cmd = ["bitbake", "a1:do_patch", "a1:do_populate_sysroot"]
sstatevalid = self.a1_sstatevalid
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
expected = ['a1:fetch', 'a1:unpack', 'a1:patch', 'a1:populate_sysroot_setscene']
self.assertEqual(set(tasks), set(expected))
# Test targets with intermediate setscene tasks alongside a target with no intermediate setscene tasks
def test_mixed_direct_tasks_setscene_tasks(self):
with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
cmd = ["bitbake", "c1:do_patch", "a1"]
sstatevalid = self.a1_sstatevalid
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
expected = ['c1:fetch', 'c1:unpack', 'c1:patch', 'a1:package_write_ipk_setscene', 'a1:package_write_rpm_setscene', 'a1:packagedata_setscene',
'a1:package_qa_setscene', 'a1:build', 'a1:populate_sysroot_setscene']
self.assertEqual(set(tasks), set(expected))
# This test slows down the execution of do_package_setscene until after other real tasks have
# started running which tests for a bug where tasks were being lost from the buildable list of real
# tasks if they weren't in tasks_covered or tasks_notcovered
def test_slow_setscene(self):
with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
cmd = ["bitbake", "a1"]
sstatevalid = "a1:do_package"
slowtasks = "a1:package_setscene"
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, slowtasks)
expected = ['a1:package_setscene', 'a1:fetch', 'a1:unpack', 'a1:patch', 'a1:prepare_recipe_sysroot', 'a1:configure',
'a1:compile', 'a1:install', 'a1:packagedata', 'a1:package_qa', 'a1:package_write_rpm', 'a1:package_write_ipk',
'a1:populate_sysroot', 'a1:build']
self.assertEqual(set(tasks), set(expected))
def test_setscenewhitelist(self):
with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
cmd = ["bitbake", "a1"]
extraenv = {
"BB_SETSCENE_ENFORCE" : "1",
"BB_SETSCENE_ENFORCE_WHITELIST" : "a1:do_package_write_rpm a1:do_build"
}
sstatevalid = "a1:do_package a1:do_package_qa a1:do_packagedata a1:do_package_write_ipk a1:do_populate_lic a1:do_populate_sysroot"
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv)
expected = ['a1:packagedata_setscene', 'a1:package_qa_setscene', 'a1:package_write_ipk_setscene',
'a1:populate_sysroot_setscene', 'a1:package_setscene']
self.assertEqual(set(tasks), set(expected))
# Tests for problems with dependencies between setscene tasks
def test_no_setscenevalid_harddeps(self):
with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
cmd = ["bitbake", "d1"]
sstatevalid = ""
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
expected = ['a1:package', 'a1:fetch', 'a1:unpack', 'a1:patch', 'a1:prepare_recipe_sysroot', 'a1:configure',
'a1:compile', 'a1:install', 'a1:packagedata', 'a1:package_write_rpm', 'a1:package_write_ipk',
'a1:populate_sysroot', 'd1:package', 'd1:fetch', 'd1:unpack', 'd1:patch', 'd1:prepare_recipe_sysroot', 'd1:configure',
'd1:compile', 'd1:install', 'd1:packagedata', 'd1:package_qa', 'd1:package_write_rpm', 'd1:package_write_ipk',
'd1:populate_sysroot', 'd1:build']
self.assertEqual(set(tasks), set(expected))
def test_no_setscenevalid_withdeps(self):
with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
cmd = ["bitbake", "b1"]
sstatevalid = ""
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
expected = ['a1:' + x for x in self.alltasks] + ['b1:' + x for x in self.alltasks]
expected.remove('a1:build')
expected.remove('a1:package_qa')
self.assertEqual(set(tasks), set(expected))
def test_single_a1_setscenevalid_withdeps(self):
with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
cmd = ["bitbake", "b1"]
sstatevalid = "a1:do_package"
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
expected = ['a1:package_setscene', 'a1:fetch', 'a1:unpack', 'a1:patch', 'a1:prepare_recipe_sysroot', 'a1:configure',
'a1:compile', 'a1:install', 'a1:packagedata', 'a1:package_write_rpm', 'a1:package_write_ipk',
'a1:populate_sysroot'] + ['b1:' + x for x in self.alltasks]
self.assertEqual(set(tasks), set(expected))
def test_single_b1_setscenevalid_withdeps(self):
with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
cmd = ["bitbake", "b1"]
sstatevalid = "b1:do_package"
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
expected = ['a1:package', 'a1:fetch', 'a1:unpack', 'a1:patch', 'a1:prepare_recipe_sysroot', 'a1:configure',
'a1:compile', 'a1:install', 'a1:packagedata', 'a1:package_write_rpm', 'a1:package_write_ipk',
'a1:populate_sysroot', 'b1:package_setscene'] + ['b1:' + x for x in self.alltasks]
expected.remove('b1:package')
self.assertEqual(set(tasks), set(expected))
def test_intermediate_setscenevalid_withdeps(self):
with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
cmd = ["bitbake", "b1"]
sstatevalid = "a1:do_package a1:do_populate_sysroot b1:do_package"
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
expected = ['a1:package_setscene', 'a1:packagedata', 'a1:package_write_rpm', 'a1:package_write_ipk',
'a1:populate_sysroot_setscene', 'b1:package_setscene'] + ['b1:' + x for x in self.alltasks]
expected.remove('b1:package')
self.assertEqual(set(tasks), set(expected))
def test_all_setscenevalid_withdeps(self):
with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
cmd = ["bitbake", "b1"]
sstatevalid = self.a1_sstatevalid + " " + self.b1_sstatevalid
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
expected = ['a1:package_write_ipk_setscene', 'a1:package_write_rpm_setscene', 'a1:packagedata_setscene',
'b1:build', 'a1:populate_sysroot_setscene', 'b1:package_write_ipk_setscene', 'b1:package_write_rpm_setscene',
'b1:packagedata_setscene', 'b1:package_qa_setscene', 'b1:populate_sysroot_setscene']
self.assertEqual(set(tasks), set(expected))
def test_multiconfig_setscene_optimise(self):
with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
extraenv = {
"BBMULTICONFIG" : "mc1 mc2",
"BB_SIGNATURE_HANDLER" : "basic"
}
cmd = ["bitbake", "b1", "mc:mc1:b1", "mc:mc2:b1"]
setscenetasks = ['package_write_ipk_setscene', 'package_write_rpm_setscene', 'packagedata_setscene',
'populate_sysroot_setscene', 'package_qa_setscene']
sstatevalid = ""
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv)
expected = ['a1:' + x for x in self.alltasks] + ['b1:' + x for x in self.alltasks] + \
['mc1:b1:' + x for x in setscenetasks] + ['mc1:a1:' + x for x in setscenetasks] + \
['mc2:b1:' + x for x in setscenetasks] + ['mc2:a1:' + x for x in setscenetasks] + \
['mc1:b1:build', 'mc2:b1:build']
for x in ['mc1:a1:package_qa_setscene', 'mc2:a1:package_qa_setscene', 'a1:build', 'a1:package_qa']:
expected.remove(x)
self.assertEqual(set(tasks), set(expected))
@unittest.skipIf(sys.version_info < (3, 5, 0), 'Python 3.5 or later required')
def test_hashserv_single(self):
with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
extraenv = {
"BB_HASHSERVE" : "auto",
"BB_SIGNATURE_HANDLER" : "TestEquivHash"
}
cmd = ["bitbake", "a1", "b1"]
setscenetasks = ['package_write_ipk_setscene', 'package_write_rpm_setscene', 'packagedata_setscene',
'populate_sysroot_setscene', 'package_qa_setscene']
sstatevalid = ""
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
expected = ['a1:' + x for x in self.alltasks] + ['b1:' + x for x in self.alltasks]
self.assertEqual(set(tasks), set(expected))
cmd = ["bitbake", "a1", "-c", "install", "-f"]
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
expected = ['a1:install']
self.assertEqual(set(tasks), set(expected))
cmd = ["bitbake", "a1", "b1"]
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
expected = ['a1:populate_sysroot', 'a1:package', 'a1:package_write_rpm_setscene', 'a1:packagedata_setscene',
'a1:package_write_ipk_setscene', 'a1:package_qa_setscene', 'a1:build']
self.assertEqual(set(tasks), set(expected))
self.shutdown(tempdir)
@unittest.skipIf(sys.version_info < (3, 5, 0), 'Python 3.5 or later required')
def test_hashserv_double(self):
with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
extraenv = {
"BB_HASHSERVE" : "auto",
"BB_SIGNATURE_HANDLER" : "TestEquivHash"
}
cmd = ["bitbake", "a1", "b1", "e1"]
setscenetasks = ['package_write_ipk_setscene', 'package_write_rpm_setscene', 'packagedata_setscene',
'populate_sysroot_setscene', 'package_qa_setscene']
sstatevalid = ""
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
expected = ['a1:' + x for x in self.alltasks] + ['b1:' + x for x in self.alltasks] + ['e1:' + x for x in self.alltasks]
self.assertEqual(set(tasks), set(expected))
cmd = ["bitbake", "a1", "b1", "-c", "install", "-fn"]
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
cmd = ["bitbake", "e1"]
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
expected = ['a1:package', 'a1:install', 'b1:package', 'b1:install', 'a1:populate_sysroot', 'b1:populate_sysroot',
'a1:package_write_ipk_setscene', 'b1:packagedata_setscene', 'b1:package_write_rpm_setscene',
'a1:package_write_rpm_setscene', 'b1:package_write_ipk_setscene', 'a1:packagedata_setscene']
self.assertEqual(set(tasks), set(expected))
self.shutdown(tempdir)
@unittest.skipIf(sys.version_info < (3, 5, 0), 'Python 3.5 or later required')
def test_hashserv_multiple_setscene(self):
# Runs e1:do_package_setscene twice
with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
extraenv = {
"BB_HASHSERVE" : "auto",
"BB_SIGNATURE_HANDLER" : "TestEquivHash"
}
cmd = ["bitbake", "a1", "b1", "e1"]
setscenetasks = ['package_write_ipk_setscene', 'package_write_rpm_setscene', 'packagedata_setscene',
'populate_sysroot_setscene', 'package_qa_setscene']
sstatevalid = ""
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
expected = ['a1:' + x for x in self.alltasks] + ['b1:' + x for x in self.alltasks] + ['e1:' + x for x in self.alltasks]
self.assertEqual(set(tasks), set(expected))
cmd = ["bitbake", "a1", "b1", "-c", "install", "-fn"]
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
cmd = ["bitbake", "e1"]
sstatevalid = "e1:do_package"
tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True, slowtasks="a1:populate_sysroot b1:populate_sysroot")
expected = ['a1:package', 'a1:install', 'b1:package', 'b1:install', 'a1:populate_sysroot', 'b1:populate_sysroot',
'a1:package_write_ipk_setscene', 'b1:packagedata_setscene', 'b1:package_write_rpm_setscene',
'a1:package_write_rpm_setscene', 'b1:package_write_ipk_setscene', 'a1:packagedata_setscene',
'e1:package_setscene']
self.assertEqual(set(tasks), set(expected))
for i in expected:
self.assertEqual(tasks.count(i), 1, "%s not in task list once" % i)
self.shutdown(tempdir)
def shutdown(self, tempdir):
# Wait for the hashserve socket to disappear else we'll see races with the tempdir cleanup
while os.path.exists(tempdir + "/hashserve.sock"):
time.sleep(0.5)

View File

@@ -1,9 +1,22 @@
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# BitBake Tests for utils.py
#
# Copyright (C) 2012 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
#
import unittest
@@ -29,10 +42,6 @@ class VerCmpString(unittest.TestCase):
self.assertTrue(result < 0)
result = bb.utils.vercmp_string('1.1', '1.0+1.1-beta1')
self.assertTrue(result > 0)
result = bb.utils.vercmp_string('1a', '1a1')
self.assertTrue(result < 0)
result = bb.utils.vercmp_string('1a1', '1a')
self.assertTrue(result > 0)
result = bb.utils.vercmp_string('1.', '1.1')
self.assertTrue(result < 0)
result = bb.utils.vercmp_string('1.1', '1.')
@@ -103,32 +112,6 @@ class Path(unittest.TestCase):
result = bb.utils._check_unsafe_delete_path(arg1)
self.assertEqual(result, correctresult, '_check_unsafe_delete_path("%s") != %s' % (arg1, correctresult))
class Checksum(unittest.TestCase):
filler = b"Shiver me timbers square-rigged spike Gold Road galleon bilge water boatswain wherry jack pirate. Mizzenmast rum lad Privateer jack salmagundi hang the jib piracy Pieces of Eight Corsair. Parrel marooned black spot yawl provost quarterdeck cable no prey, no pay spirits lateen sail."
def test_md5(self):
import hashlib
with tempfile.NamedTemporaryFile() as f:
f.write(self.filler)
f.flush()
checksum = bb.utils.md5_file(f.name)
self.assertEqual(checksum, "bd572cd5de30a785f4efcb6eaf5089e3")
def test_sha1(self):
import hashlib
with tempfile.NamedTemporaryFile() as f:
f.write(self.filler)
f.flush()
checksum = bb.utils.sha1_file(f.name)
self.assertEqual(checksum, "249eb8fd654732ea836d5e702d7aa567898eca71")
def test_sha256(self):
import hashlib
with tempfile.NamedTemporaryFile() as f:
f.write(self.filler)
f.flush()
checksum = bb.utils.sha256_file(f.name)
self.assertEqual(checksum, "fcfbae8bf6b721dbb9d2dc6a9334a58f2031a9a9b302999243f99da4d7f12d0f")
class EditMetadataFile(unittest.TestCase):
_origfile = """

View File

@@ -4,8 +4,18 @@
# Copyright (C) 2011 Mentor Graphics Corporation
# Copyright (C) 2006-2012 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import logging
import os

View File

@@ -3,5 +3,15 @@
#
# Copyright (C) 2006-2007 Richard Purdie
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.

View File

@@ -3,8 +3,18 @@
#
# Copyright (C) 2013 Intel Corporation
#
# SPDX-License-Identifier: GPL-2.0-only
# 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.
import sys
import bb
@@ -646,9 +656,6 @@ class ORMWrapper(object):
Target_Installed_Package.objects.create(target = target_obj, package = packagedict[p]['object'])
packagedeps_objs = []
pattern_so = re.compile(r'.*\.so(\.\d*)?$')
pattern_lib = re.compile(r'.*\-suffix(\d*)?$')
pattern_ko = re.compile(r'^kernel-module-.*')
for p in packagedict:
for (px,deptype) in packagedict[p]['depends']:
if deptype == 'depends':
@@ -657,13 +664,6 @@ class ORMWrapper(object):
tdeptype = Package_Dependency.TYPE_TRECOMMENDS
try:
# Skip known non-package objects like libraries and kernel modules
if pattern_so.match(px) or pattern_lib.match(px):
logger.info("Toaster does not add library file dependencies to packages (%s,%s)", p, px)
continue
if pattern_ko.match(px):
logger.info("Toaster does not add kernel module dependencies to packages (%s,%s)", p, px)
continue
packagedeps_objs.append(Package_Dependency(
package = packagedict[p]['object'],
depends_on = packagedict[px]['object'],

Some files were not shown because too many files have changed in this diff Show More