Initial commit

This commit is contained in:
Your Name
2026-04-23 17:07:55 +08:00
commit b7e39e063b
16725 changed files with 1625565 additions and 0 deletions
+85
View File
@@ -0,0 +1,85 @@
#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#
import logging
import os
import stat
import sys
import shutil
import json
import bb.utils
import bb.process
from bblayers.common import LayerPlugin
logger = logging.getLogger('bitbake-layers')
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
import oe.buildcfg
def plugin_init(plugins):
return BuildConfPlugin()
class BuildConfPlugin(LayerPlugin):
notes_fixme = """FIXME: Please place here the description of this build configuration.
It will be shown to the users when they set up their builds via TEMPLATECONF.
"""
def _save_conf(self, templatename, templatepath, oecorepath, relpaths_to_oecore):
confdir = os.path.join(os.environ["BBPATH"], "conf")
destdir = os.path.join(templatepath, "conf", "templates", templatename)
os.makedirs(destdir, exist_ok=True)
with open(os.path.join(confdir, "local.conf")) as src:
with open(os.path.join(destdir, "local.conf.sample"), 'w') as dest:
dest.write(src.read())
with open(os.path.join(confdir, "bblayers.conf")) as src:
with open(os.path.join(destdir, "bblayers.conf.sample"), 'w') as dest:
bblayers_data = src.read()
for (abspath, relpath) in relpaths_to_oecore:
bblayers_data = bblayers_data.replace(abspath, "##OEROOT##/" + relpath)
dest.write(bblayers_data)
with open(os.path.join(destdir, "conf-notes.txt"), 'w') as dest:
dest.write(self.notes_fixme)
logger.info("""Configuration template placed into {}
Please review the files in there, and particularly provide a configuration description in {}
You can try out the configuration with
TEMPLATECONF={} . {}/oe-init-build-env build-try-{}"""
.format(destdir, os.path.join(destdir, "conf-notes.txt"), destdir, oecorepath, templatename))
def do_save_build_conf(self, args):
""" Save the currently active build configuration (conf/local.conf, conf/bblayers.conf) as a template into a layer.\n This template can later be used for setting up builds via TEMPLATECONF. """
repos = {}
layers = oe.buildcfg.get_layer_revisions(self.tinfoil.config_data)
targetlayer = None
oecore = None
for l in layers:
if os.path.abspath(l[0]) == os.path.abspath(args.layerpath):
targetlayer = l[0]
if l[1] == 'meta':
oecore = os.path.dirname(l[0])
if not targetlayer:
logger.error("Layer {} not in one of the currently enabled layers:\n{}".format(args.layerpath, "\n".join([l[0] for l in layers])))
elif not oecore:
logger.error("Openembedded-core not in one of the currently enabled layers:\n{}".format("\n".join([l[0] for l in layers])))
else:
relpaths_to_oecore = [(l[0], os.path.relpath(l[0], start=oecore)) for l in layers]
self._save_conf(args.templatename, targetlayer, oecore, relpaths_to_oecore)
def register_commands(self, sp):
parser_build_conf = self.add_command(sp, 'save-build-conf', self.do_save_build_conf, parserecipes=False)
parser_build_conf.add_argument('layerpath',
help='The path to the layer where the configuration template should be saved.')
parser_build_conf.add_argument('templatename',
help='The name of the configuration template.')
+90
View File
@@ -0,0 +1,90 @@
#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#
import logging
import os
import sys
import shutil
import bb.utils
from bblayers.common import LayerPlugin
from bblayers.action import ActionPlugin
logger = logging.getLogger('bitbake-layers')
def plugin_init(plugins):
return CreatePlugin()
def read_template(template, template_dir='templates'):
lines = str()
with open(os.path.join(os.path.dirname(__file__), template_dir, template)) as fd:
lines = ''.join(fd.readlines())
return lines
class CreatePlugin(LayerPlugin):
def do_create_layer(self, args):
"""Create a basic layer"""
layerdir = os.path.abspath(args.layerdir)
if os.path.exists(layerdir):
sys.stderr.write("Specified layer directory exists\n")
return 1
# create dirs
conf = os.path.join(layerdir, 'conf')
bb.utils.mkdirhier(conf)
layername = os.path.basename(os.path.normpath(args.layerdir))
layerid = args.layerid if args.layerid is not None else layername
# Create the README from templates/README
readme_template = read_template('README').format(layername=layername)
readme = os.path.join(layerdir, 'README')
with open(readme, 'w') as fd:
fd.write(readme_template)
# Copy the MIT license from meta
copying = 'COPYING.MIT'
dn = os.path.dirname
license_src = os.path.join(dn(dn(dn(__file__))), copying)
license_dst = os.path.join(layerdir, copying)
shutil.copy(license_src, license_dst)
# Get the compat value for core layer.
compat = self.tinfoil.config_data.getVar('LAYERSERIES_CORENAMES') or ""
# Create the layer.conf from templates/layer.conf
layerconf_template = read_template('layer.conf').format(
layerid=layerid, priority=args.priority, compat=compat)
layerconf = os.path.join(conf, 'layer.conf')
with open(layerconf, 'w') as fd:
fd.write(layerconf_template)
# Create the example from templates/example.bb
example_template = read_template('example.bb')
example = os.path.join(layerdir, 'recipes-' + args.examplerecipe, args.examplerecipe)
bb.utils.mkdirhier(example)
with open(os.path.join(example, args.examplerecipe + '_%s.bb') % args.version, 'w') as fd:
fd.write(example_template)
if args.add_layer:
# Add the layer to bblayers.conf
args.layerdir = [layerdir]
ActionPlugin.do_add_layer(self, args)
logger.plain('Layer added %s' % args.layerdir)
else:
logger.plain('Add your new layer with \'bitbake-layers add-layer %s\'' % args.layerdir)
def register_commands(self, sp):
parser_create_layer = self.add_command(sp, 'create-layer', self.do_create_layer, parserecipes=False)
parser_create_layer.add_argument('layerdir', help='Layer directory to create')
parser_create_layer.add_argument('--add-layer', '-a', action='store_true', help='Add the layer to bblayers.conf after creation')
parser_create_layer.add_argument('--layerid', '-i', help='Layer id to use if different from layername')
parser_create_layer.add_argument('--priority', '-p', default=6, help='Priority of recipes in layer')
parser_create_layer.add_argument('--example-recipe-name', '-e', dest='examplerecipe', default='example', help='Filename of the example recipe')
parser_create_layer.add_argument('--example-recipe-version', '-v', dest='version', default='0.1', help='Version number for the example recipe')
+117
View File
@@ -0,0 +1,117 @@
#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#
import logging
import os
import stat
import sys
import shutil
import bb.utils
import bb.process
from bblayers.common import LayerPlugin
logger = logging.getLogger('bitbake-layers')
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
import oe.buildcfg
def plugin_init(plugins):
return MakeSetupPlugin()
class MakeSetupPlugin(LayerPlugin):
def _get_repo_path(self, layer_path):
repo_path, _ = bb.process.run('git rev-parse --show-toplevel', cwd=layer_path)
return repo_path.strip()
def _get_remotes(self, repo_path):
remotes = {}
remotes_list,_ = bb.process.run('git remote', cwd=repo_path)
for r in remotes_list.split():
uri,_ = bb.process.run('git remote get-url {r}'.format(r=r), cwd=repo_path)
remotes[r] = {'uri':uri.strip()}
return remotes
def _get_describe(self, repo_path):
try:
describe,_ = bb.process.run('git describe --tags', cwd=repo_path)
except bb.process.ExecutionError:
return ""
return describe.strip()
def _is_submodule(self, repo_path):
# This is slightly brittle: git does not offer a way to tell whether
# a given repo dir is a submodule checkout, so we need to rely on .git
# being a file (rather than a dir like it is in standalone checkouts).
# The file typically contains a gitdir pointer to elsewhere.
return os.path.isfile(os.path.join(repo_path,".git"))
def make_repo_config(self, destdir):
""" This is a helper function for the writer plugins that discovers currently configured layers.
The writers do not have to use it, but it can save a bit of work and avoid duplicated code, hence it is
available here. """
repos = {}
layers = oe.buildcfg.get_layer_revisions(self.tinfoil.config_data)
try:
destdir_repo = self._get_repo_path(destdir)
except bb.process.ExecutionError:
destdir_repo = None
for (l_path, l_name, l_branch, l_rev, l_ismodified) in layers:
if l_name == 'workspace':
continue
if l_ismodified:
logger.error("Layer {name} in {path} has uncommitted modifications or is not in a git repository.".format(name=l_name,path=l_path))
return
repo_path = self._get_repo_path(l_path)
if self._is_submodule(repo_path):
continue
if repo_path not in repos.keys():
repos[repo_path] = {'path':os.path.basename(repo_path),'git-remote':{'rev':l_rev, 'branch':l_branch, 'remotes':self._get_remotes(repo_path), 'describe':self._get_describe(repo_path)}}
if repo_path == destdir_repo:
repos[repo_path]['contains_this_file'] = True
if not repos[repo_path]['git-remote']['remotes'] and not repos[repo_path]['contains_this_file']:
logger.error("Layer repository in {path} does not have any remotes configured. Please add at least one with 'git remote add'.".format(path=repo_path))
return
top_path = os.path.commonpath([os.path.dirname(r) for r in repos.keys()])
repos_nopaths = {}
for r in repos.keys():
r_nopath = os.path.basename(r)
repos_nopaths[r_nopath] = repos[r]
r_relpath = os.path.relpath(r, top_path)
repos_nopaths[r_nopath]['path'] = r_relpath
return repos_nopaths
def do_make_setup(self, args):
""" Writes out a configuration file and/or a script that replicate the directory structure and revisions of the layers in a current build. """
for p in self.plugins:
if str(p) == args.writer:
p.do_write(self, args)
def register_commands(self, sp):
parser_setup_layers = self.add_command(sp, 'create-layers-setup', self.do_make_setup, parserecipes=False)
parser_setup_layers.add_argument('destdir',
help='Directory where to write the output\n(if it is inside one of the layers, the layer becomes a bootstrap repository and thus will be excluded from fetching).')
parser_setup_layers.add_argument('--output-prefix', '-o',
help='File name prefix for the output files, if the default (setup-layers) is undesirable.')
self.plugins = []
for path in (self.tinfoil.config_data.getVar('BBPATH').split(':')):
pluginpath = os.path.join(path, 'lib', 'bblayers', 'setupwriters')
bb.utils.load_plugins(logger, self.plugins, pluginpath)
parser_setup_layers.add_argument('--writer', '-w', choices=[str(p) for p in self.plugins], help="Choose the output format (defaults to oe-setup-layers).\n\nCurrently supported options are:\noe-setup-layers - a self-contained python script and a json config for it.\n\n", default="oe-setup-layers")
for plugin in self.plugins:
if hasattr(plugin, 'register_arguments'):
plugin.register_arguments(parser_setup_layers)
@@ -0,0 +1,52 @@
#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#
import logging
import os
import json
import stat
logger = logging.getLogger('bitbake-layers')
def plugin_init(plugins):
return OeSetupLayersWriter()
class OeSetupLayersWriter():
def __str__(self):
return "oe-setup-layers"
def _write_python(self, input, output):
with open(input) as f:
script = f.read()
with open(output, 'w') as f:
f.write(script)
st = os.stat(output)
os.chmod(output, st.st_mode | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH)
def _write_json(self, repos, output):
with open(output, 'w') as f:
json.dump(repos, f, sort_keys=True, indent=4)
def do_write(self, parent, args):
""" Writes out a python script and a json config that replicate the directory structure and revisions of the layers in a current build. """
if not os.path.exists(args.destdir):
os.makedirs(args.destdir)
repos = parent.make_repo_config(args.destdir)
json = {"version":"1.0","sources":repos}
if not repos:
raise Exception("Could not determine layer sources")
output = args.output_prefix or "setup-layers"
output = os.path.join(os.path.abspath(args.destdir),output)
self._write_json(json, output + ".json")
logger.info('Created {}.json'.format(output))
if not args.json_only:
self._write_python(os.path.join(os.path.dirname(__file__),'../../../../scripts/oe-setup-layers'), output)
logger.info('Created {}'.format(output))
def register_arguments(self, parser):
parser.add_argument('--json-only', action='store_true',
help='When using the oe-setup-layers writer, write only the layer configuruation in json format. Otherwise, also a copy of scripts/oe-setup-layers (from oe-core or poky) is provided, which is a self contained python script that fetches all the needed layers and sets them to correct revisions using the data from the json.')
+41
View File
@@ -0,0 +1,41 @@
This README file contains information on the contents of the {layername} layer.
Please see the corresponding sections below for details.
Dependencies
============
URI: <first dependency>
branch: <branch name>
URI: <second dependency>
branch: <branch name>
.
.
.
Patches
=======
Please submit any patches against the {layername} layer to the xxxx mailing list (xxxx@zzzz.org)
and cc: the maintainer:
Maintainer: XXX YYYYYY <xxx.yyyyyy@zzzzz.com>
Table of Contents
=================
I. Adding the {layername} layer to your build
II. Misc
I. Adding the {layername} layer to your build
=================================================
Run 'bitbake-layers add-layer {layername}'
II. Misc
========
--- replace with specific information about the {layername} layer ---
@@ -0,0 +1,13 @@
SUMMARY = "bitbake-layers recipe"
DESCRIPTION = "Recipe created by bitbake-layers"
LICENSE = "MIT"
python do_display_banner() {
bb.plain("***********************************************");
bb.plain("* *");
bb.plain("* Example recipe created by bitbake-layers *");
bb.plain("* *");
bb.plain("***********************************************");
}
addtask display_banner before do_build
@@ -0,0 +1,13 @@
# We have a conf and classes directory, add to BBPATH
BBPATH .= ":${{LAYERDIR}}"
# We have recipes-* directories, add to BBFILES
BBFILES += "${{LAYERDIR}}/recipes-*/*/*.bb \
${{LAYERDIR}}/recipes-*/*/*.bbappend"
BBFILE_COLLECTIONS += "{layerid}"
BBFILE_PATTERN_{layerid} = "^${{LAYERDIR}}/"
BBFILE_PRIORITY_{layerid} = "{priority}"
LAYERDEPENDS_{layerid} = "core"
LAYERSERIES_COMPAT_{layerid} = "{compat}"