mirror of
git://git.yoctoproject.org/poky.git
synced 2025-07-19 21:09:03 +02:00

The purpouse of this function was to check dependencies for building a hybrid iso and build them using bitbake if not found. Calling bitbake in this context means this wic plugin itself cannot be instrumented inside bitbake recipes which is undesirable, the benefits of this are clear: there is no need to maintain outside scripts to generate an iso using wic and the isohybrid building logic can be further abstracted away into an isohybrid.bbclass in the future which can be easily inherited or something similar. So remove the function and add all dependencies to NATIVE_RECIPES so that wic can print useful errors when they're not built. To automate building the isohybrid image dependencies, add the following somewhere in your image build inheritence hierarcy (or maybe create a bbclass in the future to do these sort of things automatically): DEPENDS += "syslinux syslinux-native cdrtools-native e2fsprogs-native \ parted-native dosfstools-native mtools-native grub-efi-native" (From OE-Core rev: ba4346069ab87f1cf942d1928f911eca6a9d65cd) Signed-off-by: Ioan-Adrian Ratiu <adrian.ratiu@ni.com> Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
249 lines
7.9 KiB
Python
249 lines
7.9 KiB
Python
# ex:ts=4:sw=4:sts=4:et
|
|
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
|
|
#
|
|
# Copyright (c) 2013, Intel Corporation.
|
|
# All rights reserved.
|
|
#
|
|
# 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.
|
|
#
|
|
# DESCRIPTION
|
|
# This module provides a place to collect various wic-related utils
|
|
# for the OpenEmbedded Image Tools.
|
|
#
|
|
# AUTHORS
|
|
# Tom Zanussi <tom.zanussi (at] linux.intel.com>
|
|
#
|
|
"""Miscellaneous functions."""
|
|
|
|
import os
|
|
import re
|
|
from collections import defaultdict
|
|
from distutils import spawn
|
|
|
|
from wic import msger
|
|
from wic.utils import runner
|
|
|
|
# executable -> recipe pairs for exec_native_cmd
|
|
NATIVE_RECIPES = {"bmaptool": "bmap-tools",
|
|
"grub-mkimage": "grub-efi-native",
|
|
"isohybrid": "syslinux",
|
|
"mcopy": "mtools",
|
|
"mkdosfs": "dosfstools",
|
|
"mkisofs": "cdrtools",
|
|
"mkfs.btrfs": "btrfs-tools",
|
|
"mkfs.ext2": "e2fsprogs",
|
|
"mkfs.ext3": "e2fsprogs",
|
|
"mkfs.ext4": "e2fsprogs",
|
|
"mkfs.vfat": "dosfstools",
|
|
"mksquashfs": "squashfs-tools",
|
|
"mkswap": "util-linux",
|
|
"mmd": "syslinux",
|
|
"parted": "parted",
|
|
"sfdisk": "util-linux",
|
|
"sgdisk": "gptfdisk",
|
|
"syslinux": "syslinux"
|
|
}
|
|
|
|
def _exec_cmd(cmd_and_args, as_shell=False, catch=3):
|
|
"""
|
|
Execute command, catching stderr, stdout
|
|
|
|
Need to execute as_shell if the command uses wildcards
|
|
"""
|
|
msger.debug("_exec_cmd: %s" % cmd_and_args)
|
|
args = cmd_and_args.split()
|
|
msger.debug(args)
|
|
|
|
if as_shell:
|
|
ret, out = runner.runtool(cmd_and_args, catch)
|
|
else:
|
|
ret, out = runner.runtool(args, catch)
|
|
out = out.strip()
|
|
msger.debug("_exec_cmd: output for %s (rc = %d): %s" % \
|
|
(cmd_and_args, ret, out))
|
|
|
|
return (ret, out)
|
|
|
|
|
|
def exec_cmd(cmd_and_args, as_shell=False, catch=3):
|
|
"""
|
|
Execute command, catching stderr, stdout
|
|
|
|
Exits if rc non-zero
|
|
"""
|
|
ret, out = _exec_cmd(cmd_and_args, as_shell, catch)
|
|
|
|
if ret != 0:
|
|
msger.error("exec_cmd: %s returned '%s' instead of 0" % \
|
|
(cmd_and_args, ret))
|
|
|
|
return out
|
|
|
|
def exec_native_cmd(cmd_and_args, native_sysroot, catch=3, pseudo=""):
|
|
"""
|
|
Execute native command, catching stderr, stdout
|
|
|
|
Need to execute as_shell if the command uses wildcards
|
|
|
|
Always need to execute native commands as_shell
|
|
"""
|
|
# The reason -1 is used is because there may be "export" commands.
|
|
args = cmd_and_args.split(';')[-1].split()
|
|
msger.debug(args)
|
|
|
|
if pseudo:
|
|
cmd_and_args = pseudo + cmd_and_args
|
|
native_paths = \
|
|
"%s/sbin:%s/usr/sbin:%s/usr/bin" % \
|
|
(native_sysroot, native_sysroot, native_sysroot)
|
|
native_cmd_and_args = "export PATH=%s:$PATH;%s" % \
|
|
(native_paths, cmd_and_args)
|
|
msger.debug("exec_native_cmd: %s" % cmd_and_args)
|
|
|
|
# If the command isn't in the native sysroot say we failed.
|
|
if spawn.find_executable(args[0], native_paths):
|
|
ret, out = _exec_cmd(native_cmd_and_args, True, catch)
|
|
else:
|
|
ret = 127
|
|
|
|
prog = args[0]
|
|
# shell command-not-found
|
|
if ret == 127 \
|
|
or (pseudo and ret == 1 and out == "Can't find '%s' in $PATH." % prog):
|
|
msg = "A native program %s required to build the image "\
|
|
"was not found (see details above).\n\n" % prog
|
|
recipe = NATIVE_RECIPES.get(prog)
|
|
if recipe:
|
|
msg += "Please bake it with 'bitbake %s-native' "\
|
|
"and try again.\n" % recipe
|
|
else:
|
|
msg += "Wic failed to find a recipe to build native %s. Please "\
|
|
"file a bug against wic.\n" % prog
|
|
msger.error(msg)
|
|
if out:
|
|
msger.debug('"%s" output: %s' % (args[0], out))
|
|
|
|
if ret != 0:
|
|
msger.error("exec_cmd: '%s' returned '%s' instead of 0" % \
|
|
(cmd_and_args, ret))
|
|
|
|
return ret, out
|
|
|
|
BOOTDD_EXTRA_SPACE = 16384
|
|
|
|
class BitbakeVars(defaultdict):
|
|
"""
|
|
Container for Bitbake variables.
|
|
"""
|
|
def __init__(self):
|
|
defaultdict.__init__(self, dict)
|
|
|
|
# default_image and vars_dir attributes should be set from outside
|
|
self.default_image = None
|
|
self.vars_dir = None
|
|
|
|
def _parse_line(self, line, image, matcher=re.compile(r"^(\w+)=(.+)")):
|
|
"""
|
|
Parse one line from bitbake -e output or from .env file.
|
|
Put result key-value pair into the storage.
|
|
"""
|
|
if "=" not in line:
|
|
return
|
|
match = matcher.match(line)
|
|
if not match:
|
|
return
|
|
key, val = match.groups()
|
|
self[image][key] = val.strip('"')
|
|
|
|
def get_var(self, var, image=None):
|
|
"""
|
|
Get bitbake variable from 'bitbake -e' output or from .env file.
|
|
This is a lazy method, i.e. it runs bitbake or parses file only when
|
|
only when variable is requested. It also caches results.
|
|
"""
|
|
if not image:
|
|
image = self.default_image
|
|
|
|
if image not in self:
|
|
if image and self.vars_dir:
|
|
fname = os.path.join(self.vars_dir, image + '.env')
|
|
if os.path.isfile(fname):
|
|
# parse .env file
|
|
with open(fname) as varsfile:
|
|
for line in varsfile:
|
|
self._parse_line(line, image)
|
|
else:
|
|
print("Couldn't get bitbake variable from %s." % fname)
|
|
print("File %s doesn't exist." % fname)
|
|
return
|
|
else:
|
|
# Get bitbake -e output
|
|
cmd = "bitbake -e"
|
|
if image:
|
|
cmd += " %s" % image
|
|
|
|
log_level = msger.get_loglevel()
|
|
msger.set_loglevel('normal')
|
|
ret, lines = _exec_cmd(cmd)
|
|
msger.set_loglevel(log_level)
|
|
|
|
if ret:
|
|
print("Couldn't get '%s' output." % cmd)
|
|
print("Bitbake failed with error:\n%s\n" % lines)
|
|
return
|
|
|
|
# Parse bitbake -e output
|
|
for line in lines.split('\n'):
|
|
self._parse_line(line, image)
|
|
|
|
# Make first image a default set of variables
|
|
images = [key for key in self if key]
|
|
if len(images) == 1:
|
|
self[None] = self[image]
|
|
|
|
return self[image].get(var)
|
|
|
|
# Create BB_VARS singleton
|
|
BB_VARS = BitbakeVars()
|
|
|
|
def get_bitbake_var(var, image=None):
|
|
"""
|
|
Provide old get_bitbake_var API by wrapping
|
|
get_var method of BB_VARS singleton.
|
|
"""
|
|
return BB_VARS.get_var(var, image)
|
|
|
|
def parse_sourceparams(sourceparams):
|
|
"""
|
|
Split sourceparams string of the form key1=val1[,key2=val2,...]
|
|
into a dict. Also accepts valueless keys i.e. without =.
|
|
|
|
Returns dict of param key/val pairs (note that val may be None).
|
|
"""
|
|
params_dict = {}
|
|
|
|
params = sourceparams.split(',')
|
|
if params:
|
|
for par in params:
|
|
if not par:
|
|
continue
|
|
if not '=' in par:
|
|
key = par
|
|
val = None
|
|
else:
|
|
key, val = par.split('=')
|
|
params_dict[key] = val
|
|
|
|
return params_dict
|