summaryrefslogtreecommitdiffstats
path: root/scripts/lib/bsp/kernel.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/lib/bsp/kernel.py')
-rw-r--r--scripts/lib/bsp/kernel.py1069
1 files changed, 0 insertions, 1069 deletions
diff --git a/scripts/lib/bsp/kernel.py b/scripts/lib/bsp/kernel.py
deleted file mode 100644
index a3ee325a8f..0000000000
--- a/scripts/lib/bsp/kernel.py
+++ /dev/null
@@ -1,1069 +0,0 @@
-# ex:ts=4:sw=4:sts=4:et
-# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
-#
-# Copyright (c) 2012, 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 implements the kernel-related functions used by
-# 'yocto-kernel' to manage kernel config items and patches for Yocto
-# BSPs.
-#
-# AUTHORS
-# Tom Zanussi <tom.zanussi (at] intel.com>
-#
-
-import sys
-import os
-import shutil
-from .tags import *
-import glob
-import subprocess
-from .engine import create_context
-
-def find_bblayers():
- """
- Find and return a sanitized list of the layers found in BBLAYERS.
- """
- try:
- builddir = os.environ["BUILDDIR"]
- except KeyError:
- print("BUILDDIR not found, exiting. (Did you forget to source oe-init-build-env?)")
- sys.exit(1)
- bblayers_conf = os.path.join(builddir, "conf/bblayers.conf")
-
- layers = []
-
- bitbake_env_cmd = "bitbake -e"
- bitbake_env_lines = subprocess.Popen(bitbake_env_cmd, shell=True,
- stdout=subprocess.PIPE).stdout.read().decode('utf-8')
-
- if not bitbake_env_lines:
- print("Couldn't get '%s' output, exiting." % bitbake_env_cmd)
- sys.exit(1)
-
- for line in bitbake_env_lines.split('\n'):
- bblayers = get_line_val(line, "BBLAYERS")
- if (bblayers):
- break
-
- if not bblayers:
- print("Couldn't find BBLAYERS in %s output, exiting." % bitbake_env_cmd)
- sys.exit(1)
-
- raw_layers = bblayers.split()
-
- for layer in raw_layers:
- if layer == 'BBLAYERS' or '=' in layer:
- continue
- layers.append(layer)
-
- return layers
-
-
-def get_line_val(line, key):
- """
- Extract the value from the VAR="val" string
- """
- if line.startswith(key + "="):
- stripped_line = line.split('=')[1]
- stripped_line = stripped_line.replace('\"', '')
- return stripped_line
- return None
-
-
-def find_meta_layer():
- """
- Find and return the meta layer in BBLAYERS.
- """
- layers = find_bblayers()
-
- for layer in layers:
- if layer.endswith("meta"):
- return layer
-
- return None
-
-
-def find_bsp_layer(machine):
- """
- Find and return a machine's BSP layer in BBLAYERS.
- """
- layers = find_bblayers()
-
- for layer in layers:
- if layer.endswith(machine):
- return layer
-
- print("Unable to find the BSP layer for machine %s." % machine)
- print("Please make sure it is listed in bblayers.conf")
- sys.exit(1)
-
-
-def gen_choices_str(choices):
- """
- Generate a numbered list of choices from a list of choices for
- display to the user.
- """
- choices_str = ""
-
- for i, choice in enumerate(choices):
- choices_str += "\t" + str(i + 1) + ") " + choice + "\n"
-
- return choices_str
-
-
-def open_user_file(scripts_path, machine, userfile, mode):
- """
- Find one of the user files (user-config.cfg, user-patches.scc)
- associated with the machine (could be in files/,
- linux-yocto-custom/, etc). Returns the open file if found, None
- otherwise.
-
- The caller is responsible for closing the file returned.
- """
- layer = find_bsp_layer(machine)
- linuxdir = os.path.join(layer, "recipes-kernel/linux")
- linuxdir_list = os.listdir(linuxdir)
- for fileobj in linuxdir_list:
- fileobj_path = os.path.join(linuxdir, fileobj)
- if os.path.isdir(fileobj_path):
- userfile_name = os.path.join(fileobj_path, userfile)
- try:
- f = open(userfile_name, mode)
- return f
- except IOError:
- continue
- return None
-
-
-def read_config_items(scripts_path, machine):
- """
- Find and return a list of config items (CONFIG_XXX) in a machine's
- user-defined config fragment [${machine}-user-config.cfg].
- """
- config_items = []
-
- f = open_user_file(scripts_path, machine, machine+"-user-config.cfg", "r")
- lines = f.readlines()
- for line in lines:
- s = line.strip()
- if s and not s.startswith("#"):
- config_items.append(s)
- f.close()
-
- return config_items
-
-
-def write_config_items(scripts_path, machine, config_items):
- """
- Write (replace) the list of config items (CONFIG_XXX) in a
- machine's user-defined config fragment [${machine}=user-config.cfg].
- """
- f = open_user_file(scripts_path, machine, machine+"-user-config.cfg", "w")
- for item in config_items:
- f.write(item + "\n")
- f.close()
-
- kernel_contents_changed(scripts_path, machine)
-
-
-def yocto_kernel_config_list(scripts_path, machine):
- """
- Display the list of config items (CONFIG_XXX) in a machine's
- user-defined config fragment [${machine}-user-config.cfg].
- """
- config_items = read_config_items(scripts_path, machine)
-
- print("The current set of machine-specific kernel config items for %s is:" % machine)
- print(gen_choices_str(config_items))
-
-
-def yocto_kernel_config_rm(scripts_path, machine):
- """
- Display the list of config items (CONFIG_XXX) in a machine's
- user-defined config fragment [${machine}-user-config.cfg], prompt the user
- for one or more to remove, and remove them.
- """
- config_items = read_config_items(scripts_path, machine)
-
- print("Specify the kernel config items to remove:")
- inp = input(gen_choices_str(config_items))
- rm_choices = inp.split()
- rm_choices.sort()
-
- removed = []
-
- for choice in reversed(rm_choices):
- try:
- idx = int(choice) - 1
- except ValueError:
- print("Invalid choice (%s), exiting" % choice)
- sys.exit(1)
- if idx < 0 or idx >= len(config_items):
- print("Invalid choice (%d), exiting" % (idx + 1))
- sys.exit(1)
- removed.append(config_items.pop(idx))
-
- write_config_items(scripts_path, machine, config_items)
-
- print("Removed items:")
- for r in removed:
- print("\t%s" % r)
-
-
-def yocto_kernel_config_add(scripts_path, machine, config_items):
- """
- Add one or more config items (CONFIG_XXX) to a machine's
- user-defined config fragment [${machine}-user-config.cfg].
- """
- new_items = []
- dup_items = []
-
- cur_items = read_config_items(scripts_path, machine)
-
- for item in config_items:
- if not item.startswith("CONFIG") or (not "=y" in item and not "=m" in item):
- print("Invalid config item (%s), exiting" % item)
- sys.exit(1)
- if item not in cur_items and item not in new_items:
- new_items.append(item)
- else:
- dup_items.append(item)
-
- if len(new_items) > 0:
- cur_items.extend(new_items)
- write_config_items(scripts_path, machine, cur_items)
- print("Added item%s:" % ("" if len(new_items)==1 else "s"))
- for n in new_items:
- print("\t%s" % n)
-
- if len(dup_items) > 0:
- output="The following item%s already exist%s in the current configuration, ignoring %s:" % \
- (("","s", "it") if len(dup_items)==1 else ("s", "", "them" ))
- print(output)
- for n in dup_items:
- print("\t%s" % n)
-
-def find_current_kernel(bsp_layer, machine):
- """
- Determine the kernel and version currently being used in the BSP.
- """
- machine_conf = os.path.join(bsp_layer, "conf/machine/" + machine + ".conf")
-
- preferred_kernel = preferred_kernel_version = preferred_version_varname = None
-
- f = open(machine_conf, "r")
- lines = f.readlines()
- for line in lines:
- if line.strip().startswith("PREFERRED_PROVIDER_virtual/kernel"):
- preferred_kernel = line.split()[-1]
- preferred_kernel = preferred_kernel.replace('\"','')
- preferred_version_varname = "PREFERRED_VERSION_" + preferred_kernel
- if preferred_version_varname and line.strip().startswith(preferred_version_varname):
- preferred_kernel_version = line.split()[-1]
- preferred_kernel_version = preferred_kernel_version.replace('\"','')
- preferred_kernel_version = preferred_kernel_version.replace('%','')
-
- if preferred_kernel and preferred_kernel_version:
- return preferred_kernel + "_" + preferred_kernel_version
- elif preferred_kernel:
- return preferred_kernel
-
-
-def find_filesdir(scripts_path, machine):
- """
- Find the name of the 'files' dir associated with the machine
- (could be in files/, linux-yocto-custom/, etc). Returns the name
- of the files dir if found, None otherwise.
- """
- layer = find_bsp_layer(machine)
- filesdir = None
- linuxdir = os.path.join(layer, "recipes-kernel/linux")
- linuxdir_list = os.listdir(linuxdir)
- for fileobj in linuxdir_list:
- fileobj_path = os.path.join(linuxdir, fileobj)
- if os.path.isdir(fileobj_path):
- # this could be files/ or linux-yocto-custom/, we have no way of distinguishing
- # so we take the first (and normally only) dir we find as the 'filesdir'
- filesdir = fileobj_path
-
- return filesdir
-
-
-def read_patch_items(scripts_path, machine):
- """
- Find and return a list of patch items in a machine's user-defined
- patch list [${machine}-user-patches.scc].
- """
- patch_items = []
-
- f = open_user_file(scripts_path, machine, machine+"-user-patches.scc", "r")
- lines = f.readlines()
- for line in lines:
- s = line.strip()
- if s and not s.startswith("#"):
- fields = s.split()
- if not fields[0] == "patch":
- continue
- patch_items.append(fields[1])
- f.close()
-
- return patch_items
-
-
-def write_patch_items(scripts_path, machine, patch_items):
- """
- Write (replace) the list of patches in a machine's user-defined
- patch list [${machine}-user-patches.scc].
- """
- f = open_user_file(scripts_path, machine, machine+"-user-patches.scc", "w")
- for item in patch_items:
- f.write("patch " + item + "\n")
- f.close()
-
- kernel_contents_changed(scripts_path, machine)
-
-
-def yocto_kernel_patch_list(scripts_path, machine):
- """
- Display the list of patches in a machine's user-defined patch list
- [${machine}-user-patches.scc].
- """
- patches = read_patch_items(scripts_path, machine)
-
- print("The current set of machine-specific patches for %s is:" % machine)
- print(gen_choices_str(patches))
-
-
-def yocto_kernel_patch_rm(scripts_path, machine):
- """
- Remove one or more patches from a machine's user-defined patch
- list [${machine}-user-patches.scc].
- """
- patches = read_patch_items(scripts_path, machine)
-
- print("Specify the patches to remove:")
- inp = input(gen_choices_str(patches))
- rm_choices = inp.split()
- rm_choices.sort()
-
- removed = []
-
- filesdir = find_filesdir(scripts_path, machine)
- if not filesdir:
- print("Couldn't rm patch(es) since we couldn't find a 'files' dir")
- sys.exit(1)
-
- for choice in reversed(rm_choices):
- try:
- idx = int(choice) - 1
- except ValueError:
- print("Invalid choice (%s), exiting" % choice)
- sys.exit(1)
- if idx < 0 or idx >= len(patches):
- print("Invalid choice (%d), exiting" % (idx + 1))
- sys.exit(1)
- filesdir_patch = os.path.join(filesdir, patches[idx])
- if os.path.isfile(filesdir_patch):
- os.remove(filesdir_patch)
- removed.append(patches[idx])
- patches.pop(idx)
-
- write_patch_items(scripts_path, machine, patches)
-
- print("Removed patches:")
- for r in removed:
- print("\t%s" % r)
-
-
-def yocto_kernel_patch_add(scripts_path, machine, patches):
- """
- Add one or more patches to a machine's user-defined patch list
- [${machine}-user-patches.scc].
- """
- existing_patches = read_patch_items(scripts_path, machine)
-
- for patch in patches:
- if os.path.basename(patch) in existing_patches:
- print("Couldn't add patch (%s) since it's already been added" % os.path.basename(patch))
- sys.exit(1)
-
- filesdir = find_filesdir(scripts_path, machine)
- if not filesdir:
- print("Couldn't add patch (%s) since we couldn't find a 'files' dir to add it to" % os.path.basename(patch))
- sys.exit(1)
-
- new_patches = []
-
- for patch in patches:
- if not os.path.isfile(patch):
- print("Couldn't find patch (%s), exiting" % patch)
- sys.exit(1)
- basename = os.path.basename(patch)
- filesdir_patch = os.path.join(filesdir, basename)
- shutil.copyfile(patch, filesdir_patch)
- new_patches.append(basename)
-
- cur_items = read_patch_items(scripts_path, machine)
- cur_items.extend(new_patches)
- write_patch_items(scripts_path, machine, cur_items)
-
- print("Added patches:")
- for n in new_patches:
- print("\t%s" % n)
-
-
-def inc_pr(line):
- """
- Add 1 to the PR value in the given bbappend PR line. For the PR
- lines in kernel .bbappends after modifications. Handles PRs of
- the form PR := "${PR}.1" as well as PR = "r0".
- """
- idx = line.find("\"")
-
- pr_str = line[idx:]
- pr_str = pr_str.replace('\"','')
- fields = pr_str.split('.')
- if len(fields) > 1:
- fields[1] = str(int(fields[1]) + 1)
- pr_str = "\"" + '.'.join(fields) + "\"\n"
- else:
- pr_val = pr_str[1:]
- pr_str = "\"" + "r" + str(int(pr_val) + 1) + "\"\n"
- idx2 = line.find("\"", idx + 1)
- line = line[:idx] + pr_str
-
- return line
-
-
-def kernel_contents_changed(scripts_path, machine):
- """
- Do what we need to do to notify the system that the kernel
- recipe's contents have changed.
- """
- layer = find_bsp_layer(machine)
-
- kernel = find_current_kernel(layer, machine)
- if not kernel:
- print("Couldn't determine the kernel for this BSP, exiting.")
- sys.exit(1)
-
- kernel_bbfile = os.path.join(layer, "recipes-kernel/linux/" + kernel + ".bbappend")
- if not os.path.isfile(kernel_bbfile):
- kernel_bbfile = os.path.join(layer, "recipes-kernel/linux/" + kernel + ".bb")
- if not os.path.isfile(kernel_bbfile):
- return
- kernel_bbfile_prev = kernel_bbfile + ".prev"
- shutil.copyfile(kernel_bbfile, kernel_bbfile_prev)
-
- ifile = open(kernel_bbfile_prev, "r")
- ofile = open(kernel_bbfile, "w")
- ifile_lines = ifile.readlines()
- for ifile_line in ifile_lines:
- if ifile_line.strip().startswith("PR"):
- ifile_line = inc_pr(ifile_line)
- ofile.write(ifile_line)
- ofile.close()
- ifile.close()
-
-
-def kernels(context):
- """
- Return the list of available kernels in the BSP i.e. corresponding
- to the kernel .bbappends found in the layer.
- """
- archdir = os.path.join(context["scripts_path"], "lib/bsp/substrate/target/arch/" + context["arch"])
- kerndir = os.path.join(archdir, "recipes-kernel/linux")
- bbglob = os.path.join(kerndir, "*.bbappend")
-
- bbappends = glob.glob(bbglob)
-
- kernels = []
-
- for kernel in bbappends:
- filename = os.path.splitext(os.path.basename(kernel))[0]
- idx = filename.find(CLOSE_TAG)
- if idx != -1:
- filename = filename[idx + len(CLOSE_TAG):].strip()
- kernels.append(filename)
-
- kernels.append("custom")
-
- return kernels
-
-
-def extract_giturl(file):
- """
- Extract the git url of the kernel repo from the kernel recipe's
- SRC_URI.
- """
- url = None
- f = open(file, "r")
- lines = f.readlines()
- for line in lines:
- line = line.strip()
- if line.startswith("SRC_URI"):
- line = line[len("SRC_URI"):].strip()
- if line.startswith("="):
- line = line[1:].strip()
- if line.startswith("\""):
- line = line[1:].strip()
- prot = "git"
- for s in line.split(";"):
- if s.startswith("git://"):
- url = s
- if s.startswith("protocol="):
- prot = s.split("=")[1]
- if url:
- url = prot + url[3:]
- return url
-
-
-def find_giturl(context):
- """
- Find the git url of the kernel repo from the kernel recipe's
- SRC_URI.
- """
- name = context["name"]
- filebase = context["filename"]
- scripts_path = context["scripts_path"]
-
- meta_layer = find_meta_layer()
-
- kerndir = os.path.join(meta_layer, "recipes-kernel/linux")
- bbglob = os.path.join(kerndir, "*.bb")
- bbs = glob.glob(bbglob)
- for kernel in bbs:
- filename = os.path.splitext(os.path.basename(kernel))[0]
- if filename in filebase:
- giturl = extract_giturl(kernel)
- return giturl
-
- return None
-
-
-def read_features(scripts_path, machine):
- """
- Find and return a list of features in a machine's user-defined
- features fragment [${machine}-user-features.scc].
- """
- features = []
-
- f = open_user_file(scripts_path, machine, machine+"-user-features.scc", "r")
- lines = f.readlines()
- for line in lines:
- s = line.strip()
- if s and not s.startswith("#"):
- feature_include = s.split()
- features.append(feature_include[1].strip())
- f.close()
-
- return features
-
-
-def write_features(scripts_path, machine, features):
- """
- Write (replace) the list of feature items in a
- machine's user-defined features fragment [${machine}=user-features.cfg].
- """
- f = open_user_file(scripts_path, machine, machine+"-user-features.scc", "w")
- for item in features:
- f.write("include " + item + "\n")
- f.close()
-
- kernel_contents_changed(scripts_path, machine)
-
-
-def yocto_kernel_feature_list(scripts_path, machine):
- """
- Display the list of features used in a machine's user-defined
- features fragment [${machine}-user-features.scc].
- """
- features = read_features(scripts_path, machine)
-
- print("The current set of machine-specific features for %s is:" % machine)
- print(gen_choices_str(features))
-
-
-def yocto_kernel_feature_rm(scripts_path, machine):
- """
- Display the list of features used in a machine's user-defined
- features fragment [${machine}-user-features.scc], prompt the user
- for one or more to remove, and remove them.
- """
- features = read_features(scripts_path, machine)
-
- print("Specify the features to remove:")
- inp = input(gen_choices_str(features))
- rm_choices = inp.split()
- rm_choices.sort()
-
- removed = []
-
- for choice in reversed(rm_choices):
- try:
- idx = int(choice) - 1
- except ValueError:
- print("Invalid choice (%s), exiting" % choice)
- sys.exit(1)
- if idx < 0 or idx >= len(features):
- print("Invalid choice (%d), exiting" % (idx + 1))
- sys.exit(1)
- removed.append(features.pop(idx))
-
- write_features(scripts_path, machine, features)
-
- print("Removed features:")
- for r in removed:
- print("\t%s" % r)
-
-
-def yocto_kernel_feature_add(scripts_path, machine, features):
- """
- Add one or more features a machine's user-defined features
- fragment [${machine}-user-features.scc].
- """
- new_items = []
-
- for item in features:
- if not item.endswith(".scc"):
- print("Invalid feature (%s), exiting" % item)
- sys.exit(1)
- new_items.append(item)
-
- cur_items = read_features(scripts_path, machine)
- cur_items.extend(new_items)
-
- write_features(scripts_path, machine, cur_items)
-
- print("Added features:")
- for n in new_items:
- print("\t%s" % n)
-
-
-def find_feature_url(git_url):
- """
- Find the url of the kern-features.rc kernel for the kernel repo
- specified from the BSP's kernel recipe SRC_URI.
- """
- feature_url = ""
- if git_url.startswith("git://"):
- git_url = git_url[len("git://"):].strip()
- s = git_url.split("/")
- if s[1].endswith(".git"):
- s[1] = s[1][:len(s[1]) - len(".git")]
- feature_url = "http://" + s[0] + "/cgit/cgit.cgi/" + s[1] + \
- "/plain/meta/cfg/kern-features.rc?h=meta"
-
- return feature_url
-
-
-def find_feature_desc(lines):
- """
- Find the feature description and compatibility in the passed-in
- set of lines. Returns a string string of the form 'desc
- [compat]'.
- """
- desc = "no description available"
- compat = "unknown"
-
- for line in lines:
- idx = line.find("KFEATURE_DESCRIPTION")
- if idx != -1:
- desc = line[idx + len("KFEATURE_DESCRIPTION"):].strip()
- if desc.startswith("\""):
- desc = desc[1:]
- if desc.endswith("\""):
- desc = desc[:-1]
- else:
- idx = line.find("KFEATURE_COMPATIBILITY")
- if idx != -1:
- compat = line[idx + len("KFEATURE_COMPATIBILITY"):].strip()
-
- return desc + " [" + compat + "]"
-
-
-def print_feature_descs(layer, feature_dir):
- """
- Print the feature descriptions for the features in feature_dir.
- """
- kernel_files_features = os.path.join(layer, "recipes-kernel/linux/files/" +
- feature_dir)
- for root, dirs, files in os.walk(kernel_files_features):
- for file in files:
- if file.endswith("~") or file.endswith("#"):
- continue
- if file.endswith(".scc"):
- fullpath = os.path.join(layer, "recipes-kernel/linux/files/" +
- feature_dir + "/" + file)
- f = open(fullpath)
- feature_desc = find_feature_desc(f.readlines())
- print(feature_dir + "/" + file + ": " + feature_desc)
-
-
-def yocto_kernel_available_features_list(scripts_path, machine):
- """
- Display the list of all the kernel features available for use in
- BSPs, as gathered from the set of feature sources.
- """
- layer = find_bsp_layer(machine)
- kernel = find_current_kernel(layer, machine)
- if not kernel:
- print("Couldn't determine the kernel for this BSP, exiting.")
- sys.exit(1)
-
- context = create_context(machine, "arch", scripts_path)
- context["name"] = "name"
- context["filename"] = kernel
- giturl = find_giturl(context)
- feature_url = find_feature_url(giturl)
-
- feature_cmd = "wget -q -O - " + feature_url
- tmp = subprocess.Popen(feature_cmd, shell=True, stdout=subprocess.PIPE).stdout.read().decode('utf-8')
-
- print("The current set of kernel features available to %s is:\n" % machine)
-
- if tmp:
- tmpline = tmp.split("\n")
- in_kernel_options = False
- for line in tmpline:
- if not "=" in line:
- if in_kernel_options:
- break
- if "kernel-options" in line:
- in_kernel_options = True
- continue
- if in_kernel_options:
- feature_def = line.split("=")
- feature_type = feature_def[0].strip()
- feature = feature_def[1].strip()
- desc = get_feature_desc(giturl, feature)
- print("%s: %s" % (feature, desc))
-
- print("[local]")
-
- print_feature_descs(layer, "cfg")
- print_feature_descs(layer, "features")
-
-
-def find_feature_desc_url(git_url, feature):
- """
- Find the url of the kernel feature in the kernel repo specified
- from the BSP's kernel recipe SRC_URI.
- """
- feature_desc_url = ""
- if git_url.startswith("git://"):
- git_url = git_url[len("git://"):].strip()
- s = git_url.split("/")
- if s[1].endswith(".git"):
- s[1] = s[1][:len(s[1]) - len(".git")]
- feature_desc_url = "http://" + s[0] + "/cgit/cgit.cgi/" + s[1] + \
- "/plain/meta/cfg/kernel-cache/" + feature + "?h=meta"
-
- return feature_desc_url
-
-
-def get_feature_desc(git_url, feature):
- """
- Return a feature description of the form 'description [compatibility]
- BSPs, as gathered from the set of feature sources.
- """
- feature_desc_url = find_feature_desc_url(git_url, feature)
- feature_desc_cmd = "wget -q -O - " + feature_desc_url
- tmp = subprocess.Popen(feature_desc_cmd, shell=True, stdout=subprocess.PIPE).stdout.read().decode('utf-8')
-
- return find_feature_desc(tmp.split("\n"))
-
-
-def yocto_kernel_feature_describe(scripts_path, machine, feature):
- """
- Display the description of a specific kernel feature available for
- use in a BSP.
- """
- layer = find_bsp_layer(machine)
-
- kernel = find_current_kernel(layer, machine)
- if not kernel:
- print("Couldn't determine the kernel for this BSP, exiting.")
- sys.exit(1)
-
- context = create_context(machine, "arch", scripts_path)
- context["name"] = "name"
- context["filename"] = kernel
- giturl = find_giturl(context)
-
- desc = get_feature_desc(giturl, feature)
-
- print(desc)
-
-
-def check_feature_name(feature_name):
- """
- Sanity-check the feature name for create/destroy. Return False if not OK.
- """
- if not feature_name.endswith(".scc"):
- print("Invalid feature name (must end with .scc) [%s], exiting" % feature_name)
- return False
-
- if "/" in feature_name:
- print("Invalid feature name (don't specify directory) [%s], exiting" % feature_name)
- return False
-
- return True
-
-
-def check_create_input(feature_items):
- """
- Sanity-check the create input. Return False if not OK.
- """
- if not check_feature_name(feature_items[0]):
- return False
-
- if feature_items[1].endswith(".patch") or feature_items[1].startswith("CONFIG_"):
- print("Missing description and/or compatibilty [%s], exiting" % feature_items[1])
- return False
-
- if feature_items[2].endswith(".patch") or feature_items[2].startswith("CONFIG_"):
- print("Missing description and/or compatibility [%s], exiting" % feature_items[1])
- return False
-
- return True
-
-
-def yocto_kernel_feature_create(scripts_path, machine, feature_items):
- """
- Create a recipe-space kernel feature in a BSP.
- """
- if not check_create_input(feature_items):
- sys.exit(1)
-
- feature = feature_items[0]
- feature_basename = feature.split(".")[0]
- feature_description = feature_items[1]
- feature_compat = feature_items[2]
-
- patches = []
- cfg_items = []
-
- for item in feature_items[3:]:
- if item.endswith(".patch"):
- patches.append(item)
- elif item.startswith("CONFIG"):
- if ("=y" in item or "=m" in item):
- cfg_items.append(item)
- else:
- print("Invalid feature item (must be .patch or CONFIG_*) [%s], exiting" % item)
- sys.exit(1)
-
- feature_dirname = "cfg"
- if patches:
- feature_dirname = "features"
-
- filesdir = find_filesdir(scripts_path, machine)
- if not filesdir:
- print("Couldn't add feature (%s), no 'files' dir found" % feature)
- sys.exit(1)
-
- featdir = os.path.join(filesdir, feature_dirname)
- if not os.path.exists(featdir):
- os.mkdir(featdir)
-
- for patch in patches:
- if not os.path.isfile(patch):
- print("Couldn't find patch (%s), exiting" % patch)
- sys.exit(1)
- basename = os.path.basename(patch)
- featdir_patch = os.path.join(featdir, basename)
- shutil.copyfile(patch, featdir_patch)
-
- new_cfg_filename = os.path.join(featdir, feature_basename + ".cfg")
- new_cfg_file = open(new_cfg_filename, "w")
- for cfg_item in cfg_items:
- new_cfg_file.write(cfg_item + "\n")
- new_cfg_file.close()
-
- new_feature_filename = os.path.join(featdir, feature_basename + ".scc")
- new_feature_file = open(new_feature_filename, "w")
- new_feature_file.write("define KFEATURE_DESCRIPTION \"" + feature_description + "\"\n")
- new_feature_file.write("define KFEATURE_COMPATIBILITY " + feature_compat + "\n\n")
-
- for patch in patches:
- patch_dir, patch_file = os.path.split(patch)
- new_feature_file.write("patch " + patch_file + "\n")
-
- new_feature_file.write("kconf non-hardware " + feature_basename + ".cfg\n")
- new_feature_file.close()
-
- print("Added feature:")
- print("\t%s" % feature_dirname + "/" + feature)
-
-
-def feature_in_use(scripts_path, machine, feature):
- """
- Determine whether the specified feature is in use by the BSP.
- Return True if so, False otherwise.
- """
- features = read_features(scripts_path, machine)
- for f in features:
- if f == feature:
- return True
- return False
-
-
-def feature_remove(scripts_path, machine, feature):
- """
- Remove the specified feature from the available recipe-space
- features defined for the BSP.
- """
- features = read_features(scripts_path, machine)
- new_features = []
- for f in features:
- if f == feature:
- continue
- new_features.append(f)
- write_features(scripts_path, machine, new_features)
-
-
-def yocto_kernel_feature_destroy(scripts_path, machine, feature):
- """
- Remove a recipe-space kernel feature from a BSP.
- """
- if not check_feature_name(feature):
- sys.exit(1)
-
- if feature_in_use(scripts_path, machine, "features/" + feature) or \
- feature_in_use(scripts_path, machine, "cfg/" + feature):
- print("Feature %s is in use (use 'feature rm' to un-use it first), exiting" % feature)
- sys.exit(1)
-
- filesdir = find_filesdir(scripts_path, machine)
- if not filesdir:
- print("Couldn't destroy feature (%s), no 'files' dir found" % feature)
- sys.exit(1)
-
- feature_dirname = "features"
- featdir = os.path.join(filesdir, feature_dirname)
- if not os.path.exists(featdir):
- print("Couldn't find feature directory (%s)" % feature_dirname)
- sys.exit(1)
-
- feature_fqn = os.path.join(featdir, feature)
- if not os.path.exists(feature_fqn):
- feature_dirname = "cfg"
- featdir = os.path.join(filesdir, feature_dirname)
- if not os.path.exists(featdir):
- print("Couldn't find feature directory (%s)" % feature_dirname)
- sys.exit(1)
- feature_fqn = os.path.join(featdir, feature_filename)
- if not os.path.exists(feature_fqn):
- print("Couldn't find feature (%s)" % feature)
- sys.exit(1)
-
- f = open(feature_fqn, "r")
- lines = f.readlines()
- for line in lines:
- s = line.strip()
- if s.startswith("patch ") or s.startswith("kconf "):
- split_line = s.split()
- filename = os.path.join(featdir, split_line[-1])
- if os.path.exists(filename):
- os.remove(filename)
- f.close()
- os.remove(feature_fqn)
-
- feature_remove(scripts_path, machine, feature)
-
- print("Removed feature:")
- print("\t%s" % feature_dirname + "/" + feature)
-
-
-def base_branches(context):
- """
- Return a list of the base branches found in the kernel git repo.
- """
- giturl = find_giturl(context)
-
- print("Getting branches from remote repo %s..." % giturl)
-
- gitcmd = "git ls-remote %s *heads* 2>&1" % (giturl)
- tmp = subprocess.Popen(gitcmd, shell=True, stdout=subprocess.PIPE).stdout.read().decode('utf-8')
-
- branches = []
-
- if tmp:
- tmpline = tmp.split("\n")
- for line in tmpline:
- if len(line)==0:
- break;
- if not line.endswith("base"):
- continue;
- idx = line.find("refs/heads/")
- kbranch = line[idx + len("refs/heads/"):]
- if kbranch.find("/") == -1 and kbranch.find("base") == -1:
- continue
- idx = kbranch.find("base")
- branches.append(kbranch[:idx - 1])
-
- return branches
-
-
-def all_branches(context):
- """
- Return a list of all the branches found in the kernel git repo.
- """
- giturl = find_giturl(context)
-
- print("Getting branches from remote repo %s..." % giturl)
-
- gitcmd = "git ls-remote %s *heads* 2>&1" % (giturl)
- tmp = subprocess.Popen(gitcmd, shell=True, stdout=subprocess.PIPE).stdout.read().decode('utf-8')
-
- branches = []
-
- base_prefixes = None
-
- try:
- branches_base = context["branches_base"]
- if branches_base:
- base_prefixes = branches_base.split(":")
- except KeyError:
- pass
-
- arch = context["arch"]
-
- if tmp:
- tmpline = tmp.split("\n")
- for line in tmpline:
- if len(line)==0:
- break;
- idx = line.find("refs/heads/")
- kbranch = line[idx + len("refs/heads/"):]
- kbranch_prefix = kbranch.rsplit("/", 1)[0]
-
- if base_prefixes:
- for base_prefix in base_prefixes:
- if kbranch_prefix == base_prefix:
- branches.append(kbranch)
- continue
-
- if (kbranch.find("/") != -1 and
- (kbranch.find("standard") != -1 or kbranch.find("base") != -1) or
- kbranch == "base"):
- branches.append(kbranch)
- continue
-
- return branches