Compare commits
137 Commits
sumo-19.0.
...
rocko-18.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2b641c8a0 | ||
|
|
ab4310e7b8 | ||
|
|
551d18e4b8 | ||
|
|
7030d5b4f9 | ||
|
|
f88c841a2d | ||
|
|
1c61ba0a3f | ||
|
|
babf923312 | ||
|
|
a1bff37c3f | ||
|
|
738fc234fa | ||
|
|
f79c0d45fa | ||
|
|
a5e95c2a85 | ||
|
|
4b2d0192b2 | ||
|
|
fd93e26f0d | ||
|
|
15542ff2b3 | ||
|
|
b472addc93 | ||
|
|
2f07e71a9e | ||
|
|
66a0b5b550 | ||
|
|
adaefc1880 | ||
|
|
1a2fb23f56 | ||
|
|
937beb5d94 | ||
|
|
45139bd079 | ||
|
|
8c56b0b2f4 | ||
|
|
f04d6842d3 | ||
|
|
c889bffda2 | ||
|
|
1655dfeffc | ||
|
|
ebf2523922 | ||
|
|
7de56ebc2a | ||
|
|
d0640da88e | ||
|
|
776fb31844 | ||
|
|
80ed9207a7 | ||
|
|
1e4d4762b1 | ||
|
|
968145b24e | ||
|
|
3c28d31fed | ||
|
|
65d09a7d1e | ||
|
|
311245d89f | ||
|
|
0845fa12b8 | ||
|
|
2d9aecf044 | ||
|
|
c32f44ebf5 | ||
|
|
c6d473f460 | ||
|
|
7104d48590 | ||
|
|
d164445477 | ||
|
|
7e0b00fd12 | ||
|
|
25c0d7d891 | ||
|
|
7df22af792 | ||
|
|
351192c314 | ||
|
|
fe51ddba06 | ||
|
|
c8730962a4 | ||
|
|
1e944f79b4 | ||
|
|
994e3674a8 | ||
|
|
69490b4280 | ||
|
|
e27fd333df | ||
|
|
216a839e1b | ||
|
|
bd884dd998 | ||
|
|
e36cf9e621 | ||
|
|
611e4b43d8 | ||
|
|
d4e3893e2d | ||
|
|
99c18e36e2 | ||
|
|
fbddd3917f | ||
|
|
5481891748 | ||
|
|
18b51a13af | ||
|
|
e46fa69897 | ||
|
|
7d934ff315 | ||
|
|
2f6cffd605 | ||
|
|
ed4708db31 | ||
|
|
8d53ceebaf | ||
|
|
f97450203f | ||
|
|
572b9c54a1 | ||
|
|
3f6fbed1e1 | ||
|
|
292c2ae888 | ||
|
|
539a852504 | ||
|
|
10d0ace274 | ||
|
|
852c71956b | ||
|
|
254013ce5f | ||
|
|
de78322f16 | ||
|
|
61f319db67 | ||
|
|
88d92fb301 | ||
|
|
ef6babd638 | ||
|
|
f8c7eff81d | ||
|
|
8d3edc9821 | ||
|
|
8d706de096 | ||
|
|
59cbf69299 | ||
|
|
02f64e5db8 | ||
|
|
c76a25b6ac | ||
|
|
1002359e5e | ||
|
|
3eca58ca70 | ||
|
|
aa6e825bf0 | ||
|
|
2ef0fd2364 | ||
|
|
ee7f665f0a | ||
|
|
ab31d76bc8 | ||
|
|
dd03b7399b | ||
|
|
55d21c7fb6 | ||
|
|
4e28c8d6b7 | ||
|
|
18941419c8 | ||
|
|
da8f32a3bb | ||
|
|
e6fe54ce38 | ||
|
|
23ee931b9d | ||
|
|
e4f256000f | ||
|
|
fbc12e0794 | ||
|
|
c45bdab6b9 | ||
|
|
a97fecb3bd | ||
|
|
87577b8a53 | ||
|
|
5599639b65 | ||
|
|
c388d72c60 | ||
|
|
d40531211c | ||
|
|
8eeed4220e | ||
|
|
0fbaee9077 | ||
|
|
33a48469bd | ||
|
|
e52027eef7 | ||
|
|
9d5296bba5 | ||
|
|
8754f4779c | ||
|
|
e0bfc22475 | ||
|
|
f165c52e57 | ||
|
|
e6c74f7ac9 | ||
|
|
ce3bbc6972 | ||
|
|
f483bdf9c4 | ||
|
|
24c9708492 | ||
|
|
221c4877f1 | ||
|
|
e303b3cadc | ||
|
|
500ce8d139 | ||
|
|
f7e10b532c | ||
|
|
0fc114ba76 | ||
|
|
b21f8e361b | ||
|
|
f515778225 | ||
|
|
40ed9adb53 | ||
|
|
96d525dc03 | ||
|
|
d61b65f35c | ||
|
|
3190ba0b38 | ||
|
|
a027091807 | ||
|
|
9779fc2bdd | ||
|
|
cb258fef83 | ||
|
|
0d84cdfaac | ||
|
|
f609c3f755 | ||
|
|
9217de77b9 | ||
|
|
87f8aafd53 | ||
|
|
6709452171 | ||
|
|
f7b90ab3ea | ||
|
|
7226a1c600 |
10
.gitignore
vendored
@@ -18,13 +18,9 @@ hob-image-*.bb
|
||||
!meta-yocto
|
||||
!meta-yocto-bsp
|
||||
!meta-yocto-imported
|
||||
/documentation/*/eclipse/
|
||||
/documentation/*/*.html
|
||||
/documentation/*/*.pdf
|
||||
/documentation/*/*.tgz
|
||||
/bitbake/doc/bitbake-user-manual/bitbake-user-manual.html
|
||||
/bitbake/doc/bitbake-user-manual/bitbake-user-manual.pdf
|
||||
/bitbake/doc/bitbake-user-manual/bitbake-user-manual.tgz
|
||||
documentation/user-manual/user-manual.html
|
||||
documentation/user-manual/user-manual.pdf
|
||||
documentation/user-manual/user-manual.tgz
|
||||
pull-*/
|
||||
bitbake/lib/toaster/contrib/tts/backlog.txt
|
||||
bitbake/lib/toaster/contrib/tts/log/*
|
||||
|
||||
@@ -23,4 +23,3 @@ therefore provides compatibility with the following caveats:
|
||||
* libpng 1.2 isn't provided; oe-core includes the latest release of libpng
|
||||
instead.
|
||||
|
||||
* pax (POSIX standard archive) tool is not provided.
|
||||
|
||||
@@ -38,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.37.0"
|
||||
__version__ = "1.36.0"
|
||||
|
||||
if __name__ == "__main__":
|
||||
if __version__ != bb.__version__:
|
||||
|
||||
@@ -18,10 +18,9 @@
|
||||
# along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
|
||||
HELP="
|
||||
Usage: source toaster start|stop [webport=<address:port>] [noweb] [nobuild]
|
||||
Usage: source toaster start|stop [webport=<address:port>] [noweb]
|
||||
Optional arguments:
|
||||
[nobuild] Setup the environment for capturing builds with toaster but disable managed builds
|
||||
[noweb] Setup the environment for capturing builds with toaster but don't start the web server
|
||||
[noweb] Setup the environment for building with toaster but don't start the development server
|
||||
[webport] Set the development server (default: localhost:8000)
|
||||
"
|
||||
|
||||
@@ -68,7 +67,7 @@ webserverKillAll()
|
||||
if [ -f ${pidfile} ]; then
|
||||
pid=`cat ${pidfile}`
|
||||
while kill -0 $pid 2>/dev/null; do
|
||||
kill -SIGTERM $pid 2>/dev/null
|
||||
kill -SIGTERM -$pid 2>/dev/null
|
||||
sleep 1
|
||||
done
|
||||
rm ${pidfile}
|
||||
@@ -91,7 +90,7 @@ webserverStartAll()
|
||||
|
||||
echo "Starting webserver..."
|
||||
|
||||
$MANAGE runserver --noreload "$ADDR_PORT" \
|
||||
$MANAGE runserver "$ADDR_PORT" \
|
||||
</dev/null >>${BUILDDIR}/toaster_web.log 2>&1 \
|
||||
& echo $! >${BUILDDIR}/.toastermain.pid
|
||||
|
||||
@@ -184,7 +183,6 @@ unset OE_ROOT
|
||||
|
||||
|
||||
WEBSERVER=1
|
||||
export TOASTER_BUILDSERVER=1
|
||||
ADDR_PORT="localhost:8000"
|
||||
unset CMD
|
||||
for param in $*; do
|
||||
@@ -192,9 +190,6 @@ for param in $*; do
|
||||
noweb )
|
||||
WEBSERVER=0
|
||||
;;
|
||||
nobuild )
|
||||
TOASTER_BUILDSERVER=0
|
||||
;;
|
||||
start )
|
||||
CMD=$param
|
||||
;;
|
||||
@@ -291,13 +286,9 @@ case $CMD in
|
||||
return 4
|
||||
fi
|
||||
export BITBAKE_UI='toasterui'
|
||||
if [ $TOASTER_BUILDSERVER -eq 1 ] ; then
|
||||
$MANAGE runbuilds \
|
||||
</dev/null >>${BUILDDIR}/toaster_runbuilds.log 2>&1 \
|
||||
& echo $! >${BUILDDIR}/.runbuilds.pid
|
||||
else
|
||||
echo "Toaster build server not started."
|
||||
fi
|
||||
$MANAGE runbuilds \
|
||||
</dev/null >>${BUILDDIR}/toaster_runbuilds.log 2>&1 \
|
||||
& echo $! >${BUILDDIR}/.runbuilds.pid
|
||||
|
||||
# set fail safe stop system on terminal exit
|
||||
trap stop_system SIGHUP
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# 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.
|
||||
# Copyright (C) 2012 Wind River Systems, Inc.
|
||||
#
|
||||
# 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
|
||||
@@ -18,68 +18,51 @@
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
#
|
||||
# Used for dumping the bb_cache.dat
|
||||
# This is used for dumping the bb_cache.dat, the output format is:
|
||||
# recipe_path PN PV PACKAGES
|
||||
#
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import warnings
|
||||
|
||||
# For importing bb.cache
|
||||
sys.path.insert(0, os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), '../lib'))
|
||||
from bb.cache import CoreRecipeInfo
|
||||
|
||||
import pickle
|
||||
import pickle as pickle
|
||||
|
||||
class DumpCache(object):
|
||||
def __init__(self):
|
||||
parser = argparse.ArgumentParser(
|
||||
description="bb_cache.dat's dumper",
|
||||
epilog="Use %(prog)s --help to get help")
|
||||
parser.add_argument("-r", "--recipe",
|
||||
help="specify the recipe, default: all recipes", action="store")
|
||||
parser.add_argument("-m", "--members",
|
||||
help = "specify the member, use comma as separator for multiple ones, default: all members", action="store", default="")
|
||||
parser.add_argument("-s", "--skip",
|
||||
help = "skip skipped recipes", action="store_true")
|
||||
parser.add_argument("cachefile",
|
||||
help = "specify bb_cache.dat", nargs = 1, action="store", default="")
|
||||
def main(argv=None):
|
||||
"""
|
||||
Get the mapping for the target recipe.
|
||||
"""
|
||||
if len(argv) != 1:
|
||||
print("Error, need one argument!", file=sys.stderr)
|
||||
return 2
|
||||
|
||||
self.args = parser.parse_args()
|
||||
cachefile = argv[0]
|
||||
|
||||
def main(self):
|
||||
with open(self.args.cachefile[0], "rb") as cachefile:
|
||||
pickled = pickle.Unpickler(cachefile)
|
||||
while True:
|
||||
try:
|
||||
key = pickled.load()
|
||||
val = pickled.load()
|
||||
except Exception:
|
||||
break
|
||||
if isinstance(val, CoreRecipeInfo):
|
||||
pn = val.pn
|
||||
with open(cachefile, "rb") as cachefile:
|
||||
pickled = pickle.Unpickler(cachefile)
|
||||
while cachefile:
|
||||
try:
|
||||
key = pickled.load()
|
||||
val = pickled.load()
|
||||
except Exception:
|
||||
break
|
||||
if isinstance(val, CoreRecipeInfo) and (not val.skipped):
|
||||
pn = val.pn
|
||||
# Filter out the native recipes.
|
||||
if key.startswith('virtual:native:') or pn.endswith("-native"):
|
||||
continue
|
||||
|
||||
if self.args.recipe and self.args.recipe != pn:
|
||||
continue
|
||||
# 1.0 is the default version for a no PV recipe.
|
||||
if "pv" in val.__dict__:
|
||||
pv = val.pv
|
||||
else:
|
||||
pv = "1.0"
|
||||
|
||||
if self.args.skip and val.skipped:
|
||||
continue
|
||||
|
||||
if self.args.members:
|
||||
out = key
|
||||
for member in self.args.members.split(','):
|
||||
out += ": %s" % val.__dict__.get(member)
|
||||
print("%s" % out)
|
||||
else:
|
||||
print("%s: %s" % (key, val.__dict__))
|
||||
elif not self.args.recipe:
|
||||
print("%s %s" % (key, val))
|
||||
print("%s %s %s %s" % (key, pn, pv, ' '.join(val.packages)))
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
dump = DumpCache()
|
||||
ret = dump.main()
|
||||
except Exception as esc:
|
||||
ret = 1
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
sys.exit(ret)
|
||||
sys.exit(main(sys.argv[1:]))
|
||||
|
||||
|
||||
@@ -781,7 +781,7 @@
|
||||
The code in <filename>meta/lib/oe/sstatesig.py</filename> shows two examples
|
||||
of this and also illustrates how you can insert your own policy into the system
|
||||
if so desired.
|
||||
This file defines the two basic signature generators OpenEmbedded-Core
|
||||
This file defines the two basic signature generators OpenEmbedded Core
|
||||
uses: "OEBasic" and "OEBasicHash".
|
||||
By default, there is a dummy "noop" signature handler enabled in BitBake.
|
||||
This means that behavior is unchanged from previous versions.
|
||||
|
||||
@@ -777,43 +777,6 @@
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='repo-fetcher'>
|
||||
<title>Repo Fetcher (<filename>repo://</filename>)</title>
|
||||
|
||||
<para>
|
||||
This fetcher submodule fetches code from
|
||||
<filename>google-repo</filename> source control system.
|
||||
The fetcher works by initiating and syncing sources of the
|
||||
repository into
|
||||
<link linkend='var-REPODIR'><filename>REPODIR</filename></link>,
|
||||
which is usually
|
||||
<link linkend='var-DL_DIR'><filename>DL_DIR</filename></link><filename>/repo</filename>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This fetcher supports the following parameters:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
<emphasis>"protocol":</emphasis>
|
||||
Protocol to fetch the repository manifest (default: git).
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>"branch":</emphasis>
|
||||
Branch or tag of repository to get (default: master).
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>"manifest":</emphasis>
|
||||
Name of the manifest file (default: <filename>default.xml</filename>).
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
Here are some example URLs:
|
||||
<literallayout class='monospaced'>
|
||||
SRC_URI = "repo://REPOROOT;protocol=git;branch=some_branch;manifest=my_manifest.xml"
|
||||
SRC_URI = "repo://REPOROOT;protocol=file;branch=some_branch;manifest=my_manifest.xml"
|
||||
</literallayout>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='other-fetchers'>
|
||||
<title>Other Fetchers</title>
|
||||
|
||||
@@ -832,6 +795,9 @@
|
||||
<listitem><para>
|
||||
Secure Shell (<filename>ssh://</filename>)
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Repo (<filename>repo://</filename>)
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
OSC (<filename>osc://</filename>)
|
||||
</para></listitem>
|
||||
|
||||
@@ -260,7 +260,7 @@
|
||||
files.
|
||||
For this example, you need to create the file in your project directory
|
||||
and define some key BitBake variables.
|
||||
For more information on the <filename>bitbake.conf</filename> file,
|
||||
For more information on the <filename>bitbake.conf</filename>,
|
||||
see
|
||||
<ulink url='http://git.openembedded.org/bitbake/tree/conf/bitbake.conf'></ulink>.
|
||||
</para>
|
||||
@@ -273,32 +273,14 @@
|
||||
some editor to create the <filename>bitbake.conf</filename>
|
||||
so that it contains the following:
|
||||
<literallayout class='monospaced'>
|
||||
<link linkend='var-PN'>PN</link> = "${@bb.parse.BBHandler.vars_from_file(d.getVar('FILE', False),d)[0] or 'defaultpkgname'}"
|
||||
</literallayout>
|
||||
<literallayout class='monospaced'>
|
||||
TMPDIR = "${<link linkend='var-TOPDIR'>TOPDIR</link>}/tmp"
|
||||
<link linkend='var-CACHE'>CACHE</link> = "${TMPDIR}/cache"
|
||||
<link linkend='var-STAMP'>STAMP</link> = "${TMPDIR}/${PN}/stamps"
|
||||
<link linkend='var-T'>T</link> = "${TMPDIR}/${PN}/work"
|
||||
<link linkend='var-B'>B</link> = "${TMPDIR}/${PN}"
|
||||
<link linkend='var-STAMP'>STAMP</link> = "${TMPDIR}/stamps"
|
||||
<link linkend='var-T'>T</link> = "${TMPDIR}/work"
|
||||
<link linkend='var-B'>B</link> = "${TMPDIR}"
|
||||
</literallayout>
|
||||
<note>
|
||||
Without a value for <filename>PN</filename>, the
|
||||
variables <filename>STAMP</filename>,
|
||||
<filename>T</filename>, and <filename>B</filename>,
|
||||
prevent more than one recipe from working. You can fix
|
||||
this by either setting <filename>PN</filename> to have
|
||||
a value similar to what OpenEmbedded and BitBake use
|
||||
in the default <filename>bitbake.conf</filename> file
|
||||
(see previous example). Or, by manually updating each
|
||||
recipe to set <filename>PN</filename>. You will also
|
||||
need to include <filename>PN</filename> as part of the
|
||||
<filename>STAMP</filename>, <filename>T</filename>, and
|
||||
<filename>B</filename> variable definitions in the
|
||||
<filename>local.conf</filename> file.
|
||||
</note>
|
||||
The <filename>TMPDIR</filename> variable establishes a directory
|
||||
that BitBake uses for build output and intermediate files other
|
||||
that BitBake uses for build output and intermediate files (other
|
||||
than the cached information used by the
|
||||
<link linkend='setscene'>Setscene</link> process.
|
||||
Here, the <filename>TMPDIR</filename> directory is set to
|
||||
@@ -318,19 +300,19 @@
|
||||
file exists, you can run the <filename>bitbake</filename>
|
||||
command again:
|
||||
<literallayout class='monospaced'>
|
||||
$ bitbake
|
||||
ERROR: Traceback (most recent call last):
|
||||
File "/home/scott-lenovo/bitbake/lib/bb/cookerdata.py", line 163, in wrapped
|
||||
return func(fn, *args)
|
||||
File "/home/scott-lenovo/bitbake/lib/bb/cookerdata.py", line 177, in _inherit
|
||||
bb.parse.BBHandler.inherit(bbclass, "configuration INHERITs", 0, data)
|
||||
File "/home/scott-lenovo/bitbake/lib/bb/parse/parse_py/BBHandler.py", line 92, in inherit
|
||||
include(fn, file, lineno, d, "inherit")
|
||||
File "/home/scott-lenovo/bitbake/lib/bb/parse/parse_py/ConfHandler.py", line 100, in include
|
||||
raise ParseError("Could not %(error_out)s file %(fn)s" % vars(), oldfn, lineno)
|
||||
ParseError: ParseError in configuration INHERITs: Could not inherit file classes/base.bbclass
|
||||
$ bitbake
|
||||
ERROR: Traceback (most recent call last):
|
||||
File "/home/scott-lenovo/bitbake/lib/bb/cookerdata.py", line 163, in wrapped
|
||||
return func(fn, *args)
|
||||
File "/home/scott-lenovo/bitbake/lib/bb/cookerdata.py", line 177, in _inherit
|
||||
bb.parse.BBHandler.inherit(bbclass, "configuration INHERITs", 0, data)
|
||||
File "/home/scott-lenovo/bitbake/lib/bb/parse/parse_py/BBHandler.py", line 92, in inherit
|
||||
include(fn, file, lineno, d, "inherit")
|
||||
File "/home/scott-lenovo/bitbake/lib/bb/parse/parse_py/ConfHandler.py", line 100, in include
|
||||
raise ParseError("Could not %(error_out)s file %(fn)s" % vars(), oldfn, lineno)
|
||||
ParseError: ParseError in configuration INHERITs: Could not inherit file classes/base.bbclass
|
||||
|
||||
ERROR: Unable to parse base: ParseError in configuration INHERITs: Could not inherit file classes/base.bbclass
|
||||
ERROR: Unable to parse base: ParseError in configuration INHERITs: Could not inherit file classes/base.bbclass
|
||||
</literallayout>
|
||||
In the sample output, BitBake could not find the
|
||||
<filename>classes/base.bbclass</filename> file.
|
||||
@@ -383,10 +365,10 @@
|
||||
code separate from the general metadata used by BitBake.
|
||||
Thus, this example creates and uses a layer called "mylayer".
|
||||
<note>
|
||||
You can find additional information on layers in the
|
||||
"<link linkend='layers'>Layers</link>" section.
|
||||
</note></para>
|
||||
|
||||
You can find additional information on layers at
|
||||
<ulink url='http://www.yoctoproject.org/docs/2.3/bitbake-user-manual/bitbake-user-manual.html#layers'></ulink>.
|
||||
</note>
|
||||
</para>
|
||||
<para>Minimally, you need a recipe file and a layer configuration
|
||||
file in your layer.
|
||||
The configuration file needs to be in the <filename>conf</filename>
|
||||
|
||||
@@ -488,6 +488,8 @@
|
||||
target that failed and anything depending on it cannot
|
||||
be built, as much as possible will be built before
|
||||
stopping.
|
||||
-a, --tryaltconfigs Continue with builds by trying to use alternative
|
||||
providers where possible.
|
||||
-f, --force Force the specified targets/task to run (invalidating
|
||||
any existing stamp file).
|
||||
-c CMD, --cmd=CMD Specify the task to execute. The exact options
|
||||
@@ -502,20 +504,19 @@
|
||||
Read the specified file before bitbake.conf.
|
||||
-R POSTFILE, --postread=POSTFILE
|
||||
Read the specified file after bitbake.conf.
|
||||
-v, --verbose Enable tracing of shell tasks (with 'set -x'). Also
|
||||
print bb.note(...) messages to stdout (in addition to
|
||||
writing them to ${T}/log.do_<task>).
|
||||
-D, --debug Increase the debug level. You can specify this more
|
||||
than once. -D sets the debug level to 1, where only
|
||||
bb.debug(1, ...) messages are printed to stdout; -DD
|
||||
sets the debug level to 2, where both bb.debug(1, ...)
|
||||
and bb.debug(2, ...) messages are printed; etc.
|
||||
Without -D, no debug messages are printed. Note that
|
||||
-D only affects output to stdout. All debug messages
|
||||
are written to ${T}/log.do_taskname, regardless of the
|
||||
debug level.
|
||||
-q, --quiet Output less log message data to the terminal. You can
|
||||
specify this more than once.
|
||||
-v, --verbose Enable tracing of shell tasks (with 'set -x').
|
||||
Also print bb.note(...) messages to stdout (in
|
||||
addition to writing them to ${T}/log.do_<task>).
|
||||
-D, --debug Increase the debug level. You can specify this
|
||||
more than once. -D sets the debug level to 1,
|
||||
where only bb.debug(1, ...) messages are printed
|
||||
to stdout; -DD sets the debug level to 2, where
|
||||
both bb.debug(1, ...) and bb.debug(2, ...)
|
||||
messages are printed; etc. Without -D, no debug
|
||||
messages are printed. Note that -D only affects
|
||||
output to stdout. All debug messages are written
|
||||
to ${T}/log.do_taskname, regardless of the debug
|
||||
level.
|
||||
-n, --dry-run Don't execute, just go through the motions.
|
||||
-S SIGNATURE_HANDLER, --dump-signatures=SIGNATURE_HANDLER
|
||||
Dump out the signature construction information, with
|
||||
@@ -538,38 +539,30 @@
|
||||
-l DEBUG_DOMAINS, --log-domains=DEBUG_DOMAINS
|
||||
Show debug logging for the specified logging domains
|
||||
-P, --profile Profile the command and save reports.
|
||||
-u UI, --ui=UI The user interface to use (knotty, ncurses or taskexp
|
||||
- default knotty).
|
||||
-u UI, --ui=UI The user interface to use (taskexp, knotty or
|
||||
ncurses - default knotty).
|
||||
-t SERVERTYPE, --servertype=SERVERTYPE
|
||||
Choose which server type to use (process or xmlrpc -
|
||||
default process).
|
||||
--token=XMLRPCTOKEN Specify the connection token to be used when
|
||||
connecting to a remote server.
|
||||
--revisions-changed Set the exit code depending on whether upstream
|
||||
floating revisions have changed or not.
|
||||
--server-only Run bitbake without a UI, only starting a server
|
||||
(cooker) process.
|
||||
-B BIND, --bind=BIND The name/address for the bitbake xmlrpc server to bind
|
||||
to.
|
||||
-T SERVER_TIMEOUT, --idle-timeout=SERVER_TIMEOUT
|
||||
Set timeout to unload bitbake server due to
|
||||
inactivity, set to -1 means no unload, default:
|
||||
Environment variable BB_SERVER_TIMEOUT.
|
||||
-B BIND, --bind=BIND The name/address for the bitbake server to bind to.
|
||||
--no-setscene Do not run any setscene tasks. sstate will be ignored
|
||||
and everything needed, built.
|
||||
--setscene-only Only run setscene tasks, don't run any real tasks.
|
||||
--remote-server=REMOTE_SERVER
|
||||
Connect to the specified server.
|
||||
-m, --kill-server Terminate any running bitbake server.
|
||||
-m, --kill-server Terminate the remote server.
|
||||
--observe-only Connect to a server as an observing-only client.
|
||||
--status-only Check the status of the remote bitbake server.
|
||||
-w WRITEEVENTLOG, --write-log=WRITEEVENTLOG
|
||||
Writes the event log of the build to a bitbake event
|
||||
json file. Use '' (empty string) to assign the name
|
||||
automatically.
|
||||
--runall=RUNALL Run the specified task for any recipe in the taskgraph
|
||||
of the specified target (even if it wouldn't otherwise
|
||||
have run).
|
||||
--runonly=RUNONLY Run only the specified task within the taskgraph of
|
||||
the specified targets (and any task dependencies those
|
||||
tasks may have).
|
||||
</literallayout>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -2132,8 +2132,6 @@
|
||||
<listitem><para>
|
||||
<filename>bb.event.BuildStarted()</filename>:
|
||||
Fired when a new build starts.
|
||||
BitBake fires multiple "BuildStarted" events (one per configuration)
|
||||
when multiple configuration (multiconfig) is enabled.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<filename>bb.build.TaskStarted()</filename>:
|
||||
@@ -2652,70 +2650,47 @@
|
||||
</para>
|
||||
|
||||
<para>
|
||||
These checksums are stored in
|
||||
<link linkend='var-STAMP'><filename>STAMP</filename></link>.
|
||||
You can examine the checksums using the following BitBake command:
|
||||
<literallayout class='monospaced'>
|
||||
$ bitbake-dumpsigs
|
||||
</literallayout>
|
||||
This command returns the signature data in a readable format
|
||||
that allows you to examine the inputs used when the
|
||||
OpenEmbedded build system generates signatures.
|
||||
For example, using <filename>bitbake-dumpsigs</filename>
|
||||
allows you to examine the <filename>do_compile</filename>
|
||||
task's “sigdata” for a C application (e.g.
|
||||
<filename>bash</filename>).
|
||||
Running the command also reveals that the “CC” variable is part of
|
||||
the inputs that are hashed.
|
||||
Any changes to this variable would invalidate the stamp and
|
||||
cause the <filename>do_compile</filename> task to run.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The following list describes related variables:
|
||||
This list is a place holder of content existed from previous work
|
||||
on the manual.
|
||||
Some or all of it probably needs integrated into the subsections
|
||||
that make up this section.
|
||||
For now, I have just provided a short glossary-like description
|
||||
for each variable.
|
||||
Ultimately, this list goes away.
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
<link linkend='var-BB_HASHCHECK_FUNCTION'><filename>BB_HASHCHECK_FUNCTION</filename></link>:
|
||||
<listitem><para><filename>STAMP</filename>:
|
||||
The base path to create stamp files.</para></listitem>
|
||||
<listitem><para><filename>STAMPCLEAN</filename>
|
||||
Again, the base path to create stamp files but can use wildcards
|
||||
for matching a range of files for clean operations.
|
||||
</para></listitem>
|
||||
<listitem><para><filename>BB_STAMP_WHITELIST</filename>
|
||||
Lists stamp files that are looked at when the stamp policy
|
||||
is "whitelist".
|
||||
</para></listitem>
|
||||
<listitem><para><filename>BB_STAMP_POLICY</filename>
|
||||
Defines the mode for comparing timestamps of stamp files.
|
||||
</para></listitem>
|
||||
<listitem><para><filename>BB_HASHCHECK_FUNCTION</filename>
|
||||
Specifies the name of the function to call during
|
||||
the "setscene" part of the task's execution in order
|
||||
to validate the list of task hashes.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<link linkend='var-BB_SETSCENE_DEPVALID'><filename>BB_SETSCENE_DEPVALID</filename></link>:
|
||||
Specifies a function BitBake calls that determines
|
||||
whether BitBake requires a setscene dependency to
|
||||
be met.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<link linkend='var-BB_SETSCENE_VERIFY_FUNCTION2'><filename>BB_SETSCENE_VERIFY_FUNCTION2</filename></link>:
|
||||
<listitem><para><filename>BB_SETSCENE_VERIFY_FUNCTION2</filename>
|
||||
Specifies a function to call that verifies the list of
|
||||
planned task execution before the main task execution
|
||||
happens.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<link linkend='var-BB_STAMP_POLICY'><filename>BB_STAMP_POLICY</filename></link>:
|
||||
Defines the mode for comparing timestamps of stamp files.
|
||||
<listitem><para><filename>BB_SETSCENE_DEPVALID</filename>
|
||||
Specifies a function BitBake calls that determines
|
||||
whether BitBake requires a setscene dependency to
|
||||
be met.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<link linkend='var-BB_STAMP_WHITELIST'><filename>BB_STAMP_WHITELIST</filename></link>:
|
||||
Lists stamp files that are looked at when the stamp policy
|
||||
is "whitelist".
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<link linkend='var-BB_TASKHASH'><filename>BB_TASKHASH</filename></link>:
|
||||
<listitem><para><filename>BB_TASKHASH</filename>
|
||||
Within an executing task, this variable holds the hash
|
||||
of the task as returned by the currently enabled
|
||||
signature generator.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<link linkend='var-STAMP'><filename>STAMP</filename></link>:
|
||||
The base path to create stamp files.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<link linkend='var-STAMPCLEAN'><filename>STAMPCLEAN</filename></link>:
|
||||
Again, the base path to create stamp files but can use wildcards
|
||||
for matching a range of files for clean operations.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In OpenEmbedded-Core, <filename>ASSUME_PROVIDED</filename>
|
||||
In OpenEmbedded Core, <filename>ASSUME_PROVIDED</filename>
|
||||
mostly specifies native tools that should not be built.
|
||||
An example is <filename>git-native</filename>, which
|
||||
when specified allows for the Git binary from the host to
|
||||
@@ -964,7 +964,7 @@
|
||||
Allows you to extend a recipe so that it builds variants
|
||||
of the software.
|
||||
Some examples of these variants for recipes from the
|
||||
OpenEmbedded-Core metadata are "natives" such as
|
||||
OpenEmbedded Core metadata are "natives" such as
|
||||
<filename>quilt-native</filename>, which is a copy of
|
||||
Quilt built to run on the build system; "crosses" such
|
||||
as <filename>gcc-cross</filename>, which is a compiler
|
||||
@@ -980,7 +980,7 @@
|
||||
amount of code, it usually is as simple as adding the
|
||||
variable to your recipe.
|
||||
Here are two examples.
|
||||
The "native" variants are from the OpenEmbedded-Core
|
||||
The "native" variants are from the OpenEmbedded Core
|
||||
metadata:
|
||||
<literallayout class='monospaced'>
|
||||
BBCLASSEXTEND =+ "native nativesdk"
|
||||
@@ -2089,16 +2089,6 @@
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id='var-REPODIR'><glossterm>REPODIR</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
The directory in which a local copy of a
|
||||
<filename>google-repo</filename> directory is stored
|
||||
when it is synced.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry id='var-RPROVIDES'><glossterm>RPROVIDES</glossterm>
|
||||
<glossdef>
|
||||
<para>
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
-->
|
||||
|
||||
<copyright>
|
||||
<year>2004-2017</year>
|
||||
<year>2004-2016</year>
|
||||
<holder>Richard Purdie</holder>
|
||||
<holder>Chris Larson</holder>
|
||||
<holder>and Phil Blundell</holder>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
__version__ = "1.37.0"
|
||||
__version__ = "1.36.0"
|
||||
|
||||
import sys
|
||||
if sys.version_info < (3, 4, 0):
|
||||
|
||||
@@ -872,12 +872,6 @@ def preceedtask(task, with_recrdeptasks, d):
|
||||
that this may lead to the task itself being listed.
|
||||
"""
|
||||
preceed = set()
|
||||
|
||||
# Ignore tasks which don't exist
|
||||
tasks = d.getVar('__BBTASKS', False)
|
||||
if task not in tasks:
|
||||
return preceed
|
||||
|
||||
preceed.update(d.getVarFlag(task, 'deps') or [])
|
||||
if with_recrdeptasks:
|
||||
recrdeptask = d.getVarFlag(task, 'recrdeptask')
|
||||
|
||||
@@ -395,7 +395,7 @@ class Cache(NoCache):
|
||||
self.has_cache = True
|
||||
self.cachefile = getCacheFile(self.cachedir, "bb_cache.dat", self.data_hash)
|
||||
|
||||
logger.debug(1, "Cache dir: %s", self.cachedir)
|
||||
logger.debug(1, "Using cache in '%s'", self.cachedir)
|
||||
bb.utils.mkdirhier(self.cachedir)
|
||||
|
||||
cache_ok = True
|
||||
@@ -408,8 +408,6 @@ class Cache(NoCache):
|
||||
self.load_cachefile()
|
||||
elif os.path.isfile(self.cachefile):
|
||||
logger.info("Out of date cache found, rebuilding...")
|
||||
else:
|
||||
logger.debug(1, "Cache file %s not found, building..." % self.cachefile)
|
||||
|
||||
def load_cachefile(self):
|
||||
cachesize = 0
|
||||
@@ -426,7 +424,6 @@ class Cache(NoCache):
|
||||
|
||||
for cache_class in self.caches_array:
|
||||
cachefile = getCacheFile(self.cachedir, cache_class.cachefile, self.data_hash)
|
||||
logger.debug(1, 'Loading cache file: %s' % cachefile)
|
||||
with open(cachefile, "rb") as cachefile:
|
||||
pickled = pickle.Unpickler(cachefile)
|
||||
# Check cache version information
|
||||
|
||||
@@ -516,8 +516,6 @@ class BBCooker:
|
||||
fn = runlist[0][3]
|
||||
else:
|
||||
envdata = self.data
|
||||
data.expandKeys(envdata)
|
||||
parse.ast.runAnonFuncs(envdata)
|
||||
|
||||
if fn:
|
||||
try:
|
||||
@@ -538,6 +536,7 @@ class BBCooker:
|
||||
logger.plain(env.getvalue())
|
||||
|
||||
# emit the metadata which isnt valid shell
|
||||
data.expandKeys(envdata)
|
||||
for e in sorted(envdata.keys()):
|
||||
if envdata.getVarFlag(e, 'func', False) and envdata.getVarFlag(e, 'python', False):
|
||||
logger.plain("\npython %s () {\n%s}\n", e, envdata.getVar(e, False))
|
||||
@@ -857,12 +856,12 @@ class BBCooker:
|
||||
|
||||
with open('task-depends.dot', 'w') as f:
|
||||
f.write("digraph depends {\n")
|
||||
for task in sorted(depgraph["tdepends"]):
|
||||
for task in depgraph["tdepends"]:
|
||||
(pn, taskname) = task.rsplit(".", 1)
|
||||
fn = depgraph["pn"][pn]["filename"]
|
||||
version = depgraph["pn"][pn]["version"]
|
||||
f.write('"%s.%s" [label="%s %s\\n%s\\n%s"]\n' % (pn, taskname, pn, taskname, version, fn))
|
||||
for dep in sorted(depgraph["tdepends"][task]):
|
||||
for dep in depgraph["tdepends"][task]:
|
||||
f.write('"%s" -> "%s"\n' % (task, dep))
|
||||
f.write("}\n")
|
||||
logger.info("Task dependencies saved to 'task-depends.dot'")
|
||||
@@ -870,23 +869,23 @@ class BBCooker:
|
||||
with open('recipe-depends.dot', 'w') as f:
|
||||
f.write("digraph depends {\n")
|
||||
pndeps = {}
|
||||
for task in sorted(depgraph["tdepends"]):
|
||||
for task in depgraph["tdepends"]:
|
||||
(pn, taskname) = task.rsplit(".", 1)
|
||||
if pn not in pndeps:
|
||||
pndeps[pn] = set()
|
||||
for dep in sorted(depgraph["tdepends"][task]):
|
||||
for dep in depgraph["tdepends"][task]:
|
||||
(deppn, deptaskname) = dep.rsplit(".", 1)
|
||||
pndeps[pn].add(deppn)
|
||||
for pn in sorted(pndeps):
|
||||
for pn in 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]):
|
||||
for dep in 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'")
|
||||
logger.info("Flatened recipe dependencies saved to 'recipe-depends.dot'")
|
||||
|
||||
def show_appends_with_no_recipes(self):
|
||||
# Determine which bbappends haven't been applied
|
||||
@@ -1171,7 +1170,6 @@ class BBCooker:
|
||||
elif regex == "":
|
||||
parselog.debug(1, "BBFILE_PATTERN_%s is empty" % c)
|
||||
errors = False
|
||||
continue
|
||||
else:
|
||||
try:
|
||||
cre = re.compile(regex)
|
||||
@@ -1605,6 +1603,8 @@ class BBCooker:
|
||||
|
||||
if self.parser:
|
||||
self.parser.shutdown(clean=not force, force=force)
|
||||
self.notifier.stop()
|
||||
self.confignotifier.stop()
|
||||
|
||||
def finishcommand(self):
|
||||
self.state = state.initial
|
||||
@@ -1807,25 +1807,21 @@ class CookerCollectFiles(object):
|
||||
realfn, cls, mc = bb.cache.virtualfn2realfn(p)
|
||||
priorities[p] = self.calc_bbfile_priority(realfn, matched)
|
||||
|
||||
# Don't show the warning if the BBFILE_PATTERN did match .bbappend files
|
||||
unmatched = set()
|
||||
for _, _, regex, pri in self.bbfile_config_priorities:
|
||||
if not regex in matched:
|
||||
unmatched.add(regex)
|
||||
|
||||
# Don't show the warning if the BBFILE_PATTERN did match .bbappend files
|
||||
def find_bbappend_match(regex):
|
||||
def findmatch(regex):
|
||||
for b in self.bbappends:
|
||||
(bbfile, append) = b
|
||||
if regex.match(append):
|
||||
# If the bbappend is matched by already "matched set", return False
|
||||
for matched_regex in matched:
|
||||
if matched_regex.match(append):
|
||||
return False
|
||||
return True
|
||||
return False
|
||||
|
||||
for unmatch in unmatched.copy():
|
||||
if find_bbappend_match(unmatch):
|
||||
if findmatch(unmatch):
|
||||
unmatched.remove(unmatch)
|
||||
|
||||
for collection, pattern, regex, _ in self.bbfile_config_priorities:
|
||||
|
||||
@@ -143,8 +143,7 @@ class CookerConfiguration(object):
|
||||
self.writeeventlog = False
|
||||
self.server_only = False
|
||||
self.limited_deps = False
|
||||
self.runall = []
|
||||
self.runonly = []
|
||||
self.runall = None
|
||||
|
||||
self.env = {}
|
||||
|
||||
@@ -396,8 +395,6 @@ class CookerDataBuilder(object):
|
||||
if compat and not (compat & layerseries):
|
||||
bb.fatal("Layer %s is not compatible with the core layer which only supports these series: %s (layer is compatible with %s)"
|
||||
% (c, " ".join(layerseries), " ".join(compat)))
|
||||
elif not compat and not data.getVar("BB_WORKERCONTEXT"):
|
||||
bb.warn("Layer %s should set LAYERSERIES_COMPAT_%s in its conf/layer.conf file to list the core layer names it is compatible with." % (c, c))
|
||||
|
||||
if not data.getVar("BBPATH"):
|
||||
msg = "The BBPATH variable is not set"
|
||||
|
||||
@@ -449,6 +449,12 @@ class BuildBase(Event):
|
||||
def setName(self, name):
|
||||
self._name = name
|
||||
|
||||
def getCfg(self):
|
||||
return self.data
|
||||
|
||||
def setCfg(self, cfg):
|
||||
self.data = cfg
|
||||
|
||||
def getFailures(self):
|
||||
"""
|
||||
Return the number of failed packages
|
||||
@@ -457,6 +463,9 @@ class BuildBase(Event):
|
||||
|
||||
pkgs = property(getPkgs, setPkgs, None, "pkgs property")
|
||||
name = property(getName, setName, None, "name property")
|
||||
cfg = property(getCfg, setCfg, None, "cfg property")
|
||||
|
||||
|
||||
|
||||
class BuildInit(BuildBase):
|
||||
"""buildFile or buildTargets was invoked"""
|
||||
|
||||
@@ -643,25 +643,26 @@ def verify_donestamp(ud, d, origud=None):
|
||||
if not ud.needdonestamp or (origud and not origud.needdonestamp):
|
||||
return True
|
||||
|
||||
if not os.path.exists(ud.localpath):
|
||||
# local path does not exist
|
||||
if os.path.exists(ud.donestamp):
|
||||
# done stamp exists, but the downloaded file does not; the done stamp
|
||||
# must be incorrect, re-trigger the download
|
||||
bb.utils.remove(ud.donestamp)
|
||||
if not os.path.exists(ud.donestamp):
|
||||
return False
|
||||
|
||||
if (not ud.method.supports_checksum(ud) or
|
||||
(origud and not origud.method.supports_checksum(origud))):
|
||||
# if done stamp exists and checksums not supported; assume the local
|
||||
# file is current
|
||||
return os.path.exists(ud.donestamp)
|
||||
# done stamp exists, checksums not supported; assume the local file is
|
||||
# current
|
||||
return True
|
||||
|
||||
if not os.path.exists(ud.localpath):
|
||||
# done stamp exists, but the downloaded file does not; the done stamp
|
||||
# must be incorrect, re-trigger the download
|
||||
bb.utils.remove(ud.donestamp)
|
||||
return False
|
||||
|
||||
precomputed_checksums = {}
|
||||
# Only re-use the precomputed checksums if the donestamp is newer than the
|
||||
# file. Do not rely on the mtime of directories, though. If ud.localpath is
|
||||
# a directory, there will probably not be any checksums anyway.
|
||||
if os.path.exists(ud.donestamp) and (os.path.isdir(ud.localpath) or
|
||||
if (os.path.isdir(ud.localpath) or
|
||||
os.path.getmtime(ud.localpath) < os.path.getmtime(ud.donestamp)):
|
||||
try:
|
||||
with open(ud.donestamp, "rb") as cachefile:
|
||||
@@ -852,9 +853,6 @@ def runfetchcmd(cmd, d, quiet=False, cleanup=None, log=None, workdir=None):
|
||||
if val:
|
||||
cmd = 'export ' + var + '=\"%s\"; %s' % (val, cmd)
|
||||
|
||||
# Disable pseudo as it may affect ssh, potentially causing it to hang.
|
||||
cmd = 'export PSEUDO_DISABLED=1; ' + cmd
|
||||
|
||||
logger.debug(1, "Running %s", cmd)
|
||||
|
||||
success = False
|
||||
@@ -1426,7 +1424,7 @@ class FetchMethod(object):
|
||||
cmd = 'gzip -dc %s > %s' % (file, efile)
|
||||
elif file.endswith('.bz2'):
|
||||
cmd = 'bzip2 -dc %s > %s' % (file, efile)
|
||||
elif file.endswith('.txz') or file.endswith('.tar.xz'):
|
||||
elif file.endswith('.tar.xz'):
|
||||
cmd = 'xz -dc %s | tar x --no-same-owner -f -' % file
|
||||
elif file.endswith('.xz'):
|
||||
cmd = 'xz -dc %s > %s' % (file, efile)
|
||||
|
||||
@@ -125,9 +125,6 @@ class GitProgressHandler(bb.progress.LineFilterProgressHandler):
|
||||
|
||||
|
||||
class Git(FetchMethod):
|
||||
bitbake_dir = os.path.abspath(os.path.join(os.path.dirname(os.path.join(os.path.abspath(__file__))), '..', '..', '..'))
|
||||
make_shallow_path = os.path.join(bitbake_dir, 'bin', 'git-make-shallow')
|
||||
|
||||
"""Class to fetch a module or modules from git repositories"""
|
||||
def init(self, d):
|
||||
pass
|
||||
@@ -366,7 +363,6 @@ class Git(FetchMethod):
|
||||
progresshandler = GitProgressHandler(d)
|
||||
runfetchcmd(fetch_cmd, d, log=progresshandler, workdir=ud.clonedir)
|
||||
runfetchcmd("%s prune-packed" % ud.basecmd, d, workdir=ud.clonedir)
|
||||
runfetchcmd("%s pack-refs --all" % ud.basecmd, d, workdir=ud.clonedir)
|
||||
runfetchcmd("%s pack-redundant --all | xargs -r rm" % ud.basecmd, d, workdir=ud.clonedir)
|
||||
try:
|
||||
os.unlink(ud.fullmirror)
|
||||
@@ -449,7 +445,7 @@ class Git(FetchMethod):
|
||||
shallow_branches.append(r)
|
||||
|
||||
# Make the repository shallow
|
||||
shallow_cmd = [self.make_shallow_path, '-s']
|
||||
shallow_cmd = ['git', 'make-shallow', '-s']
|
||||
for b in shallow_branches:
|
||||
shallow_cmd.append('-r')
|
||||
shallow_cmd.append(b)
|
||||
@@ -595,8 +591,7 @@ class Git(FetchMethod):
|
||||
tagregex = re.compile(d.getVar('UPSTREAM_CHECK_GITTAGREGEX') or "(?P<pver>([0-9][\.|_]?)+)")
|
||||
try:
|
||||
output = self._lsremote(ud, d, "refs/tags/*")
|
||||
except (bb.fetch2.FetchError, bb.fetch2.NetworkAccess) as e:
|
||||
bb.note("Could not list remote: %s" % str(e))
|
||||
except bb.fetch2.FetchError or bb.fetch2.NetworkAccess:
|
||||
return pupver
|
||||
|
||||
verstring = ""
|
||||
|
||||
@@ -195,11 +195,9 @@ class Npm(FetchMethod):
|
||||
outputurl = pdata['dist']['tarball']
|
||||
data[pkg] = {}
|
||||
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)
|
||||
if not outputurl in fetchedlist:
|
||||
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', {})
|
||||
|
||||
@@ -250,7 +250,6 @@ class Wget(FetchMethod):
|
||||
return ""
|
||||
def close(self):
|
||||
pass
|
||||
closed = False
|
||||
|
||||
resp = addinfourl(fp_dummy(), r.msg, req.get_full_url())
|
||||
resp.code = r.status
|
||||
@@ -333,8 +332,7 @@ class Wget(FetchMethod):
|
||||
except (TypeError, ImportError, IOError, netrc.NetrcParseError):
|
||||
pass
|
||||
|
||||
with opener.open(r) as response:
|
||||
pass
|
||||
opener.open(r)
|
||||
except urllib.error.URLError as e:
|
||||
if try_again:
|
||||
logger.debug(2, "checkstatus: trying again")
|
||||
|
||||
@@ -292,12 +292,8 @@ class BitBakeConfigParameters(cookerdata.ConfigParameters):
|
||||
help="Writes the event log of the build to a bitbake event json file. "
|
||||
"Use '' (empty string) to assign the name automatically.")
|
||||
|
||||
parser.add_option("", "--runall", action="append", dest="runall",
|
||||
help="Run the specified task for any recipe in the taskgraph of the specified target (even if it wouldn't otherwise have run).")
|
||||
|
||||
parser.add_option("", "--runonly", action="append", dest="runonly",
|
||||
help="Run only the specified task within the taskgraph of the specified targets (and any task dependencies those tasks may have).")
|
||||
|
||||
parser.add_option("", "--runall", action="store", dest="runall",
|
||||
help="Run the specified task for all build targets and their dependencies.")
|
||||
|
||||
options, targets = parser.parse_args(argv)
|
||||
|
||||
|
||||
@@ -134,9 +134,8 @@ def resolve_file(fn, d):
|
||||
if not newfn:
|
||||
raise IOError(errno.ENOENT, "file %s not found in %s" % (fn, bbpath))
|
||||
fn = newfn
|
||||
else:
|
||||
mark_dependency(d, fn)
|
||||
|
||||
mark_dependency(d, fn)
|
||||
if not os.path.isfile(fn):
|
||||
raise IOError(errno.ENOENT, "file %s not found" % fn)
|
||||
|
||||
|
||||
@@ -335,12 +335,6 @@ def handleInherit(statements, filename, lineno, m):
|
||||
classes = m.group(1)
|
||||
statements.append(InheritNode(filename, lineno, classes))
|
||||
|
||||
def runAnonFuncs(d):
|
||||
code = []
|
||||
for funcname in d.getVar("__BBANONFUNCS", False) or []:
|
||||
code.append("%s(d)" % funcname)
|
||||
bb.utils.better_exec("\n".join(code), {"d": d})
|
||||
|
||||
def finalize(fn, d, variant = None):
|
||||
saved_handlers = bb.event.get_handlers().copy()
|
||||
|
||||
@@ -355,7 +349,10 @@ def finalize(fn, d, variant = None):
|
||||
bb.event.fire(bb.event.RecipePreFinalise(fn), d)
|
||||
|
||||
bb.data.expandKeys(d)
|
||||
runAnonFuncs(d)
|
||||
code = []
|
||||
for funcname in d.getVar("__BBANONFUNCS", False) or []:
|
||||
code.append("%s(d)" % funcname)
|
||||
bb.utils.better_exec("\n".join(code), {"d": d})
|
||||
|
||||
tasklist = d.getVar('__BBTASKS', False) or []
|
||||
bb.event.fire(bb.event.RecipeTaskPreProcess(fn, list(tasklist)), d)
|
||||
|
||||
@@ -131,6 +131,9 @@ def handle(fn, d, include):
|
||||
|
||||
abs_fn = resolve_file(fn, d)
|
||||
|
||||
if include:
|
||||
bb.parse.mark_dependency(d, abs_fn)
|
||||
|
||||
# actual loading
|
||||
statements = get_statements(fn, abs_fn, base_name)
|
||||
|
||||
|
||||
@@ -134,6 +134,9 @@ def handle(fn, data, include):
|
||||
abs_fn = resolve_file(fn, data)
|
||||
f = open(abs_fn, 'r')
|
||||
|
||||
if include:
|
||||
bb.parse.mark_dependency(data, abs_fn)
|
||||
|
||||
statements = ast.StatementGroup()
|
||||
lineno = 0
|
||||
while True:
|
||||
|
||||
@@ -244,17 +244,17 @@ def _filterProviders(providers, item, cfgData, dataCache):
|
||||
pkg_pn[pn] = []
|
||||
pkg_pn[pn].append(p)
|
||||
|
||||
logger.debug(1, "providers for %s are: %s", item, list(sorted(pkg_pn.keys())))
|
||||
logger.debug(1, "providers for %s are: %s", item, list(pkg_pn.keys()))
|
||||
|
||||
# First add PREFERRED_VERSIONS
|
||||
for pn in sorted(pkg_pn):
|
||||
for pn in pkg_pn:
|
||||
sortpkg_pn[pn] = sortPriorities(pn, dataCache, pkg_pn)
|
||||
preferred_versions[pn] = findPreferredProvider(pn, cfgData, dataCache, sortpkg_pn[pn], item)
|
||||
if preferred_versions[pn][1]:
|
||||
eligible.append(preferred_versions[pn][1])
|
||||
|
||||
# Now add latest versions
|
||||
for pn in sorted(sortpkg_pn):
|
||||
for pn in sortpkg_pn:
|
||||
if pn in preferred_versions and preferred_versions[pn][1]:
|
||||
continue
|
||||
preferred_versions[pn] = findLatestProvider(pn, cfgData, dataCache, sortpkg_pn[pn][0])
|
||||
|
||||
@@ -181,7 +181,7 @@ class RunQueueScheduler(object):
|
||||
if self.rq.stats.active < self.rq.number_tasks:
|
||||
return self.next_buildable_task()
|
||||
|
||||
def newbuildable(self, task):
|
||||
def newbuilable(self, task):
|
||||
self.buildable.append(task)
|
||||
|
||||
def describe_task(self, taskid):
|
||||
@@ -581,6 +581,12 @@ class RunQueueData:
|
||||
if t in taskData[mc].taskentries:
|
||||
depends.add(t)
|
||||
|
||||
def add_resolved_dependencies(mc, fn, tasknames, depends):
|
||||
for taskname in tasknames:
|
||||
tid = build_tid(mc, fn, taskname)
|
||||
if tid in self.runtaskentries:
|
||||
depends.add(tid)
|
||||
|
||||
for mc in taskData:
|
||||
for tid in taskData[mc].taskentries:
|
||||
|
||||
@@ -667,106 +673,57 @@ class RunQueueData:
|
||||
recursiveitasks[tid].append(newdep)
|
||||
|
||||
self.runtaskentries[tid].depends = depends
|
||||
# Remove all self references
|
||||
self.runtaskentries[tid].depends.discard(tid)
|
||||
|
||||
#self.dump_data()
|
||||
|
||||
self.init_progress_reporter.next_stage()
|
||||
|
||||
# Resolve recursive 'recrdeptask' dependencies (Part B)
|
||||
#
|
||||
# e.g. do_sometask[recrdeptask] = "do_someothertask"
|
||||
# (makes sure sometask runs after someothertask of all DEPENDS, RDEPENDS and intertask dependencies, recursively)
|
||||
# We need to do this separately since we need all of runtaskentries[*].depends to be complete before this is processed
|
||||
self.init_progress_reporter.next_stage(len(recursivetasks))
|
||||
extradeps = {}
|
||||
for taskcounter, tid in enumerate(recursivetasks):
|
||||
extradeps[tid] = set(self.runtaskentries[tid].depends)
|
||||
|
||||
# Generating/interating recursive lists of dependencies is painful and potentially slow
|
||||
# Precompute recursive task dependencies here by:
|
||||
# a) create a temp list of reverse dependencies (revdeps)
|
||||
# b) walk up the ends of the chains (when a given task no longer has dependencies i.e. len(deps) == 0)
|
||||
# c) combine the total list of dependencies in cumulativedeps
|
||||
# d) optimise by pre-truncating 'task' off the items in cumulativedeps (keeps items in sets lower)
|
||||
tasknames = recursivetasks[tid]
|
||||
seendeps = set()
|
||||
|
||||
def generate_recdeps(t):
|
||||
newdeps = set()
|
||||
(mc, fn, taskname, _) = split_tid_mcfn(t)
|
||||
add_resolved_dependencies(mc, fn, tasknames, newdeps)
|
||||
extradeps[tid].update(newdeps)
|
||||
seendeps.add(t)
|
||||
newdeps.add(t)
|
||||
for i in newdeps:
|
||||
if i not in self.runtaskentries:
|
||||
# Not all recipes might have the recrdeptask task as a task
|
||||
continue
|
||||
task = self.runtaskentries[i].task
|
||||
for n in self.runtaskentries[i].depends:
|
||||
if n not in seendeps:
|
||||
generate_recdeps(n)
|
||||
generate_recdeps(tid)
|
||||
|
||||
if tid in recursiveitasks:
|
||||
for dep in recursiveitasks[tid]:
|
||||
generate_recdeps(dep)
|
||||
self.init_progress_reporter.update(taskcounter)
|
||||
|
||||
# Remove circular references so that do_a[recrdeptask] = "do_a do_b" can work
|
||||
for tid in recursivetasks:
|
||||
extradeps[tid].difference_update(recursivetasksselfref)
|
||||
|
||||
revdeps = {}
|
||||
deps = {}
|
||||
cumulativedeps = {}
|
||||
for tid in self.runtaskentries:
|
||||
deps[tid] = set(self.runtaskentries[tid].depends)
|
||||
revdeps[tid] = set()
|
||||
cumulativedeps[tid] = set()
|
||||
# Generate a temp list of reverse dependencies
|
||||
for tid in self.runtaskentries:
|
||||
for dep in self.runtaskentries[tid].depends:
|
||||
revdeps[dep].add(tid)
|
||||
# Find the dependency chain endpoints
|
||||
endpoints = set()
|
||||
for tid in self.runtaskentries:
|
||||
if len(deps[tid]) == 0:
|
||||
endpoints.add(tid)
|
||||
# Iterate the chains collating dependencies
|
||||
while endpoints:
|
||||
next = set()
|
||||
for tid in endpoints:
|
||||
for dep in revdeps[tid]:
|
||||
cumulativedeps[dep].add(fn_from_tid(tid))
|
||||
cumulativedeps[dep].update(cumulativedeps[tid])
|
||||
if tid in deps[dep]:
|
||||
deps[dep].remove(tid)
|
||||
if len(deps[dep]) == 0:
|
||||
next.add(dep)
|
||||
endpoints = next
|
||||
#for tid in deps:
|
||||
# if len(deps[tid]) != 0:
|
||||
# bb.warn("Sanity test failure, dependencies left for %s (%s)" % (tid, deps[tid]))
|
||||
|
||||
# Loop here since recrdeptasks can depend upon other recrdeptasks and we have to
|
||||
# resolve these recursively until we aren't adding any further extra dependencies
|
||||
extradeps = True
|
||||
while extradeps:
|
||||
extradeps = 0
|
||||
for tid in recursivetasks:
|
||||
tasknames = recursivetasks[tid]
|
||||
|
||||
totaldeps = set(self.runtaskentries[tid].depends)
|
||||
if tid in recursiveitasks:
|
||||
totaldeps.update(recursiveitasks[tid])
|
||||
for dep in recursiveitasks[tid]:
|
||||
if dep not in self.runtaskentries:
|
||||
continue
|
||||
totaldeps.update(self.runtaskentries[dep].depends)
|
||||
|
||||
deps = set()
|
||||
for dep in totaldeps:
|
||||
if dep in cumulativedeps:
|
||||
deps.update(cumulativedeps[dep])
|
||||
|
||||
for t in deps:
|
||||
for taskname in tasknames:
|
||||
newtid = t + ":" + taskname
|
||||
if newtid == tid:
|
||||
continue
|
||||
if newtid in self.runtaskentries and newtid not in self.runtaskentries[tid].depends:
|
||||
extradeps += 1
|
||||
self.runtaskentries[tid].depends.add(newtid)
|
||||
|
||||
# Handle recursive tasks which depend upon other recursive tasks
|
||||
deps = set()
|
||||
for dep in self.runtaskentries[tid].depends.intersection(recursivetasks):
|
||||
deps.update(self.runtaskentries[dep].depends.difference(self.runtaskentries[tid].depends))
|
||||
for newtid in deps:
|
||||
for taskname in tasknames:
|
||||
if not newtid.endswith(":" + taskname):
|
||||
continue
|
||||
if newtid in self.runtaskentries:
|
||||
extradeps += 1
|
||||
self.runtaskentries[tid].depends.add(newtid)
|
||||
|
||||
bb.debug(1, "Added %s recursive dependencies in this loop" % extradeps)
|
||||
|
||||
# Remove recrdeptask circular references so that do_a[recrdeptask] = "do_a do_b" can work
|
||||
for tid in recursivetasksselfref:
|
||||
self.runtaskentries[tid].depends.difference_update(recursivetasksselfref)
|
||||
task = self.runtaskentries[tid].task
|
||||
# Add in extra dependencies
|
||||
if tid in extradeps:
|
||||
self.runtaskentries[tid].depends = extradeps[tid]
|
||||
# Remove all self references
|
||||
if tid in self.runtaskentries[tid].depends:
|
||||
logger.debug(2, "Task %s contains self reference!", tid)
|
||||
self.runtaskentries[tid].depends.remove(tid)
|
||||
|
||||
self.init_progress_reporter.next_stage()
|
||||
|
||||
@@ -841,57 +798,30 @@ class RunQueueData:
|
||||
#
|
||||
# Once all active tasks are marked, prune the ones we don't need.
|
||||
|
||||
delcount = {}
|
||||
delcount = 0
|
||||
for tid in list(self.runtaskentries.keys()):
|
||||
if tid not in runq_build:
|
||||
delcount[tid] = self.runtaskentries[tid]
|
||||
del self.runtaskentries[tid]
|
||||
|
||||
# Handle --runall
|
||||
if self.cooker.configuration.runall:
|
||||
# re-run the mark_active and then drop unused tasks from new list
|
||||
runq_build = {}
|
||||
|
||||
for task in self.cooker.configuration.runall:
|
||||
runall_tids = set()
|
||||
for tid in list(self.runtaskentries):
|
||||
wanttid = fn_from_tid(tid) + ":do_%s" % task
|
||||
if wanttid in delcount:
|
||||
self.runtaskentries[wanttid] = delcount[wanttid]
|
||||
if wanttid in self.runtaskentries:
|
||||
runall_tids.add(wanttid)
|
||||
|
||||
for tid in list(runall_tids):
|
||||
mark_active(tid,1)
|
||||
|
||||
for tid in list(self.runtaskentries.keys()):
|
||||
if tid not in runq_build:
|
||||
delcount[tid] = self.runtaskentries[tid]
|
||||
del self.runtaskentries[tid]
|
||||
|
||||
if len(self.runtaskentries) == 0:
|
||||
bb.msg.fatal("RunQueue", "Could not find any tasks with the tasknames %s to run within the recipes of the taskgraphs of the targets %s" % (str(self.cooker.configuration.runall), str(self.targets)))
|
||||
delcount += 1
|
||||
|
||||
self.init_progress_reporter.next_stage()
|
||||
|
||||
# Handle runonly
|
||||
if self.cooker.configuration.runonly:
|
||||
if self.cooker.configuration.runall is not None:
|
||||
runall = "do_%s" % self.cooker.configuration.runall
|
||||
runall_tids = { k: v for k, v in self.runtaskentries.items() if taskname_from_tid(k) == runall }
|
||||
|
||||
# re-run the mark_active and then drop unused tasks from new list
|
||||
runq_build = {}
|
||||
|
||||
for task in self.cooker.configuration.runonly:
|
||||
runonly_tids = { k: v for k, v in self.runtaskentries.items() if taskname_from_tid(k) == "do_%s" % task }
|
||||
|
||||
for tid in list(runonly_tids):
|
||||
mark_active(tid,1)
|
||||
for tid in list(runall_tids):
|
||||
mark_active(tid,1)
|
||||
|
||||
for tid in list(self.runtaskentries.keys()):
|
||||
if tid not in runq_build:
|
||||
delcount[tid] = self.runtaskentries[tid]
|
||||
del self.runtaskentries[tid]
|
||||
delcount += 1
|
||||
|
||||
if len(self.runtaskentries) == 0:
|
||||
bb.msg.fatal("RunQueue", "Could not find any tasks with the tasknames %s to run within the taskgraphs of the targets %s" % (str(self.cooker.configuration.runonly), str(self.targets)))
|
||||
bb.msg.fatal("RunQueue", "No remaining tasks to run for build target %s with runall %s" % (target, runall))
|
||||
|
||||
#
|
||||
# Step D - Sanity checks and computation
|
||||
@@ -904,7 +834,7 @@ class RunQueueData:
|
||||
else:
|
||||
bb.msg.fatal("RunQueue", "No active tasks and not in --continue mode?! Please report this bug.")
|
||||
|
||||
logger.verbose("Pruned %s inactive tasks, %s left", len(delcount), len(self.runtaskentries))
|
||||
logger.verbose("Pruned %s inactive tasks, %s left", delcount, len(self.runtaskentries))
|
||||
|
||||
logger.verbose("Assign Weightings")
|
||||
|
||||
@@ -1851,7 +1781,7 @@ class RunQueueExecuteTasks(RunQueueExecute):
|
||||
|
||||
def setbuildable(self, task):
|
||||
self.runq_buildable.add(task)
|
||||
self.sched.newbuildable(task)
|
||||
self.sched.newbuilable(task)
|
||||
|
||||
def task_completeoutright(self, task):
|
||||
"""
|
||||
|
||||
@@ -223,8 +223,6 @@ class ProcessServer(multiprocessing.Process):
|
||||
|
||||
try:
|
||||
self.cooker.shutdown(True)
|
||||
self.cooker.notifier.stop()
|
||||
self.cooker.confignotifier.stop()
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
820
bitbake/lib/bb/shell.py
Normal file
@@ -0,0 +1,820 @@
|
||||
# ex:ts=4:sw=4:sts=4:et
|
||||
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
|
||||
##########################################################################
|
||||
#
|
||||
# Copyright (C) 2005-2006 Michael 'Mickey' Lauer <mickey@Vanille.de>
|
||||
# Copyright (C) 2005-2006 Vanille Media
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
##########################################################################
|
||||
#
|
||||
# Thanks to:
|
||||
# * Holger Freyther <zecke@handhelds.org>
|
||||
# * Justin Patrin <papercrane@reversefold.com>
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
"""
|
||||
BitBake Shell
|
||||
|
||||
IDEAS:
|
||||
* list defined tasks per package
|
||||
* list classes
|
||||
* toggle force
|
||||
* command to reparse just one (or more) bbfile(s)
|
||||
* automatic check if reparsing is necessary (inotify?)
|
||||
* frontend for bb file manipulation
|
||||
* more shell-like features:
|
||||
- output control, i.e. pipe output into grep, sort, etc.
|
||||
- job control, i.e. bring running commands into background and foreground
|
||||
* start parsing in background right after startup
|
||||
* ncurses interface
|
||||
|
||||
PROBLEMS:
|
||||
* force doesn't always work
|
||||
* readline completion for commands with more than one parameters
|
||||
|
||||
"""
|
||||
|
||||
##########################################################################
|
||||
# Import and setup global variables
|
||||
##########################################################################
|
||||
|
||||
from __future__ import print_function
|
||||
from functools import reduce
|
||||
try:
|
||||
set
|
||||
except NameError:
|
||||
from sets import Set as set
|
||||
import sys, os, readline, socket, httplib, urllib, commands, popen2, shlex, Queue, fnmatch
|
||||
from bb import data, parse, build, cache, taskdata, runqueue, providers as Providers
|
||||
|
||||
__version__ = "0.5.3.1"
|
||||
__credits__ = """BitBake Shell Version %s (C) 2005 Michael 'Mickey' Lauer <mickey@Vanille.de>
|
||||
Type 'help' for more information, press CTRL-D to exit.""" % __version__
|
||||
|
||||
cmds = {}
|
||||
leave_mainloop = False
|
||||
last_exception = None
|
||||
cooker = None
|
||||
parsed = False
|
||||
debug = os.environ.get( "BBSHELL_DEBUG", "" )
|
||||
|
||||
##########################################################################
|
||||
# Class BitBakeShellCommands
|
||||
##########################################################################
|
||||
|
||||
class BitBakeShellCommands:
|
||||
"""This class contains the valid commands for the shell"""
|
||||
|
||||
def __init__( self, shell ):
|
||||
"""Register all the commands"""
|
||||
self._shell = shell
|
||||
for attr in BitBakeShellCommands.__dict__:
|
||||
if not attr.startswith( "_" ):
|
||||
if attr.endswith( "_" ):
|
||||
command = attr[:-1].lower()
|
||||
else:
|
||||
command = attr[:].lower()
|
||||
method = getattr( BitBakeShellCommands, attr )
|
||||
debugOut( "registering command '%s'" % command )
|
||||
# scan number of arguments
|
||||
usage = getattr( method, "usage", "" )
|
||||
if usage != "<...>":
|
||||
numArgs = len( usage.split() )
|
||||
else:
|
||||
numArgs = -1
|
||||
shell.registerCommand( command, method, numArgs, "%s %s" % ( command, usage ), method.__doc__ )
|
||||
|
||||
def _checkParsed( self ):
|
||||
if not parsed:
|
||||
print("SHELL: This command needs to parse bbfiles...")
|
||||
self.parse( None )
|
||||
|
||||
def _findProvider( self, item ):
|
||||
self._checkParsed()
|
||||
# Need to use taskData for this information
|
||||
preferred = data.getVar( "PREFERRED_PROVIDER_%s" % item, cooker.configuration.data, 1 )
|
||||
if not preferred: preferred = item
|
||||
try:
|
||||
lv, lf, pv, pf = Providers.findBestProvider(preferred, cooker.configuration.data, cooker.status)
|
||||
except KeyError:
|
||||
if item in cooker.status.providers:
|
||||
pf = cooker.status.providers[item][0]
|
||||
else:
|
||||
pf = None
|
||||
return pf
|
||||
|
||||
def alias( self, params ):
|
||||
"""Register a new name for a command"""
|
||||
new, old = params
|
||||
if not old in cmds:
|
||||
print("ERROR: Command '%s' not known" % old)
|
||||
else:
|
||||
cmds[new] = cmds[old]
|
||||
print("OK")
|
||||
alias.usage = "<alias> <command>"
|
||||
|
||||
def buffer( self, params ):
|
||||
"""Dump specified output buffer"""
|
||||
index = params[0]
|
||||
print(self._shell.myout.buffer( int( index ) ))
|
||||
buffer.usage = "<index>"
|
||||
|
||||
def buffers( self, params ):
|
||||
"""Show the available output buffers"""
|
||||
commands = self._shell.myout.bufferedCommands()
|
||||
if not commands:
|
||||
print("SHELL: No buffered commands available yet. Start doing something.")
|
||||
else:
|
||||
print("="*35, "Available Output Buffers", "="*27)
|
||||
for index, cmd in enumerate( commands ):
|
||||
print("| %s %s" % ( str( index ).ljust( 3 ), cmd ))
|
||||
print("="*88)
|
||||
|
||||
def build( self, params, cmd = "build" ):
|
||||
"""Build a providee"""
|
||||
global last_exception
|
||||
globexpr = params[0]
|
||||
self._checkParsed()
|
||||
names = globfilter( cooker.status.pkg_pn, globexpr )
|
||||
if len( names ) == 0: names = [ globexpr ]
|
||||
print("SHELL: Building %s" % ' '.join( names ))
|
||||
|
||||
td = taskdata.TaskData(cooker.configuration.abort)
|
||||
localdata = data.createCopy(cooker.configuration.data)
|
||||
data.update_data(localdata)
|
||||
data.expandKeys(localdata)
|
||||
|
||||
try:
|
||||
tasks = []
|
||||
for name in names:
|
||||
td.add_provider(localdata, cooker.status, name)
|
||||
providers = td.get_provider(name)
|
||||
|
||||
if len(providers) == 0:
|
||||
raise Providers.NoProvider
|
||||
|
||||
tasks.append([name, "do_%s" % cmd])
|
||||
|
||||
td.add_unresolved(localdata, cooker.status)
|
||||
|
||||
rq = runqueue.RunQueue(cooker, localdata, cooker.status, td, tasks)
|
||||
rq.prepare_runqueue()
|
||||
rq.execute_runqueue()
|
||||
|
||||
except Providers.NoProvider:
|
||||
print("ERROR: No Provider")
|
||||
last_exception = Providers.NoProvider
|
||||
|
||||
except runqueue.TaskFailure as fnids:
|
||||
last_exception = runqueue.TaskFailure
|
||||
|
||||
except build.FuncFailed as e:
|
||||
print("ERROR: Couldn't build '%s'" % names)
|
||||
last_exception = e
|
||||
|
||||
|
||||
build.usage = "<providee>"
|
||||
|
||||
def clean( self, params ):
|
||||
"""Clean a providee"""
|
||||
self.build( params, "clean" )
|
||||
clean.usage = "<providee>"
|
||||
|
||||
def compile( self, params ):
|
||||
"""Execute 'compile' on a providee"""
|
||||
self.build( params, "compile" )
|
||||
compile.usage = "<providee>"
|
||||
|
||||
def configure( self, params ):
|
||||
"""Execute 'configure' on a providee"""
|
||||
self.build( params, "configure" )
|
||||
configure.usage = "<providee>"
|
||||
|
||||
def install( self, params ):
|
||||
"""Execute 'install' on a providee"""
|
||||
self.build( params, "install" )
|
||||
install.usage = "<providee>"
|
||||
|
||||
def edit( self, params ):
|
||||
"""Call $EDITOR on a providee"""
|
||||
name = params[0]
|
||||
bbfile = self._findProvider( name )
|
||||
if bbfile is not None:
|
||||
os.system( "%s %s" % ( os.environ.get( "EDITOR", "vi" ), bbfile ) )
|
||||
else:
|
||||
print("ERROR: Nothing provides '%s'" % name)
|
||||
edit.usage = "<providee>"
|
||||
|
||||
def environment( self, params ):
|
||||
"""Dump out the outer BitBake environment"""
|
||||
cooker.showEnvironment()
|
||||
|
||||
def exit_( self, params ):
|
||||
"""Leave the BitBake Shell"""
|
||||
debugOut( "setting leave_mainloop to true" )
|
||||
global leave_mainloop
|
||||
leave_mainloop = True
|
||||
|
||||
def fetch( self, params ):
|
||||
"""Fetch a providee"""
|
||||
self.build( params, "fetch" )
|
||||
fetch.usage = "<providee>"
|
||||
|
||||
def fileBuild( self, params, cmd = "build" ):
|
||||
"""Parse and build a .bb file"""
|
||||
global last_exception
|
||||
name = params[0]
|
||||
bf = completeFilePath( name )
|
||||
print("SHELL: Calling '%s' on '%s'" % ( cmd, bf ))
|
||||
|
||||
try:
|
||||
cooker.buildFile(bf, cmd)
|
||||
except parse.ParseError:
|
||||
print("ERROR: Unable to open or parse '%s'" % bf)
|
||||
except build.FuncFailed as e:
|
||||
print("ERROR: Couldn't build '%s'" % name)
|
||||
last_exception = e
|
||||
|
||||
fileBuild.usage = "<bbfile>"
|
||||
|
||||
def fileClean( self, params ):
|
||||
"""Clean a .bb file"""
|
||||
self.fileBuild( params, "clean" )
|
||||
fileClean.usage = "<bbfile>"
|
||||
|
||||
def fileEdit( self, params ):
|
||||
"""Call $EDITOR on a .bb file"""
|
||||
name = params[0]
|
||||
os.system( "%s %s" % ( os.environ.get( "EDITOR", "vi" ), completeFilePath( name ) ) )
|
||||
fileEdit.usage = "<bbfile>"
|
||||
|
||||
def fileRebuild( self, params ):
|
||||
"""Rebuild (clean & build) a .bb file"""
|
||||
self.fileBuild( params, "rebuild" )
|
||||
fileRebuild.usage = "<bbfile>"
|
||||
|
||||
def fileReparse( self, params ):
|
||||
"""(re)Parse a bb file"""
|
||||
bbfile = params[0]
|
||||
print("SHELL: Parsing '%s'" % bbfile)
|
||||
parse.update_mtime( bbfile )
|
||||
cooker.parser.reparse(bbfile)
|
||||
if False: #fromCache:
|
||||
print("SHELL: File has not been updated, not reparsing")
|
||||
else:
|
||||
print("SHELL: Parsed")
|
||||
fileReparse.usage = "<bbfile>"
|
||||
|
||||
def abort( self, params ):
|
||||
"""Toggle abort task execution flag (see bitbake -k)"""
|
||||
cooker.configuration.abort = not cooker.configuration.abort
|
||||
print("SHELL: Abort Flag is now '%s'" % repr( cooker.configuration.abort ))
|
||||
|
||||
def force( self, params ):
|
||||
"""Toggle force task execution flag (see bitbake -f)"""
|
||||
cooker.configuration.force = not cooker.configuration.force
|
||||
print("SHELL: Force Flag is now '%s'" % repr( cooker.configuration.force ))
|
||||
|
||||
def help( self, params ):
|
||||
"""Show a comprehensive list of commands and their purpose"""
|
||||
print("="*30, "Available Commands", "="*30)
|
||||
for cmd in sorted(cmds):
|
||||
function, numparams, usage, helptext = cmds[cmd]
|
||||
print("| %s | %s" % (usage.ljust(30), helptext))
|
||||
print("="*78)
|
||||
|
||||
def lastError( self, params ):
|
||||
"""Show the reason or log that was produced by the last BitBake event exception"""
|
||||
if last_exception is None:
|
||||
print("SHELL: No Errors yet (Phew)...")
|
||||
else:
|
||||
reason, event = last_exception.args
|
||||
print("SHELL: Reason for the last error: '%s'" % reason)
|
||||
if ':' in reason:
|
||||
msg, filename = reason.split( ':' )
|
||||
filename = filename.strip()
|
||||
print("SHELL: Dumping log file for last error:")
|
||||
try:
|
||||
print(open( filename ).read())
|
||||
except IOError:
|
||||
print("ERROR: Couldn't open '%s'" % filename)
|
||||
|
||||
def match( self, params ):
|
||||
"""Dump all files or providers matching a glob expression"""
|
||||
what, globexpr = params
|
||||
if what == "files":
|
||||
self._checkParsed()
|
||||
for key in globfilter( cooker.status.pkg_fn, globexpr ): print(key)
|
||||
elif what == "providers":
|
||||
self._checkParsed()
|
||||
for key in globfilter( cooker.status.pkg_pn, globexpr ): print(key)
|
||||
else:
|
||||
print("Usage: match %s" % self.print_.usage)
|
||||
match.usage = "<files|providers> <glob>"
|
||||
|
||||
def new( self, params ):
|
||||
"""Create a new .bb file and open the editor"""
|
||||
dirname, filename = params
|
||||
packages = '/'.join( data.getVar( "BBFILES", cooker.configuration.data, 1 ).split('/')[:-2] )
|
||||
fulldirname = "%s/%s" % ( packages, dirname )
|
||||
|
||||
if not os.path.exists( fulldirname ):
|
||||
print("SHELL: Creating '%s'" % fulldirname)
|
||||
os.mkdir( fulldirname )
|
||||
if os.path.exists( fulldirname ) and os.path.isdir( fulldirname ):
|
||||
if os.path.exists( "%s/%s" % ( fulldirname, filename ) ):
|
||||
print("SHELL: ERROR: %s/%s already exists" % ( fulldirname, filename ))
|
||||
return False
|
||||
print("SHELL: Creating '%s/%s'" % ( fulldirname, filename ))
|
||||
newpackage = open( "%s/%s" % ( fulldirname, filename ), "w" )
|
||||
print("""DESCRIPTION = ""
|
||||
SECTION = ""
|
||||
AUTHOR = ""
|
||||
HOMEPAGE = ""
|
||||
MAINTAINER = ""
|
||||
LICENSE = "GPL"
|
||||
PR = "r0"
|
||||
|
||||
SRC_URI = ""
|
||||
|
||||
#inherit base
|
||||
|
||||
#do_configure() {
|
||||
#
|
||||
#}
|
||||
|
||||
#do_compile() {
|
||||
#
|
||||
#}
|
||||
|
||||
#do_stage() {
|
||||
#
|
||||
#}
|
||||
|
||||
#do_install() {
|
||||
#
|
||||
#}
|
||||
""", file=newpackage)
|
||||
newpackage.close()
|
||||
os.system( "%s %s/%s" % ( os.environ.get( "EDITOR" ), fulldirname, filename ) )
|
||||
new.usage = "<directory> <filename>"
|
||||
|
||||
def package( self, params ):
|
||||
"""Execute 'package' on a providee"""
|
||||
self.build( params, "package" )
|
||||
package.usage = "<providee>"
|
||||
|
||||
def pasteBin( self, params ):
|
||||
"""Send a command + output buffer to the pastebin at http://rafb.net/paste"""
|
||||
index = params[0]
|
||||
contents = self._shell.myout.buffer( int( index ) )
|
||||
sendToPastebin( "output of " + params[0], contents )
|
||||
pasteBin.usage = "<index>"
|
||||
|
||||
def pasteLog( self, params ):
|
||||
"""Send the last event exception error log (if there is one) to http://rafb.net/paste"""
|
||||
if last_exception is None:
|
||||
print("SHELL: No Errors yet (Phew)...")
|
||||
else:
|
||||
reason, event = last_exception.args
|
||||
print("SHELL: Reason for the last error: '%s'" % reason)
|
||||
if ':' in reason:
|
||||
msg, filename = reason.split( ':' )
|
||||
filename = filename.strip()
|
||||
print("SHELL: Pasting log file to pastebin...")
|
||||
|
||||
file = open( filename ).read()
|
||||
sendToPastebin( "contents of " + filename, file )
|
||||
|
||||
def patch( self, params ):
|
||||
"""Execute 'patch' command on a providee"""
|
||||
self.build( params, "patch" )
|
||||
patch.usage = "<providee>"
|
||||
|
||||
def parse( self, params ):
|
||||
"""(Re-)parse .bb files and calculate the dependency graph"""
|
||||
cooker.status = cache.CacheData(cooker.caches_array)
|
||||
ignore = data.getVar("ASSUME_PROVIDED", cooker.configuration.data, 1) or ""
|
||||
cooker.status.ignored_dependencies = set( ignore.split() )
|
||||
cooker.handleCollections( data.getVar("BBFILE_COLLECTIONS", cooker.configuration.data, 1) )
|
||||
|
||||
(filelist, masked) = cooker.collect_bbfiles()
|
||||
cooker.parse_bbfiles(filelist, masked, cooker.myProgressCallback)
|
||||
cooker.buildDepgraph()
|
||||
global parsed
|
||||
parsed = True
|
||||
print()
|
||||
|
||||
def reparse( self, params ):
|
||||
"""(re)Parse a providee's bb file"""
|
||||
bbfile = self._findProvider( params[0] )
|
||||
if bbfile is not None:
|
||||
print("SHELL: Found bbfile '%s' for '%s'" % ( bbfile, params[0] ))
|
||||
self.fileReparse( [ bbfile ] )
|
||||
else:
|
||||
print("ERROR: Nothing provides '%s'" % params[0])
|
||||
reparse.usage = "<providee>"
|
||||
|
||||
def getvar( self, params ):
|
||||
"""Dump the contents of an outer BitBake environment variable"""
|
||||
var = params[0]
|
||||
value = data.getVar( var, cooker.configuration.data, 1 )
|
||||
print(value)
|
||||
getvar.usage = "<variable>"
|
||||
|
||||
def peek( self, params ):
|
||||
"""Dump contents of variable defined in providee's metadata"""
|
||||
name, var = params
|
||||
bbfile = self._findProvider( name )
|
||||
if bbfile is not None:
|
||||
the_data = cache.Cache.loadDataFull(bbfile, cooker.configuration.data)
|
||||
value = the_data.getVar( var, 1 )
|
||||
print(value)
|
||||
else:
|
||||
print("ERROR: Nothing provides '%s'" % name)
|
||||
peek.usage = "<providee> <variable>"
|
||||
|
||||
def poke( self, params ):
|
||||
"""Set contents of variable defined in providee's metadata"""
|
||||
name, var, value = params
|
||||
bbfile = self._findProvider( name )
|
||||
if bbfile is not None:
|
||||
print("ERROR: Sorry, this functionality is currently broken")
|
||||
#d = cooker.pkgdata[bbfile]
|
||||
#data.setVar( var, value, d )
|
||||
|
||||
# mark the change semi persistant
|
||||
#cooker.pkgdata.setDirty(bbfile, d)
|
||||
#print "OK"
|
||||
else:
|
||||
print("ERROR: Nothing provides '%s'" % name)
|
||||
poke.usage = "<providee> <variable> <value>"
|
||||
|
||||
def print_( self, params ):
|
||||
"""Dump all files or providers"""
|
||||
what = params[0]
|
||||
if what == "files":
|
||||
self._checkParsed()
|
||||
for key in cooker.status.pkg_fn: print(key)
|
||||
elif what == "providers":
|
||||
self._checkParsed()
|
||||
for key in cooker.status.providers: print(key)
|
||||
else:
|
||||
print("Usage: print %s" % self.print_.usage)
|
||||
print_.usage = "<files|providers>"
|
||||
|
||||
def python( self, params ):
|
||||
"""Enter the expert mode - an interactive BitBake Python Interpreter"""
|
||||
sys.ps1 = "EXPERT BB>>> "
|
||||
sys.ps2 = "EXPERT BB... "
|
||||
import code
|
||||
interpreter = code.InteractiveConsole( dict( globals() ) )
|
||||
interpreter.interact( "SHELL: Expert Mode - BitBake Python %s\nType 'help' for more information, press CTRL-D to switch back to BBSHELL." % sys.version )
|
||||
|
||||
def showdata( self, params ):
|
||||
"""Execute 'showdata' on a providee"""
|
||||
cooker.showEnvironment(None, params)
|
||||
showdata.usage = "<providee>"
|
||||
|
||||
def setVar( self, params ):
|
||||
"""Set an outer BitBake environment variable"""
|
||||
var, value = params
|
||||
data.setVar( var, value, cooker.configuration.data )
|
||||
print("OK")
|
||||
setVar.usage = "<variable> <value>"
|
||||
|
||||
def rebuild( self, params ):
|
||||
"""Clean and rebuild a .bb file or a providee"""
|
||||
self.build( params, "clean" )
|
||||
self.build( params, "build" )
|
||||
rebuild.usage = "<providee>"
|
||||
|
||||
def shell( self, params ):
|
||||
"""Execute a shell command and dump the output"""
|
||||
if params != "":
|
||||
print(commands.getoutput( " ".join( params ) ))
|
||||
shell.usage = "<...>"
|
||||
|
||||
def stage( self, params ):
|
||||
"""Execute 'stage' on a providee"""
|
||||
self.build( params, "populate_staging" )
|
||||
stage.usage = "<providee>"
|
||||
|
||||
def status( self, params ):
|
||||
"""<just for testing>"""
|
||||
print("-" * 78)
|
||||
print("building list = '%s'" % cooker.building_list)
|
||||
print("build path = '%s'" % cooker.build_path)
|
||||
print("consider_msgs_cache = '%s'" % cooker.consider_msgs_cache)
|
||||
print("build stats = '%s'" % cooker.stats)
|
||||
if last_exception is not None: print("last_exception = '%s'" % repr( last_exception.args ))
|
||||
print("memory output contents = '%s'" % self._shell.myout._buffer)
|
||||
|
||||
def test( self, params ):
|
||||
"""<just for testing>"""
|
||||
print("testCommand called with '%s'" % params)
|
||||
|
||||
def unpack( self, params ):
|
||||
"""Execute 'unpack' on a providee"""
|
||||
self.build( params, "unpack" )
|
||||
unpack.usage = "<providee>"
|
||||
|
||||
def which( self, params ):
|
||||
"""Computes the providers for a given providee"""
|
||||
# Need to use taskData for this information
|
||||
item = params[0]
|
||||
|
||||
self._checkParsed()
|
||||
|
||||
preferred = data.getVar( "PREFERRED_PROVIDER_%s" % item, cooker.configuration.data, 1 )
|
||||
if not preferred: preferred = item
|
||||
|
||||
try:
|
||||
lv, lf, pv, pf = Providers.findBestProvider(preferred, cooker.configuration.data, cooker.status)
|
||||
except KeyError:
|
||||
lv, lf, pv, pf = (None,)*4
|
||||
|
||||
try:
|
||||
providers = cooker.status.providers[item]
|
||||
except KeyError:
|
||||
print("SHELL: ERROR: Nothing provides", preferred)
|
||||
else:
|
||||
for provider in providers:
|
||||
if provider == pf: provider = " (***) %s" % provider
|
||||
else: provider = " %s" % provider
|
||||
print(provider)
|
||||
which.usage = "<providee>"
|
||||
|
||||
##########################################################################
|
||||
# Common helper functions
|
||||
##########################################################################
|
||||
|
||||
def completeFilePath( bbfile ):
|
||||
"""Get the complete bbfile path"""
|
||||
if not cooker.status: return bbfile
|
||||
if not cooker.status.pkg_fn: return bbfile
|
||||
for key in cooker.status.pkg_fn:
|
||||
if key.endswith( bbfile ):
|
||||
return key
|
||||
return bbfile
|
||||
|
||||
def sendToPastebin( desc, content ):
|
||||
"""Send content to http://oe.pastebin.com"""
|
||||
mydata = {}
|
||||
mydata["lang"] = "Plain Text"
|
||||
mydata["desc"] = desc
|
||||
mydata["cvt_tabs"] = "No"
|
||||
mydata["nick"] = "%s@%s" % ( os.environ.get( "USER", "unknown" ), socket.gethostname() or "unknown" )
|
||||
mydata["text"] = content
|
||||
params = urllib.urlencode( mydata )
|
||||
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
|
||||
|
||||
host = "rafb.net"
|
||||
conn = httplib.HTTPConnection( "%s:80" % host )
|
||||
conn.request("POST", "/paste/paste.php", params, headers )
|
||||
|
||||
response = conn.getresponse()
|
||||
conn.close()
|
||||
|
||||
if response.status == 302:
|
||||
location = response.getheader( "location" ) or "unknown"
|
||||
print("SHELL: Pasted to http://%s%s" % ( host, location ))
|
||||
else:
|
||||
print("ERROR: %s %s" % ( response.status, response.reason ))
|
||||
|
||||
def completer( text, state ):
|
||||
"""Return a possible readline completion"""
|
||||
debugOut( "completer called with text='%s', state='%d'" % ( text, state ) )
|
||||
|
||||
if state == 0:
|
||||
line = readline.get_line_buffer()
|
||||
if " " in line:
|
||||
line = line.split()
|
||||
# we are in second (or more) argument
|
||||
if line[0] in cmds and hasattr( cmds[line[0]][0], "usage" ): # known command and usage
|
||||
u = getattr( cmds[line[0]][0], "usage" ).split()[0]
|
||||
if u == "<variable>":
|
||||
allmatches = cooker.configuration.data.keys()
|
||||
elif u == "<bbfile>":
|
||||
if cooker.status.pkg_fn is None: allmatches = [ "(No Matches Available. Parsed yet?)" ]
|
||||
else: allmatches = [ x.split("/")[-1] for x in cooker.status.pkg_fn ]
|
||||
elif u == "<providee>":
|
||||
if cooker.status.pkg_fn is None: allmatches = [ "(No Matches Available. Parsed yet?)" ]
|
||||
else: allmatches = cooker.status.providers.iterkeys()
|
||||
else: allmatches = [ "(No tab completion available for this command)" ]
|
||||
else: allmatches = [ "(No tab completion available for this command)" ]
|
||||
else:
|
||||
# we are in first argument
|
||||
allmatches = cmds.iterkeys()
|
||||
|
||||
completer.matches = [ x for x in allmatches if x[:len(text)] == text ]
|
||||
#print "completer.matches = '%s'" % completer.matches
|
||||
if len( completer.matches ) > state:
|
||||
return completer.matches[state]
|
||||
else:
|
||||
return None
|
||||
|
||||
def debugOut( text ):
|
||||
if debug:
|
||||
sys.stderr.write( "( %s )\n" % text )
|
||||
|
||||
def columnize( alist, width = 80 ):
|
||||
"""
|
||||
A word-wrap function that preserves existing line breaks
|
||||
and most spaces in the text. Expects that existing line
|
||||
breaks are posix newlines (\n).
|
||||
"""
|
||||
return reduce(lambda line, word, width=width: '%s%s%s' %
|
||||
(line,
|
||||
' \n'[(len(line[line.rfind('\n')+1:])
|
||||
+ len(word.split('\n', 1)[0]
|
||||
) >= width)],
|
||||
word),
|
||||
alist
|
||||
)
|
||||
|
||||
def globfilter( names, pattern ):
|
||||
return fnmatch.filter( names, pattern )
|
||||
|
||||
##########################################################################
|
||||
# Class MemoryOutput
|
||||
##########################################################################
|
||||
|
||||
class MemoryOutput:
|
||||
"""File-like output class buffering the output of the last 10 commands"""
|
||||
def __init__( self, delegate ):
|
||||
self.delegate = delegate
|
||||
self._buffer = []
|
||||
self.text = []
|
||||
self._command = None
|
||||
|
||||
def startCommand( self, command ):
|
||||
self._command = command
|
||||
self.text = []
|
||||
def endCommand( self ):
|
||||
if self._command is not None:
|
||||
if len( self._buffer ) == 10: del self._buffer[0]
|
||||
self._buffer.append( ( self._command, self.text ) )
|
||||
def removeLast( self ):
|
||||
if self._buffer:
|
||||
del self._buffer[ len( self._buffer ) - 1 ]
|
||||
self.text = []
|
||||
self._command = None
|
||||
def lastBuffer( self ):
|
||||
if self._buffer:
|
||||
return self._buffer[ len( self._buffer ) -1 ][1]
|
||||
def bufferedCommands( self ):
|
||||
return [ cmd for cmd, output in self._buffer ]
|
||||
def buffer( self, i ):
|
||||
if i < len( self._buffer ):
|
||||
return "BB>> %s\n%s" % ( self._buffer[i][0], "".join( self._buffer[i][1] ) )
|
||||
else: return "ERROR: Invalid buffer number. Buffer needs to be in (0, %d)" % ( len( self._buffer ) - 1 )
|
||||
def write( self, text ):
|
||||
if self._command is not None and text != "BB>> ": self.text.append( text )
|
||||
if self.delegate is not None: self.delegate.write( text )
|
||||
def flush( self ):
|
||||
return self.delegate.flush()
|
||||
def fileno( self ):
|
||||
return self.delegate.fileno()
|
||||
def isatty( self ):
|
||||
return self.delegate.isatty()
|
||||
|
||||
##########################################################################
|
||||
# Class BitBakeShell
|
||||
##########################################################################
|
||||
|
||||
class BitBakeShell:
|
||||
|
||||
def __init__( self ):
|
||||
"""Register commands and set up readline"""
|
||||
self.commandQ = Queue.Queue()
|
||||
self.commands = BitBakeShellCommands( self )
|
||||
self.myout = MemoryOutput( sys.stdout )
|
||||
self.historyfilename = os.path.expanduser( "~/.bbsh_history" )
|
||||
self.startupfilename = os.path.expanduser( "~/.bbsh_startup" )
|
||||
|
||||
readline.set_completer( completer )
|
||||
readline.set_completer_delims( " " )
|
||||
readline.parse_and_bind("tab: complete")
|
||||
|
||||
try:
|
||||
readline.read_history_file( self.historyfilename )
|
||||
except IOError:
|
||||
pass # It doesn't exist yet.
|
||||
|
||||
print(__credits__)
|
||||
|
||||
def cleanup( self ):
|
||||
"""Write readline history and clean up resources"""
|
||||
debugOut( "writing command history" )
|
||||
try:
|
||||
readline.write_history_file( self.historyfilename )
|
||||
except:
|
||||
print("SHELL: Unable to save command history")
|
||||
|
||||
def registerCommand( self, command, function, numparams = 0, usage = "", helptext = "" ):
|
||||
"""Register a command"""
|
||||
if usage == "": usage = command
|
||||
if helptext == "": helptext = function.__doc__ or "<not yet documented>"
|
||||
cmds[command] = ( function, numparams, usage, helptext )
|
||||
|
||||
def processCommand( self, command, params ):
|
||||
"""Process a command. Check number of params and print a usage string, if appropriate"""
|
||||
debugOut( "processing command '%s'..." % command )
|
||||
try:
|
||||
function, numparams, usage, helptext = cmds[command]
|
||||
except KeyError:
|
||||
print("SHELL: ERROR: '%s' command is not a valid command." % command)
|
||||
self.myout.removeLast()
|
||||
else:
|
||||
if (numparams != -1) and (not len( params ) == numparams):
|
||||
print("Usage: '%s'" % usage)
|
||||
return
|
||||
|
||||
result = function( self.commands, params )
|
||||
debugOut( "result was '%s'" % result )
|
||||
|
||||
def processStartupFile( self ):
|
||||
"""Read and execute all commands found in $HOME/.bbsh_startup"""
|
||||
if os.path.exists( self.startupfilename ):
|
||||
startupfile = open( self.startupfilename, "r" )
|
||||
for cmdline in startupfile:
|
||||
debugOut( "processing startup line '%s'" % cmdline )
|
||||
if not cmdline:
|
||||
continue
|
||||
if "|" in cmdline:
|
||||
print("ERROR: '|' in startup file is not allowed. Ignoring line")
|
||||
continue
|
||||
self.commandQ.put( cmdline.strip() )
|
||||
|
||||
def main( self ):
|
||||
"""The main command loop"""
|
||||
while not leave_mainloop:
|
||||
try:
|
||||
if self.commandQ.empty():
|
||||
sys.stdout = self.myout.delegate
|
||||
cmdline = raw_input( "BB>> " )
|
||||
sys.stdout = self.myout
|
||||
else:
|
||||
cmdline = self.commandQ.get()
|
||||
if cmdline:
|
||||
allCommands = cmdline.split( ';' )
|
||||
for command in allCommands:
|
||||
pipecmd = None
|
||||
#
|
||||
# special case for expert mode
|
||||
if command == 'python':
|
||||
sys.stdout = self.myout.delegate
|
||||
self.processCommand( command, "" )
|
||||
sys.stdout = self.myout
|
||||
else:
|
||||
self.myout.startCommand( command )
|
||||
if '|' in command: # disable output
|
||||
command, pipecmd = command.split( '|' )
|
||||
delegate = self.myout.delegate
|
||||
self.myout.delegate = None
|
||||
tokens = shlex.split( command, True )
|
||||
self.processCommand( tokens[0], tokens[1:] or "" )
|
||||
self.myout.endCommand()
|
||||
if pipecmd is not None: # restore output
|
||||
self.myout.delegate = delegate
|
||||
|
||||
pipe = popen2.Popen4( pipecmd )
|
||||
pipe.tochild.write( "\n".join( self.myout.lastBuffer() ) )
|
||||
pipe.tochild.close()
|
||||
sys.stdout.write( pipe.fromchild.read() )
|
||||
#
|
||||
except EOFError:
|
||||
print()
|
||||
return
|
||||
except KeyboardInterrupt:
|
||||
print()
|
||||
|
||||
##########################################################################
|
||||
# Start function - called from the BitBake command line utility
|
||||
##########################################################################
|
||||
|
||||
def start( aCooker ):
|
||||
global cooker
|
||||
cooker = aCooker
|
||||
bbshell = BitBakeShell()
|
||||
bbshell.processStartupFile()
|
||||
bbshell.main()
|
||||
bbshell.cleanup()
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("SHELL: Sorry, this program should only be called by BitBake.")
|
||||
@@ -30,45 +30,28 @@ import time
|
||||
import pickle
|
||||
from unittest.mock import Mock
|
||||
from unittest.mock import call
|
||||
from bb.msg import BBLogFormatter
|
||||
|
||||
|
||||
class EventQueueStubBase(object):
|
||||
""" Base class for EventQueueStub classes """
|
||||
def __init__(self):
|
||||
self.event_calls = []
|
||||
return
|
||||
|
||||
def _store_event_data_string(self, event):
|
||||
if isinstance(event, logging.LogRecord):
|
||||
formatter = BBLogFormatter("%(levelname)s: %(message)s")
|
||||
self.event_calls.append(formatter.format(event))
|
||||
else:
|
||||
self.event_calls.append(bb.event.getName(event))
|
||||
return
|
||||
|
||||
|
||||
class EventQueueStub(EventQueueStubBase):
|
||||
class EventQueueStub():
|
||||
""" Class used as specification for UI event handler queue stub objects """
|
||||
def __init__(self):
|
||||
super(EventQueueStub, self).__init__()
|
||||
return
|
||||
|
||||
def send(self, event):
|
||||
super(EventQueueStub, self)._store_event_data_string(event)
|
||||
return
|
||||
|
||||
|
||||
class PickleEventQueueStub(EventQueueStubBase):
|
||||
class PickleEventQueueStub():
|
||||
""" Class used as specification for UI event handler queue stub objects
|
||||
with sendpickle method """
|
||||
def __init__(self):
|
||||
super(PickleEventQueueStub, self).__init__()
|
||||
return
|
||||
|
||||
def sendpickle(self, pickled_event):
|
||||
event = pickle.loads(pickled_event)
|
||||
super(PickleEventQueueStub, self)._store_event_data_string(event)
|
||||
return
|
||||
|
||||
|
||||
class UIClientStub(object):
|
||||
class UIClientStub():
|
||||
""" Class used as specification for UI event handler stub objects """
|
||||
def __init__(self):
|
||||
self.event = None
|
||||
@@ -76,7 +59,7 @@ class UIClientStub(object):
|
||||
|
||||
class EventHandlingTest(unittest.TestCase):
|
||||
""" Event handling test class """
|
||||
|
||||
_threadlock_test_calls = []
|
||||
|
||||
def setUp(self):
|
||||
self._test_process = Mock()
|
||||
@@ -196,33 +179,6 @@ class EventHandlingTest(unittest.TestCase):
|
||||
self.assertEqual(self._test_process.event_handler2.call_args_list,
|
||||
expected_event_handler2)
|
||||
|
||||
def test_class_handler_filters(self):
|
||||
""" Test filters for class handlers """
|
||||
mask = ["bb.event.OperationStarted"]
|
||||
result = bb.event.register("event_handler1",
|
||||
self._test_process.event_handler1,
|
||||
mask)
|
||||
self.assertEqual(result, bb.event.Registered)
|
||||
result = bb.event.register("event_handler2",
|
||||
self._test_process.event_handler2,
|
||||
"*")
|
||||
self.assertEqual(result, bb.event.Registered)
|
||||
bb.event.set_eventfilter(
|
||||
lambda name, handler, event, d :
|
||||
name == 'event_handler2' and
|
||||
bb.event.getName(event) == "OperationStarted")
|
||||
event1 = bb.event.OperationStarted()
|
||||
event2 = bb.event.OperationCompleted(total=123)
|
||||
bb.event.fire_class_handlers(event1, None)
|
||||
bb.event.fire_class_handlers(event2, None)
|
||||
bb.event.fire_class_handlers(event2, None)
|
||||
expected_event_handler1 = []
|
||||
expected_event_handler2 = [call(event1)]
|
||||
self.assertEqual(self._test_process.event_handler1.call_args_list,
|
||||
expected_event_handler1)
|
||||
self.assertEqual(self._test_process.event_handler2.call_args_list,
|
||||
expected_event_handler2)
|
||||
|
||||
def test_change_handler_event_mapping(self):
|
||||
""" Test changing the event mapping for class handlers """
|
||||
event1 = bb.event.OperationStarted()
|
||||
@@ -240,8 +196,8 @@ class EventHandlingTest(unittest.TestCase):
|
||||
expected)
|
||||
|
||||
# unregister handler and register it only for OperationStarted
|
||||
bb.event.remove("event_handler1",
|
||||
self._test_process.event_handler1)
|
||||
result = bb.event.remove("event_handler1",
|
||||
self._test_process.event_handler1)
|
||||
mask = ["bb.event.OperationStarted"]
|
||||
result = bb.event.register("event_handler1",
|
||||
self._test_process.event_handler1,
|
||||
@@ -254,8 +210,8 @@ class EventHandlingTest(unittest.TestCase):
|
||||
expected)
|
||||
|
||||
# unregister handler and register it only for OperationCompleted
|
||||
bb.event.remove("event_handler1",
|
||||
self._test_process.event_handler1)
|
||||
result = bb.event.remove("event_handler1",
|
||||
self._test_process.event_handler1)
|
||||
mask = ["bb.event.OperationCompleted"]
|
||||
result = bb.event.register("event_handler1",
|
||||
self._test_process.event_handler1,
|
||||
@@ -303,61 +259,6 @@ class EventHandlingTest(unittest.TestCase):
|
||||
self.assertEqual(self._test_ui2.event.sendpickle.call_args_list,
|
||||
expected)
|
||||
|
||||
def test_ui_handler_mask_filter(self):
|
||||
""" Test filters for UI handlers """
|
||||
mask = ["bb.event.OperationStarted"]
|
||||
debug_domains = {}
|
||||
self._test_ui1.event = Mock(spec_set=EventQueueStub)
|
||||
result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
|
||||
bb.event.set_UIHmask(result, logging.INFO, debug_domains, mask)
|
||||
self._test_ui2.event = Mock(spec_set=PickleEventQueueStub)
|
||||
result = bb.event.register_UIHhandler(self._test_ui2, mainui=True)
|
||||
bb.event.set_UIHmask(result, logging.INFO, debug_domains, mask)
|
||||
|
||||
event1 = bb.event.OperationStarted()
|
||||
event2 = bb.event.OperationCompleted(total=1)
|
||||
|
||||
bb.event.fire_ui_handlers(event1, None)
|
||||
bb.event.fire_ui_handlers(event2, None)
|
||||
expected = [call(event1)]
|
||||
self.assertEqual(self._test_ui1.event.send.call_args_list,
|
||||
expected)
|
||||
expected = [call(pickle.dumps(event1))]
|
||||
self.assertEqual(self._test_ui2.event.sendpickle.call_args_list,
|
||||
expected)
|
||||
|
||||
def test_ui_handler_log_filter(self):
|
||||
""" Test log filters for UI handlers """
|
||||
mask = ["*"]
|
||||
debug_domains = {'BitBake.Foo': logging.WARNING}
|
||||
|
||||
self._test_ui1.event = EventQueueStub()
|
||||
result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
|
||||
bb.event.set_UIHmask(result, logging.ERROR, debug_domains, mask)
|
||||
self._test_ui2.event = PickleEventQueueStub()
|
||||
result = bb.event.register_UIHhandler(self._test_ui2, mainui=True)
|
||||
bb.event.set_UIHmask(result, logging.ERROR, debug_domains, mask)
|
||||
|
||||
event1 = bb.event.OperationStarted()
|
||||
bb.event.fire_ui_handlers(event1, None) # All events match
|
||||
|
||||
event_log_handler = bb.event.LogHandler()
|
||||
logger = logging.getLogger("BitBake")
|
||||
logger.addHandler(event_log_handler)
|
||||
logger1 = logging.getLogger("BitBake.Foo")
|
||||
logger1.warning("Test warning LogRecord1") # Matches debug_domains level
|
||||
logger1.info("Test info LogRecord") # Filtered out
|
||||
logger2 = logging.getLogger("BitBake.Bar")
|
||||
logger2.error("Test error LogRecord") # Matches filter base level
|
||||
logger2.warning("Test warning LogRecord2") # Filtered out
|
||||
logger.removeHandler(event_log_handler)
|
||||
|
||||
expected = ['OperationStarted',
|
||||
'WARNING: Test warning LogRecord1',
|
||||
'ERROR: Test error LogRecord']
|
||||
self.assertEqual(self._test_ui1.event.event_calls, expected)
|
||||
self.assertEqual(self._test_ui2.event.event_calls, expected)
|
||||
|
||||
def test_fire(self):
|
||||
""" Test fire method used to trigger class and ui event handlers """
|
||||
mask = ["bb.event.ConfigParsed"]
|
||||
@@ -388,28 +289,18 @@ class EventHandlingTest(unittest.TestCase):
|
||||
self.assertEqual(self._test_ui1.event.send.call_args_list,
|
||||
expected)
|
||||
|
||||
def test_worker_fire(self):
|
||||
""" Test the triggering of bb.event.worker_fire callback """
|
||||
bb.event.worker_fire = Mock()
|
||||
event = bb.event.Event()
|
||||
bb.event.fire(event, None)
|
||||
expected = [call(event, None)]
|
||||
self.assertEqual(bb.event.worker_fire.call_args_list, expected)
|
||||
|
||||
def test_print_ui_queue(self):
|
||||
""" Test print_ui_queue method """
|
||||
event1 = bb.event.OperationStarted()
|
||||
event2 = bb.event.OperationCompleted(total=123)
|
||||
bb.event.fire(event1, None)
|
||||
bb.event.fire(event2, None)
|
||||
event_log_handler = bb.event.LogHandler()
|
||||
logger = logging.getLogger("BitBake")
|
||||
logger.addHandler(event_log_handler)
|
||||
logger.addHandler(bb.event.LogHandler())
|
||||
logger.info("Test info LogRecord")
|
||||
logger.warning("Test warning LogRecord")
|
||||
with self.assertLogs("BitBake", level="INFO") as cm:
|
||||
bb.event.print_ui_queue()
|
||||
logger.removeHandler(event_log_handler)
|
||||
self.assertEqual(cm.output,
|
||||
["INFO:BitBake:Test info LogRecord",
|
||||
"WARNING:BitBake:Test warning LogRecord"])
|
||||
@@ -473,7 +364,6 @@ class EventHandlingTest(unittest.TestCase):
|
||||
self.assertEqual(self._threadlock_test_calls,
|
||||
["w1_ui1", "w1_ui2", "w2_ui1", "w2_ui2"])
|
||||
|
||||
|
||||
def test_disable_threadlock(self):
|
||||
""" Test disable_threadlock method """
|
||||
self._set_threadlock_test_mockups()
|
||||
@@ -485,502 +375,3 @@ class EventHandlingTest(unittest.TestCase):
|
||||
# processed before finishing handling the first worker event.
|
||||
self.assertEqual(self._threadlock_test_calls,
|
||||
["w1_ui1", "w2_ui1", "w1_ui2", "w2_ui2"])
|
||||
|
||||
|
||||
class EventClassesTest(unittest.TestCase):
|
||||
""" Event classes test class """
|
||||
|
||||
_worker_pid = 54321
|
||||
|
||||
def setUp(self):
|
||||
bb.event.worker_pid = EventClassesTest._worker_pid
|
||||
|
||||
def test_Event(self):
|
||||
""" Test the Event base class """
|
||||
event = bb.event.Event()
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_HeartbeatEvent(self):
|
||||
""" Test the HeartbeatEvent class """
|
||||
time = 10
|
||||
event = bb.event.HeartbeatEvent(time)
|
||||
self.assertEqual(event.time, time)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_OperationStarted(self):
|
||||
""" Test OperationStarted event class """
|
||||
msg = "Foo Bar"
|
||||
event = bb.event.OperationStarted(msg)
|
||||
self.assertEqual(event.msg, msg)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_OperationCompleted(self):
|
||||
""" Test OperationCompleted event class """
|
||||
msg = "Foo Bar"
|
||||
total = 123
|
||||
event = bb.event.OperationCompleted(total, msg)
|
||||
self.assertEqual(event.msg, msg)
|
||||
self.assertEqual(event.total, total)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_OperationProgress(self):
|
||||
""" Test OperationProgress event class """
|
||||
msg = "Foo Bar"
|
||||
total = 123
|
||||
current = 111
|
||||
event = bb.event.OperationProgress(current, total, msg)
|
||||
self.assertEqual(event.msg, msg + ": %s/%s" % (current, total))
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_ConfigParsed(self):
|
||||
""" Test the ConfigParsed class """
|
||||
event = bb.event.ConfigParsed()
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_MultiConfigParsed(self):
|
||||
""" Test MultiConfigParsed event class """
|
||||
mcdata = {"foobar": "Foo Bar"}
|
||||
event = bb.event.MultiConfigParsed(mcdata)
|
||||
self.assertEqual(event.mcdata, mcdata)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_RecipeEvent(self):
|
||||
""" Test RecipeEvent event base class """
|
||||
callback = lambda a: 2 * a
|
||||
event = bb.event.RecipeEvent(callback)
|
||||
self.assertEqual(event.fn(1), callback(1))
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_RecipePreFinalise(self):
|
||||
""" Test RecipePreFinalise event class """
|
||||
callback = lambda a: 2 * a
|
||||
event = bb.event.RecipePreFinalise(callback)
|
||||
self.assertEqual(event.fn(1), callback(1))
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_RecipeTaskPreProcess(self):
|
||||
""" Test RecipeTaskPreProcess event class """
|
||||
callback = lambda a: 2 * a
|
||||
tasklist = [("foobar", callback)]
|
||||
event = bb.event.RecipeTaskPreProcess(callback, tasklist)
|
||||
self.assertEqual(event.fn(1), callback(1))
|
||||
self.assertEqual(event.tasklist, tasklist)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_RecipeParsed(self):
|
||||
""" Test RecipeParsed event base class """
|
||||
callback = lambda a: 2 * a
|
||||
event = bb.event.RecipeParsed(callback)
|
||||
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"
|
||||
pkgs = ["bar"]
|
||||
failures = 123
|
||||
event = bb.event.BuildBase(name, pkgs, failures)
|
||||
self.assertEqual(event.name, name)
|
||||
self.assertEqual(event.pkgs, pkgs)
|
||||
self.assertEqual(event.getFailures(), failures)
|
||||
name = event.name = "bar"
|
||||
pkgs = event.pkgs = ["foo"]
|
||||
self.assertEqual(event.name, name)
|
||||
self.assertEqual(event.pkgs, pkgs)
|
||||
self.assertEqual(event.getFailures(), failures)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_BuildInit(self):
|
||||
""" Test class for bitbake build invocation events """
|
||||
event = bb.event.BuildInit()
|
||||
self.assertEqual(event.name, None)
|
||||
self.assertEqual(event.pkgs, [])
|
||||
self.assertEqual(event.getFailures(), 0)
|
||||
name = event.name = "bar"
|
||||
pkgs = event.pkgs = ["foo"]
|
||||
self.assertEqual(event.name, name)
|
||||
self.assertEqual(event.pkgs, pkgs)
|
||||
self.assertEqual(event.getFailures(), 0)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_BuildStarted(self):
|
||||
""" Test class for build started events """
|
||||
name = "foo"
|
||||
pkgs = ["bar"]
|
||||
failures = 123
|
||||
event = bb.event.BuildStarted(name, pkgs, failures)
|
||||
self.assertEqual(event.name, name)
|
||||
self.assertEqual(event.pkgs, pkgs)
|
||||
self.assertEqual(event.getFailures(), failures)
|
||||
self.assertEqual(event.msg, "Building Started")
|
||||
name = event.name = "bar"
|
||||
pkgs = event.pkgs = ["foo"]
|
||||
msg = event.msg = "foobar"
|
||||
self.assertEqual(event.name, name)
|
||||
self.assertEqual(event.pkgs, pkgs)
|
||||
self.assertEqual(event.getFailures(), failures)
|
||||
self.assertEqual(event.msg, msg)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_BuildCompleted(self):
|
||||
""" Test class for build completed events """
|
||||
total = 1000
|
||||
name = "foo"
|
||||
pkgs = ["bar"]
|
||||
failures = 123
|
||||
interrupted = 1
|
||||
event = bb.event.BuildCompleted(total, name, pkgs, failures,
|
||||
interrupted)
|
||||
self.assertEqual(event.name, name)
|
||||
self.assertEqual(event.pkgs, pkgs)
|
||||
self.assertEqual(event.getFailures(), failures)
|
||||
self.assertEqual(event.msg, "Building Failed")
|
||||
event2 = bb.event.BuildCompleted(total, name, pkgs)
|
||||
self.assertEqual(event2.name, name)
|
||||
self.assertEqual(event2.pkgs, pkgs)
|
||||
self.assertEqual(event2.getFailures(), 0)
|
||||
self.assertEqual(event2.msg, "Building Succeeded")
|
||||
self.assertEqual(event2.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_DiskFull(self):
|
||||
""" Test DiskFull event class """
|
||||
dev = "/dev/foo"
|
||||
type = "ext4"
|
||||
freespace = "104M"
|
||||
mountpoint = "/"
|
||||
event = bb.event.DiskFull(dev, type, freespace, mountpoint)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_MonitorDiskEvent(self):
|
||||
""" Test MonitorDiskEvent class """
|
||||
available_bytes = 10000000
|
||||
free_bytes = 90000000
|
||||
total_bytes = 1000000000
|
||||
du = bb.event.DiskUsageSample(available_bytes, free_bytes,
|
||||
total_bytes)
|
||||
event = bb.event.MonitorDiskEvent(du)
|
||||
self.assertEqual(event.disk_usage.available_bytes, available_bytes)
|
||||
self.assertEqual(event.disk_usage.free_bytes, free_bytes)
|
||||
self.assertEqual(event.disk_usage.total_bytes, total_bytes)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_NoProvider(self):
|
||||
""" Test NoProvider event class """
|
||||
item = "foobar"
|
||||
event1 = bb.event.NoProvider(item)
|
||||
self.assertEqual(event1.getItem(), item)
|
||||
self.assertEqual(event1.isRuntime(), False)
|
||||
self.assertEqual(str(event1), "Nothing PROVIDES 'foobar'")
|
||||
runtime = True
|
||||
dependees = ["foo", "bar"]
|
||||
reasons = None
|
||||
close_matches = ["foibar", "footbar"]
|
||||
event2 = bb.event.NoProvider(item, runtime, dependees, reasons,
|
||||
close_matches)
|
||||
self.assertEqual(event2.isRuntime(), True)
|
||||
expected = ("Nothing RPROVIDES 'foobar' (but foo, bar RDEPENDS"
|
||||
" on or otherwise requires it). Close matches:\n"
|
||||
" foibar\n"
|
||||
" footbar")
|
||||
self.assertEqual(str(event2), expected)
|
||||
reasons = ["Item does not exist on database"]
|
||||
close_matches = ["foibar", "footbar"]
|
||||
event3 = bb.event.NoProvider(item, runtime, dependees, reasons,
|
||||
close_matches)
|
||||
expected = ("Nothing RPROVIDES 'foobar' (but foo, bar RDEPENDS"
|
||||
" on or otherwise requires it)\n"
|
||||
"Item does not exist on database")
|
||||
self.assertEqual(str(event3), expected)
|
||||
self.assertEqual(event3.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_MultipleProviders(self):
|
||||
""" Test MultipleProviders event class """
|
||||
item = "foobar"
|
||||
candidates = ["foobarv1", "foobars"]
|
||||
event1 = bb.event.MultipleProviders(item, candidates)
|
||||
self.assertEqual(event1.isRuntime(), False)
|
||||
self.assertEqual(event1.getItem(), item)
|
||||
self.assertEqual(event1.getCandidates(), candidates)
|
||||
expected = ("Multiple providers are available for foobar (foobarv1,"
|
||||
" foobars)\n"
|
||||
"Consider defining a PREFERRED_PROVIDER entry to match "
|
||||
"foobar")
|
||||
self.assertEqual(str(event1), expected)
|
||||
runtime = True
|
||||
event2 = bb.event.MultipleProviders(item, candidates, runtime)
|
||||
self.assertEqual(event2.isRuntime(), runtime)
|
||||
expected = ("Multiple providers are available for runtime foobar "
|
||||
"(foobarv1, foobars)\n"
|
||||
"Consider defining a PREFERRED_RPROVIDER entry to match "
|
||||
"foobar")
|
||||
self.assertEqual(str(event2), expected)
|
||||
self.assertEqual(event2.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_ParseStarted(self):
|
||||
""" Test ParseStarted event class """
|
||||
total = 123
|
||||
event = bb.event.ParseStarted(total)
|
||||
self.assertEqual(event.msg, "Recipe parsing Started")
|
||||
self.assertEqual(event.total, total)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_ParseCompleted(self):
|
||||
""" Test ParseCompleted event class """
|
||||
cached = 10
|
||||
parsed = 13
|
||||
skipped = 7
|
||||
virtuals = 2
|
||||
masked = 1
|
||||
errors = 0
|
||||
total = 23
|
||||
event = bb.event.ParseCompleted(cached, parsed, skipped, masked,
|
||||
virtuals, errors, total)
|
||||
self.assertEqual(event.msg, "Recipe parsing Completed")
|
||||
expected = [cached, parsed, skipped, virtuals, masked, errors,
|
||||
cached + parsed, total]
|
||||
actual = [event.cached, event.parsed, event.skipped, event.virtuals,
|
||||
event.masked, event.errors, event.sofar, event.total]
|
||||
self.assertEqual(str(actual), str(expected))
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_ParseProgress(self):
|
||||
""" Test ParseProgress event class """
|
||||
current = 10
|
||||
total = 100
|
||||
event = bb.event.ParseProgress(current, total)
|
||||
self.assertEqual(event.msg,
|
||||
"Recipe parsing" + ": %s/%s" % (current, total))
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_CacheLoadStarted(self):
|
||||
""" Test CacheLoadStarted event class """
|
||||
total = 123
|
||||
event = bb.event.CacheLoadStarted(total)
|
||||
self.assertEqual(event.msg, "Loading cache Started")
|
||||
self.assertEqual(event.total, total)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_CacheLoadProgress(self):
|
||||
""" Test CacheLoadProgress event class """
|
||||
current = 10
|
||||
total = 100
|
||||
event = bb.event.CacheLoadProgress(current, total)
|
||||
self.assertEqual(event.msg,
|
||||
"Loading cache" + ": %s/%s" % (current, total))
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_CacheLoadCompleted(self):
|
||||
""" Test CacheLoadCompleted event class """
|
||||
total = 23
|
||||
num_entries = 12
|
||||
event = bb.event.CacheLoadCompleted(total, num_entries)
|
||||
self.assertEqual(event.msg, "Loading cache Completed")
|
||||
expected = [total, num_entries]
|
||||
actual = [event.total, event.num_entries]
|
||||
self.assertEqual(str(actual), str(expected))
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_TreeDataPreparationStarted(self):
|
||||
""" Test TreeDataPreparationStarted event class """
|
||||
event = bb.event.TreeDataPreparationStarted()
|
||||
self.assertEqual(event.msg, "Preparing tree data Started")
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_TreeDataPreparationProgress(self):
|
||||
""" Test TreeDataPreparationProgress event class """
|
||||
current = 10
|
||||
total = 100
|
||||
event = bb.event.TreeDataPreparationProgress(current, total)
|
||||
self.assertEqual(event.msg,
|
||||
"Preparing tree data" + ": %s/%s" % (current, total))
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_TreeDataPreparationCompleted(self):
|
||||
""" Test TreeDataPreparationCompleted event class """
|
||||
total = 23
|
||||
event = bb.event.TreeDataPreparationCompleted(total)
|
||||
self.assertEqual(event.msg, "Preparing tree data Completed")
|
||||
self.assertEqual(event.total, total)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_DepTreeGenerated(self):
|
||||
""" Test DepTreeGenerated event class """
|
||||
depgraph = Mock()
|
||||
event = bb.event.DepTreeGenerated(depgraph)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_TargetsTreeGenerated(self):
|
||||
""" Test TargetsTreeGenerated event class """
|
||||
model = Mock()
|
||||
event = bb.event.TargetsTreeGenerated(model)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_ReachableStamps(self):
|
||||
""" Test ReachableStamps event class """
|
||||
stamps = [Mock(), Mock()]
|
||||
event = bb.event.ReachableStamps(stamps)
|
||||
self.assertEqual(event.stamps, stamps)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_FilesMatchingFound(self):
|
||||
""" Test FilesMatchingFound event class """
|
||||
pattern = "foo.*bar"
|
||||
matches = ["foobar"]
|
||||
event = bb.event.FilesMatchingFound(pattern, matches)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_ConfigFilesFound(self):
|
||||
""" Test ConfigFilesFound event class """
|
||||
variable = "FOO_BAR"
|
||||
values = ["foo", "bar"]
|
||||
event = bb.event.ConfigFilesFound(variable, values)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_ConfigFilePathFound(self):
|
||||
""" Test ConfigFilePathFound event class """
|
||||
path = "/foo/bar"
|
||||
event = bb.event.ConfigFilePathFound(path)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_message_classes(self):
|
||||
""" Test message event classes """
|
||||
msg = "foobar foo bar"
|
||||
event = bb.event.MsgBase(msg)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
event = bb.event.MsgDebug(msg)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
event = bb.event.MsgNote(msg)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
event = bb.event.MsgWarn(msg)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
event = bb.event.MsgError(msg)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
event = bb.event.MsgFatal(msg)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
event = bb.event.MsgPlain(msg)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_LogExecTTY(self):
|
||||
""" Test LogExecTTY event class """
|
||||
msg = "foo bar"
|
||||
prog = "foo.sh"
|
||||
sleep_delay = 10
|
||||
retries = 3
|
||||
event = bb.event.LogExecTTY(msg, prog, sleep_delay, retries)
|
||||
self.assertEqual(event.msg, msg)
|
||||
self.assertEqual(event.prog, prog)
|
||||
self.assertEqual(event.sleep_delay, sleep_delay)
|
||||
self.assertEqual(event.retries, retries)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def _throw_zero_division_exception(self):
|
||||
a = 1 / 0
|
||||
return
|
||||
|
||||
def _worker_handler(self, event, d):
|
||||
self._returned_event = event
|
||||
return
|
||||
|
||||
def test_LogHandler(self):
|
||||
""" Test LogHandler class """
|
||||
logger = logging.getLogger("TestEventClasses")
|
||||
logger.propagate = False
|
||||
handler = bb.event.LogHandler(logging.INFO)
|
||||
logger.addHandler(handler)
|
||||
bb.event.worker_fire = self._worker_handler
|
||||
try:
|
||||
self._throw_zero_division_exception()
|
||||
except ZeroDivisionError as ex:
|
||||
logger.exception(ex)
|
||||
event = self._returned_event
|
||||
try:
|
||||
pe = pickle.dumps(event)
|
||||
newevent = pickle.loads(pe)
|
||||
except:
|
||||
self.fail('Logged event is not serializable')
|
||||
self.assertEqual(event.taskpid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_MetadataEvent(self):
|
||||
""" Test MetadataEvent class """
|
||||
eventtype = "footype"
|
||||
eventdata = {"foo": "bar"}
|
||||
event = bb.event.MetadataEvent(eventtype, eventdata)
|
||||
self.assertEqual(event.type, eventtype)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_ProcessStarted(self):
|
||||
""" Test ProcessStarted class """
|
||||
processname = "foo"
|
||||
total = 9783128974
|
||||
event = bb.event.ProcessStarted(processname, total)
|
||||
self.assertEqual(event.processname, processname)
|
||||
self.assertEqual(event.total, total)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_ProcessProgress(self):
|
||||
""" Test ProcessProgress class """
|
||||
processname = "foo"
|
||||
progress = 243224
|
||||
event = bb.event.ProcessProgress(processname, progress)
|
||||
self.assertEqual(event.processname, processname)
|
||||
self.assertEqual(event.progress, progress)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_ProcessFinished(self):
|
||||
""" Test ProcessFinished class """
|
||||
processname = "foo"
|
||||
total = 1242342344
|
||||
event = bb.event.ProcessFinished(processname)
|
||||
self.assertEqual(event.processname, processname)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_SanityCheck(self):
|
||||
""" Test SanityCheck class """
|
||||
event1 = bb.event.SanityCheck()
|
||||
self.assertEqual(event1.generateevents, True)
|
||||
self.assertEqual(event1.pid, EventClassesTest._worker_pid)
|
||||
generateevents = False
|
||||
event2 = bb.event.SanityCheck(generateevents)
|
||||
self.assertEqual(event2.generateevents, generateevents)
|
||||
self.assertEqual(event2.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_SanityCheckPassed(self):
|
||||
""" Test SanityCheckPassed class """
|
||||
event = bb.event.SanityCheckPassed()
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_SanityCheckFailed(self):
|
||||
""" Test SanityCheckFailed class """
|
||||
msg = "The sanity test failed."
|
||||
event1 = bb.event.SanityCheckFailed(msg)
|
||||
self.assertEqual(event1.pid, EventClassesTest._worker_pid)
|
||||
network_error = True
|
||||
event2 = bb.event.SanityCheckFailed(msg, network_error)
|
||||
self.assertEqual(event2.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_network_event_classes(self):
|
||||
""" Test network event classes """
|
||||
event1 = bb.event.NetworkTest()
|
||||
generateevents = False
|
||||
self.assertEqual(event1.pid, EventClassesTest._worker_pid)
|
||||
event2 = bb.event.NetworkTest(generateevents)
|
||||
self.assertEqual(event2.pid, EventClassesTest._worker_pid)
|
||||
event3 = bb.event.NetworkTestPassed()
|
||||
self.assertEqual(event3.pid, EventClassesTest._worker_pid)
|
||||
event4 = bb.event.NetworkTestFailed()
|
||||
self.assertEqual(event4.pid, EventClassesTest._worker_pid)
|
||||
|
||||
def test_FindSigInfoResult(self):
|
||||
""" Test FindSigInfoResult event class """
|
||||
result = [Mock()]
|
||||
event = bb.event.FindSigInfoResult(result)
|
||||
self.assertEqual(event.result, result)
|
||||
self.assertEqual(event.pid, EventClassesTest._worker_pid)
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#
|
||||
|
||||
import unittest
|
||||
import hashlib
|
||||
import tempfile
|
||||
import subprocess
|
||||
import collections
|
||||
@@ -523,109 +522,6 @@ class FetcherLocalTest(FetcherTest):
|
||||
with self.assertRaises(bb.fetch2.UnpackError):
|
||||
self.fetchUnpack(['file://a;subdir=/bin/sh'])
|
||||
|
||||
class FetcherNoNetworkTest(FetcherTest):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
# all test cases are based on not having network
|
||||
self.d.setVar("BB_NO_NETWORK", "1")
|
||||
|
||||
def test_missing(self):
|
||||
string = "this is a test file\n".encode("utf-8")
|
||||
self.d.setVarFlag("SRC_URI", "md5sum", hashlib.md5(string).hexdigest())
|
||||
self.d.setVarFlag("SRC_URI", "sha256sum", hashlib.sha256(string).hexdigest())
|
||||
|
||||
self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
|
||||
self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
|
||||
fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/test-file.tar.gz"], self.d)
|
||||
with self.assertRaises(bb.fetch2.NetworkAccess):
|
||||
fetcher.download()
|
||||
|
||||
def test_valid_missing_donestamp(self):
|
||||
# create the file in the download directory with correct hash
|
||||
string = "this is a test file\n".encode("utf-8")
|
||||
with open(os.path.join(self.dldir, "test-file.tar.gz"), "wb") as f:
|
||||
f.write(string)
|
||||
|
||||
self.d.setVarFlag("SRC_URI", "md5sum", hashlib.md5(string).hexdigest())
|
||||
self.d.setVarFlag("SRC_URI", "sha256sum", hashlib.sha256(string).hexdigest())
|
||||
|
||||
self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
|
||||
self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
|
||||
fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/test-file.tar.gz"], self.d)
|
||||
fetcher.download()
|
||||
self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
|
||||
|
||||
def test_invalid_missing_donestamp(self):
|
||||
# create an invalid file in the download directory with incorrect hash
|
||||
string = "this is a test file\n".encode("utf-8")
|
||||
with open(os.path.join(self.dldir, "test-file.tar.gz"), "wb"):
|
||||
pass
|
||||
|
||||
self.d.setVarFlag("SRC_URI", "md5sum", hashlib.md5(string).hexdigest())
|
||||
self.d.setVarFlag("SRC_URI", "sha256sum", hashlib.sha256(string).hexdigest())
|
||||
|
||||
self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
|
||||
self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
|
||||
fetcher = bb.fetch.Fetch(["http://invalid.yoctoproject.org/test-file.tar.gz"], self.d)
|
||||
with self.assertRaises(bb.fetch2.NetworkAccess):
|
||||
fetcher.download()
|
||||
# the existing file should not exist or should have be moved to "bad-checksum"
|
||||
self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
|
||||
|
||||
def test_nochecksums_missing(self):
|
||||
self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
|
||||
self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
|
||||
# ssh fetch does not support checksums
|
||||
fetcher = bb.fetch.Fetch(["ssh://invalid@invalid.yoctoproject.org/test-file.tar.gz"], self.d)
|
||||
# attempts to download with missing donestamp
|
||||
with self.assertRaises(bb.fetch2.NetworkAccess):
|
||||
fetcher.download()
|
||||
|
||||
def test_nochecksums_missing_donestamp(self):
|
||||
# create a file in the download directory
|
||||
with open(os.path.join(self.dldir, "test-file.tar.gz"), "wb"):
|
||||
pass
|
||||
|
||||
self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
|
||||
self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
|
||||
# ssh fetch does not support checksums
|
||||
fetcher = bb.fetch.Fetch(["ssh://invalid@invalid.yoctoproject.org/test-file.tar.gz"], self.d)
|
||||
# attempts to download with missing donestamp
|
||||
with self.assertRaises(bb.fetch2.NetworkAccess):
|
||||
fetcher.download()
|
||||
|
||||
def test_nochecksums_has_donestamp(self):
|
||||
# create a file in the download directory with the donestamp
|
||||
with open(os.path.join(self.dldir, "test-file.tar.gz"), "wb"):
|
||||
pass
|
||||
with open(os.path.join(self.dldir, "test-file.tar.gz.done"), "wb"):
|
||||
pass
|
||||
|
||||
self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
|
||||
self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
|
||||
# ssh fetch does not support checksums
|
||||
fetcher = bb.fetch.Fetch(["ssh://invalid@invalid.yoctoproject.org/test-file.tar.gz"], self.d)
|
||||
# should not fetch
|
||||
fetcher.download()
|
||||
# both files should still exist
|
||||
self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
|
||||
self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
|
||||
|
||||
def test_nochecksums_missing_has_donestamp(self):
|
||||
# create a file in the download directory with the donestamp
|
||||
with open(os.path.join(self.dldir, "test-file.tar.gz.done"), "wb"):
|
||||
pass
|
||||
|
||||
self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
|
||||
self.assertTrue(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
|
||||
# ssh fetch does not support checksums
|
||||
fetcher = bb.fetch.Fetch(["ssh://invalid@invalid.yoctoproject.org/test-file.tar.gz"], self.d)
|
||||
with self.assertRaises(bb.fetch2.NetworkAccess):
|
||||
fetcher.download()
|
||||
# both files should still exist
|
||||
self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz")))
|
||||
self.assertFalse(os.path.exists(os.path.join(self.dldir, "test-file.tar.gz.done")))
|
||||
|
||||
class FetcherNetworkTest(FetcherTest):
|
||||
@skipIfNoNetwork()
|
||||
def test_fetch(self):
|
||||
@@ -913,7 +809,7 @@ class FetchLatestVersionTest(FetcherTest):
|
||||
ud = bb.fetch2.FetchData(k[1], self.d)
|
||||
pupver= ud.method.latest_versionstring(ud, self.d)
|
||||
verstring = pupver[0]
|
||||
self.assertTrue(verstring, msg="Could not find upstream version for %s" % k[0])
|
||||
self.assertTrue(verstring, msg="Could not find upstream version")
|
||||
r = bb.utils.vercmp_string(v, verstring)
|
||||
self.assertTrue(r == -1 or r == 0, msg="Package %s, version: %s <= %s" % (k[0], v, verstring))
|
||||
|
||||
@@ -926,7 +822,7 @@ class FetchLatestVersionTest(FetcherTest):
|
||||
ud = bb.fetch2.FetchData(k[1], self.d)
|
||||
pupver = ud.method.latest_versionstring(ud, self.d)
|
||||
verstring = pupver[0]
|
||||
self.assertTrue(verstring, msg="Could not find upstream version for %s" % k[0])
|
||||
self.assertTrue(verstring, msg="Could not find upstream version")
|
||||
r = bb.utils.vercmp_string(v, verstring)
|
||||
self.assertTrue(r == -1 or r == 0, msg="Package %s, version: %s <= %s" % (k[0], v, verstring))
|
||||
|
||||
@@ -978,6 +874,9 @@ class FetchCheckStatusTest(FetcherTest):
|
||||
|
||||
|
||||
class GitMakeShallowTest(FetcherTest):
|
||||
bitbake_dir = os.path.join(os.path.dirname(os.path.join(__file__)), '..', '..', '..')
|
||||
make_shallow_path = os.path.join(bitbake_dir, 'bin', 'git-make-shallow')
|
||||
|
||||
def setUp(self):
|
||||
FetcherTest.setUp(self)
|
||||
self.gitdir = os.path.join(self.tempdir, 'gitshallow')
|
||||
@@ -1006,7 +905,7 @@ class GitMakeShallowTest(FetcherTest):
|
||||
def make_shallow(self, args=None):
|
||||
if args is None:
|
||||
args = ['HEAD']
|
||||
return bb.process.run([bb.fetch2.git.Git.make_shallow_path] + args, cwd=self.gitdir)
|
||||
return bb.process.run([self.make_shallow_path] + args, cwd=self.gitdir)
|
||||
|
||||
def add_empty_file(self, path, msg=None):
|
||||
if msg is None:
|
||||
|
||||
@@ -604,16 +604,13 @@ class Tinfoil:
|
||||
recipecache = self.cooker.recipecaches[mc]
|
||||
prov = self.find_best_provider(pn)
|
||||
fn = prov[3]
|
||||
if fn:
|
||||
actual_pn = recipecache.pkg_fn[fn]
|
||||
recipe = TinfoilRecipeInfo(recipecache,
|
||||
self.config_data,
|
||||
pn=actual_pn,
|
||||
fn=fn,
|
||||
fns=recipecache.pkg_pn[actual_pn])
|
||||
return recipe
|
||||
else:
|
||||
return None
|
||||
actual_pn = recipecache.pkg_fn[fn]
|
||||
recipe = TinfoilRecipeInfo(recipecache,
|
||||
self.config_data,
|
||||
pn=actual_pn,
|
||||
fn=fn,
|
||||
fns=recipecache.pkg_pn[actual_pn])
|
||||
return recipe
|
||||
|
||||
def parse_recipe(self, pn):
|
||||
"""
|
||||
|
||||
@@ -719,11 +719,7 @@ class ORMWrapper(object):
|
||||
|
||||
def save_build_package_information(self, build_obj, package_info, recipes,
|
||||
built_package):
|
||||
# assert isinstance(build_obj, Build)
|
||||
|
||||
if not 'PN' in package_info.keys():
|
||||
# no package data to save (e.g. 'OPKGN'="lib64-*"|"lib32-*")
|
||||
return None
|
||||
# assert isinstance(build_obj, Build)
|
||||
|
||||
# create and save the object
|
||||
pname = package_info['PKG']
|
||||
|
||||
@@ -187,7 +187,7 @@ def explode_deps(s):
|
||||
#r[-1] += ' ' + ' '.join(j)
|
||||
return r
|
||||
|
||||
def explode_dep_versions2(s, *, sort=True):
|
||||
def explode_dep_versions2(s):
|
||||
"""
|
||||
Take an RDEPENDS style string of format:
|
||||
"DEPEND1 (optional version) DEPEND2 (optional version) ..."
|
||||
@@ -250,8 +250,7 @@ def explode_dep_versions2(s, *, sort=True):
|
||||
if not (i in r and r[i]):
|
||||
r[lastdep] = []
|
||||
|
||||
if sort:
|
||||
r = collections.OrderedDict(sorted(r.items(), key=lambda x: x[0]))
|
||||
r = collections.OrderedDict(sorted(r.items(), key=lambda x: x[0]))
|
||||
return r
|
||||
|
||||
def explode_dep_versions(s):
|
||||
@@ -807,8 +806,8 @@ def movefile(src, dest, newmtime = None, sstat = None):
|
||||
return None # failure
|
||||
try:
|
||||
if didcopy:
|
||||
os.lchown(destpath, sstat[stat.ST_UID], sstat[stat.ST_GID])
|
||||
os.chmod(destpath, stat.S_IMODE(sstat[stat.ST_MODE])) # Sticky is reset on chown
|
||||
os.lchown(dest, sstat[stat.ST_UID], sstat[stat.ST_GID])
|
||||
os.chmod(dest, stat.S_IMODE(sstat[stat.ST_MODE])) # Sticky is reset on chown
|
||||
os.unlink(src)
|
||||
except Exception as e:
|
||||
print("movefile: Failed to chown/chmod/unlink", dest, e)
|
||||
|
||||
@@ -18,18 +18,16 @@ def plugin_init(plugins):
|
||||
|
||||
class ActionPlugin(LayerPlugin):
|
||||
def do_add_layer(self, args):
|
||||
"""Add one or more layers to bblayers.conf."""
|
||||
layerdirs = [os.path.abspath(ldir) for ldir in args.layerdir]
|
||||
"""Add a layer to bblayers.conf."""
|
||||
layerdir = os.path.abspath(args.layerdir)
|
||||
if not os.path.exists(layerdir):
|
||||
sys.stderr.write("Specified layer directory doesn't exist\n")
|
||||
return 1
|
||||
|
||||
for layerdir in layerdirs:
|
||||
if not os.path.exists(layerdir):
|
||||
sys.stderr.write("Specified layer directory %s doesn't exist\n" % layerdir)
|
||||
return 1
|
||||
|
||||
layer_conf = os.path.join(layerdir, 'conf', 'layer.conf')
|
||||
if not os.path.exists(layer_conf):
|
||||
sys.stderr.write("Specified layer directory %s doesn't contain a conf/layer.conf file\n" % layerdir)
|
||||
return 1
|
||||
layer_conf = os.path.join(layerdir, 'conf', 'layer.conf')
|
||||
if not os.path.exists(layer_conf):
|
||||
sys.stderr.write("Specified layer directory doesn't contain a conf/layer.conf file\n")
|
||||
return 1
|
||||
|
||||
bblayers_conf = os.path.join('conf', 'bblayers.conf')
|
||||
if not os.path.exists(bblayers_conf):
|
||||
@@ -42,7 +40,7 @@ class ActionPlugin(LayerPlugin):
|
||||
shutil.copy2(bblayers_conf, backup)
|
||||
|
||||
try:
|
||||
notadded, _ = bb.utils.edit_bblayers_conf(bblayers_conf, layerdirs, None)
|
||||
notadded, _ = bb.utils.edit_bblayers_conf(bblayers_conf, layerdir, None)
|
||||
if not (args.force or notadded):
|
||||
try:
|
||||
self.tinfoil.parseRecipes()
|
||||
@@ -58,22 +56,19 @@ class ActionPlugin(LayerPlugin):
|
||||
shutil.rmtree(tempdir)
|
||||
|
||||
def do_remove_layer(self, args):
|
||||
"""Remove one or more layers from bblayers.conf."""
|
||||
"""Remove a layer from bblayers.conf."""
|
||||
bblayers_conf = os.path.join('conf', 'bblayers.conf')
|
||||
if not os.path.exists(bblayers_conf):
|
||||
sys.stderr.write("Unable to find bblayers.conf\n")
|
||||
return 1
|
||||
|
||||
layerdirs = []
|
||||
for item in args.layerdir:
|
||||
if item.startswith('*'):
|
||||
layerdir = item
|
||||
elif not '/' in item:
|
||||
layerdir = '*/%s' % item
|
||||
else:
|
||||
layerdir = os.path.abspath(item)
|
||||
layerdirs.append(layerdir)
|
||||
(_, notremoved) = bb.utils.edit_bblayers_conf(bblayers_conf, None, layerdirs)
|
||||
if args.layerdir.startswith('*'):
|
||||
layerdir = args.layerdir
|
||||
elif not '/' in args.layerdir:
|
||||
layerdir = '*/%s' % args.layerdir
|
||||
else:
|
||||
layerdir = os.path.abspath(args.layerdir)
|
||||
(_, notremoved) = bb.utils.edit_bblayers_conf(bblayers_conf, None, layerdir)
|
||||
if notremoved:
|
||||
for item in notremoved:
|
||||
sys.stderr.write("No layers matching %s found in BBLAYERS\n" % item)
|
||||
@@ -245,10 +240,10 @@ build results (as the layer priority order has effectively changed).
|
||||
|
||||
def register_commands(self, sp):
|
||||
parser_add_layer = self.add_command(sp, 'add-layer', self.do_add_layer, parserecipes=False)
|
||||
parser_add_layer.add_argument('layerdir', nargs='+', help='Layer directory/directories to add')
|
||||
parser_add_layer.add_argument('layerdir', help='Layer directory to add')
|
||||
|
||||
parser_remove_layer = self.add_command(sp, 'remove-layer', self.do_remove_layer, parserecipes=False)
|
||||
parser_remove_layer.add_argument('layerdir', nargs='+', help='Layer directory/directories to remove (wildcards allowed, enclose in quotes to avoid shell expansion)')
|
||||
parser_remove_layer.add_argument('layerdir', help='Layer directory to remove (wildcards allowed, enclose in quotes to avoid shell expansion)')
|
||||
parser_remove_layer.set_defaults(func=self.do_remove_layer)
|
||||
|
||||
parser_flatten = self.add_command(sp, 'flatten', self.do_flatten)
|
||||
|
||||
@@ -161,12 +161,7 @@ skipped recipes will also be listed, with a " (skipped)" suffix.
|
||||
items_listed = False
|
||||
for p in sorted(pkg_pn):
|
||||
if pnspec:
|
||||
found=False
|
||||
for pnm in pnspec:
|
||||
if fnmatch.fnmatch(p, pnm):
|
||||
found=True
|
||||
break
|
||||
if not found:
|
||||
if not fnmatch.fnmatch(p, pnspec):
|
||||
continue
|
||||
|
||||
if len(allproviders[p]) > 1 or not show_multi_provider_only:
|
||||
@@ -256,14 +251,8 @@ Lists recipes with the bbappends that apply to them as subitems.
|
||||
pnlist.sort()
|
||||
appends = False
|
||||
for pn in pnlist:
|
||||
if args.pnspec:
|
||||
found=False
|
||||
for pnm in args.pnspec:
|
||||
if fnmatch.fnmatch(pn, pnm):
|
||||
found=True
|
||||
break
|
||||
if not found:
|
||||
continue
|
||||
if args.pnspec and pn != args.pnspec:
|
||||
continue
|
||||
|
||||
if self.show_appends_for_pn(pn):
|
||||
appends = True
|
||||
@@ -490,11 +479,11 @@ NOTE: .bbappend files can impact the dependencies.
|
||||
parser_show_recipes = self.add_command(sp, 'show-recipes', self.do_show_recipes)
|
||||
parser_show_recipes.add_argument('-f', '--filenames', help='instead of the default formatting, list filenames of higher priority recipes with the ones they overlay indented underneath', action='store_true')
|
||||
parser_show_recipes.add_argument('-m', '--multiple', help='only list where multiple recipes (in the same layer or different layers) exist for the same recipe name', action='store_true')
|
||||
parser_show_recipes.add_argument('-i', '--inherits', help='only list recipes that inherit the named class(es) - separate multiple classes using , (without spaces)', metavar='CLASS', default='')
|
||||
parser_show_recipes.add_argument('pnspec', nargs='*', help='optional recipe name specification (wildcards allowed, enclose in quotes to avoid shell expansion)')
|
||||
parser_show_recipes.add_argument('-i', '--inherits', help='only list recipes that inherit the named class', metavar='CLASS', default='')
|
||||
parser_show_recipes.add_argument('pnspec', nargs='?', help='optional recipe name specification (wildcards allowed, enclose in quotes to avoid shell expansion)')
|
||||
|
||||
parser_show_appends = self.add_command(sp, 'show-appends', self.do_show_appends)
|
||||
parser_show_appends.add_argument('pnspec', nargs='*', help='optional recipe name specification (wildcards allowed, enclose in quotes to avoid shell expansion)')
|
||||
parser_show_appends.add_argument('pnspec', nargs='?', help='optional recipe name specification (wildcards allowed, enclose in quotes to avoid shell expansion)')
|
||||
|
||||
parser_show_cross_depends = self.add_command(sp, 'show-cross-depends', self.do_show_cross_depends)
|
||||
parser_show_cross_depends.add_argument('-f', '--filenames', help='show full file path', action='store_true')
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
|
||||
from django.conf.urls import include, url
|
||||
from django.conf.urls import patterns, include, url
|
||||
|
||||
import bldcollector.views
|
||||
|
||||
|
||||
@@ -52,14 +52,12 @@ class LocalhostBEController(BuildEnvironmentController):
|
||||
self.pokydirname = None
|
||||
self.islayerset = False
|
||||
|
||||
def _shellcmd(self, command, cwd=None, nowait=False,env=None):
|
||||
def _shellcmd(self, command, cwd=None, nowait=False):
|
||||
if cwd is None:
|
||||
cwd = self.be.sourcedir
|
||||
if env is None:
|
||||
env=os.environ.copy()
|
||||
|
||||
logger.debug("lbc_shellcmd: (%s) %s" % (cwd, command))
|
||||
p = subprocess.Popen(command, cwd = cwd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
|
||||
logger.debug("lbc_shellcmmd: (%s) %s" % (cwd, command))
|
||||
p = subprocess.Popen(command, cwd = cwd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
if nowait:
|
||||
return
|
||||
(out,err) = p.communicate()
|
||||
@@ -100,8 +98,6 @@ class LocalhostBEController(BuildEnvironmentController):
|
||||
|
||||
layerlist = []
|
||||
nongitlayerlist = []
|
||||
git_env = os.environ.copy()
|
||||
# (note: add custom environment settings here)
|
||||
|
||||
# set layers in the layersource
|
||||
|
||||
@@ -142,7 +138,7 @@ class LocalhostBEController(BuildEnvironmentController):
|
||||
cached_layers = {}
|
||||
|
||||
try:
|
||||
for remotes in self._shellcmd("git remote -v", self.be.sourcedir,env=git_env).split("\n"):
|
||||
for remotes in self._shellcmd("git remote -v", self.be.sourcedir).split("\n"):
|
||||
try:
|
||||
remote = remotes.split("\t")[1].split(" ")[0]
|
||||
if remote not in cached_layers:
|
||||
@@ -171,7 +167,7 @@ class LocalhostBEController(BuildEnvironmentController):
|
||||
if os.path.exists(localdirname):
|
||||
try:
|
||||
localremotes = self._shellcmd("git remote -v",
|
||||
localdirname,env=git_env)
|
||||
localdirname)
|
||||
if not giturl in localremotes and commit != 'HEAD':
|
||||
raise BuildSetupException("Existing git repository at %s, but with different remotes ('%s', expected '%s'). Toaster will not continue out of fear of damaging something." % (localdirname, ", ".join(localremotes.split("\n")), giturl))
|
||||
except ShellCmdException:
|
||||
@@ -181,18 +177,18 @@ class LocalhostBEController(BuildEnvironmentController):
|
||||
else:
|
||||
if giturl in cached_layers:
|
||||
logger.debug("localhostbecontroller git-copying %s to %s" % (cached_layers[giturl], localdirname))
|
||||
self._shellcmd("git clone \"%s\" \"%s\"" % (cached_layers[giturl], localdirname),env=git_env)
|
||||
self._shellcmd("git remote remove origin", localdirname,env=git_env)
|
||||
self._shellcmd("git remote add origin \"%s\"" % giturl, localdirname,env=git_env)
|
||||
self._shellcmd("git clone \"%s\" \"%s\"" % (cached_layers[giturl], localdirname))
|
||||
self._shellcmd("git remote remove origin", localdirname)
|
||||
self._shellcmd("git remote add origin \"%s\"" % giturl, localdirname)
|
||||
else:
|
||||
logger.debug("localhostbecontroller: cloning %s in %s" % (giturl, localdirname))
|
||||
self._shellcmd('git clone "%s" "%s"' % (giturl, localdirname),env=git_env)
|
||||
self._shellcmd('git clone "%s" "%s"' % (giturl, localdirname))
|
||||
|
||||
# branch magic name "HEAD" will inhibit checkout
|
||||
if commit != "HEAD":
|
||||
logger.debug("localhostbecontroller: checking out commit %s to %s " % (commit, localdirname))
|
||||
ref = commit if re.match('^[a-fA-F0-9]+$', commit) else 'origin/%s' % commit
|
||||
self._shellcmd('git fetch && git reset --hard "%s"' % ref, localdirname,env=git_env)
|
||||
self._shellcmd('git fetch --all && git reset --hard "%s"' % ref, localdirname)
|
||||
|
||||
# take the localdirname as poky dir if we can find the oe-init-build-env
|
||||
if self.pokydirname is None and os.path.exists(os.path.join(localdirname, "oe-init-build-env")):
|
||||
@@ -202,7 +198,7 @@ class LocalhostBEController(BuildEnvironmentController):
|
||||
# make sure we have a working bitbake
|
||||
if not os.path.exists(os.path.join(self.pokydirname, 'bitbake')):
|
||||
logger.debug("localhostbecontroller: checking bitbake into the poky dirname %s " % self.pokydirname)
|
||||
self._shellcmd("git clone -b \"%s\" \"%s\" \"%s\" " % (bitbake.commit, bitbake.giturl, os.path.join(self.pokydirname, 'bitbake')),env=git_env)
|
||||
self._shellcmd("git clone -b \"%s\" \"%s\" \"%s\" " % (bitbake.commit, bitbake.giturl, os.path.join(self.pokydirname, 'bitbake')))
|
||||
|
||||
# verify our repositories
|
||||
for name, dirpath in gitrepos[(giturl, commit)]:
|
||||
@@ -336,18 +332,15 @@ class LocalhostBEController(BuildEnvironmentController):
|
||||
conf.write('%s="%s"\n' % (var.name, var.value))
|
||||
conf.write('INHERIT+="toaster buildhistory"')
|
||||
|
||||
# clean the Toaster to build environment
|
||||
env_clean = 'unset BBPATH;' # clean BBPATH for <= YP-2.4.0
|
||||
|
||||
# run bitbake server from the clone
|
||||
bitbake = os.path.join(self.pokydirname, 'bitbake', 'bin', 'bitbake')
|
||||
toasterlayers = os.path.join(builddir,"conf/toaster-bblayers.conf")
|
||||
self._shellcmd('%s bash -c \"source %s %s; BITBAKE_UI="knotty" %s --read %s --read %s '
|
||||
'--server-only -B 0.0.0.0:0\"' % (env_clean, oe_init,
|
||||
self._shellcmd('bash -c \"source %s %s; BITBAKE_UI="knotty" %s --read %s --read %s '
|
||||
'--server-only -B 0.0.0.0:0\"' % (oe_init,
|
||||
builddir, bitbake, confpath, toasterlayers), self.be.sourcedir)
|
||||
|
||||
# read port number from bitbake.lock
|
||||
self.be.bbport = -1
|
||||
self.be.bbport = ""
|
||||
bblock = os.path.join(builddir, 'bitbake.lock')
|
||||
# allow 10 seconds for bb lock file to appear but also be populated
|
||||
for lock_check in range(10):
|
||||
@@ -359,9 +352,6 @@ class LocalhostBEController(BuildEnvironmentController):
|
||||
break
|
||||
logger.debug("localhostbecontroller: waiting for bblock content to appear")
|
||||
time.sleep(1)
|
||||
else:
|
||||
raise BuildSetupException("Cannot find bitbake server lock file '%s'. Aborting." % bblock)
|
||||
|
||||
with open(bblock) as fplock:
|
||||
for line in fplock:
|
||||
if ":" in line:
|
||||
@@ -369,7 +359,7 @@ class LocalhostBEController(BuildEnvironmentController):
|
||||
logger.debug("localhostbecontroller: bitbake port %s", self.be.bbport)
|
||||
break
|
||||
|
||||
if -1 == self.be.bbport:
|
||||
if not self.be.bbport:
|
||||
raise BuildSetupException("localhostbecontroller: can't read bitbake port from %s" % bblock)
|
||||
|
||||
self.be.bbaddress = "localhost"
|
||||
@@ -390,10 +380,10 @@ class LocalhostBEController(BuildEnvironmentController):
|
||||
log = os.path.join(builddir, 'toaster_ui.log')
|
||||
local_bitbake = os.path.join(os.path.dirname(os.getenv('BBBASEDIR')),
|
||||
'bitbake')
|
||||
self._shellcmd(['%s bash -c \"(TOASTER_BRBE="%s" BBSERVER="0.0.0.0:%s" '
|
||||
self._shellcmd(['bash -c \"(TOASTER_BRBE="%s" BBSERVER="0.0.0.0:%s" '
|
||||
'%s %s -u toasterui --read %s --read %s --token="" >>%s 2>&1;'
|
||||
'BITBAKE_UI="knotty" BBSERVER=0.0.0.0:%s %s -m)&\"' \
|
||||
% (env_clean, brbe, self.be.bbport, local_bitbake, bbtargets, confpath, toasterlayers, log,
|
||||
% (brbe, self.be.bbport, local_bitbake, bbtargets, confpath, toasterlayers, log,
|
||||
self.be.bbport, bitbake,)],
|
||||
builddir, nowait=True)
|
||||
|
||||
|
||||
@@ -107,10 +107,7 @@ class Command(BaseCommand):
|
||||
action="ignore",
|
||||
message="^.*No fixture named.*$")
|
||||
print("Importing custom settings if present")
|
||||
try:
|
||||
call_command("loaddata", "custom")
|
||||
except:
|
||||
print("NOTE: optional fixture 'custom' not found")
|
||||
call_command("loaddata", "custom")
|
||||
|
||||
# we run lsupdates after config update
|
||||
print("\nFetching information from the layer index, "
|
||||
|
||||
@@ -110,7 +110,6 @@
|
||||
All builds
|
||||
</a>
|
||||
</li>
|
||||
{% if project_enable %}
|
||||
<li id="navbar-all-projects"
|
||||
{% if request.resolver_match.url_name == 'all-projects' %}
|
||||
class="active"
|
||||
@@ -120,7 +119,6 @@
|
||||
All projects
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<li id="navbar-docs">
|
||||
<a target="_blank" href="http://www.yoctoproject.org/docs/latest/toaster-manual/toaster-manual.html">
|
||||
@@ -129,9 +127,7 @@
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
{% if project_enable %}
|
||||
<a class="btn btn-default navbar-btn navbar-right" id="new-project-button" href="{% url 'newproject' %}">New project</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
@@ -14,20 +14,12 @@
|
||||
|
||||
<p>A web interface to <a href="http://www.openembedded.org">OpenEmbedded</a> and <a href="http://www.yoctoproject.org/tools-resources/projects/bitbake">BitBake</a>, the <a href="http://www.yoctoproject.org">Yocto Project</a> build system.</p>
|
||||
|
||||
<p class="top-air">
|
||||
<a class="btn btn-info btn-lg" href="http://www.yoctoproject.org/docs/latest/toaster-manual/toaster-manual.html#toaster-manual-setup-and-use">
|
||||
Toaster is ready to capture your command line builds
|
||||
</a>
|
||||
</p>
|
||||
|
||||
{% if lvs_nos %}
|
||||
{% if project_enable %}
|
||||
<p class="top-air">
|
||||
<a class="btn btn-primary btn-lg" href="{% url 'newproject' %}">
|
||||
Create your first Toaster project to run manage builds
|
||||
To start building, create your first Toaster project
|
||||
</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="alert alert-info lead top-air">
|
||||
Toaster has no layer information. Without layer information, you cannot run builds. To generate layer information you can:
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
from django.conf.urls import include, url
|
||||
from django.conf.urls import patterns, include, url
|
||||
from django.views.generic import RedirectView, TemplateView
|
||||
|
||||
from django.http import HttpResponseBadRequest
|
||||
|
||||
@@ -49,8 +49,6 @@ import logging
|
||||
|
||||
logger = logging.getLogger("toaster")
|
||||
|
||||
# Project creation and managed build enable
|
||||
project_enable = ('1' == os.environ.get('TOASTER_BUILDSERVER'))
|
||||
|
||||
class MimeTypeFinder(object):
|
||||
# setting this to False enables additional non-standard mimetypes
|
||||
@@ -67,12 +65,6 @@ class MimeTypeFinder(object):
|
||||
guessed_type = 'application/octet-stream'
|
||||
return guessed_type
|
||||
|
||||
# single point to add global values into the context before rendering
|
||||
def toaster_render(request, page, context):
|
||||
context['project_enable'] = project_enable
|
||||
return render(request, page, context)
|
||||
|
||||
|
||||
# all new sessions should come through the landing page;
|
||||
# determine in which mode we are running in, and redirect appropriately
|
||||
def landing(request):
|
||||
@@ -94,7 +86,7 @@ def landing(request):
|
||||
|
||||
context = {'lvs_nos' : Layer_Version.objects.all().count()}
|
||||
|
||||
return toaster_render(request, 'landing.html', context)
|
||||
return render(request, 'landing.html', context)
|
||||
|
||||
def objtojson(obj):
|
||||
from django.db.models.query import QuerySet
|
||||
@@ -285,7 +277,7 @@ def _validate_input(field_input, model):
|
||||
return None, invalid + str(field_input_list)
|
||||
|
||||
# Check we are looking for a valid field
|
||||
valid_fields = [f.name for f in model._meta.get_fields()]
|
||||
valid_fields = model._meta.get_all_field_names()
|
||||
for field in field_input_list[0].split(AND_VALUE_SEPARATOR):
|
||||
if True in [field.startswith(x) for x in valid_fields]:
|
||||
break
|
||||
@@ -527,7 +519,7 @@ def builddashboard( request, build_id ):
|
||||
'packagecount' : packageCount,
|
||||
'logmessages' : logmessages,
|
||||
}
|
||||
return toaster_render( request, template, context )
|
||||
return render( request, template, context )
|
||||
|
||||
|
||||
|
||||
@@ -599,7 +591,7 @@ def task( request, build_id, task_id ):
|
||||
build__completed_on__lt=task_object.build.completed_on).exclude(
|
||||
order__isnull=True).exclude(outcome=Task.OUTCOME_NA).order_by('-build__completed_on')
|
||||
|
||||
return toaster_render( request, template, context )
|
||||
return render( request, template, context )
|
||||
|
||||
def recipe(request, build_id, recipe_id, active_tab="1"):
|
||||
template = "recipe.html"
|
||||
@@ -626,7 +618,7 @@ def recipe(request, build_id, recipe_id, active_tab="1"):
|
||||
'package_count' : package_count,
|
||||
'tab_states' : tab_states,
|
||||
}
|
||||
return toaster_render(request, template, context)
|
||||
return render(request, template, context)
|
||||
|
||||
def recipe_packages(request, build_id, recipe_id):
|
||||
template = "recipe_packages.html"
|
||||
@@ -671,7 +663,7 @@ def recipe_packages(request, build_id, recipe_id):
|
||||
},
|
||||
]
|
||||
}
|
||||
response = toaster_render(request, template, context)
|
||||
response = render(request, template, context)
|
||||
_set_parameters_values(pagesize, orderby, request)
|
||||
return response
|
||||
|
||||
@@ -793,7 +785,7 @@ def dirinfo(request, build_id, target_id, file_path=None):
|
||||
'dir_list': dir_list,
|
||||
'file_path': file_path,
|
||||
}
|
||||
return toaster_render(request, template, context)
|
||||
return render(request, template, context)
|
||||
|
||||
def _find_task_dep(task_object):
|
||||
tdeps = Task_Dependency.objects.filter(task=task_object).filter(depends_on__order__gt=0)
|
||||
@@ -845,7 +837,7 @@ def configuration(request, build_id):
|
||||
'build': build,
|
||||
'project': build.project,
|
||||
'targets': Target.objects.filter(build=build_id)})
|
||||
return toaster_render(request, template, context)
|
||||
return render(request, template, context)
|
||||
|
||||
|
||||
def configvars(request, build_id):
|
||||
@@ -934,7 +926,7 @@ def configvars(request, build_id):
|
||||
],
|
||||
}
|
||||
|
||||
response = toaster_render(request, template, context)
|
||||
response = render(request, template, context)
|
||||
_set_parameters_values(pagesize, orderby, request)
|
||||
return response
|
||||
|
||||
@@ -947,7 +939,7 @@ def bfile(request, build_id, package_id):
|
||||
'project': build.project,
|
||||
'objects' : files
|
||||
}
|
||||
return toaster_render(request, template, context)
|
||||
return render(request, template, context)
|
||||
|
||||
|
||||
# A set of dependency types valid for both included and built package views
|
||||
@@ -1100,7 +1092,7 @@ def package_built_detail(request, build_id, package_id):
|
||||
if paths.all().count() < 2:
|
||||
context['disable_sort'] = True;
|
||||
|
||||
response = toaster_render(request, template, context)
|
||||
response = render(request, template, context)
|
||||
_set_parameters_values(pagesize, orderby, request)
|
||||
return response
|
||||
|
||||
@@ -1119,7 +1111,7 @@ def package_built_dependencies(request, build_id, package_id):
|
||||
'other_deps' : dependencies['other_deps'],
|
||||
'dependency_count' : _get_package_dependency_count(package, -1, False)
|
||||
}
|
||||
return toaster_render(request, template, context)
|
||||
return render(request, template, context)
|
||||
|
||||
|
||||
def package_included_detail(request, build_id, target_id, package_id):
|
||||
@@ -1165,7 +1157,7 @@ def package_included_detail(request, build_id, target_id, package_id):
|
||||
}
|
||||
if paths.all().count() < 2:
|
||||
context['disable_sort'] = True
|
||||
response = toaster_render(request, template, context)
|
||||
response = render(request, template, context)
|
||||
_set_parameters_values(pagesize, orderby, request)
|
||||
return response
|
||||
|
||||
@@ -1189,7 +1181,7 @@ def package_included_dependencies(request, build_id, target_id, package_id):
|
||||
'reverse_count' : _get_package_reverse_dep_count(package, target_id),
|
||||
'dependency_count' : _get_package_dependency_count(package, target_id, True)
|
||||
}
|
||||
return toaster_render(request, template, context)
|
||||
return render(request, template, context)
|
||||
|
||||
def package_included_reverse_dependencies(request, build_id, target_id, package_id):
|
||||
template = "package_included_reverse_dependencies.html"
|
||||
@@ -1240,7 +1232,7 @@ def package_included_reverse_dependencies(request, build_id, target_id, package_
|
||||
}
|
||||
if objects.all().count() < 2:
|
||||
context['disable_sort'] = True
|
||||
response = toaster_render(request, template, context)
|
||||
response = render(request, template, context)
|
||||
_set_parameters_values(pagesize, orderby, request)
|
||||
return response
|
||||
|
||||
@@ -1373,9 +1365,6 @@ if True:
|
||||
|
||||
# new project
|
||||
def newproject(request):
|
||||
if not project_enable:
|
||||
return redirect( landing )
|
||||
|
||||
template = "newproject.html"
|
||||
context = {
|
||||
'email': request.user.email if request.user.is_authenticated() else '',
|
||||
@@ -1390,7 +1379,7 @@ if True:
|
||||
|
||||
if request.method == "GET":
|
||||
# render new project page
|
||||
return toaster_render(request, template, context)
|
||||
return render(request, template, context)
|
||||
elif request.method == "POST":
|
||||
mandatory_fields = ['projectname', 'ptype']
|
||||
try:
|
||||
@@ -1430,7 +1419,7 @@ if True:
|
||||
context['alert'] = "Your chosen username is already used"
|
||||
else:
|
||||
context['alert'] = str(e)
|
||||
return toaster_render(request, template, context)
|
||||
return render(request, template, context)
|
||||
|
||||
raise Exception("Invalid HTTP method for this page")
|
||||
|
||||
@@ -1438,7 +1427,7 @@ if True:
|
||||
def project(request, pid):
|
||||
project = Project.objects.get(pk=pid)
|
||||
context = {"project": project}
|
||||
return toaster_render(request, "project.html", context)
|
||||
return render(request, "project.html", context)
|
||||
|
||||
def jsunittests(request):
|
||||
""" Provides a page for the js unit tests """
|
||||
@@ -1464,7 +1453,7 @@ if True:
|
||||
name="MACHINE",
|
||||
value="qemux86")
|
||||
context = {'project': new_project}
|
||||
return toaster_render(request, "js-unit-tests.html", context)
|
||||
return render(request, "js-unit-tests.html", context)
|
||||
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
@csrf_exempt
|
||||
@@ -1599,7 +1588,7 @@ if True:
|
||||
context = {
|
||||
'project': Project.objects.get(id=pid),
|
||||
}
|
||||
return toaster_render(request, template, context)
|
||||
return render(request, template, context)
|
||||
|
||||
def layerdetails(request, pid, layerid):
|
||||
project = Project.objects.get(pk=pid)
|
||||
@@ -1628,7 +1617,7 @@ if True:
|
||||
'projectlayers': list(project_layers)
|
||||
}
|
||||
|
||||
return toaster_render(request, 'layerdetails.html', context)
|
||||
return render(request, 'layerdetails.html', context)
|
||||
|
||||
|
||||
def get_project_configvars_context():
|
||||
@@ -1718,7 +1707,7 @@ if True:
|
||||
except (ProjectVariable.DoesNotExist, BuildEnvironment.DoesNotExist):
|
||||
pass
|
||||
|
||||
return toaster_render(request, "projectconf.html", context)
|
||||
return render(request, "projectconf.html", context)
|
||||
|
||||
def _file_names_for_artifact(build, artifact_type, artifact_id):
|
||||
"""
|
||||
@@ -1785,7 +1774,7 @@ if True:
|
||||
|
||||
return response
|
||||
else:
|
||||
return toaster_render(request, "unavailable_artifact.html")
|
||||
return render(request, "unavailable_artifact.html")
|
||||
except (ObjectDoesNotExist, IOError):
|
||||
return toaster_render(request, "unavailable_artifact.html")
|
||||
return render(request, "unavailable_artifact.html")
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ import types
|
||||
import json
|
||||
import collections
|
||||
import re
|
||||
import os
|
||||
|
||||
from toastergui.tablefilter import TableFilterMap
|
||||
|
||||
@@ -87,9 +86,6 @@ class ToasterTable(TemplateView):
|
||||
context['table_name'] = type(self).__name__.lower()
|
||||
context['empty_state'] = self.empty_state
|
||||
|
||||
# global variables
|
||||
context['project_enable'] = ('1' == os.environ.get('TOASTER_BUILDSERVER'))
|
||||
|
||||
return context
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
|
||||
@@ -186,7 +186,7 @@ TEMPLATES = [
|
||||
'django.template.context_processors.tz',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
# Custom
|
||||
'django.template.context_processors.request',
|
||||
'django.core.context_processors.request',
|
||||
'toastergui.views.managedcontextprocessor',
|
||||
|
||||
],
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
from django.conf.urls import include, url
|
||||
from django.conf.urls import patterns, include, url
|
||||
from django.views.generic import RedirectView, TemplateView
|
||||
from django.views.decorators.cache import never_cache
|
||||
import bldcollector.views
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
Django>1.8,<1.11.9
|
||||
Django>1.8,<1.9.9
|
||||
beautifulsoup4>=4.4.0
|
||||
pytz
|
||||
|
||||
@@ -84,52 +84,6 @@
|
||||
# for the 'denzil' branch.
|
||||
#
|
||||
|
||||
ifeq ($(DOC),brief-yoctoprojectqs)
|
||||
XSLTOPTS = --stringparam html.stylesheet brief-yoctoprojectqs-style.css \
|
||||
--stringparam chapter.autolabel 0 \
|
||||
--stringparam section.autolabel 0 \
|
||||
--stringparam section.label.includes.component.label 0 \
|
||||
--xinclude
|
||||
ALLPREQ = html tarball
|
||||
TARFILES = brief-yoctoprojectqs-style.css brief-yoctoprojectqs.html figures/ypqs-title.png \
|
||||
figures/yocto-project-transp.png
|
||||
MANUALS = $(DOC)/$(DOC).html $(DOC)/eclipse
|
||||
FIGURES = figures
|
||||
STYLESHEET = $(DOC)/*.css
|
||||
|
||||
endif
|
||||
|
||||
ifeq ($(DOC),getting-started)
|
||||
XSLTOPTS = --xinclude
|
||||
ALLPREQ = html eclipse tarball
|
||||
TARFILES = getting-started-style.css getting-started.html figures/getting-started-title.png \
|
||||
figures/git-workflow.png figures/source-repos.png figures/index-downloads.png \
|
||||
figures/yp-download.png figures/YP-flow-diagram.png figures/key-dev-elements.png \
|
||||
figures/poky-reference-distribution.png \
|
||||
eclipse
|
||||
MANUALS = $(DOC)/$(DOC).html $(DOC)/eclipse
|
||||
FIGURES = figures
|
||||
STYLESHEET = $(DOC)/*.css
|
||||
|
||||
endif
|
||||
|
||||
ifeq ($(DOC),concepts-manual)
|
||||
XSLTOPTS = --xinclude
|
||||
ALLPREQ = html eclipse tarball
|
||||
TARFILES = concepts-manual-style.css concepts-manual.html figures/concepts-manual-title.png \
|
||||
figures/cross-development-toolchains.png figures/yocto-environment-ref.png \
|
||||
figures/user-configuration.png figures/layer-input.png figures/source-input.png \
|
||||
figures/package-feeds.png figures/patching.png figures/source-fetching.png \
|
||||
figures/configuration-compile-autoreconf.png figures/analysis-for-package-splitting.png \
|
||||
figures/image-generation.png figures/sdk-generation.png figures/images.png \
|
||||
figures/sdk.png \
|
||||
eclipse
|
||||
MANUALS = $(DOC)/$(DOC).html $(DOC)/eclipse
|
||||
FIGURES = figures
|
||||
STYLESHEET = $(DOC)/*.css
|
||||
|
||||
endif
|
||||
|
||||
ifeq ($(DOC),bsp-guide)
|
||||
XSLTOPTS = --xinclude
|
||||
ALLPREQ = html eclipse tarball
|
||||
@@ -174,8 +128,8 @@ TARFILES = dev-style.css dev-manual.html \
|
||||
figures/source-repos.png figures/yp-download.png \
|
||||
figures/wip.png
|
||||
else
|
||||
TARFILES = dev-style.css dev-manual.html figures/buildhistory-web.png \
|
||||
figures/dev-title.png figures/buildhistory.png \
|
||||
TARFILES = dev-style.css dev-manual.html \
|
||||
figures/dev-title.png \
|
||||
figures/recipe-workflow.png figures/bitbake-build-flow.png \
|
||||
eclipse
|
||||
endif
|
||||
@@ -187,15 +141,10 @@ STYLESHEET = $(DOC)/*.css
|
||||
endif
|
||||
|
||||
ifeq ($(DOC),yocto-project-qs)
|
||||
XSLTOPTS = --stringparam html.stylesheet qs-style.css \
|
||||
--stringparam chapter.autolabel 1 \
|
||||
--stringparam section.autolabel 1 \
|
||||
--stringparam section.label.includes.component.label 1 \
|
||||
--xinclude
|
||||
XSLTOPTS = --xinclude
|
||||
ALLPREQ = html eclipse tarball
|
||||
|
||||
TARFILES = yocto-project-qs.html qs-style.css \
|
||||
figures/yocto-project-transp.png figures/ypqs-title.png \
|
||||
figures/yocto-project-transp.png \
|
||||
eclipse
|
||||
MANUALS = $(DOC)/$(DOC).html $(DOC)/eclipse
|
||||
FIGURES = figures
|
||||
@@ -241,8 +190,8 @@ TARFILES = mega-manual.html mega-style.css figures/yocto-environment.png \
|
||||
figures/source-repos.png figures/yp-download.png \
|
||||
figures/wip.png
|
||||
else
|
||||
TARFILES = mega-manual.html mega-style.css \
|
||||
figures/YP-flow-diagram.png \
|
||||
TARFILES = mega-manual.html mega-style.css figures/yocto-environment.png \
|
||||
figures/building-an-image.png figures/YP-flow-diagram.png \
|
||||
figures/using-a-pre-built-image.png \
|
||||
figures/poky-title.png figures/buildhistory.png \
|
||||
figures/buildhistory-web.png \
|
||||
@@ -286,17 +235,16 @@ TARFILES = mega-manual.html mega-style.css \
|
||||
figures/source-fetching.png figures/patching.png \
|
||||
figures/configuration-compile-autoreconf.png \
|
||||
figures/analysis-for-package-splitting.png \
|
||||
figures/image-generation.png figures/key-dev-elements.png\
|
||||
figures/image-generation.png \
|
||||
figures/sdk-generation.png figures/recipe-workflow.png \
|
||||
figures/build-workspace-directory.png figures/mega-title.png \
|
||||
figures/toaster-title.png figures/hosted-service.png \
|
||||
figures/simple-configuration.png figures/poky-reference-distribution.png \
|
||||
figures/simple-configuration.png \
|
||||
figures/compatible-layers.png figures/import-layer.png figures/new-project.png \
|
||||
figures/sdk-environment.png figures/sdk-installed-standard-sdk-directory.png \
|
||||
figures/sdk-devtool-add-flow.png figures/sdk-installed-extensible-sdk-directory.png \
|
||||
figures/sdk-devtool-modify-flow.png figures/sdk-eclipse-dev-flow.png \
|
||||
figures/sdk-devtool-upgrade-flow.png figures/bitbake-build-flow.png figures/ypqs-title.png \
|
||||
figures/getting-started-title.png figures/concepts-manual-title.png
|
||||
figures/sdk-devtool-upgrade-flow.png figures/bitbake-build-flow.png
|
||||
endif
|
||||
|
||||
MANUALS = $(DOC)/$(DOC).html
|
||||
@@ -308,9 +256,17 @@ endif
|
||||
ifeq ($(DOC),ref-manual)
|
||||
XSLTOPTS = --xinclude
|
||||
ALLPREQ = html eclipse tarball
|
||||
TARFILES = ref-manual.html ref-style.css figures/poky-title.png \
|
||||
figures/build-workspace-directory.png \
|
||||
eclipse
|
||||
TARFILES = ref-manual.html ref-style.css figures/poky-title.png figures/YP-flow-diagram.png \
|
||||
figures/buildhistory.png figures/buildhistory-web.png eclipse \
|
||||
figures/cross-development-toolchains.png figures/layer-input.png \
|
||||
figures/package-feeds.png figures/source-input.png \
|
||||
figures/user-configuration.png figures/yocto-environment-ref.png \
|
||||
figures/images.png figures/sdk.png figures/source-fetching.png \
|
||||
figures/patching.png figures/configuration-compile-autoreconf.png \
|
||||
figures/analysis-for-package-splitting.png figures/image-generation.png \
|
||||
figures/sdk-generation.png figures/building-an-image.png \
|
||||
figures/build-workspace-directory.png figures/source-repos.png \
|
||||
figures/index-downloads.png figures/yp-download.png figures/git-workflow.png
|
||||
MANUALS = $(DOC)/$(DOC).html $(DOC)/eclipse
|
||||
FIGURES = figures
|
||||
STYLESHEET = $(DOC)/*.css
|
||||
@@ -399,9 +355,9 @@ XSL_XHTML_URI = $(XSL_BASE_URI)/xhtml/docbook.xsl
|
||||
all: $(ALLPREQ)
|
||||
|
||||
pdf:
|
||||
ifeq ($(DOC),yocto-project-qs brief-yoctoprojectqs)
|
||||
ifeq ($(DOC),yocto-project-qs)
|
||||
@echo " "
|
||||
@echo "ERROR: You cannot generate yocto-project-qs or brief-yoctoprojectqs PDF files."
|
||||
@echo "ERROR: You cannot generate a yocto-project-qs PDF file."
|
||||
@echo " "
|
||||
|
||||
else ifeq ($(DOC),mega-manual)
|
||||
@@ -445,12 +401,10 @@ eclipse: eclipse-generate eclipse-resolve-links
|
||||
.PHONY : eclipse-generate eclipse-resolve-links
|
||||
|
||||
eclipse-generate:
|
||||
ifeq ($(filter $(DOC), concepts-manual getting-started sdk-manual bsp-guide dev-manual kernel-dev profile-manual ref-manual yocto-project-qs),)
|
||||
ifeq ($(filter $(DOC), sdk-manual bsp-guide dev-manual kernel-dev profile-manual ref-manual yocto-project-qs),)
|
||||
@echo " "
|
||||
@echo "ERROR: You can only create eclipse documentation"
|
||||
@echo " of the following documentation parts:"
|
||||
@echo " - concepts-manual"
|
||||
@echo " - getting-started"
|
||||
@echo " - sdk-manual"
|
||||
@echo " - bsp-guide"
|
||||
@echo " - dev-manual"
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
|
||||
|
||||
<xsl:import href="http://downloads.yoctoproject.org/mirror/docbook-mirror/docbook-xsl-1.76.1/xhtml/docbook.xsl" />
|
||||
|
||||
<!--
|
||||
|
||||
<xsl:import href="../template/1.76.1/docbook-xsl-1.76.1/xhtml/docbook.xsl" />
|
||||
|
||||
<xsl:import href="http://docbook.sourceforge.net/release/xsl/1.76.1/xhtml/docbook.xsl" />
|
||||
|
||||
-->
|
||||
|
||||
<xsl:import href="brief-yoctoprojectqs-titlepage.xsl"/>
|
||||
|
||||
<xsl:include href="../template/permalinks.xsl"/>
|
||||
<xsl:include href="../template/section.title.xsl"/>
|
||||
<xsl:include href="../template/component.title.xsl"/>
|
||||
<xsl:include href="../template/division.title.xsl"/>
|
||||
<xsl:include href="../template/formal.object.heading.xsl"/>
|
||||
|
||||
<xsl:param name="generate.toc" select="'article nop'"></xsl:param>
|
||||
<xsl:param name="html.stylesheet" select="'brief-yoctoprojectqs-style.css'" />
|
||||
</xsl:stylesheet>
|
||||
@@ -1,989 +0,0 @@
|
||||
/*
|
||||
Generic XHTML / DocBook XHTML CSS Stylesheet.
|
||||
|
||||
Browser wrangling and typographic design by
|
||||
Oyvind Kolas / pippin@gimp.org
|
||||
|
||||
Customised for Poky by
|
||||
Matthew Allum / mallum@o-hand.com
|
||||
|
||||
Thanks to:
|
||||
Liam R. E. Quin
|
||||
William Skaggs
|
||||
Jakub Steiner
|
||||
|
||||
Structure
|
||||
---------
|
||||
|
||||
The stylesheet is divided into the following sections:
|
||||
|
||||
Positioning
|
||||
Margins, paddings, width, font-size, clearing.
|
||||
Decorations
|
||||
Borders, style
|
||||
Colors
|
||||
Colors
|
||||
Graphics
|
||||
Graphical backgrounds
|
||||
Nasty IE tweaks
|
||||
Workarounds needed to make it work in internet explorer,
|
||||
currently makes the stylesheet non validating, but up until
|
||||
this point it is validating.
|
||||
Mozilla extensions
|
||||
Transparency for footer
|
||||
Rounded corners on boxes
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*************** /
|
||||
/ Positioning /
|
||||
/ ***************/
|
||||
|
||||
body {
|
||||
font-family: Verdana, Sans, sans-serif;
|
||||
|
||||
min-width: 640px;
|
||||
width: 80%;
|
||||
margin: 0em auto;
|
||||
padding: 2em 5em 5em 5em;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6,h7 {
|
||||
font-family: Arial, Sans;
|
||||
color: #00557D;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
text-align: left;
|
||||
padding: 0em 0em 0em 0em;
|
||||
margin: 2em 0em 0em 0em;
|
||||
}
|
||||
|
||||
h2.subtitle {
|
||||
margin: 0.10em 0em 3.0em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
font-size: 1.8em;
|
||||
padding-left: 20%;
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 2em 0em 0.66em 0em;
|
||||
padding: 0.5em 0em 0em 0em;
|
||||
font-size: 1.5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h3.subtitle {
|
||||
margin: 0em 0em 1em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
font-size: 142.14%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 1em 0em 0.5em 0em;
|
||||
padding: 1em 0em 0em 0em;
|
||||
font-size: 140%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin: 1em 0em 0.5em 0em;
|
||||
padding: 1em 0em 0em 0em;
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h5 {
|
||||
margin: 1em 0em 0.5em 0em;
|
||||
padding: 1em 0em 0em 0em;
|
||||
font-size: 110%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h6 {
|
||||
margin: 1em 0em 0em 0em;
|
||||
padding: 1em 0em 0em 0em;
|
||||
font-size: 110%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.authorgroup {
|
||||
background-color: transparent;
|
||||
background-repeat: no-repeat;
|
||||
padding-top: 256px;
|
||||
background-image: url("figures/ypqs-title.png");
|
||||
background-position: left top;
|
||||
margin-top: -256px;
|
||||
padding-right: 50px;
|
||||
margin-left: 0px;
|
||||
text-align: right;
|
||||
width: 740px;
|
||||
}
|
||||
|
||||
h3.author {
|
||||
margin: 0em 0me 0em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
font-weight: normal;
|
||||
font-size: 100%;
|
||||
color: #333;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.author tt.email {
|
||||
font-size: 66%;
|
||||
}
|
||||
|
||||
.titlepage hr {
|
||||
width: 0em;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.revhistory {
|
||||
padding-top: 2em;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.toc,
|
||||
.list-of-tables,
|
||||
.list-of-examples,
|
||||
.list-of-figures {
|
||||
padding: 1.33em 0em 2.5em 0em;
|
||||
color: #00557D;
|
||||
}
|
||||
|
||||
.toc p,
|
||||
.list-of-tables p,
|
||||
.list-of-figures p,
|
||||
.list-of-examples p {
|
||||
padding: 0em 0em 0em 0em;
|
||||
padding: 0em 0em 0.3em;
|
||||
margin: 1.5em 0em 0em 0em;
|
||||
}
|
||||
|
||||
.toc p b,
|
||||
.list-of-tables p b,
|
||||
.list-of-figures p b,
|
||||
.list-of-examples p b{
|
||||
font-size: 100.0%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.toc dl,
|
||||
.list-of-tables dl,
|
||||
.list-of-figures dl,
|
||||
.list-of-examples dl {
|
||||
margin: 0em 0em 0.5em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
.toc dt {
|
||||
margin: 0em 0em 0em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
.toc dd {
|
||||
margin: 0em 0em 0em 2.6em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
div.glossary dl,
|
||||
div.variablelist dl {
|
||||
}
|
||||
|
||||
.glossary dl dt,
|
||||
.variablelist dl dt,
|
||||
.variablelist dl dt span.term {
|
||||
font-weight: normal;
|
||||
width: 20em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.variablelist dl dt {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
.glossary dl dd,
|
||||
.variablelist dl dd {
|
||||
margin-top: -1em;
|
||||
margin-left: 25.5em;
|
||||
}
|
||||
|
||||
.glossary dd p,
|
||||
.variablelist dd p {
|
||||
margin-top: 0em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
|
||||
div.calloutlist table td {
|
||||
padding: 0em 0em 0em 0em;
|
||||
margin: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
div.calloutlist table td p {
|
||||
margin-top: 0em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
div p.copyright {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div.legalnotice p.legalnotice-title {
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 1.5em;
|
||||
margin-top: 0em;
|
||||
|
||||
}
|
||||
|
||||
dl {
|
||||
padding-top: 0em;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: solid 1px;
|
||||
}
|
||||
|
||||
|
||||
.mediaobject,
|
||||
.mediaobjectco {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
img {
|
||||
border: none;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding: 0em 0em 0em 1.5em;
|
||||
}
|
||||
|
||||
ul li {
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
ul li p {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
table {
|
||||
width :100%;
|
||||
}
|
||||
|
||||
th {
|
||||
padding: 0.25em;
|
||||
text-align: left;
|
||||
font-weight: normal;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0.25em;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
p a[id] {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
display: inline;
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: underline;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
pre {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
/*font-weight: bold;*/
|
||||
}
|
||||
|
||||
/* This style defines how the permalink character
|
||||
appears by itself and when hovered over with
|
||||
the mouse. */
|
||||
|
||||
[alt='Permalink'] { color: #eee; }
|
||||
[alt='Permalink']:hover { color: black; }
|
||||
|
||||
|
||||
div.informalfigure,
|
||||
div.informalexample,
|
||||
div.informaltable,
|
||||
div.figure,
|
||||
div.table,
|
||||
div.example {
|
||||
margin: 1em 0em;
|
||||
padding: 1em;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
|
||||
div.informalfigure p.title b,
|
||||
div.informalexample p.title b,
|
||||
div.informaltable p.title b,
|
||||
div.figure p.title b,
|
||||
div.example p.title b,
|
||||
div.table p.title b{
|
||||
padding-top: 0em;
|
||||
margin-top: 0em;
|
||||
font-size: 100%;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.mediaobject .caption,
|
||||
.mediaobject .caption p {
|
||||
text-align: center;
|
||||
font-size: 80%;
|
||||
padding-top: 0.5em;
|
||||
padding-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.epigraph {
|
||||
padding-left: 55%;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.epigraph p {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.epigraph .quote {
|
||||
font-style: italic;
|
||||
}
|
||||
.epigraph .attribution {
|
||||
font-style: normal;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
span.application {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.programlisting {
|
||||
font-family: monospace;
|
||||
font-size: 80%;
|
||||
white-space: pre;
|
||||
margin: 1.33em 0em;
|
||||
padding: 1.33em;
|
||||
}
|
||||
|
||||
.tip,
|
||||
.warning,
|
||||
.caution,
|
||||
.note {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
|
||||
}
|
||||
|
||||
/* force full width of table within div */
|
||||
.tip table,
|
||||
.warning table,
|
||||
.caution table,
|
||||
.note table {
|
||||
border: none;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
.tip table th,
|
||||
.warning table th,
|
||||
.caution table th,
|
||||
.note table th {
|
||||
padding: 0.8em 0.0em 0.0em 0.0em;
|
||||
margin : 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
.tip p,
|
||||
.warning p,
|
||||
.caution p,
|
||||
.note p {
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
padding-right: 1em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.acronym {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
b.keycap,
|
||||
.keycap {
|
||||
padding: 0.09em 0.3em;
|
||||
margin: 0em;
|
||||
}
|
||||
|
||||
.itemizedlist li {
|
||||
clear: none;
|
||||
}
|
||||
|
||||
.filename {
|
||||
font-size: medium;
|
||||
font-family: Courier, monospace;
|
||||
}
|
||||
|
||||
|
||||
div.navheader, div.heading{
|
||||
position: absolute;
|
||||
left: 0em;
|
||||
top: 0em;
|
||||
width: 100%;
|
||||
background-color: #cdf;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.navfooter, div.footing{
|
||||
position: fixed;
|
||||
left: 0em;
|
||||
bottom: 0em;
|
||||
background-color: #eee;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
div.navheader td,
|
||||
div.navfooter td {
|
||||
font-size: 66%;
|
||||
}
|
||||
|
||||
div.navheader table th {
|
||||
/*font-family: Georgia, Times, serif;*/
|
||||
/*font-size: x-large;*/
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
div.navheader table {
|
||||
border-left: 0em;
|
||||
border-right: 0em;
|
||||
border-top: 0em;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.navfooter table {
|
||||
border-left: 0em;
|
||||
border-right: 0em;
|
||||
border-bottom: 0em;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.navheader table td a,
|
||||
div.navfooter table td a {
|
||||
color: #777;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* normal text in the footer */
|
||||
div.navfooter table td {
|
||||
color: black;
|
||||
}
|
||||
|
||||
div.navheader table td a:visited,
|
||||
div.navfooter table td a:visited {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
|
||||
/* links in header and footer */
|
||||
div.navheader table td a:hover,
|
||||
div.navfooter table td a:hover {
|
||||
text-decoration: underline;
|
||||
background-color: transparent;
|
||||
color: #33a;
|
||||
}
|
||||
|
||||
div.navheader hr,
|
||||
div.navfooter hr {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.qandaset tr.question td p {
|
||||
margin: 0em 0em 1em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
.qandaset tr.answer td p {
|
||||
margin: 0em 0em 1em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
.answer td {
|
||||
padding-bottom: 1.5em;
|
||||
}
|
||||
|
||||
.emphasis {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
/************* /
|
||||
/ decorations /
|
||||
/ *************/
|
||||
|
||||
.titlepage {
|
||||
}
|
||||
|
||||
.part .title {
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/*
|
||||
h1 {
|
||||
border: none;
|
||||
}
|
||||
|
||||
h2 {
|
||||
border-top: solid 0.2em;
|
||||
border-bottom: solid 0.06em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
border-top: 0em;
|
||||
border-bottom: solid 0.06em;
|
||||
}
|
||||
|
||||
h4 {
|
||||
border: 0em;
|
||||
border-bottom: solid 0.06em;
|
||||
}
|
||||
|
||||
h5 {
|
||||
border: 0em;
|
||||
}
|
||||
*/
|
||||
|
||||
.programlisting {
|
||||
border: solid 1px;
|
||||
}
|
||||
|
||||
div.figure,
|
||||
div.table,
|
||||
div.informalfigure,
|
||||
div.informaltable,
|
||||
div.informalexample,
|
||||
div.example {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.tip,
|
||||
.warning,
|
||||
.caution,
|
||||
.note {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.tip table th,
|
||||
.warning table th,
|
||||
.caution table th,
|
||||
.note table th {
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
|
||||
.question td {
|
||||
border-top: 1px solid black;
|
||||
}
|
||||
|
||||
.answer {
|
||||
}
|
||||
|
||||
|
||||
b.keycap,
|
||||
.keycap {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
|
||||
div.navheader, div.heading{
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
|
||||
|
||||
div.navfooter, div.footing{
|
||||
border-top: 1px solid;
|
||||
}
|
||||
|
||||
/********* /
|
||||
/ colors /
|
||||
/ *********/
|
||||
|
||||
body {
|
||||
color: #333;
|
||||
background: white;
|
||||
}
|
||||
|
||||
a {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
background-color: #dedede;
|
||||
}
|
||||
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
h7,
|
||||
h8 {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
hr {
|
||||
border-color: #aaa;
|
||||
}
|
||||
|
||||
|
||||
.tip, .warning, .caution, .note {
|
||||
border-color: #fff;
|
||||
}
|
||||
|
||||
|
||||
.tip table th,
|
||||
.warning table th,
|
||||
.caution table th,
|
||||
.note table th {
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
|
||||
|
||||
.warning {
|
||||
background-color: #f0f0f2;
|
||||
}
|
||||
|
||||
.caution {
|
||||
background-color: #f0f0f2;
|
||||
}
|
||||
|
||||
.tip {
|
||||
background-color: #f0f0f2;
|
||||
}
|
||||
|
||||
.note {
|
||||
background-color: #f0f0f2;
|
||||
}
|
||||
|
||||
.glossary dl dt,
|
||||
.variablelist dl dt,
|
||||
.variablelist dl dt span.term {
|
||||
color: #044;
|
||||
}
|
||||
|
||||
div.figure,
|
||||
div.table,
|
||||
div.example,
|
||||
div.informalfigure,
|
||||
div.informaltable,
|
||||
div.informalexample {
|
||||
border-color: #aaa;
|
||||
}
|
||||
|
||||
pre.programlisting {
|
||||
color: black;
|
||||
background-color: #fff;
|
||||
border-color: #aaa;
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.guimenu,
|
||||
.guilabel,
|
||||
.guimenuitem {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
|
||||
b.keycap,
|
||||
.keycap {
|
||||
background-color: #eee;
|
||||
border-color: #999;
|
||||
}
|
||||
|
||||
|
||||
div.navheader {
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
|
||||
div.navfooter {
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
|
||||
.writernotes {
|
||||
color: red;
|
||||
}
|
||||
|
||||
|
||||
/*********** /
|
||||
/ graphics /
|
||||
/ ***********/
|
||||
|
||||
/*
|
||||
body {
|
||||
background-image: url("images/body_bg.jpg");
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
.navheader,
|
||||
.note,
|
||||
.tip {
|
||||
background-image: url("images/note_bg.jpg");
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
.warning,
|
||||
.caution {
|
||||
background-image: url("images/warning_bg.jpg");
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
.figure,
|
||||
.informalfigure,
|
||||
.example,
|
||||
.informalexample,
|
||||
.table,
|
||||
.informaltable {
|
||||
background-image: url("images/figure_bg.jpg");
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
*/
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
h7{
|
||||
}
|
||||
|
||||
/*
|
||||
Example of how to stick an image as part of the title.
|
||||
|
||||
div.article .titlepage .title
|
||||
{
|
||||
background-image: url("figures/white-on-black.png");
|
||||
background-position: center;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
*/
|
||||
|
||||
div.preface .titlepage .title,
|
||||
div.colophon .title,
|
||||
div.chapter .titlepage .title {
|
||||
background-position: bottom;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
div.section div.section .titlepage .title,
|
||||
div.sect2 .titlepage .title {
|
||||
background: none;
|
||||
}
|
||||
|
||||
|
||||
h1.title {
|
||||
background-color: transparent;
|
||||
background-repeat: no-repeat;
|
||||
height: 256px;
|
||||
text-indent: -9000px;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
h2.subtitle {
|
||||
background-color: transparent;
|
||||
text-indent: -9000px;
|
||||
overflow:hidden;
|
||||
width: 0px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*************************************** /
|
||||
/ pippin.gimp.org specific alterations /
|
||||
/ ***************************************/
|
||||
|
||||
/*
|
||||
div.heading, div.navheader {
|
||||
color: #777;
|
||||
font-size: 80%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
text-align: left;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
background: url('/gfx/heading_bg.png') transparent;
|
||||
background-repeat: repeat-x;
|
||||
background-attachment: fixed;
|
||||
border: none;
|
||||
}
|
||||
|
||||
div.heading a {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
div.footing, div.navfooter {
|
||||
border: none;
|
||||
color: #ddd;
|
||||
font-size: 80%;
|
||||
text-align:right;
|
||||
|
||||
width: 100%;
|
||||
padding-top: 10px;
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
|
||||
background: url('/gfx/footing_bg.png') transparent;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/****************** /
|
||||
/ nasty ie tweaks /
|
||||
/ ******************/
|
||||
|
||||
/*
|
||||
div.heading, div.navheader {
|
||||
width:expression(document.body.clientWidth + "px");
|
||||
}
|
||||
|
||||
div.footing, div.navfooter {
|
||||
width:expression(document.body.clientWidth + "px");
|
||||
margin-left:expression("-5em");
|
||||
}
|
||||
body {
|
||||
padding:expression("4em 5em 0em 5em");
|
||||
}
|
||||
*/
|
||||
|
||||
/**************************************** /
|
||||
/ mozilla vendor specific css extensions /
|
||||
/ ****************************************/
|
||||
/*
|
||||
div.navfooter, div.footing{
|
||||
-moz-opacity: 0.8em;
|
||||
}
|
||||
|
||||
div.figure,
|
||||
div.table,
|
||||
div.informalfigure,
|
||||
div.informaltable,
|
||||
div.informalexample,
|
||||
div.example,
|
||||
.tip,
|
||||
.warning,
|
||||
.caution,
|
||||
.note {
|
||||
-moz-border-radius: 0.5em;
|
||||
}
|
||||
|
||||
b.keycap,
|
||||
.keycap {
|
||||
-moz-border-radius: 0.3em;
|
||||
}
|
||||
*/
|
||||
|
||||
table tr td table tr td {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
hr {
|
||||
display: none;
|
||||
}
|
||||
|
||||
table {
|
||||
border: 0em;
|
||||
}
|
||||
|
||||
.photo {
|
||||
float: right;
|
||||
margin-left: 1.5em;
|
||||
margin-bottom: 1.5em;
|
||||
margin-top: 0em;
|
||||
max-width: 17em;
|
||||
border: 1px solid gray;
|
||||
padding: 3px;
|
||||
background: white;
|
||||
}
|
||||
.seperator {
|
||||
padding-top: 2em;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#validators {
|
||||
margin-top: 5em;
|
||||
text-align: right;
|
||||
color: #777;
|
||||
}
|
||||
@media print {
|
||||
body {
|
||||
font-size: 8pt;
|
||||
}
|
||||
.noprint {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.tip,
|
||||
.note {
|
||||
background: #f0f0f2;
|
||||
color: #333;
|
||||
padding: 20px;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.tip h3,
|
||||
.note h3 {
|
||||
padding: 0em;
|
||||
margin: 0em;
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.tip a,
|
||||
.note a {
|
||||
color: #333;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.footnote {
|
||||
font-size: small;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* Changes the announcement text */
|
||||
.tip h3,
|
||||
.warning h3,
|
||||
.caution h3,
|
||||
.note h3 {
|
||||
font-size:large;
|
||||
color: #00557D;
|
||||
}
|
||||
@@ -1,357 +0,0 @@
|
||||
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
|
||||
[<!ENTITY % poky SYSTEM "../poky.ent"> %poky; ] >
|
||||
|
||||
<article id='brief-yocto-project-qs-intro'>
|
||||
<articleinfo>
|
||||
<title>My First Yocto Project Build</title>
|
||||
|
||||
<copyright>
|
||||
<year>©RIGHT_YEAR;</year>
|
||||
<holder>Linux Foundation</holder>
|
||||
</copyright>
|
||||
|
||||
<legalnotice>
|
||||
<para>
|
||||
Permission is granted to copy, distribute and/or modify this document under
|
||||
the terms of the <ulink type="http" url="http://creativecommons.org/licenses/by-sa/2.0/uk/">Creative Commons Attribution-Share Alike 2.0 UK: England & Wales</ulink> as published by Creative Commons.
|
||||
</para>
|
||||
<!--
|
||||
<note><title>Manual Notes</title>
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
For the latest version of this document associated with
|
||||
this Yocto Project release
|
||||
(version &YOCTO_DOC_VERSION;), see the "My First
|
||||
Yocto Project Build" from the
|
||||
<ulink url='&YOCTO_HOME_URL;/documentation'>Yocto Project documentation page</ulink>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
This paper is written for the &YOCTO_DOC_VERSION;.
|
||||
For later releases of the Yocto Project (if they exist),
|
||||
go to the
|
||||
<ulink url='&YOCTO_HOME_URL;/documentation'>Yocto Project documentation page</ulink>
|
||||
and use the drop-down "Active Releases" button
|
||||
and choose the Yocto Project version for which you want
|
||||
the manual.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</note>
|
||||
-->
|
||||
</legalnotice>
|
||||
|
||||
|
||||
<abstract>
|
||||
<imagedata fileref="figures/yocto-project-transp.png"
|
||||
width="6in" depth="1in"
|
||||
align="right" scale="25" />
|
||||
</abstract>
|
||||
</articleinfo>
|
||||
|
||||
<section id='brief-welcome'>
|
||||
<title>Welcome!</title>
|
||||
|
||||
<para>
|
||||
Welcome!
|
||||
This short document steps you through the process for a typical
|
||||
image build using the Yocto Project.
|
||||
You will use Yocto Project to build a reference embedded OS
|
||||
called Poky.
|
||||
<note>
|
||||
The examples in this paper assume you are using a native Linux
|
||||
system running a recent Ubuntu Linux distribution.
|
||||
If the machine you want to use
|
||||
Yocto Project on to build an image is not a native Linux
|
||||
system, you can still perform these steps by using CROss
|
||||
PlatformS (CROPS) and setting up a Poky container.
|
||||
See the
|
||||
<ulink url='&YOCTO_DOCS_DEV_URL;#setting-up-to-use-crops'>Setting Up to Use CROss PlatformS (CROPS)</ulink>"
|
||||
section in the Yocto Project Development Tasks Manual for more
|
||||
information.
|
||||
</note>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If you want more conceptual or background information on the
|
||||
Yocto Project, see the
|
||||
<ulink url='&YOCTO_DOCS_GS_URL;'>Getting Started With Yocto Project Manual</ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='brief-compatible-distro'>
|
||||
<title>Compatible Linux Distribution</title>
|
||||
|
||||
<para>
|
||||
Make sure your build system meets the following requirements:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
50 Gbytes of free disk space
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Runs a supported Linux distribution (i.e. recent releases of
|
||||
Fedora, openSUSE, CentOS, Debian, or Ubuntu). For a list of
|
||||
Linux distributions that support the Yocto Project, see the
|
||||
"<ulink url='&YOCTO_DOCS_REF_URL;#detailed-supported-distros'>Supported Linux Distributions</ulink>"
|
||||
section in the Yocto Project Reference Manual.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
Git 1.8.3.1 or greater
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
tar 1.27 or greater
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Python 3.4.0 or greater.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
If your build host does not meet any of these three listed
|
||||
version requirements, you can take steps to prepare the
|
||||
system so that you can still use the Yocto Project.
|
||||
See the
|
||||
"<ulink url='&YOCTO_DOCS_REF_URL;#required-git-tar-and-python-versions'>Required Git, tar, and Python Versions</ulink>"
|
||||
section in the Yocto Project Reference Manual for information.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='brief-build-system-packages'>
|
||||
<title>Build System Packages</title>
|
||||
|
||||
<para>
|
||||
You must install essential host packages on your
|
||||
development host.
|
||||
The following command installs the host packages based on an
|
||||
Ubuntu distribution:
|
||||
<note>
|
||||
For host package requirements on all supported Linux
|
||||
distributions, see the
|
||||
"<ulink url='&YOCTO_DOCS_REF_URL;#required-packages-for-the-host-development-system'>Required Packages for the Host Development System</ulink>"
|
||||
section in the Yocto Project Reference Manual.
|
||||
</note>
|
||||
<literallayout class='monospaced'>
|
||||
$ sudo apt-get install &UBUNTU_HOST_PACKAGES_ESSENTIAL; libsdl1.2-dev xterm
|
||||
</literallayout>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='brief-use-git-to-clone-poky'>
|
||||
<title>Use Git to Clone Poky</title>
|
||||
|
||||
<para>
|
||||
Once you complete the setup instructions for your machine,
|
||||
you need to get a copy of the Poky repository on your build
|
||||
system.
|
||||
Use the following commands to clone the Poky
|
||||
repository and then checkout the &DISTRO_REL_TAG; release:
|
||||
<literallayout class='monospaced'>
|
||||
$ git clone git://git.yoctoproject.org/poky
|
||||
Cloning into 'poky'...
|
||||
remote: Counting objects: 361782, done.
|
||||
remote: Compressing objects: 100% (87100/87100), done.
|
||||
remote: Total 361782 (delta 268619), reused 361439 (delta 268277)
|
||||
Receiving objects: 100% (361782/361782), 131.94 MiB | 6.88 MiB/s, done.
|
||||
Resolving deltas: 100% (268619/268619), done.
|
||||
Checking connectivity... done.
|
||||
$ git checkout tags/yocto-2.5 -b my-yocto-2.5
|
||||
</literallayout>
|
||||
The previous Git checkout command creates a local branch
|
||||
named my-&DISTRO_REL_TAG;. The files available to you in that
|
||||
branch exactly match the repository's files in the
|
||||
"&DISTRO_NAME_NO_CAP;" development branch at the time of the
|
||||
Yocto Project &DISTRO; release.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For more options and information about accessing Yocto
|
||||
Project related repositories, see the
|
||||
"<ulink url='&YOCTO_DOCS_DEV_URL;#working-with-yocto-project-source-files'>Working With Yocto Project Source Files</ulink>"
|
||||
section in the Yocto Project Development Tasks Manual.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='brief-building-your-image'>
|
||||
<title>Building Your Image</title>
|
||||
|
||||
<para>
|
||||
Use the following steps to build your image.
|
||||
The OpenEmbedded build system creates an entire Linux
|
||||
distribution, including the toolchain, from source.
|
||||
<note>
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
If you are working behind a firewall and your build
|
||||
host is not set up for proxies, you could encounter
|
||||
problems with the build process when fetching source
|
||||
code (e.g. fetcher failures or Git failures).
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
If you do not know your proxy settings, consult your
|
||||
local network infrastructure resources and get that
|
||||
information.
|
||||
A good starting point could also be to check your
|
||||
web browser settings.
|
||||
Finally, you can find more information on the
|
||||
"<ulink url='https://wiki.yoctoproject.org/wiki/Working_Behind_a_Network_Proxy'>Working Behind a Network Proxy</ulink>"
|
||||
page of the Yocto Project Wiki.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</note>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<orderedlist>
|
||||
<listitem><para>
|
||||
<emphasis>Initialize the Build Environment:</emphasis>
|
||||
Run the
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#structure-core-script'><filename>&OE_INIT_FILE;</filename></ulink>
|
||||
environment setup script to define the OpenEmbedded
|
||||
build environment on your build host.
|
||||
<literallayout class='monospaced'>
|
||||
$ source &OE_INIT_FILE;
|
||||
</literallayout>
|
||||
Among other things, the script creates the
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#build-directory'>Build Directory</ulink>,
|
||||
which is <filename>build</filename> in this case
|
||||
and is located in the
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#source-directory'>Source Directory</ulink>.
|
||||
After the script runs, your current working directory
|
||||
is set to the Build Directory.
|
||||
Later, when the build completes, the Build Directory
|
||||
contains all the files created during the build.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Examine Your Local Configuration File:</emphasis>
|
||||
When you set up the build environment, a local
|
||||
configuration file named
|
||||
<filename>local.conf</filename> becomes available in
|
||||
a <filename>conf</filename> subdirectory of the
|
||||
Build Directory.
|
||||
For this example, the defaults are set to build
|
||||
for a <filename>qemux86</filename> target, which is
|
||||
suitable for emulation.
|
||||
The package manager used is set to the RPM package
|
||||
manager.
|
||||
<tip>
|
||||
You can significantly speed up your build and guard
|
||||
against fetcher failures by using mirrors.
|
||||
To use mirrors, add these lines to your
|
||||
<filename>local.conf</filename> file in the Build
|
||||
directory:
|
||||
<literallayout class='monospaced'>
|
||||
SSTATE_MIRRORS = "\
|
||||
file://.* http://sstate.yoctoproject.org/dev/PATH;downloadfilename=PATH \n \
|
||||
file://.* http://sstate.yoctoproject.org/2.3/PATH;downloadfilename=PATH \n \
|
||||
file://.* http://sstate.yoctoproject.org/2.4/PATH;downloadfilename=PATH \n \
|
||||
"
|
||||
</literallayout>
|
||||
The previous examples showed how to add sstate
|
||||
paths for Yocto Project 2.3, 2.4, and a development
|
||||
area.
|
||||
For a complete index of sstate locations, see
|
||||
<ulink url='http://sstate.yoctoproject.org/'></ulink>.
|
||||
</tip>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Start the Build:</emphasis>
|
||||
Continue with the following command to build an OS image
|
||||
for the target, which is
|
||||
<filename>core-image-sato</filename> in this example:
|
||||
<literallayout class='monospaced'>
|
||||
$ bitbake core-image-sato
|
||||
</literallayout>
|
||||
For information on using the
|
||||
<filename>bitbake</filename> command, see the
|
||||
"<ulink url='&YOCTO_DOCS_OVERVIEW_URL;#usingpoky-components-bitbake'>BitBake</ulink>"
|
||||
section in the Yocto Project Overview Manual, or
|
||||
see the
|
||||
"<ulink url='&YOCTO_DOCS_BB_URL;#bitbake-user-manual-command'>BitBake Command</ulink>"
|
||||
section in the BitBake User Manual.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Simulate Your Image Using QEMU:</emphasis>
|
||||
Once this particular image is built, you can start
|
||||
QEMU, which is a Quick EMUlator that ships with
|
||||
the Yocto Project:
|
||||
<literallayout class='monospaced'>
|
||||
$ runqemu qemux86
|
||||
</literallayout>
|
||||
If you want to learn more about running QEMU, see the
|
||||
"<ulink url="&YOCTO_DOCS_DEV_URL;#dev-manual-qemu">Using the Quick EMUlator (QEMU)</ulink>"
|
||||
chapter in the Yocto Project Development Tasks Manual.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Exit QEMU:</emphasis>
|
||||
Exit QEMU by either clicking on the shutdown icon or by
|
||||
typing <filename>Ctrl-C</filename> in the QEMU
|
||||
transcript window from which you evoked QEMU.
|
||||
</para></listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='brief-where-to-go-next'>
|
||||
<title>Where To Go Next</title>
|
||||
|
||||
<para>
|
||||
Now that you have experienced using the Yocto Project, you might
|
||||
be asking yourself "What now?"
|
||||
The Yocto Project has many sources of information including
|
||||
the website, wiki pages, and user manuals:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
<emphasis>Website:</emphasis>
|
||||
The
|
||||
<ulink url='&YOCTO_HOME_URL;'>Yocto Project Website</ulink>
|
||||
provides background information, the latest builds,
|
||||
breaking news, full development documentation, and
|
||||
access to a rich Yocto Project Development Community
|
||||
into which you can tap.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Developer Screencast:</emphasis>
|
||||
The
|
||||
<ulink url='http://vimeo.com/36450321'>Getting Started with the Yocto Project - New Developer Screencast Tutorial</ulink>
|
||||
provides a 30-minute video created for users unfamiliar
|
||||
with the Yocto Project but familiar with Linux build
|
||||
hosts.
|
||||
While this screencast is somewhat dated, the
|
||||
introductory and fundamental concepts are useful for
|
||||
the beginner.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Yocto Project Wiki:</emphasis>
|
||||
The
|
||||
<ulink url='&YOCTO_WIKI_URL;'>Yocto Project Wiki</ulink>
|
||||
provides additional information on where to go next
|
||||
when ramping up with the Yocto Project, release
|
||||
information, project planning, and QA information.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Yocto Project Mailing Lists:</emphasis>
|
||||
Related mailing lists provide a forum for discussion,
|
||||
patch submission and announcements.
|
||||
Several mailing lists exist and are grouped according
|
||||
to areas of concern.
|
||||
See the
|
||||
"<ulink url='&YOCTO_DOCS_REF_URL;#resources-mailinglist'>Mailing lists</ulink>"
|
||||
section in the Yocto Project Reference Manual for a
|
||||
complete list of Yocto Project mailing lists.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Comprehensive List of Links and Other Documentation:</emphasis>
|
||||
The
|
||||
"<ulink url='&YOCTO_DOCS_REF_URL;#resources-links-and-related-documentation'>Links and Related Documentation</ulink>"
|
||||
section in the Yocto Project Reference Manual provides a
|
||||
comprehensive list of all related links and other
|
||||
user documentation.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
</article>
|
||||
<!--
|
||||
vim: expandtab tw=80 ts=4
|
||||
-->
|
||||
|
Before Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 11 KiB |
@@ -116,11 +116,6 @@
|
||||
<date>October 2017</date>
|
||||
<revremark>Released with the Yocto Project 2.4 Release.</revremark>
|
||||
</revision>
|
||||
<revision>
|
||||
<revnumber>2.5</revnumber>
|
||||
<date>April 2018</date>
|
||||
<revremark>Released with the Yocto Project 2.5 Release.</revremark>
|
||||
</revision>
|
||||
</revhistory>
|
||||
|
||||
<copyright>
|
||||
|
||||
@@ -730,9 +730,6 @@ div.navfooter {
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
.writernotes {
|
||||
color: red;
|
||||
}
|
||||
|
||||
/*********** /
|
||||
/ graphics /
|
||||
|
||||
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 62 KiB |
@@ -1,27 +0,0 @@
|
||||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
|
||||
|
||||
<xsl:import href="http://downloads.yoctoproject.org/mirror/docbook-mirror/docbook-xsl-1.76.1/xhtml/docbook.xsl" />
|
||||
|
||||
<!--
|
||||
|
||||
<xsl:import href="../template/1.76.1/docbook-xsl-1.76.1/xhtml/docbook.xsl" />
|
||||
|
||||
<xsl:import href="http://docbook.sourceforge.net/release/xsl/1.76.1/xhtml/docbook.xsl" />
|
||||
|
||||
-->
|
||||
|
||||
<xsl:include href="../template/permalinks.xsl"/>
|
||||
<xsl:include href="../template/section.title.xsl"/>
|
||||
<xsl:include href="../template/component.title.xsl"/>
|
||||
<xsl:include href="../template/division.title.xsl"/>
|
||||
<xsl:include href="../template/formal.object.heading.xsl"/>
|
||||
|
||||
<xsl:param name="html.stylesheet" select="'concepts-manual-style.css'" />
|
||||
<xsl:param name="chapter.autolabel" select="1" />
|
||||
<xsl:param name="appendix.autolabel" select="A" />
|
||||
<xsl:param name="section.autolabel" select="1" />
|
||||
<xsl:param name="section.label.includes.component.label" select="1" />
|
||||
<xsl:param name="generate.id.attributes" select="1" />
|
||||
|
||||
</xsl:stylesheet>
|
||||
@@ -1,35 +0,0 @@
|
||||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:fo="http://www.w3.org/1999/XSL/Format"
|
||||
version="1.0">
|
||||
|
||||
<xsl:import href="http://downloads.yoctoproject.org/mirror/docbook-mirror/docbook-xsl-1.76.1/eclipse/eclipse3.xsl" />
|
||||
|
||||
<!--
|
||||
|
||||
<xsl:import href="../template/1.76.1/docbook-xsl-1.76.1/eclipse/eclipse3.xsl" />
|
||||
|
||||
<xsl:import
|
||||
href="http://docbook.sourceforge.net/release/xsl/1.76.1/eclipse/eclipse3.xsl" />
|
||||
|
||||
-->
|
||||
|
||||
<xsl:param name="chunker.output.indent" select="'yes'"/>
|
||||
<xsl:param name="chunk.quietly" select="1"/>
|
||||
<xsl:param name="chunk.first.sections" select="1"/>
|
||||
<xsl:param name="chunk.section.depth" select="10"/>
|
||||
<xsl:param name="use.id.as.filename" select="1"/>
|
||||
<xsl:param name="ulink.target" select="'_self'" />
|
||||
<xsl:param name="base.dir" select="'html/concepts-manual/'"/>
|
||||
<xsl:param name="html.stylesheet" select="'../book.css'"/>
|
||||
<xsl:param name="eclipse.manifest" select="0"/>
|
||||
<xsl:param name="create.plugin.xml" select="0"/>
|
||||
<xsl:param name="suppress.navigation" select="1"/>
|
||||
<xsl:param name="generate.index" select="0"/>
|
||||
<xsl:param name="chapter.autolabel" select="1" />
|
||||
<xsl:param name="appendix.autolabel" select="1" />
|
||||
<xsl:param name="section.autolabel" select="1" />
|
||||
<xsl:param name="section.label.includes.component.label" select="1" />
|
||||
</xsl:stylesheet>
|
||||
@@ -1,87 +0,0 @@
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
|
||||
[<!ENTITY % poky SYSTEM "../poky.ent"> %poky; ] >
|
||||
|
||||
<chapter id='concepts-manual-intro'>
|
||||
|
||||
<title>The Yocto Project Concepts Manual</title>
|
||||
<section id='concepts-overview-welcome'>
|
||||
<title>Welcome</title>
|
||||
|
||||
<para>
|
||||
Welcome to the Yocto Project Concepts Manual!
|
||||
This manual provides conceptual information that helps you
|
||||
better understand the Yocto Project.
|
||||
You can learn about Yocto Project components,
|
||||
cross-development toolchain generation, shared-state cache,
|
||||
and many other concepts.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This manual does not give you the following:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
<emphasis>Complete Step-by-step Instructions for Development Tasks:</emphasis>
|
||||
Instructional procedures reside in other manuals within
|
||||
the Yocto Project documentation set.
|
||||
For example, the
|
||||
<ulink url='&YOCTO_DOCS_DEV_URL;'>Yocto Project Development Tasks Manual</ulink>
|
||||
provides examples on how to perform various development
|
||||
tasks.
|
||||
As another example, the
|
||||
<ulink url='&YOCTO_DOCS_SDK_URL;'>Yocto Project Application Development and the Extensible Software Development Kit (eSDK)</ulink>
|
||||
manual contains detailed instructions on how to install an
|
||||
SDK, which is used to develop applications for target
|
||||
hardware.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Reference Material:</emphasis>
|
||||
This type of material resides in an appropriate reference
|
||||
manual.
|
||||
For example, system variables are documented in the
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;'>Yocto Project Reference Manual</ulink>.
|
||||
As another example, the
|
||||
<ulink url='&YOCTO_DOCS_BSP_URL;'>Yocto Project Board Support Package (BSP) Developer's Guide</ulink>
|
||||
contains reference information on BSPs.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Getting Started Material:</emphasis>
|
||||
This type of material resides in the
|
||||
<ulink url='&YOCTO_DOCS_GS_URL;'>Getting Started With Yocto Project Manual</ulink>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Detailed Public Information Not Specific to the
|
||||
Yocto Project:</emphasis>
|
||||
For example, exhaustive information on how to use Git
|
||||
is better covered with Internet searches and official
|
||||
Git Documentation than through the Yocto Project
|
||||
documentation.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='concepts-overview-other-information'>
|
||||
<title>Other Information</title>
|
||||
|
||||
<para>
|
||||
Because this manual presents information for many different
|
||||
concepts, supplemental information is recommended for full
|
||||
comprehension.
|
||||
For additional introductory information on the Yocto Project, see
|
||||
the <ulink url='&YOCTO_HOME_URL;'>Yocto Project Website</ulink>.
|
||||
You can find an introductory to using the Yocto Project by working
|
||||
through the
|
||||
<ulink url='&YOCTO_DOCS_QS_URL;'>Yocto Project Quick Start</ulink>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For a comprehensive list of links and other documentation, see the
|
||||
"<ulink url='&YOCTO_DOCS_REF_URL;#resources-links-and-related-documentation'>Links and Related Documentation</ulink>"
|
||||
section in the Yocto Project Reference Manual.
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
||||
<!--
|
||||
vim: expandtab tw=80 ts=4
|
||||
-->
|
||||
@@ -1,988 +0,0 @@
|
||||
/*
|
||||
Generic XHTML / DocBook XHTML CSS Stylesheet.
|
||||
|
||||
Browser wrangling and typographic design by
|
||||
Oyvind Kolas / pippin@gimp.org
|
||||
|
||||
Customised for Poky by
|
||||
Matthew Allum / mallum@o-hand.com
|
||||
|
||||
Thanks to:
|
||||
Liam R. E. Quin
|
||||
William Skaggs
|
||||
Jakub Steiner
|
||||
|
||||
Structure
|
||||
---------
|
||||
|
||||
The stylesheet is divided into the following sections:
|
||||
|
||||
Positioning
|
||||
Margins, paddings, width, font-size, clearing.
|
||||
Decorations
|
||||
Borders, style
|
||||
Colors
|
||||
Colors
|
||||
Graphics
|
||||
Graphical backgrounds
|
||||
Nasty IE tweaks
|
||||
Workarounds needed to make it work in internet explorer,
|
||||
currently makes the stylesheet non validating, but up until
|
||||
this point it is validating.
|
||||
Mozilla extensions
|
||||
Transparency for footer
|
||||
Rounded corners on boxes
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*************** /
|
||||
/ Positioning /
|
||||
/ ***************/
|
||||
|
||||
body {
|
||||
font-family: Verdana, Sans, sans-serif;
|
||||
|
||||
min-width: 640px;
|
||||
width: 80%;
|
||||
margin: 0em auto;
|
||||
padding: 2em 5em 5em 5em;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6,h7 {
|
||||
font-family: Arial, Sans;
|
||||
color: #00557D;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
text-align: left;
|
||||
padding: 0em 0em 0em 0em;
|
||||
margin: 2em 0em 0em 0em;
|
||||
}
|
||||
|
||||
h2.subtitle {
|
||||
margin: 0.10em 0em 3.0em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
font-size: 1.8em;
|
||||
padding-left: 20%;
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 2em 0em 0.66em 0em;
|
||||
padding: 0.5em 0em 0em 0em;
|
||||
font-size: 1.5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h3.subtitle {
|
||||
margin: 0em 0em 1em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
font-size: 142.14%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 1em 0em 0.5em 0em;
|
||||
padding: 1em 0em 0em 0em;
|
||||
font-size: 140%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin: 1em 0em 0.5em 0em;
|
||||
padding: 1em 0em 0em 0em;
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h5 {
|
||||
margin: 1em 0em 0.5em 0em;
|
||||
padding: 1em 0em 0em 0em;
|
||||
font-size: 110%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h6 {
|
||||
margin: 1em 0em 0em 0em;
|
||||
padding: 1em 0em 0em 0em;
|
||||
font-size: 110%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.authorgroup {
|
||||
background-color: transparent;
|
||||
background-repeat: no-repeat;
|
||||
padding-top: 256px;
|
||||
background-image: url("figures/concepts-manual-title.png");
|
||||
background-position: left top;
|
||||
margin-top: -256px;
|
||||
padding-right: 50px;
|
||||
margin-left: 0px;
|
||||
text-align: right;
|
||||
width: 740px;
|
||||
}
|
||||
|
||||
h3.author {
|
||||
margin: 0em 0me 0em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
font-weight: normal;
|
||||
font-size: 100%;
|
||||
color: #333;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.author tt.email {
|
||||
font-size: 66%;
|
||||
}
|
||||
|
||||
.titlepage hr {
|
||||
width: 0em;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.revhistory {
|
||||
padding-top: 2em;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.toc,
|
||||
.list-of-tables,
|
||||
.list-of-examples,
|
||||
.list-of-figures {
|
||||
padding: 1.33em 0em 2.5em 0em;
|
||||
color: #00557D;
|
||||
}
|
||||
|
||||
.toc p,
|
||||
.list-of-tables p,
|
||||
.list-of-figures p,
|
||||
.list-of-examples p {
|
||||
padding: 0em 0em 0em 0em;
|
||||
padding: 0em 0em 0.3em;
|
||||
margin: 1.5em 0em 0em 0em;
|
||||
}
|
||||
|
||||
.toc p b,
|
||||
.list-of-tables p b,
|
||||
.list-of-figures p b,
|
||||
.list-of-examples p b{
|
||||
font-size: 100.0%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.toc dl,
|
||||
.list-of-tables dl,
|
||||
.list-of-figures dl,
|
||||
.list-of-examples dl {
|
||||
margin: 0em 0em 0.5em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
.toc dt {
|
||||
margin: 0em 0em 0em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
.toc dd {
|
||||
margin: 0em 0em 0em 2.6em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
div.glossary dl,
|
||||
div.variablelist dl {
|
||||
}
|
||||
|
||||
.glossary dl dt,
|
||||
.variablelist dl dt,
|
||||
.variablelist dl dt span.term {
|
||||
font-weight: normal;
|
||||
width: 20em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.variablelist dl dt {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
.glossary dl dd,
|
||||
.variablelist dl dd {
|
||||
margin-top: -1em;
|
||||
margin-left: 25.5em;
|
||||
}
|
||||
|
||||
.glossary dd p,
|
||||
.variablelist dd p {
|
||||
margin-top: 0em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
|
||||
div.calloutlist table td {
|
||||
padding: 0em 0em 0em 0em;
|
||||
margin: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
div.calloutlist table td p {
|
||||
margin-top: 0em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
div p.copyright {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div.legalnotice p.legalnotice-title {
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 1.5em;
|
||||
margin-top: 0em;
|
||||
|
||||
}
|
||||
|
||||
dl {
|
||||
padding-top: 0em;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: solid 1px;
|
||||
}
|
||||
|
||||
|
||||
.mediaobject,
|
||||
.mediaobjectco {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
img {
|
||||
border: none;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding: 0em 0em 0em 1.5em;
|
||||
}
|
||||
|
||||
ul li {
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
ul li p {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
table {
|
||||
width :100%;
|
||||
}
|
||||
|
||||
th {
|
||||
padding: 0.25em;
|
||||
text-align: left;
|
||||
font-weight: normal;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0.25em;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
p a[id] {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
display: inline;
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: underline;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
pre {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
/*font-weight: bold;*/
|
||||
}
|
||||
|
||||
/* This style defines how the permalink character
|
||||
appears by itself and when hovered over with
|
||||
the mouse. */
|
||||
|
||||
[alt='Permalink'] { color: #eee; }
|
||||
[alt='Permalink']:hover { color: black; }
|
||||
|
||||
|
||||
div.informalfigure,
|
||||
div.informalexample,
|
||||
div.informaltable,
|
||||
div.figure,
|
||||
div.table,
|
||||
div.example {
|
||||
margin: 1em 0em;
|
||||
padding: 1em;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
|
||||
div.informalfigure p.title b,
|
||||
div.informalexample p.title b,
|
||||
div.informaltable p.title b,
|
||||
div.figure p.title b,
|
||||
div.example p.title b,
|
||||
div.table p.title b{
|
||||
padding-top: 0em;
|
||||
margin-top: 0em;
|
||||
font-size: 100%;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.mediaobject .caption,
|
||||
.mediaobject .caption p {
|
||||
text-align: center;
|
||||
font-size: 80%;
|
||||
padding-top: 0.5em;
|
||||
padding-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.epigraph {
|
||||
padding-left: 55%;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.epigraph p {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.epigraph .quote {
|
||||
font-style: italic;
|
||||
}
|
||||
.epigraph .attribution {
|
||||
font-style: normal;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
span.application {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.programlisting {
|
||||
font-family: monospace;
|
||||
font-size: 80%;
|
||||
white-space: pre;
|
||||
margin: 1.33em 0em;
|
||||
padding: 1.33em;
|
||||
}
|
||||
|
||||
.tip,
|
||||
.warning,
|
||||
.caution,
|
||||
.note {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
|
||||
}
|
||||
|
||||
/* force full width of table within div */
|
||||
.tip table,
|
||||
.warning table,
|
||||
.caution table,
|
||||
.note table {
|
||||
border: none;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
.tip table th,
|
||||
.warning table th,
|
||||
.caution table th,
|
||||
.note table th {
|
||||
padding: 0.8em 0.0em 0.0em 0.0em;
|
||||
margin : 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
.tip p,
|
||||
.warning p,
|
||||
.caution p,
|
||||
.note p {
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
padding-right: 1em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.acronym {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
b.keycap,
|
||||
.keycap {
|
||||
padding: 0.09em 0.3em;
|
||||
margin: 0em;
|
||||
}
|
||||
|
||||
.itemizedlist li {
|
||||
clear: none;
|
||||
}
|
||||
|
||||
.filename {
|
||||
font-size: medium;
|
||||
font-family: Courier, monospace;
|
||||
}
|
||||
|
||||
|
||||
div.navheader, div.heading{
|
||||
position: absolute;
|
||||
left: 0em;
|
||||
top: 0em;
|
||||
width: 100%;
|
||||
background-color: #cdf;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.navfooter, div.footing{
|
||||
position: fixed;
|
||||
left: 0em;
|
||||
bottom: 0em;
|
||||
background-color: #eee;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
div.navheader td,
|
||||
div.navfooter td {
|
||||
font-size: 66%;
|
||||
}
|
||||
|
||||
div.navheader table th {
|
||||
/*font-family: Georgia, Times, serif;*/
|
||||
/*font-size: x-large;*/
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
div.navheader table {
|
||||
border-left: 0em;
|
||||
border-right: 0em;
|
||||
border-top: 0em;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.navfooter table {
|
||||
border-left: 0em;
|
||||
border-right: 0em;
|
||||
border-bottom: 0em;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.navheader table td a,
|
||||
div.navfooter table td a {
|
||||
color: #777;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* normal text in the footer */
|
||||
div.navfooter table td {
|
||||
color: black;
|
||||
}
|
||||
|
||||
div.navheader table td a:visited,
|
||||
div.navfooter table td a:visited {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
|
||||
/* links in header and footer */
|
||||
div.navheader table td a:hover,
|
||||
div.navfooter table td a:hover {
|
||||
text-decoration: underline;
|
||||
background-color: transparent;
|
||||
color: #33a;
|
||||
}
|
||||
|
||||
div.navheader hr,
|
||||
div.navfooter hr {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.qandaset tr.question td p {
|
||||
margin: 0em 0em 1em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
.qandaset tr.answer td p {
|
||||
margin: 0em 0em 1em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
.answer td {
|
||||
padding-bottom: 1.5em;
|
||||
}
|
||||
|
||||
.emphasis {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
/************* /
|
||||
/ decorations /
|
||||
/ *************/
|
||||
|
||||
.titlepage {
|
||||
}
|
||||
|
||||
.part .title {
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/*
|
||||
h1 {
|
||||
border: none;
|
||||
}
|
||||
|
||||
h2 {
|
||||
border-top: solid 0.2em;
|
||||
border-bottom: solid 0.06em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
border-top: 0em;
|
||||
border-bottom: solid 0.06em;
|
||||
}
|
||||
|
||||
h4 {
|
||||
border: 0em;
|
||||
border-bottom: solid 0.06em;
|
||||
}
|
||||
|
||||
h5 {
|
||||
border: 0em;
|
||||
}
|
||||
*/
|
||||
|
||||
.programlisting {
|
||||
border: solid 1px;
|
||||
}
|
||||
|
||||
div.figure,
|
||||
div.table,
|
||||
div.informalfigure,
|
||||
div.informaltable,
|
||||
div.informalexample,
|
||||
div.example {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.tip,
|
||||
.warning,
|
||||
.caution,
|
||||
.note {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.tip table th,
|
||||
.warning table th,
|
||||
.caution table th,
|
||||
.note table th {
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
|
||||
.question td {
|
||||
border-top: 1px solid black;
|
||||
}
|
||||
|
||||
.answer {
|
||||
}
|
||||
|
||||
|
||||
b.keycap,
|
||||
.keycap {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
|
||||
div.navheader, div.heading{
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
|
||||
|
||||
div.navfooter, div.footing{
|
||||
border-top: 1px solid;
|
||||
}
|
||||
|
||||
/********* /
|
||||
/ colors /
|
||||
/ *********/
|
||||
|
||||
body {
|
||||
color: #333;
|
||||
background: white;
|
||||
}
|
||||
|
||||
a {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
background-color: #dedede;
|
||||
}
|
||||
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
h7,
|
||||
h8 {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
hr {
|
||||
border-color: #aaa;
|
||||
}
|
||||
|
||||
|
||||
.tip, .warning, .caution, .note {
|
||||
border-color: #fff;
|
||||
}
|
||||
|
||||
|
||||
.tip table th,
|
||||
.warning table th,
|
||||
.caution table th,
|
||||
.note table th {
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
|
||||
|
||||
.warning {
|
||||
background-color: #f0f0f2;
|
||||
}
|
||||
|
||||
.caution {
|
||||
background-color: #f0f0f2;
|
||||
}
|
||||
|
||||
.tip {
|
||||
background-color: #f0f0f2;
|
||||
}
|
||||
|
||||
.note {
|
||||
background-color: #f0f0f2;
|
||||
}
|
||||
|
||||
.glossary dl dt,
|
||||
.variablelist dl dt,
|
||||
.variablelist dl dt span.term {
|
||||
color: #044;
|
||||
}
|
||||
|
||||
div.figure,
|
||||
div.table,
|
||||
div.example,
|
||||
div.informalfigure,
|
||||
div.informaltable,
|
||||
div.informalexample {
|
||||
border-color: #aaa;
|
||||
}
|
||||
|
||||
pre.programlisting {
|
||||
color: black;
|
||||
background-color: #fff;
|
||||
border-color: #aaa;
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.guimenu,
|
||||
.guilabel,
|
||||
.guimenuitem {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
|
||||
b.keycap,
|
||||
.keycap {
|
||||
background-color: #eee;
|
||||
border-color: #999;
|
||||
}
|
||||
|
||||
|
||||
div.navheader {
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
|
||||
div.navfooter {
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
.writernotes {
|
||||
color: red;
|
||||
}
|
||||
|
||||
|
||||
/*********** /
|
||||
/ graphics /
|
||||
/ ***********/
|
||||
|
||||
/*
|
||||
body {
|
||||
background-image: url("images/body_bg.jpg");
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
.navheader,
|
||||
.note,
|
||||
.tip {
|
||||
background-image: url("images/note_bg.jpg");
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
.warning,
|
||||
.caution {
|
||||
background-image: url("images/warning_bg.jpg");
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
.figure,
|
||||
.informalfigure,
|
||||
.example,
|
||||
.informalexample,
|
||||
.table,
|
||||
.informaltable {
|
||||
background-image: url("images/figure_bg.jpg");
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
*/
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
h7{
|
||||
}
|
||||
|
||||
/*
|
||||
Example of how to stick an image as part of the title.
|
||||
|
||||
div.article .titlepage .title
|
||||
{
|
||||
background-image: url("figures/white-on-black.png");
|
||||
background-position: center;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
*/
|
||||
|
||||
div.preface .titlepage .title,
|
||||
div.colophon .title,
|
||||
div.chapter .titlepage .title,
|
||||
div.article .titlepage .title
|
||||
{
|
||||
}
|
||||
|
||||
div.section div.section .titlepage .title,
|
||||
div.sect2 .titlepage .title {
|
||||
background: none;
|
||||
}
|
||||
|
||||
|
||||
h1.title {
|
||||
background-color: transparent;
|
||||
background-repeat: no-repeat;
|
||||
height: 256px;
|
||||
text-indent: -9000px;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
h2.subtitle {
|
||||
background-color: transparent;
|
||||
text-indent: -9000px;
|
||||
overflow:hidden;
|
||||
width: 0px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*************************************** /
|
||||
/ pippin.gimp.org specific alterations /
|
||||
/ ***************************************/
|
||||
|
||||
/*
|
||||
div.heading, div.navheader {
|
||||
color: #777;
|
||||
font-size: 80%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
text-align: left;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
background: url('/gfx/heading_bg.png') transparent;
|
||||
background-repeat: repeat-x;
|
||||
background-attachment: fixed;
|
||||
border: none;
|
||||
}
|
||||
|
||||
div.heading a {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
div.footing, div.navfooter {
|
||||
border: none;
|
||||
color: #ddd;
|
||||
font-size: 80%;
|
||||
text-align:right;
|
||||
|
||||
width: 100%;
|
||||
padding-top: 10px;
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
|
||||
background: url('/gfx/footing_bg.png') transparent;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/****************** /
|
||||
/ nasty ie tweaks /
|
||||
/ ******************/
|
||||
|
||||
/*
|
||||
div.heading, div.navheader {
|
||||
width:expression(document.body.clientWidth + "px");
|
||||
}
|
||||
|
||||
div.footing, div.navfooter {
|
||||
width:expression(document.body.clientWidth + "px");
|
||||
margin-left:expression("-5em");
|
||||
}
|
||||
body {
|
||||
padding:expression("4em 5em 0em 5em");
|
||||
}
|
||||
*/
|
||||
|
||||
/**************************************** /
|
||||
/ mozilla vendor specific css extensions /
|
||||
/ ****************************************/
|
||||
/*
|
||||
div.navfooter, div.footing{
|
||||
-moz-opacity: 0.8em;
|
||||
}
|
||||
|
||||
div.figure,
|
||||
div.table,
|
||||
div.informalfigure,
|
||||
div.informaltable,
|
||||
div.informalexample,
|
||||
div.example,
|
||||
.tip,
|
||||
.warning,
|
||||
.caution,
|
||||
.note {
|
||||
-moz-border-radius: 0.5em;
|
||||
}
|
||||
|
||||
b.keycap,
|
||||
.keycap {
|
||||
-moz-border-radius: 0.3em;
|
||||
}
|
||||
*/
|
||||
|
||||
table tr td table tr td {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
hr {
|
||||
display: none;
|
||||
}
|
||||
|
||||
table {
|
||||
border: 0em;
|
||||
}
|
||||
|
||||
.photo {
|
||||
float: right;
|
||||
margin-left: 1.5em;
|
||||
margin-bottom: 1.5em;
|
||||
margin-top: 0em;
|
||||
max-width: 17em;
|
||||
border: 1px solid gray;
|
||||
padding: 3px;
|
||||
background: white;
|
||||
}
|
||||
.seperator {
|
||||
padding-top: 2em;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#validators {
|
||||
margin-top: 5em;
|
||||
text-align: right;
|
||||
color: #777;
|
||||
}
|
||||
@media print {
|
||||
body {
|
||||
font-size: 8pt;
|
||||
}
|
||||
.noprint {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.tip,
|
||||
.note {
|
||||
background: #f0f0f2;
|
||||
color: #333;
|
||||
padding: 20px;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.tip h3,
|
||||
.note h3 {
|
||||
padding: 0em;
|
||||
margin: 0em;
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.tip a,
|
||||
.note a {
|
||||
color: #333;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.footnote {
|
||||
font-size: small;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* Changes the announcement text */
|
||||
.tip h3,
|
||||
.warning h3,
|
||||
.caution h3,
|
||||
.note h3 {
|
||||
font-size:large;
|
||||
color: #00557D;
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
|
||||
[<!ENTITY % poky SYSTEM "../poky.ent"> %poky; ] >
|
||||
|
||||
<book id='concepts-manual' lang='en'
|
||||
xmlns:xi="http://www.w3.org/2003/XInclude"
|
||||
xmlns="http://docbook.org/ns/docbook"
|
||||
>
|
||||
<bookinfo>
|
||||
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref='figures/concepts-manual-title.png'
|
||||
format='SVG'
|
||||
align='left' scalefit='1' width='100%'/>
|
||||
</imageobject>
|
||||
</mediaobject>
|
||||
|
||||
<title>
|
||||
Yocto Project Concepts Manual
|
||||
</title>
|
||||
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Scott</firstname> <surname>Rifenbark</surname>
|
||||
<affiliation>
|
||||
<orgname>Scotty's Documentation Services, INC</orgname>
|
||||
</affiliation>
|
||||
<email>srifenbark@gmail.com</email>
|
||||
</author>
|
||||
</authorgroup>
|
||||
|
||||
<revhistory>
|
||||
<revision>
|
||||
<revnumber>2.5</revnumber>
|
||||
<date>April 2018</date>
|
||||
<revremark>The initial document released with the Yocto Project 2.5 Release.</revremark>
|
||||
</revision>
|
||||
</revhistory>
|
||||
|
||||
<copyright>
|
||||
<year>©RIGHT_YEAR;</year>
|
||||
<holder>Linux Foundation</holder>
|
||||
</copyright>
|
||||
|
||||
<legalnotice>
|
||||
<para>
|
||||
Permission is granted to copy, distribute and/or modify this document under
|
||||
the terms of the <ulink type="http" url="http://creativecommons.org/licenses/by-sa/2.0/uk/">
|
||||
Creative Commons Attribution-Share Alike 2.0 UK: England & Wales</ulink> as published by
|
||||
Creative Commons.
|
||||
</para>
|
||||
<note><title>Manual Notes</title>
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
This version of the
|
||||
<emphasis>Yocto Project Concepts Manual</emphasis>
|
||||
is for the &YOCTO_DOC_VERSION; release of the
|
||||
Yocto Project.
|
||||
To be sure you have the latest version of the manual
|
||||
for this release, use the manual from the
|
||||
<ulink url='&YOCTO_HOME_URL;/documentation'>Yocto Project documentation page</ulink>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
For manuals associated with other releases of the Yocto
|
||||
Project, go to the
|
||||
<ulink url='&YOCTO_HOME_URL;/documentation'>Yocto Project documentation page</ulink>
|
||||
and use the drop-down "Active Releases" button
|
||||
and choose the manual associated with the desired
|
||||
Yocto Project.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
To report any inaccuracies or problems with this
|
||||
manual, send an email to the Yocto Project
|
||||
discussion group at
|
||||
<filename>yocto@yoctoproject.com</filename> or log into
|
||||
the freenode <filename>#yocto</filename> channel.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</note>
|
||||
</legalnotice>
|
||||
|
||||
</bookinfo>
|
||||
|
||||
<xi:include href="concepts-manual-intro.xml"/>
|
||||
|
||||
<xi:include href="concepts-manual-concepts.xml"/>
|
||||
|
||||
</book>
|
||||
<!--
|
||||
vim: expandtab tw=80 ts=4
|
||||
-->
|
||||
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 81 KiB |
@@ -99,7 +99,7 @@
|
||||
with the OpenEmbedded build system is advisable.
|
||||
Of the SCMs BitBake supports, the
|
||||
Yocto Project team strongly recommends using
|
||||
<ulink url='&YOCTO_DOCS_GS_URL;#git'>Git</ulink>.
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#git'>Git</ulink>.
|
||||
Git is a distributed system that is easy to backup,
|
||||
allows you to work remotely, and then connects back to the
|
||||
infrastructure.
|
||||
@@ -310,8 +310,7 @@
|
||||
Consider the following:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
Use
|
||||
<ulink url='&YOCTO_DOCS_GS_URL;#git'>Git</ulink>
|
||||
Use <ulink url='&YOCTO_DOCS_REF_URL;#git'>Git</ulink>
|
||||
as the source control system.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
@@ -325,7 +324,7 @@
|
||||
Separate the project's Metadata and code by using
|
||||
separate Git repositories.
|
||||
See the
|
||||
"<ulink url='&YOCTO_DOCS_GS_URL;#yocto-project-repositories'>Yocto Project Source Repositories</ulink>"
|
||||
"<ulink url='&YOCTO_DOCS_REF_URL;#yocto-project-repositories'>Yocto Project Source Repositories</ulink>"
|
||||
section for information on these repositories.
|
||||
See the
|
||||
"<link linkend='working-with-yocto-project-source-files'>Working With Yocto Project Source Files</link>"
|
||||
@@ -549,8 +548,8 @@
|
||||
pull the change into the component's upstream repository.
|
||||
You do this by pushing to a contribution repository that is upstream.
|
||||
See the
|
||||
"<ulink url='&YOCTO_DOCS_GS_URL;#workflows'>Workflows</ulink>"
|
||||
section in the Getting Started With Yocto Project Manual for additional
|
||||
"<ulink url='&YOCTO_DOCS_REF_URL;#workflows'>Workflows</ulink>"
|
||||
section in the Yocto Project Reference Manual for additional
|
||||
concepts on working in the Yocto Project development environment.
|
||||
</para>
|
||||
|
||||
@@ -749,7 +748,7 @@
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Search by File:</emphasis>
|
||||
Using <ulink url='&YOCTO_DOCS_GS_URL;#git'>Git</ulink>,
|
||||
Using <ulink url='&YOCTO_DOCS_REF_URL;#git'>Git</ulink>,
|
||||
you can enter the following command to bring up a
|
||||
short list of all commits against a specific file:
|
||||
<literallayout class='monospaced'>
|
||||
|
||||
@@ -7,51 +7,15 @@
|
||||
<title>Using the Quick EMUlator (QEMU)</title>
|
||||
|
||||
<para>
|
||||
The Yocto Project uses an implementation of the Quick EMUlator (QEMU)
|
||||
Open Source project as part of the Yocto Project development "tool
|
||||
set".
|
||||
This chapter provides both procedures that show you how to use the
|
||||
Quick EMUlator (QEMU) and other QEMU information helpful for
|
||||
development purposes.
|
||||
This chapter provides procedures that show you how to use the
|
||||
Quick EMUlator (QEMU), which is an Open Source project the Yocto
|
||||
Project uses as part of its development "tool set".
|
||||
For reference information on the Yocto Project implementation of QEMU,
|
||||
see the
|
||||
"<ulink url='&YOCTO_DOCS_REF_URL;#ref-quick-emulator-qemu'>Quick EMUlator (QEMU)</ulink>"
|
||||
section in the Yocto Project Reference Manual.
|
||||
</para>
|
||||
|
||||
<section id='qemu-dev-overview'>
|
||||
<title>Overview</title>
|
||||
|
||||
<para>
|
||||
Within the context of the Yocto Project, QEMU is an
|
||||
emulator and virtualization machine that allows you to run a
|
||||
complete image you have built using the Yocto Project as just
|
||||
another task on your build system.
|
||||
QEMU is useful for running and testing images and applications on
|
||||
supported Yocto Project architectures without having actual
|
||||
hardware.
|
||||
Among other things, the Yocto Project uses QEMU to run automated
|
||||
Quality Assurance (QA) tests on final images shipped with each
|
||||
release.
|
||||
<note>
|
||||
This implementation is not the same as QEMU in general.
|
||||
</note>
|
||||
This section provides a brief reference for the Yocto Project
|
||||
implementation of QEMU.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For official information and documentation on QEMU in general, see
|
||||
the following references:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
<emphasis><ulink url='http://wiki.qemu.org/Main_Page'>QEMU Website</ulink>:</emphasis>
|
||||
The official website for the QEMU Open Source project.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis><ulink url='http://wiki.qemu.org/Manual'>Documentation</ulink>:</emphasis>
|
||||
The QEMU user manual.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='qemu-running-qemu'>
|
||||
<title>Running QEMU</title>
|
||||
|
||||
@@ -63,9 +27,6 @@
|
||||
<orderedlist>
|
||||
<listitem><para>
|
||||
<emphasis>Install QEMU:</emphasis>
|
||||
QEMU is made available with the Yocto Project a number of
|
||||
ways.
|
||||
One method is to install a Software Development Kit (SDK).
|
||||
See
|
||||
"<ulink url='&YOCTO_DOCS_SDK_URL;#the-qemu-emulator'>The QEMU Emulator</ulink>"
|
||||
section in the Yocto Project Application Development and
|
||||
@@ -342,311 +303,6 @@
|
||||
</note>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='qemu-dev-performance'>
|
||||
<title>QEMU Performance</title>
|
||||
|
||||
<para>
|
||||
Using QEMU to emulate your hardware can result in speed issues
|
||||
depending on the target and host architecture mix.
|
||||
For example, using the <filename>qemux86</filename> image in the
|
||||
emulator on an Intel-based 32-bit (x86) host machine is fast
|
||||
because the target and host architectures match.
|
||||
On the other hand, using the <filename>qemuarm</filename> image
|
||||
on the same Intel-based host can be slower.
|
||||
But, you still achieve faithful emulation of ARM-specific issues.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To speed things up, the QEMU images support using
|
||||
<filename>distcc</filename> to call a cross-compiler outside the
|
||||
emulated system.
|
||||
If you used <filename>runqemu</filename> to start QEMU, and the
|
||||
<filename>distccd</filename> application is present on the host
|
||||
system, any BitBake cross-compiling toolchain available from the
|
||||
build system is automatically used from within QEMU simply by
|
||||
calling <filename>distcc</filename>.
|
||||
You can accomplish this by defining the cross-compiler variable
|
||||
(e.g. <filename>export CC="distcc"</filename>).
|
||||
Alternatively, if you are using a suitable SDK image or the
|
||||
appropriate stand-alone toolchain is present, the toolchain is
|
||||
also automatically used.
|
||||
<note>
|
||||
Several mechanisms exist that let you connect to the system
|
||||
running on the QEMU emulator:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
QEMU provides a framebuffer interface that makes
|
||||
standard consoles available.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Generally, headless embedded devices have a serial port.
|
||||
If so, you can configure the operating system of the
|
||||
running image to use that port to run a console.
|
||||
The connection uses standard IP networking.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
SSH servers exist in some QEMU images.
|
||||
The <filename>core-image-sato</filename> QEMU image
|
||||
has a Dropbear secure shell (SSH) server that runs
|
||||
with the root password disabled.
|
||||
The <filename>core-image-full-cmdline</filename> and
|
||||
<filename>core-image-lsb</filename> QEMU images
|
||||
have OpenSSH instead of Dropbear.
|
||||
Including these SSH servers allow you to use standard
|
||||
<filename>ssh</filename> and <filename>scp</filename>
|
||||
commands.
|
||||
The <filename>core-image-minimal</filename> QEMU image,
|
||||
however, contains no SSH server.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
You can use a provided, user-space NFS server to boot
|
||||
the QEMU session using a local copy of the root
|
||||
filesystem on the host.
|
||||
In order to make this connection, you must extract a
|
||||
root filesystem tarball by using the
|
||||
<filename>runqemu-extract-sdk</filename> command.
|
||||
After running the command, you must then point the
|
||||
<filename>runqemu</filename>
|
||||
script to the extracted directory instead of a root
|
||||
filesystem image file.
|
||||
See the
|
||||
"<link linkend='qemu-running-under-a-network-file-system-nfs-server'>Running Under a Network File System (NFS) Server</link>"
|
||||
section for more information.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</note>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='qemu-dev-command-line-syntax'>
|
||||
<title>QEMU Command-Line Syntax</title>
|
||||
|
||||
<para>
|
||||
The basic <filename>runqemu</filename> command syntax is as
|
||||
follows:
|
||||
<literallayout class='monospaced'>
|
||||
$ runqemu [<replaceable>option</replaceable> ] [...]
|
||||
</literallayout>
|
||||
Based on what you provide on the command line,
|
||||
<filename>runqemu</filename> does a good job of figuring out what
|
||||
you are trying to do.
|
||||
For example, by default, QEMU looks for the most recently built
|
||||
image according to the timestamp when it needs to look for an
|
||||
image.
|
||||
Minimally, through the use of options, you must provide either
|
||||
a machine name, a virtual machine image
|
||||
(<filename>*wic.vmdk</filename>), or a kernel image
|
||||
(<filename>*.bin</filename>).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Following is the command-line help output for the
|
||||
<filename>runqemu</filename> command:
|
||||
<literallayout class='monospaced'>
|
||||
$ runqemu --help
|
||||
|
||||
Usage: you can run this script with any valid combination
|
||||
of the following environment variables (in any order):
|
||||
KERNEL - the kernel image file to use
|
||||
ROOTFS - the rootfs image file or nfsroot directory to use
|
||||
MACHINE - the machine name (optional, autodetected from KERNEL filename if unspecified)
|
||||
Simplified QEMU command-line options can be passed with:
|
||||
nographic - disable video console
|
||||
serial - enable a serial console on /dev/ttyS0
|
||||
slirp - enable user networking, no root privileges is required
|
||||
kvm - enable KVM when running x86/x86_64 (VT-capable CPU required)
|
||||
kvm-vhost - enable KVM with vhost when running x86/x86_64 (VT-capable CPU required)
|
||||
publicvnc - enable a VNC server open to all hosts
|
||||
audio - enable audio
|
||||
[*/]ovmf* - OVMF firmware file or base name for booting with UEFI
|
||||
tcpserial=<port> - specify tcp serial port number
|
||||
biosdir=<dir> - specify custom bios dir
|
||||
biosfilename=<filename> - specify bios filename
|
||||
qemuparams=<xyz> - specify custom parameters to QEMU
|
||||
bootparams=<xyz> - specify custom kernel parameters during boot
|
||||
help, -h, --help: print this text
|
||||
|
||||
Examples:
|
||||
runqemu
|
||||
runqemu qemuarm
|
||||
runqemu tmp/deploy/images/qemuarm
|
||||
runqemu tmp/deploy/images/qemux86/<qemuboot.conf>
|
||||
runqemu qemux86-64 core-image-sato ext4
|
||||
runqemu qemux86-64 wic-image-minimal wic
|
||||
runqemu path/to/bzImage-qemux86.bin path/to/nfsrootdir/ serial
|
||||
runqemu qemux86 iso/hddimg/wic.vmdk/wic.qcow2/wic.vdi/ramfs/cpio.gz...
|
||||
runqemu qemux86 qemuparams="-m 256"
|
||||
runqemu qemux86 bootparams="psplash=false"
|
||||
runqemu path/to/<image>-<machine>.wic
|
||||
runqemu path/to/<image>-<machine>.wic.vmdk
|
||||
</literallayout>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='qemu-dev-runqemu-command-line-options'>
|
||||
<title><filename>runqemu</filename> Command-Line Options</title>
|
||||
|
||||
<para>
|
||||
Following is a description of <filename>runqemu</filename>
|
||||
options you can provide on the command line:
|
||||
<note><title>Tip</title>
|
||||
If you do provide some "illegal" option combination or perhaps
|
||||
you do not provide enough in the way of options,
|
||||
<filename>runqemu</filename> provides appropriate error
|
||||
messaging to help you correct the problem.
|
||||
</note>
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
<replaceable>QEMUARCH</replaceable>:
|
||||
The QEMU machine architecture, which must be "qemuarm",
|
||||
"qemuarm64", "qemumips", "qemumips64", "qemuppc",
|
||||
"qemux86", or "qemux86-64".
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<filename><replaceable>VM</replaceable></filename>:
|
||||
The virtual machine image, which must be a
|
||||
<filename>.wic.vmdk</filename> file.
|
||||
Use this option when you want to boot a
|
||||
<filename>.wic.vmdk</filename> image.
|
||||
The image filename you provide must contain one of the
|
||||
following strings: "qemux86-64", "qemux86", "qemuarm",
|
||||
"qemumips64", "qemumips", "qemuppc", or "qemush4".
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<replaceable>ROOTFS</replaceable>:
|
||||
A root filesystem that has one of the following
|
||||
filetype extensions: "ext2", "ext3", "ext4", "jffs2",
|
||||
"nfs", or "btrfs".
|
||||
If the filename you provide for this option uses “nfs”, it
|
||||
must provide an explicit root filesystem path.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<replaceable>KERNEL</replaceable>:
|
||||
A kernel image, which is a <filename>.bin</filename> file.
|
||||
When you provide a <filename>.bin</filename> file,
|
||||
<filename>runqemu</filename> detects it and assumes the
|
||||
file is a kernel image.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<replaceable>MACHINE</replaceable>:
|
||||
The architecture of the QEMU machine, which must be one
|
||||
of the following: "qemux86", "qemux86-64", "qemuarm",
|
||||
"qemuarm64", "qemumips", “qemumips64", or "qemuppc".
|
||||
The <replaceable>MACHINE</replaceable> and
|
||||
<replaceable>QEMUARCH</replaceable> options are basically
|
||||
identical.
|
||||
If you do not provide a <replaceable>MACHINE</replaceable>
|
||||
option, <filename>runqemu</filename> tries to determine
|
||||
it based on other options.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<filename>ramfs</filename>:
|
||||
Indicates you are booting an initial RAM disk (initramfs)
|
||||
image, which means the <filename>FSTYPE</filename> is
|
||||
<filename>cpio.gz</filename>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<filename>iso</filename>:
|
||||
Indicates you are booting an ISO image, which means the
|
||||
<filename>FSTYPE</filename> is
|
||||
<filename>.iso</filename>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<filename>nographic</filename>:
|
||||
Disables the video console, which sets the console to
|
||||
"ttys0".
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<filename>serial</filename>:
|
||||
Enables a serial console on
|
||||
<filename>/dev/ttyS0</filename>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<filename>biosdir</filename>:
|
||||
Establishes a custom directory for BIOS, VGA BIOS and
|
||||
keymaps.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<filename>biosfilename</filename>:
|
||||
Establishes a custom BIOS name.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<filename>qemuparams=\"<replaceable>xyz</replaceable>\"</filename>:
|
||||
Specifies custom QEMU parameters.
|
||||
Use this option to pass options other than the simple
|
||||
"kvm" and "serial" options.
|
||||
</para></listitem>
|
||||
<listitem><para><filename>bootparams=\"<replaceable>xyz</replaceable>\"</filename>:
|
||||
Specifies custom boot parameters for the kernel.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<filename>audio</filename>:
|
||||
Enables audio in QEMU.
|
||||
The <replaceable>MACHINE</replaceable> option must be
|
||||
either "qemux86" or "qemux86-64" in order for audio to be
|
||||
enabled.
|
||||
Additionally, the <filename>snd_intel8x0</filename>
|
||||
or <filename>snd_ens1370</filename> driver must be
|
||||
installed in linux guest.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<filename>slirp</filename>:
|
||||
Enables "slirp" networking, which is a different way
|
||||
of networking that does not need root access
|
||||
but also is not as easy to use or comprehensive
|
||||
as the default.
|
||||
</para></listitem>
|
||||
<listitem><para id='kvm-cond'>
|
||||
<filename>kvm</filename>:
|
||||
Enables KVM when running "qemux86" or "qemux86-64"
|
||||
QEMU architectures.
|
||||
For KVM to work, all the following conditions must be met:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
Your <replaceable>MACHINE</replaceable> must be either
|
||||
qemux86" or "qemux86-64".
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Your build host has to have the KVM modules
|
||||
installed, which are
|
||||
<filename>/dev/kvm</filename>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
The build host <filename>/dev/kvm</filename>
|
||||
directory has to be both writable and readable.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<filename>kvm-vhost</filename>:
|
||||
Enables KVM with VHOST support when running "qemux86"
|
||||
or "qemux86-64" QEMU architectures.
|
||||
For KVM with VHOST to work, the following conditions must
|
||||
be met:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
<link linkend='kvm-cond'>kvm</link> option
|
||||
conditions must be met.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Your build host has to have virtio net device, which
|
||||
are <filename>/dev/vhost-net</filename>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
The build host <filename>/dev/vhost-net</filename>
|
||||
directory has to be either readable or writable
|
||||
and “slirp-enabled”.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<filename>publicvnc</filename>:
|
||||
Enables a VNC server open to all hosts.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
||||
<!--
|
||||
vim: expandtab tw=80 ts=4
|
||||
|
||||
@@ -8,8 +8,10 @@
|
||||
|
||||
<para>
|
||||
This chapter provides procedures related to getting set up to use the
|
||||
Yocto Project, working with Yocto Project source files, and building
|
||||
an image.
|
||||
Yocto Project.
|
||||
For a more front-to-end process that takes you from minimally preparing
|
||||
a build host through building an image, see the
|
||||
<ulink url='&YOCTO_DOCS_QS_URL;'>Yocto Project Quick Start</ulink>.
|
||||
</para>
|
||||
|
||||
<section id='setting-up-the-development-host-to-use-the-yocto-project'>
|
||||
@@ -260,13 +262,13 @@
|
||||
<listitem><para>
|
||||
For concepts and introductory information about Git as it
|
||||
is used in the Yocto Project, see the
|
||||
"<ulink url='&YOCTO_DOCS_GS_URL;#git'>Git</ulink>"
|
||||
section in the Getting Started With Yocto Project Manual.
|
||||
"<ulink url='&YOCTO_DOCS_REF_URL;#git'>Git</ulink>"
|
||||
section in the Yocto Project Reference Manual.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
For concepts on Yocto Project source repositories, see the
|
||||
"<ulink url='&YOCTO_DOCS_GS_URL;#yocto-project-repositories'>Yocto Project Source Repositories</ulink>"
|
||||
section in the Getting Started With Yocto Project Manual."
|
||||
"<ulink url='&YOCTO_DOCS_REF_URL;#yocto-project-repositories'>Yocto Project Source Repositories</ulink>"
|
||||
section in the Yocto Project Reference Manual."
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</note>
|
||||
@@ -276,20 +278,9 @@
|
||||
<title>Accessing Source Repositories</title>
|
||||
|
||||
<para>
|
||||
Working from a copy of the upstream Yocto Project
|
||||
<ulink url='&YOCTO_DOCS_GS_URL;#source-repositories'>Source Repositories</ulink>
|
||||
is the preferred method for obtaining and using a Yocto Project
|
||||
release.
|
||||
You can view the Yocto Project Source Repositories at
|
||||
<ulink url='&YOCTO_GIT_URL;/cgit.cgi'></ulink>.
|
||||
In particular, you can find the
|
||||
<filename>poky</filename> repository at
|
||||
<ulink url='http://git.yoctoproject.org/cgit/cgit.cgi/poky/'></ulink>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Use the following procedure to locate the latest upstream copy of
|
||||
the <filename>poky</filename> Git repository:
|
||||
Yocto Project maintains upstream Git
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#source-repositories'>Source Repositories</ulink>
|
||||
that you can examine and access using a browser-based UI:
|
||||
<orderedlist>
|
||||
<listitem><para>
|
||||
<emphasis>Access Repositories:</emphasis>
|
||||
@@ -299,21 +290,24 @@
|
||||
repositories.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Select the Repository:</emphasis>
|
||||
Click on the repository in which you are interested (i.e.
|
||||
<emphasis>Select a Repository:</emphasis>
|
||||
Click on any repository in which you are interested (e.g.
|
||||
<filename>poky</filename>).
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Find the URL Used to Clone the Repository:</emphasis>
|
||||
At the bottom of the page, note the URL used to
|
||||
<ulink url='&YOCTO_DOCS_GS_URL;#git-commands-clone'>clone</ulink>
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#git-commands-clone'>clone</ulink>
|
||||
that repository (e.g.
|
||||
<filename>&YOCTO_GIT_URL;/poky</filename>).
|
||||
<note>
|
||||
For information on cloning a repository, see the
|
||||
"<link linkend='cloning-the-poky-repository'>Cloning the <filename>poky</filename> Repository</link>"
|
||||
section.
|
||||
</note>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Examine Change History of the Repository:</emphasis>
|
||||
At the top of the page, click on any branch in which you
|
||||
might be interested (e.g.
|
||||
<filename>&DISTRO_NAME_NO_CAP;</filename>).
|
||||
You can then view the commit log or tree view for that
|
||||
development branch.
|
||||
</para></listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
@@ -325,12 +319,12 @@
|
||||
<para>
|
||||
Yocto Project maintains an Index of Releases area that contains
|
||||
related files that contribute to the Yocto Project.
|
||||
Rather than Git repositories, these files are tarballs that
|
||||
represent snapshots in time of a given component.
|
||||
Rather than Git repositories, these files represent snapshot
|
||||
tarballs.
|
||||
<note><title>Tip</title>
|
||||
The recommended method for accessing Yocto Project
|
||||
components is to use Git to clone the upstream repository and
|
||||
work from within that locally cloned repository.
|
||||
components is to use Git to clone a repository and work from
|
||||
within that local repository.
|
||||
The procedure in this section exists should you desire a
|
||||
tarball snapshot of any given component.
|
||||
</note>
|
||||
@@ -348,8 +342,8 @@
|
||||
full array of released Poky tarballs.
|
||||
The <filename>poky</filename> directory in the
|
||||
Index of Releases was historically used for very
|
||||
early releases and exists now only for retroactive
|
||||
completeness.
|
||||
early releases and exists for retroactive
|
||||
completeness only.
|
||||
</note>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
@@ -367,7 +361,7 @@
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Download the Tarball:</emphasis>
|
||||
Click the tarball to download and save a snapshot of the
|
||||
Click a tarball to download and save a snapshot of a
|
||||
given component.
|
||||
</para></listitem>
|
||||
</orderedlist>
|
||||
@@ -380,7 +374,7 @@
|
||||
<para>
|
||||
The
|
||||
<ulink url='&YOCTO_HOME_URL;'>Yocto Project Website</ulink>
|
||||
uses a "DOWNLOADS" page from which you can locate and download
|
||||
uses a "Downloads" area from which you can locate and download
|
||||
tarballs of any Yocto Project release.
|
||||
Rather than Git repositories, these files represent snapshot
|
||||
tarballs.
|
||||
@@ -400,61 +394,17 @@
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Get to the Downloads Area:</emphasis>
|
||||
Select the "DOWNLOADS" item from the pull-down
|
||||
"SOFTWARE" tab menu.
|
||||
Click the "Downloads" tab.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Select a Yocto Project Release:</emphasis>
|
||||
Use the menu next to "RELEASE" to display and choose
|
||||
a Yocto Project release (e.g. sumo, rocko, pyro, and
|
||||
so forth.
|
||||
For a "map" of Yocto Project releases to version numbers,
|
||||
see the
|
||||
<ulink url='https://wiki.yoctoproject.org/wiki/Releases'>Releases</ulink>
|
||||
wiki page.
|
||||
<emphasis>Select the Type of Files:</emphasis>
|
||||
Click the type of files you want (i.e "Build System",
|
||||
"Tools", or "Board Support Packages (BSPs)".
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Download Tools or Board Support Packages (BSPs):</emphasis>
|
||||
From the "DOWNLOADS" page, you can download tools or
|
||||
BSPs as well.
|
||||
Just scroll down the page and look for what you need.
|
||||
</para></listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='accessing-nightly-builds'>
|
||||
<title>Accessing Nightly Builds</title>
|
||||
|
||||
<para>
|
||||
Yocto Project maintains an area for nightly builds that contains
|
||||
tarball releases at <ulink url='&YOCTO_AB_NIGHTLY_URL;'/>.
|
||||
These builds include Yocto Project releases, SDK installation
|
||||
scripts, and experimental builds.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Should you ever want to access a nightly build of a particular
|
||||
Yocto Project component, use the following procedure:
|
||||
<orderedlist>
|
||||
<listitem><para>
|
||||
<emphasis>Access the Nightly Builds:</emphasis>
|
||||
Open a browser and go to
|
||||
<ulink url='&YOCTO_AB_NIGHTLY_URL;'/> to access the
|
||||
Nightly Builds.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Select a Build:</emphasis>
|
||||
Click on any build by date in which you are interested.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Find the Tarball:</emphasis>
|
||||
Drill down to find the associated tarball.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Download the Tarball:</emphasis>
|
||||
Click the tarball to download and save a snapshot of the
|
||||
given component.
|
||||
<emphasis>Locate and Download the Tarball:</emphasis>
|
||||
From the list of releases, locate the appropriate
|
||||
download link and download the files.
|
||||
</para></listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
@@ -473,7 +423,7 @@
|
||||
|
||||
<para>
|
||||
You create your Source Directory by using
|
||||
<ulink url='&YOCTO_DOCS_GS_URL;#git'>Git</ulink> to clone a local
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#git'>Git</ulink> to clone a local
|
||||
copy of the upstream <filename>poky</filename> repository.
|
||||
<note><title>Tip</title>
|
||||
The preferred method of getting the Yocto Project Source
|
||||
@@ -685,7 +635,7 @@
|
||||
<listitem><para>
|
||||
<emphasis>Checkout the Branch:</emphasis>
|
||||
<literallayout class='monospaced'>
|
||||
$ git checkout tags/&DISTRO_REL_TAG; -b my_yocto_&DISTRO;
|
||||
$ git checkout tags/&DISTRO; -b my_yocto_&DISTRO;
|
||||
Switched to a new branch 'my_yocto_&DISTRO;'
|
||||
$ git branch
|
||||
master
|
||||
@@ -706,16 +656,13 @@
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id='dev-building-an-image'>
|
||||
<title>Building an Image</title>
|
||||
<section id='performing-a-simple-build'>
|
||||
<title>Performing a Simple Build</title>
|
||||
|
||||
<para>
|
||||
In the development environment, you need to build an image whenever
|
||||
you change hardware support, add or change system libraries, or add
|
||||
or change services that have dependencies.
|
||||
Several methods exist that allow you to build an image within the
|
||||
Yocto Project.
|
||||
This section shows you how to build an image using BitBake from a
|
||||
This procedure shows how to build an image using BitBake from a
|
||||
Linux host.
|
||||
<note><title>Notes</title>
|
||||
<itemizedlist>
|
||||
@@ -723,7 +670,7 @@
|
||||
For information on how to build an image using
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#toaster-term'>Toaster</ulink>,
|
||||
see the
|
||||
<ulink url='&YOCTO_DOCS_TOAST_URL;'>Toaster Manual</ulink>.
|
||||
<ulink url='&YOCTO_DOCS_TOAST_URL;'>Yocto Project Toaster Manual</ulink>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
For information on how to use
|
||||
@@ -732,12 +679,6 @@
|
||||
section in the Yocto Project Application Development and
|
||||
the Extensible Software Development Kit (eSDK) manual.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
For a practical example on how to build an image using the
|
||||
OpenEmbedded build system, see the
|
||||
"<ulink url='&YOCTO_DOCS_QS_URL;#qs-building-images'>Building Images</ulink>"
|
||||
section of the Yocto Project Quick Start.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</note>
|
||||
</para>
|
||||
@@ -748,8 +689,11 @@
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#build-directory'>Build Directory</ulink>
|
||||
under <filename>tmp/deploy/images</filename>.
|
||||
For detailed information on the build process using BitBake, see the
|
||||
"<ulink url='&YOCTO_DOCS_CM_URL;#images-dev-environment'>Images</ulink>"
|
||||
section in the Yocto Project Concepts Manual.
|
||||
"<ulink url='&YOCTO_DOCS_REF_URL;#images-dev-environment'>Images</ulink>"
|
||||
section in the Yocto Project Reference Manual.
|
||||
You can also reference the
|
||||
"<ulink url='&YOCTO_DOCS_QS_URL;#qs-building-images'>Building Images</ulink>"
|
||||
section in the Yocto Project Quick Start.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@@ -768,30 +712,14 @@
|
||||
<emphasis>Initialize the Build Environment:</emphasis>
|
||||
Initialize the build environment by sourcing the build
|
||||
environment script (i.e.
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#structure-core-script'><filename>&OE_INIT_FILE;</filename></ulink>):
|
||||
<literallayout class='monospaced'>
|
||||
$ source &OE_INIT_FILE; [<replaceable>build_dir</replaceable>]
|
||||
</literallayout></para>
|
||||
|
||||
<para>When you use the initialization script, the
|
||||
OpenEmbedded build system uses <filename>build</filename> as
|
||||
the default Build Directory in your current work directory.
|
||||
You can use a <replaceable>build_dir</replaceable> argument
|
||||
with the script to specify a different build directory.
|
||||
<note><title>Tip</title>
|
||||
A common practice is to use a different Build Directory for
|
||||
different targets.
|
||||
For example, <filename>~/build/x86</filename> for a
|
||||
<filename>qemux86</filename> target, and
|
||||
<filename>~/build/arm</filename> for a
|
||||
<filename>qemuarm</filename> target.
|
||||
</note>
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#structure-core-script'><filename>&OE_INIT_FILE;</filename></ulink>).
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Make Sure Your <filename>local.conf</filename>
|
||||
File is Correct:</emphasis>
|
||||
Ensure the <filename>conf/local.conf</filename> configuration
|
||||
file, which is found in the Build Directory,
|
||||
file, which is found in the
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#build-directory'>Build Directory</ulink>,
|
||||
is set up how you want it.
|
||||
This file defines many aspects of the build environment
|
||||
including the target machine architecture through the
|
||||
@@ -799,213 +727,24 @@
|
||||
the packaging format used during the build
|
||||
(<ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGE_CLASSES'><filename>PACKAGE_CLASSES</filename></ulink>),
|
||||
and a centralized tarball download directory through the
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#var-DL_DIR'><filename>DL_DIR</filename></ulink> variable.
|
||||
<filename><ulink url='&YOCTO_DOCS_REF_URL;#var-DL_DIR'>DL_DIR</ulink></filename> variable.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Build the Image:</emphasis>
|
||||
Build the image using the <filename>bitbake</filename> command:
|
||||
<literallayout class='monospaced'>
|
||||
$ bitbake <replaceable>target</replaceable>
|
||||
</literallayout>
|
||||
<note>
|
||||
For information on BitBake, see the
|
||||
<ulink url='&YOCTO_DOCS_BB_URL;'>BitBake User Manual</ulink>.
|
||||
</note>
|
||||
The <replaceable>target</replaceable> is the name of the
|
||||
recipe you want to build.
|
||||
Common targets are the images in
|
||||
<filename>meta/recipes-core/images</filename>,
|
||||
<filename>meta/recipes-sato/images</filename>, etc. all found
|
||||
in the
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#source-directory'>Source Directory</ulink>.
|
||||
Or, the target can be the name of a recipe for a specific
|
||||
piece of software such as BusyBox.
|
||||
For more details about the images the OpenEmbedded build
|
||||
system supports, see the
|
||||
"<ulink url='&YOCTO_DOCS_REF_URL;#ref-images'>Images</ulink>"
|
||||
chapter in the Yocto Project Reference Manual.</para>
|
||||
|
||||
<para>As an example, the following command builds the
|
||||
Build the image using the <filename>bitbake</filename> command.
|
||||
For example, the following command builds the
|
||||
<filename>core-image-minimal</filename> image:
|
||||
<literallayout class='monospaced'>
|
||||
$ bitbake core-image-minimal
|
||||
</literallayout>
|
||||
Once an image has been built, it often needs to be installed.
|
||||
The images and kernels built by the OpenEmbedded build system
|
||||
are placed in the Build Directory in
|
||||
<filename class="directory">tmp/deploy/images</filename>.
|
||||
For information on how to run pre-built images such as
|
||||
<filename>qemux86</filename> and <filename>qemuarm</filename>,
|
||||
see the
|
||||
<ulink url='&YOCTO_DOCS_SDK_URL;'>Yocto Project Application Development and the Extensible Software Development Kit (eSDK)</ulink>
|
||||
manual.
|
||||
For information about how to install these images, see the
|
||||
documentation for your particular board or machine.
|
||||
For information on BitBake, see the
|
||||
<ulink url='&YOCTO_DOCS_BB_URL;'>BitBake User Manual</ulink>.
|
||||
</para></listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='speeding-up-the-build'>
|
||||
<title>Speeding Up the Build</title>
|
||||
|
||||
<para>
|
||||
Build time can be an issue.
|
||||
By default, the build system uses simple controls to try and maximize
|
||||
build efficiency.
|
||||
In general, the default settings for all the following variables
|
||||
result in the most efficient build times when dealing with single
|
||||
socket systems (i.e. a single CPU).
|
||||
If you have multiple CPUs, you might try increasing the default
|
||||
values to gain more speed.
|
||||
See the descriptions in the glossary for each variable for more
|
||||
information:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#var-BB_NUMBER_THREADS'><filename>BB_NUMBER_THREADS</filename>:</ulink>
|
||||
The maximum number of threads BitBake simultaneously executes.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<ulink url='&YOCTO_DOCS_BB_URL;#var-BB_NUMBER_PARSE_THREADS'><filename>BB_NUMBER_PARSE_THREADS</filename>:</ulink>
|
||||
The number of threads BitBake uses during parsing.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#var-PARALLEL_MAKE'><filename>PARALLEL_MAKE</filename>:</ulink>
|
||||
Extra options passed to the <filename>make</filename> command
|
||||
during the
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-compile'><filename>do_compile</filename></ulink>
|
||||
task in order to specify parallel compilation on the
|
||||
local build host.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#var-PARALLEL_MAKEINST'><filename>PARALLEL_MAKEINST</filename>:</ulink>
|
||||
Extra options passed to the <filename>make</filename> command
|
||||
during the
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-install'><filename>do_install</filename></ulink>
|
||||
task in order to specify parallel installation on the
|
||||
local build host.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
As mentioned, these variables all scale to the number of processor
|
||||
cores available on the build system.
|
||||
For single socket systems, this auto-scaling ensures that the build
|
||||
system fundamentally takes advantage of potential parallel operations
|
||||
during the build based on the build machine's capabilities.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Following are additional factors that can affect build speed:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
File system type:
|
||||
The file system type that the build is being performed on can
|
||||
also influence performance.
|
||||
Using <filename>ext4</filename> is recommended as compared
|
||||
to <filename>ext2</filename> and <filename>ext3</filename>
|
||||
due to <filename>ext4</filename> improved features
|
||||
such as extents.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Disabling the updating of access time using
|
||||
<filename>noatime</filename>:
|
||||
The <filename>noatime</filename> mount option prevents the
|
||||
build system from updating file and directory access times.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Setting a longer commit:
|
||||
Using the "commit=" mount option increases the interval
|
||||
in seconds between disk cache writes.
|
||||
Changing this interval from the five second default to
|
||||
something longer increases the risk of data loss but decreases
|
||||
the need to write to the disk, thus increasing the build
|
||||
performance.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Choosing the packaging backend:
|
||||
Of the available packaging backends, IPK is the fastest.
|
||||
Additionally, selecting a singular packaging backend also
|
||||
helps.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Using <filename>tmpfs</filename> for
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#var-TMPDIR'><filename>TMPDIR</filename></ulink>
|
||||
as a temporary file system:
|
||||
While this can help speed up the build, the benefits are
|
||||
limited due to the compiler using
|
||||
<filename>-pipe</filename>.
|
||||
The build system goes to some lengths to avoid
|
||||
<filename>sync()</filename> calls into the
|
||||
file system on the principle that if there was a significant
|
||||
failure, the
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#build-directory'>Build Directory</ulink>
|
||||
contents could easily be rebuilt.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Inheriting the
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-rm-work'><filename>rm_work</filename></ulink>
|
||||
class:
|
||||
Inheriting this class has shown to speed up builds due to
|
||||
significantly lower amounts of data stored in the data
|
||||
cache as well as on disk.
|
||||
Inheriting this class also makes cleanup of
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#var-TMPDIR'><filename>TMPDIR</filename></ulink>
|
||||
faster, at the expense of being easily able to dive into the
|
||||
source code.
|
||||
File system maintainers have recommended that the fastest way
|
||||
to clean up large numbers of files is to reformat partitions
|
||||
rather than delete files due to the linear nature of
|
||||
partitions.
|
||||
This, of course, assumes you structure the disk partitions and
|
||||
file systems in a way that this is practical.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
Aside from the previous list, you should keep some trade offs in
|
||||
mind that can help you speed up the build:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
Remove items from
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#var-DISTRO_FEATURES'><filename>DISTRO_FEATURES</filename></ulink>
|
||||
that you might not need.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Exclude debug symbols and other debug information:
|
||||
If you do not need these symbols and other debug information,
|
||||
disabling the <filename>*-dbg</filename> package generation
|
||||
can speed up the build.
|
||||
You can disable this generation by setting the
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#var-INHIBIT_PACKAGE_DEBUG_SPLIT'><filename>INHIBIT_PACKAGE_DEBUG_SPLIT</filename></ulink>
|
||||
variable to "1".
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Disable static library generation for recipes derived from
|
||||
<filename>autoconf</filename> or <filename>libtool</filename>:
|
||||
Following is an example showing how to disable static
|
||||
libraries and still provide an override to handle exceptions:
|
||||
<literallayout class='monospaced'>
|
||||
STATICLIBCONF = "--disable-static"
|
||||
STATICLIBCONF_sqlite3-native = ""
|
||||
EXTRA_OECONF += "${STATICLIBCONF}"
|
||||
</literallayout>
|
||||
<note><title>Notes</title>
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
Some recipes need static libraries in order to work
|
||||
correctly (e.g. <filename>pseudo-native</filename>
|
||||
needs <filename>sqlite3-native</filename>).
|
||||
Overrides, as in the previous example, account for
|
||||
these kinds of exceptions.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Some packages have packaging code that assumes the
|
||||
presence of the static libraries.
|
||||
If so, you might need to exclude them as well.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</note>
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
-->
|
||||
</chapter>
|
||||
<!--
|
||||
vim: expandtab tw=80 ts=4
|
||||
|
||||
@@ -101,11 +101,6 @@
|
||||
<date>October 2017</date>
|
||||
<revremark>Released with the Yocto Project 2.4 Release.</revremark>
|
||||
</revision>
|
||||
<revision>
|
||||
<revnumber>2.5</revnumber>
|
||||
<date>April 2018</date>
|
||||
<revremark>Released with the Yocto Project 2.5 Release.</revremark>
|
||||
</revision>
|
||||
</revhistory>
|
||||
|
||||
<copyright>
|
||||
|
||||
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 292 KiB |
|
Before Width: | Height: | Size: 81 KiB |
@@ -1,27 +0,0 @@
|
||||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
|
||||
|
||||
<xsl:import href="http://downloads.yoctoproject.org/mirror/docbook-mirror/docbook-xsl-1.76.1/xhtml/docbook.xsl" />
|
||||
|
||||
<!--
|
||||
|
||||
<xsl:import href="../template/1.76.1/docbook-xsl-1.76.1/xhtml/docbook.xsl" />
|
||||
|
||||
<xsl:import href="http://docbook.sourceforge.net/release/xsl/1.76.1/xhtml/docbook.xsl" />
|
||||
|
||||
-->
|
||||
|
||||
<xsl:include href="../template/permalinks.xsl"/>
|
||||
<xsl:include href="../template/section.title.xsl"/>
|
||||
<xsl:include href="../template/component.title.xsl"/>
|
||||
<xsl:include href="../template/division.title.xsl"/>
|
||||
<xsl:include href="../template/formal.object.heading.xsl"/>
|
||||
|
||||
<xsl:param name="html.stylesheet" select="'getting-started-style.css'" />
|
||||
<xsl:param name="chapter.autolabel" select="1" />
|
||||
<xsl:param name="appendix.autolabel" select="A" />
|
||||
<xsl:param name="section.autolabel" select="1" />
|
||||
<xsl:param name="section.label.includes.component.label" select="1" />
|
||||
<xsl:param name="generate.id.attributes" select="1" />
|
||||
|
||||
</xsl:stylesheet>
|
||||
@@ -1,972 +0,0 @@
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
|
||||
[<!ENTITY % poky SYSTEM "../poky.ent"> %poky; ] >
|
||||
|
||||
<chapter id='overview-development-environment'>
|
||||
<title>The Yocto Project Development Environment</title>
|
||||
|
||||
<para>
|
||||
This chapter takes a look at the Yocto Project development
|
||||
environment.
|
||||
The chapter provides Yocto Project Development environment concepts that
|
||||
help you understand how work is accomplished in an open source environment,
|
||||
which is very different as compared to work accomplished in a closed,
|
||||
proprietary environment.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Specifically, this chapter addresses open source philosophy, source
|
||||
repositories, workflows, Git, and licensing.
|
||||
</para>
|
||||
|
||||
<section id='open-source-philosophy'>
|
||||
<title>Open Source Philosophy</title>
|
||||
|
||||
<para>
|
||||
Open source philosophy is characterized by software development
|
||||
directed by peer production and collaboration through an active
|
||||
community of developers.
|
||||
Contrast this to the more standard centralized development models
|
||||
used by commercial software companies where a finite set of developers
|
||||
produces a product for sale using a defined set of procedures that
|
||||
ultimately result in an end product whose architecture and source
|
||||
material are closed to the public.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Open source projects conceptually have differing concurrent agendas,
|
||||
approaches, and production.
|
||||
These facets of the development process can come from anyone in the
|
||||
public (community) who has a stake in the software project.
|
||||
The open source environment contains new copyright, licensing, domain,
|
||||
and consumer issues that differ from the more traditional development
|
||||
environment.
|
||||
In an open source environment, the end product, source material,
|
||||
and documentation are all available to the public at no cost.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
A benchmark example of an open source project is the Linux kernel,
|
||||
which was initially conceived and created by Finnish computer science
|
||||
student Linus Torvalds in 1991.
|
||||
Conversely, a good example of a non-open source project is the
|
||||
<trademark class='registered'>Windows</trademark> family of operating
|
||||
systems developed by
|
||||
<trademark class='registered'>Microsoft</trademark> Corporation.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Wikipedia has a good historical description of the Open Source
|
||||
Philosophy
|
||||
<ulink url='http://en.wikipedia.org/wiki/Open_source'>here</ulink>.
|
||||
You can also find helpful information on how to participate in the
|
||||
Linux Community
|
||||
<ulink url='http://ldn.linuxfoundation.org/book/how-participate-linux-community'>here</ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='gs-the-development-host'>
|
||||
<title>The Development Host</title>
|
||||
|
||||
<para>
|
||||
A development host or build host is key to using the Yocto Project.
|
||||
Because the goal of the Yocto Project is to develop images or
|
||||
applications that run on embedded hardware, development of those
|
||||
images and applications generally takes place on a system not
|
||||
intended to run the software - the development host.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You need to set up a development host in order to use it with the
|
||||
Yocto Project.
|
||||
Most find that it is best to have a native Linux machine function as
|
||||
the development host.
|
||||
However, it is possible to use a system that does not run Linux
|
||||
as its operating system as your development host.
|
||||
When you have a Mac or Windows-based system, you can set it up
|
||||
as the development host by using
|
||||
<ulink url='https://git.yoctoproject.org/cgit/cgit.cgi/crops/about/'>CROPS</ulink>,
|
||||
which leverages
|
||||
<ulink url='https://www.docker.com/'>Docker Containers</ulink>.
|
||||
Once you take the steps to set up a CROPS machine, you effectively
|
||||
have access to a shell environment that is similar to what you see
|
||||
when using a Linux-based development host.
|
||||
For the steps needed to set up a system using CROPS, see the
|
||||
"<ulink url='&YOCTO_DOCS_DEV_URL;#setting-up-to-use-crops'>Setting Up to Use CROss PlatformS (CROPS)</ulink>"
|
||||
section in the Yocto Project Development Tasks Manual.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If your development host is going to be a system that runs a Linux
|
||||
distribution, steps still exist that you must take to prepare the
|
||||
system for use with the Yocto Project.
|
||||
You need to be sure that the Linux distribution on the system is
|
||||
one that supports the Yocto Project.
|
||||
You also need to be sure that the correct set of host packages are
|
||||
installed that allow development using the Yocto Project.
|
||||
For the steps needed to set up a development host that runs Linux,
|
||||
see the
|
||||
"<ulink url='&YOCTO_DOCS_DEV_URL;#setting-up-a-native-linux-host'>Setting Up a Native Linux Host</ulink>"
|
||||
section in the Yocto Project Development Tasks Manual.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Once your development host is set up to use the Yocto Project,
|
||||
several methods exist for you to do work in the Yocto Project
|
||||
environment:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
<emphasis>Command Lines, BitBake, and Shells:</emphasis>
|
||||
Traditional development in the Yocto Project involves using
|
||||
OpenEmbedded build system, which uses BitBake, in a
|
||||
command-line environment from a shell on your development
|
||||
host.
|
||||
You can accomplish this from a host that is a native Linux
|
||||
machine or from a host that has been set up with CROPS.
|
||||
Either way, you create, modify, and build images and
|
||||
applications all within a shell-based environment using
|
||||
components and tools available through your Linux distribution
|
||||
and the Yocto Project.</para>
|
||||
|
||||
<para>For a general flow of the build procedures, see the
|
||||
"<ulink url='&YOCTO_DOCS_DEV_URL;#dev-building-an-image'>Building an Image</ulink>"
|
||||
section in the Yocto Project Development Tasks Manual.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Board Support Package (BSP) Development:</emphasis>
|
||||
Development of BSPs involves using the Yocto Project to
|
||||
create and test layers that allow easy development of
|
||||
images and applications targeted for specific hardware.
|
||||
To development BSPs, you need to take some additional steps
|
||||
beyond what was described in setting up a development host.
|
||||
</para>
|
||||
|
||||
<para>The
|
||||
<ulink url='&YOCTO_DOCS_BSP_URL;'>Yocto Project Board Support Package (BSP) Developer's Guide'</ulink>
|
||||
provides BSP-related development information.
|
||||
For specifics on development host preparation, see the
|
||||
"<ulink url='&YOCTO_DOCS_BSP_URL;#preparing-your-build-host-to-work-with-bsp-layers'>Preparing Your Build Host to Work With BSP Layers</ulink>"
|
||||
section in the Yocto Project Board Support Package (BSP)
|
||||
Developer's Guide.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Kernel Development:</emphasis>
|
||||
If you are going to be developing kernels using the Yocto
|
||||
Project you likely will be using <filename>devtool</filename>.
|
||||
A workflow using <filename>devtool</filename> makes kernel
|
||||
development quicker by reducing iteration cycle times.</para>
|
||||
|
||||
<para>The
|
||||
<ulink url='&YOCTO_DOCS_KERNEL_DEV_URL;'>Yocto Project Linux Kernel Development Manual</ulink>
|
||||
provides kernel-related development information.
|
||||
For specifics on development host preparation, see the
|
||||
"<ulink url='&YOCTO_DOCS_KERNEL_DEV_URL;#preparing-the-build-host-to-work-on-the-kernel'>Preparing the Build Host to Work on the Kernel</ulink>"
|
||||
section in the Yocto Project Linux Kernel Development Manual.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Using the <trademark class='trade'>Eclipse</trademark> IDE:</emphasis>
|
||||
One of two Yocto Project development methods that involves an
|
||||
interface that effectively puts the Yocto Project into the
|
||||
background is the popular Eclipse IDE.
|
||||
This method of development is advantageous if you are already
|
||||
familiar with working within Eclipse.
|
||||
Development is supported through a plugin that you install
|
||||
onto your development host.</para>
|
||||
|
||||
<para>For steps that show you how to set up your development
|
||||
host to use the Eclipse Yocto Project plugin, see the
|
||||
"<ulink url='&YOCTO_DOCS_SDK_URL;#sdk-eclipse-project'>Developing Applications Using <trademark class='trade'>Eclipse</trademark></ulink>"
|
||||
Chapter in the Yocto Project Application Development and the
|
||||
Extensible Software Development Kit (eSDK) manual.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Using the Toaster:</emphasis>
|
||||
The other Yocto Project development method that involves an
|
||||
interface that effectively puts the Yocto Project into the
|
||||
background is Toaster.
|
||||
Toaster provides an interface to the OpenEmbedded build system.
|
||||
The interface enables you to configure and run your builds.
|
||||
Information about builds is collected and stored in a database.
|
||||
You can use Toaster to configure and start builds on multiple
|
||||
remote build servers.</para>
|
||||
|
||||
<para>For steps that show you how to set up your development
|
||||
host to use Toaster and on how to use Toaster in general,
|
||||
see the
|
||||
<ulink url='&YOCTO_DOCS_TOAST_URL;'>Toaster User Manual</ulink>.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='yocto-project-repositories'>
|
||||
<title>Yocto Project Source Repositories</title>
|
||||
|
||||
<para>
|
||||
The Yocto Project team maintains complete source repositories for all
|
||||
Yocto Project files at
|
||||
<ulink url='&YOCTO_GIT_URL;/cgit/cgit.cgi'></ulink>.
|
||||
This web-based source code browser is organized into categories by
|
||||
function such as IDE Plugins, Matchbox, Poky, Yocto Linux Kernel, and
|
||||
so forth.
|
||||
From the interface, you can click on any particular item in the "Name"
|
||||
column and see the URL at the bottom of the page that you need to clone
|
||||
a Git repository for that particular item.
|
||||
Having a local Git repository of the
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#source-directory'>Source Directory</ulink>,
|
||||
which is usually named "poky", allows
|
||||
you to make changes, contribute to the history, and ultimately enhance
|
||||
the Yocto Project's tools, Board Support Packages, and so forth.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For any supported release of Yocto Project, you can also go to the
|
||||
<ulink url='&YOCTO_HOME_URL;'>Yocto Project Website</ulink> and
|
||||
select the "Downloads" tab and get a released tarball of the
|
||||
<filename>poky</filename> repository or any supported BSP tarballs.
|
||||
Unpacking these tarballs gives you a snapshot of the released
|
||||
files.
|
||||
<note><title>Notes</title>
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
The recommended method for setting up the Yocto Project
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#source-directory'>Source Directory</ulink>
|
||||
and the files for supported BSPs
|
||||
(e.g., <filename>meta-intel</filename>) is to use
|
||||
<link linkend='git'>Git</link> to create a local copy of
|
||||
the upstream repositories.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Be sure to always work in matching branches for both
|
||||
the selected BSP repository and the
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#source-directory'>Source Directory</ulink>
|
||||
(i.e. <filename>poky</filename>) repository.
|
||||
For example, if you have checked out the "master" branch
|
||||
of <filename>poky</filename> and you are going to use
|
||||
<filename>meta-intel</filename>, be sure to checkout the
|
||||
"master" branch of <filename>meta-intel</filename>.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</note>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In summary, here is where you can get the project files needed for
|
||||
development:
|
||||
<itemizedlist>
|
||||
<listitem><para id='source-repositories'>
|
||||
<emphasis>
|
||||
<ulink url='&YOCTO_GIT_URL;/cgit/cgit.cgi'>Source Repositories:</ulink>
|
||||
</emphasis>
|
||||
This area contains IDE Plugins, Matchbox, Poky, Poky Support,
|
||||
Tools, Yocto Linux Kernel, and Yocto Metadata Layers.
|
||||
You can create local copies of Git repositories for each of
|
||||
these areas.</para>
|
||||
|
||||
<para>
|
||||
<imagedata fileref="figures/source-repos.png" align="center" width="6in" depth="4in" />
|
||||
For steps on how to view and access these upstream Git
|
||||
repositories, see the
|
||||
"<ulink url='&YOCTO_DOCS_DEV_URL;#accessing-source-repositories'>Accessing Source Repositories</ulink>"
|
||||
Section in the Yocto Project Development Tasks Manual.
|
||||
</para></listitem>
|
||||
<listitem><para><anchor id='index-downloads' />
|
||||
<emphasis>
|
||||
<ulink url='&YOCTO_DL_URL;/releases/'>Index of /releases:</ulink>
|
||||
</emphasis>
|
||||
This is an index of releases such as
|
||||
the <trademark class='trade'>Eclipse</trademark>
|
||||
Yocto Plug-in, miscellaneous support, Poky, Pseudo, installers
|
||||
for cross-development toolchains, and all released versions of
|
||||
Yocto Project in the form of images or tarballs.
|
||||
Downloading and extracting these files does not produce a local
|
||||
copy of the Git repository but rather a snapshot of a
|
||||
particular release or image.</para>
|
||||
|
||||
<para>
|
||||
<imagedata fileref="figures/index-downloads.png" align="center" width="6in" depth="3.5in" />
|
||||
For steps on how to view and access these files, see the
|
||||
"<ulink url='&YOCTO_DOCS_DEV_URL;#accessing-index-of-releases'>Accessing Index of Releases</ulink>"
|
||||
section in the Yocto Project Development Tasks Manual.
|
||||
</para></listitem>
|
||||
<listitem><para id='downloads-page'>
|
||||
<emphasis>"Downloads" page for the
|
||||
<ulink url='&YOCTO_HOME_URL;'>Yocto Project Website</ulink>:
|
||||
</emphasis></para>
|
||||
|
||||
<para>The Yocto Project website includes a "DOWNLOADS" page
|
||||
accessible through the "SOFTWARE" tab
|
||||
that allows you to download any Yocto Project
|
||||
release, tool, and Board Support Package (BSP) in tarball form.
|
||||
The tarballs are similar to those found in the
|
||||
<ulink url='&YOCTO_DL_URL;/releases/'>Index of /releases:</ulink> area.</para>
|
||||
|
||||
<para>
|
||||
<imagedata fileref="figures/yp-download.png" align="center" width="6in" depth="4in" />
|
||||
For steps on how to use the "DOWNLOADS" page, see the
|
||||
"<ulink url='&YOCTO_DOCS_DEV_URL;#using-the-downloads-page'>Using the Downloads Page</ulink>"
|
||||
section in the Yocto Project Development Tasks Manual.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='gs-git-workflows-and-the-yocto-project'>
|
||||
<title>Git Workflows and the Yocto Project</title>
|
||||
|
||||
<para>
|
||||
Developing using the Yocto Project likely requires the use of
|
||||
<link linkend='git'>Git</link>.
|
||||
Git is a free, open source distributed version control system
|
||||
used as part of many collaborative design environments.
|
||||
This section provides workflow concepts using the Yocto Project and
|
||||
Git.
|
||||
In particular, the information covers basic practices that describe
|
||||
roles and actions in a collaborative development environment.
|
||||
<note>
|
||||
If you are familiar with this type of development environment, you
|
||||
might not want to read this section.
|
||||
</note>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The Yocto Project files are maintained using Git in "branches"
|
||||
whose Git histories track every change and whose structures
|
||||
provide branches for all diverging functionality.
|
||||
Although there is no need to use Git, many open source projects do so.
|
||||
<para>
|
||||
|
||||
</para>
|
||||
For the Yocto Project, a key individual called the "maintainer" is
|
||||
responsible for the integrity of the "master" branch of a given Git
|
||||
repository.
|
||||
The "master" branch is the “upstream” repository from which final or
|
||||
most recent builds of a project occur.
|
||||
The maintainer is responsible for accepting changes from other
|
||||
developers and for organizing the underlying branch structure to
|
||||
reflect release strategies and so forth.
|
||||
<note>
|
||||
For information on finding out who is responsible for (maintains)
|
||||
a particular area of code in the Yocto Project, see the
|
||||
"<ulink url='&YOCTO_DOCS_DEV_URL;#how-to-submit-a-change'>Submitting a Change to the Yocto Project</ulink>"
|
||||
section of the Yocto Project Development Tasks Manual.
|
||||
</note>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The Yocto Project <filename>poky</filename> Git repository also has an
|
||||
upstream contribution Git repository named
|
||||
<filename>poky-contrib</filename>.
|
||||
You can see all the branches in this repository using the web interface
|
||||
of the
|
||||
<ulink url='&YOCTO_GIT_URL;'>Source Repositories</ulink> organized
|
||||
within the "Poky Support" area.
|
||||
These branches hold changes (commits) to the project that have been
|
||||
submitted or committed by the Yocto Project development team and by
|
||||
community members who contribute to the project.
|
||||
The maintainer determines if the changes are qualified to be moved
|
||||
from the "contrib" branches into the "master" branch of the Git
|
||||
repository.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Developers (including contributing community members) create and
|
||||
maintain cloned repositories of upstream branches.
|
||||
The cloned repositories are local to their development platforms and
|
||||
are used to develop changes.
|
||||
When a developer is satisfied with a particular feature or change,
|
||||
they "push" the change to the appropriate "contrib" repository.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Developers are responsible for keeping their local repository
|
||||
up-to-date with whatever upstream branch they are working against.
|
||||
They are also responsible for straightening out any conflicts that
|
||||
might arise within files that are being worked on simultaneously by
|
||||
more than one person.
|
||||
All this work is done locally on the development host before
|
||||
anything is pushed to a "contrib" area and examined at the maintainer’s
|
||||
level.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
A somewhat formal method exists by which developers commit changes
|
||||
and push them into the "contrib" area and subsequently request that
|
||||
the maintainer include them into an upstream branch.
|
||||
This process is called “submitting a patch” or "submitting a change."
|
||||
For information on submitting patches and changes, see the
|
||||
"<ulink url='&YOCTO_DOCS_DEV_URL;#how-to-submit-a-change'>Submitting a Change to the Yocto Project</ulink>"
|
||||
section in the Yocto Project Development Tasks Manual.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To summarize the development workflow: a single point of entry
|
||||
exists for changes into a "master" or development branch of the
|
||||
Git repository, which is controlled by the project’s maintainer.
|
||||
And, a set of developers exist who independently develop, test, and
|
||||
submit changes to "contrib" areas for the maintainer to examine.
|
||||
The maintainer then chooses which changes are going to become a
|
||||
permanent part of the project.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<imagedata fileref="figures/git-workflow.png" width="6in" depth="3in" align="left" scalefit="1" />
|
||||
</para>
|
||||
|
||||
<para>
|
||||
While each development environment is unique, there are some best
|
||||
practices or methods that help development run smoothly.
|
||||
The following list describes some of these practices.
|
||||
For more information about Git workflows, see the workflow topics in
|
||||
the
|
||||
<ulink url='http://book.git-scm.com'>Git Community Book</ulink>.
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
<emphasis>Make Small Changes:</emphasis>
|
||||
It is best to keep the changes you commit small as compared to
|
||||
bundling many disparate changes into a single commit.
|
||||
This practice not only keeps things manageable but also allows
|
||||
the maintainer to more easily include or refuse changes.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Make Complete Changes:</emphasis>
|
||||
It is also good practice to leave the repository in a
|
||||
state that allows you to still successfully build your project.
|
||||
In other words, do not commit half of a feature,
|
||||
then add the other half as a separate, later commit.
|
||||
Each commit should take you from one buildable project state
|
||||
to another buildable state.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Use Branches Liberally:</emphasis>
|
||||
It is very easy to create, use, and delete local branches in
|
||||
your working Git repository on the development host.
|
||||
You can name these branches anything you like.
|
||||
It is helpful to give them names associated with the particular
|
||||
feature or change on which you are working.
|
||||
Once you are done with a feature or change and have merged it
|
||||
into your local master branch, simply discard the temporary
|
||||
branch.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Merge Changes:</emphasis>
|
||||
The <filename>git merge</filename> command allows you to take
|
||||
the changes from one branch and fold them into another branch.
|
||||
This process is especially helpful when more than a single
|
||||
developer might be working on different parts of the same
|
||||
feature.
|
||||
Merging changes also automatically identifies any collisions
|
||||
or "conflicts" that might happen as a result of the same lines
|
||||
of code being altered by two different developers.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Manage Branches:</emphasis>
|
||||
Because branches are easy to use, you should use a system
|
||||
where branches indicate varying levels of code readiness.
|
||||
For example, you can have a "work" branch to develop in, a
|
||||
"test" branch where the code or change is tested, a "stage"
|
||||
branch where changes are ready to be committed, and so forth.
|
||||
As your project develops, you can merge code across the
|
||||
branches to reflect ever-increasing stable states of the
|
||||
development.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Use Push and Pull:</emphasis>
|
||||
The push-pull workflow is based on the concept of developers
|
||||
"pushing" local commits to a remote repository, which is
|
||||
usually a contribution repository.
|
||||
This workflow is also based on developers "pulling" known
|
||||
states of the project down into their local development
|
||||
repositories.
|
||||
The workflow easily allows you to pull changes submitted by
|
||||
other developers from the upstream repository into your
|
||||
work area ensuring that you have the most recent software
|
||||
on which to develop.
|
||||
The Yocto Project has two scripts named
|
||||
<filename>create-pull-request</filename> and
|
||||
<filename>send-pull-request</filename> that ship with the
|
||||
release to facilitate this workflow.
|
||||
You can find these scripts in the <filename>scripts</filename>
|
||||
folder of the
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#source-directory'>Source Directory</ulink>.
|
||||
For information on how to use these scripts, see the
|
||||
"<ulink url='&YOCTO_DOCS_DEV_URL;#pushing-a-change-upstream'>Using Scripts to Push a Change Upstream and Request a Pull</ulink>"
|
||||
section in the Yocto Project Development Tasks Manual.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Patch Workflow:</emphasis>
|
||||
This workflow allows you to notify the maintainer through an
|
||||
email that you have a change (or patch) you would like
|
||||
considered for the "master" branch of the Git repository.
|
||||
To send this type of change, you format the patch and then
|
||||
send the email using the Git commands
|
||||
<filename>git format-patch</filename> and
|
||||
<filename>git send-email</filename>.
|
||||
For information on how to use these scripts, see the
|
||||
"<ulink url='&YOCTO_DOCS_DEV_URL;#how-to-submit-a-change'>Submitting a Change to the Yocto Project</ulink>"
|
||||
section in the Yocto Project Development Tasks Manual.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='git'>
|
||||
<title>Git</title>
|
||||
|
||||
<para>
|
||||
The Yocto Project makes extensive use of Git, which is a
|
||||
free, open source distributed version control system.
|
||||
Git supports distributed development, non-linear development,
|
||||
and can handle large projects.
|
||||
It is best that you have some fundamental understanding
|
||||
of how Git tracks projects and how to work with Git if
|
||||
you are going to use the Yocto Project for development.
|
||||
This section provides a quick overview of how Git works and
|
||||
provides you with a summary of some essential Git commands.
|
||||
<note><title>Notes</title>
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
For more information on Git, see
|
||||
<ulink url='http://git-scm.com/documentation'></ulink>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
If you need to download Git, it is recommended that you add
|
||||
Git to your system through your distribution's "software
|
||||
store" (e.g. for Ubuntu, use the Ubuntu Software feature).
|
||||
For the Git download page, see
|
||||
<ulink url='http://git-scm.com/download'></ulink>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
For information beyond the introductory nature in this
|
||||
section, see the
|
||||
"<ulink url='&YOCTO_DOCS_DEV_URL;#working-with-yocto-project-source-files'>Working With Yocto Project Source Files</ulink>"
|
||||
section in the Yocto Project Development Tasks Manual.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</note>
|
||||
</para>
|
||||
|
||||
<section id='repositories-tags-and-branches'>
|
||||
<title>Repositories, Tags, and Branches</title>
|
||||
|
||||
<para>
|
||||
As mentioned briefly in the previous section and also in the
|
||||
"<link linkend='gs-git-workflows-and-the-yocto-project'>Git Workflows and the Yocto Project</link>"
|
||||
section, the Yocto Project maintains source repositories at
|
||||
<ulink url='&YOCTO_GIT_URL;/cgit.cgi'></ulink>.
|
||||
If you look at this web-interface of the repositories, each item
|
||||
is a separate Git repository.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Git repositories use branching techniques that track content
|
||||
change (not files) within a project (e.g. a new feature or updated
|
||||
documentation).
|
||||
Creating a tree-like structure based on project divergence allows
|
||||
for excellent historical information over the life of a project.
|
||||
This methodology also allows for an environment from which you can
|
||||
do lots of local experimentation on projects as you develop
|
||||
changes or new features.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
A Git repository represents all development efforts for a given
|
||||
project.
|
||||
For example, the Git repository <filename>poky</filename> contains
|
||||
all changes and developments for that repository over the course
|
||||
of its entire life.
|
||||
That means that all changes that make up all releases are captured.
|
||||
The repository maintains a complete history of changes.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You can create a local copy of any repository by "cloning" it
|
||||
with the <filename>git clone</filename> command.
|
||||
When you clone a Git repository, you end up with an identical
|
||||
copy of the repository on your development system.
|
||||
Once you have a local copy of a repository, you can take steps to
|
||||
develop locally.
|
||||
For examples on how to clone Git repositories, see the
|
||||
"<ulink url='&YOCTO_DOCS_DEV_URL;#working-with-yocto-project-source-files'>Working With Yocto Project Source Files</ulink>"
|
||||
section in the Yocto Project Development Tasks Manual.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It is important to understand that Git tracks content change and
|
||||
not files.
|
||||
Git uses "branches" to organize different development efforts.
|
||||
For example, the <filename>poky</filename> repository has
|
||||
several branches that include the current "&DISTRO_NAME_NO_CAP;"
|
||||
branch, the "master" branch, and many branches for past
|
||||
Yocto Project releases.
|
||||
You can see all the branches by going to
|
||||
<ulink url='&YOCTO_GIT_URL;/cgit.cgi/poky/'></ulink> and
|
||||
clicking on the
|
||||
<filename><ulink url='&YOCTO_GIT_URL;/cgit.cgi/poky/refs/heads'>[...]</ulink></filename>
|
||||
link beneath the "Branch" heading.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Each of these branches represents a specific area of development.
|
||||
The "master" branch represents the current or most recent
|
||||
development.
|
||||
All other branches represent offshoots of the "master" branch.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
When you create a local copy of a Git repository, the copy has
|
||||
the same set of branches as the original.
|
||||
This means you can use Git to create a local working area
|
||||
(also called a branch) that tracks a specific development branch
|
||||
from the upstream source Git repository.
|
||||
in other words, you can define your local Git environment to
|
||||
work on any development branch in the repository.
|
||||
To help illustrate, consider the following example Git commands:
|
||||
<literallayout class='monospaced'>
|
||||
$ cd ~
|
||||
$ git clone git://git.yoctoproject.org/poky
|
||||
$ cd poky
|
||||
$ git checkout -b &DISTRO_NAME_NO_CAP; origin/&DISTRO_NAME_NO_CAP;
|
||||
</literallayout>
|
||||
In the previous example after moving to the home directory, the
|
||||
<filename>git clone</filename> command creates a
|
||||
local copy of the upstream <filename>poky</filename> Git repository.
|
||||
By default, Git checks out the "master" branch for your work.
|
||||
After changing the working directory to the new local repository
|
||||
(i.e. <filename>poky</filename>), the
|
||||
<filename>git checkout</filename> command creates
|
||||
and checks out a local branch named "&DISTRO_NAME_NO_CAP;", which
|
||||
tracks the upstream "origin/&DISTRO_NAME_NO_CAP;" branch.
|
||||
Changes you make while in this branch would ultimately affect
|
||||
the upstream "&DISTRO_NAME_NO_CAP;" branch of the
|
||||
<filename>poky</filename> repository.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It is important to understand that when you create and checkout a
|
||||
local working branch based on a branch name,
|
||||
your local environment matches the "tip" of that particular
|
||||
development branch at the time you created your local branch,
|
||||
which could be different from the files in the "master" branch
|
||||
of the upstream repository.
|
||||
In other words, creating and checking out a local branch based on
|
||||
the "&DISTRO_NAME_NO_CAP;" branch name is not the same as
|
||||
checking out the "master" branch in the repository.
|
||||
Keep reading to see how you create a local snapshot of a Yocto
|
||||
Project Release.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Git uses "tags" to mark specific changes in a repository branch
|
||||
structure.
|
||||
Typically, a tag is used to mark a special point such as the final
|
||||
change (or commit) before a project is released.
|
||||
You can see the tags used with the <filename>poky</filename> Git
|
||||
repository by going to
|
||||
<ulink url='&YOCTO_GIT_URL;/cgit.cgi/poky/'></ulink> and
|
||||
clicking on the
|
||||
<filename><ulink url='&YOCTO_GIT_URL;/cgit.cgi/poky/refs/tags'>[...]</ulink></filename>
|
||||
link beneath the "Tag" heading.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Some key tags for the <filename>poky</filename> repository are
|
||||
<filename>jethro-14.0.3</filename>,
|
||||
<filename>morty-16.0.1</filename>,
|
||||
<filename>pyro-17.0.0</filename>, and
|
||||
<filename>&DISTRO_NAME_NO_CAP;-&POKYVERSION;</filename>.
|
||||
These tags represent Yocto Project releases.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
When you create a local copy of the Git repository, you also
|
||||
have access to all the tags in the upstream repository.
|
||||
Similar to branches, you can create and checkout a local working
|
||||
Git branch based on a tag name.
|
||||
When you do this, you get a snapshot of the Git repository that
|
||||
reflects the state of the files when the change was made associated
|
||||
with that tag.
|
||||
The most common use is to checkout a working branch that matches
|
||||
a specific Yocto Project release.
|
||||
Here is an example:
|
||||
<literallayout class='monospaced'>
|
||||
$ cd ~
|
||||
$ git clone git://git.yoctoproject.org/poky
|
||||
$ cd poky
|
||||
$ git fetch --all --tags --prune
|
||||
$ git checkout tags/pyro-17.0.0 -b my-pyro-17.0.0
|
||||
</literallayout>
|
||||
In this example, the name of the top-level directory of your
|
||||
local Yocto Project repository is <filename>poky</filename>.
|
||||
After moving to the <filename>poky</filename> directory, the
|
||||
<filename>git fetch</filename> command makes all the upstream
|
||||
tags available locally in your repository.
|
||||
Finally, the <filename>git checkout</filename> command
|
||||
creates and checks out a branch named "my-pyro-17.0.0" that is
|
||||
based on the upstream branch whose "HEAD" matches the
|
||||
commit in the repository associated with the "pyro-17.0.0" tag.
|
||||
The files in your repository now exactly match that particular
|
||||
Yocto Project release as it is tagged in the upstream Git
|
||||
repository.
|
||||
It is important to understand that when you create and
|
||||
checkout a local working branch based on a tag, your environment
|
||||
matches a specific point in time and not the entire development
|
||||
branch (i.e. from the "tip" of the branch backwards).
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='basic-commands'>
|
||||
<title>Basic Commands</title>
|
||||
|
||||
<para>
|
||||
Git has an extensive set of commands that lets you manage changes
|
||||
and perform collaboration over the life of a project.
|
||||
Conveniently though, you can manage with a small set of basic
|
||||
operations and workflows once you understand the basic
|
||||
philosophy behind Git.
|
||||
You do not have to be an expert in Git to be functional.
|
||||
A good place to look for instruction on a minimal set of Git
|
||||
commands is
|
||||
<ulink url='http://git-scm.com/documentation'>here</ulink>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If you do not know much about Git, you should educate
|
||||
yourself by visiting the links previously mentioned.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The following list of Git commands briefly describes some basic
|
||||
Git operations as a way to get started.
|
||||
As with any set of commands, this list (in most cases) simply shows
|
||||
the base command and omits the many arguments it supports.
|
||||
See the Git documentation for complete descriptions and strategies
|
||||
on how to use these commands:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
<emphasis><filename>git init</filename>:</emphasis>
|
||||
Initializes an empty Git repository.
|
||||
You cannot use Git commands unless you have a
|
||||
<filename>.git</filename> repository.
|
||||
</para></listitem>
|
||||
<listitem><para id='git-commands-clone'>
|
||||
<emphasis><filename>git clone</filename>:</emphasis>
|
||||
Creates a local clone of a Git repository that is on
|
||||
equal footing with a fellow developer’s Git repository
|
||||
or an upstream repository.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis><filename>git add</filename>:</emphasis>
|
||||
Locally stages updated file contents to the index that
|
||||
Git uses to track changes.
|
||||
You must stage all files that have changed before you
|
||||
can commit them.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis><filename>git commit</filename>:</emphasis>
|
||||
Creates a local "commit" that documents the changes you
|
||||
made.
|
||||
Only changes that have been staged can be committed.
|
||||
Commits are used for historical purposes, for determining
|
||||
if a maintainer of a project will allow the change,
|
||||
and for ultimately pushing the change from your local
|
||||
Git repository into the project’s upstream repository.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis><filename>git status</filename>:</emphasis>
|
||||
Reports any modified files that possibly need to be
|
||||
staged and gives you a status of where you stand regarding
|
||||
local commits as compared to the upstream repository.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis><filename>git checkout</filename> <replaceable>branch-name</replaceable>:</emphasis>
|
||||
Changes your local working branch and in this form
|
||||
assumes the local branch already exists.
|
||||
This command is analogous to "cd".
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis><filename>git checkout –b</filename> <replaceable>working-branch</replaceable> <replaceable>upstream-branch</replaceable>:</emphasis>
|
||||
Creates and checks out a working branch on your local
|
||||
machine.
|
||||
The local branch tracks the upstream branch.
|
||||
You can use your local branch to isolate your work.
|
||||
It is a good idea to use local branches when adding
|
||||
specific features or changes.
|
||||
Using isolated branches facilitates easy removal of
|
||||
changes if they do not work out.
|
||||
</para></listitem>
|
||||
<listitem><para><emphasis><filename>git branch</filename>:</emphasis>
|
||||
Displays the existing local branches associated with your
|
||||
local repository.
|
||||
The branch that you have currently checked out is noted
|
||||
with an asterisk character.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis><filename>git branch -D</filename> <replaceable>branch-name</replaceable>:</emphasis>
|
||||
Deletes an existing local branch.
|
||||
You need to be in a local branch other than the one you
|
||||
are deleting in order to delete
|
||||
<replaceable>branch-name</replaceable>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis><filename>git pull --rebase</filename>:</emphasis>
|
||||
Retrieves information from an upstream Git repository
|
||||
and places it in your local Git repository.
|
||||
You use this command to make sure you are synchronized with
|
||||
the repository from which you are basing changes
|
||||
(.e.g. the "master" branch).
|
||||
The "--rebase" option ensures that any local commits you
|
||||
have in your branch are preserved at the top of your
|
||||
local branch.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis><filename>git push</filename> <replaceable>repo-name</replaceable> <replaceable>local-branch</replaceable><filename>:</filename><replaceable>upstream-branch</replaceable>:</emphasis>
|
||||
Sends all your committed local changes to the upstream Git
|
||||
repository that your local repository is tracking
|
||||
(e.g. a contribution repository).
|
||||
The maintainer of the project draws from these repositories
|
||||
to merge changes (commits) into the appropriate branch
|
||||
of project's upstream repository.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis><filename>git merge</filename>:</emphasis>
|
||||
Combines or adds changes from one
|
||||
local branch of your repository with another branch.
|
||||
When you create a local Git repository, the default branch
|
||||
is named "master".
|
||||
A typical workflow is to create a temporary branch that is
|
||||
based off "master" that you would use for isolated work.
|
||||
You would make your changes in that isolated branch,
|
||||
stage and commit them locally, switch to the "master"
|
||||
branch, and then use the <filename>git merge</filename>
|
||||
command to apply the changes from your isolated branch
|
||||
into the currently checked out branch (e.g. "master").
|
||||
After the merge is complete and if you are done with
|
||||
working in that isolated branch, you can safely delete
|
||||
the isolated branch.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis><filename>git cherry-pick</filename> <replaceable>commits</replaceable>:</emphasis>
|
||||
Choose and apply specific commits from one branch
|
||||
into another branch.
|
||||
There are times when you might not be able to merge
|
||||
all the changes in one branch with
|
||||
another but need to pick out certain ones.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis><filename>gitk</filename>:</emphasis>
|
||||
Provides a GUI view of the branches and changes in your
|
||||
local Git repository.
|
||||
This command is a good way to graphically see where things
|
||||
have diverged in your local repository.
|
||||
<note>
|
||||
You need to install the <filename>gitk</filename>
|
||||
package on your development system to use this
|
||||
command.
|
||||
</note>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis><filename>git log</filename>:</emphasis>
|
||||
Reports a history of your commits to the repository.
|
||||
This report lists all commits regardless of whether you
|
||||
have pushed them upstream or not.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis><filename>git diff</filename>:</emphasis>
|
||||
Displays line-by-line differences between a local
|
||||
working file and the same file as understood by Git.
|
||||
This command is useful to see what you have changed
|
||||
in any given file.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id='licensing'>
|
||||
<title>Licensing</title>
|
||||
|
||||
<para>
|
||||
Because open source projects are open to the public, they have
|
||||
different licensing structures in place.
|
||||
License evolution for both Open Source and Free Software has an
|
||||
interesting history.
|
||||
If you are interested in this history, you can find basic information
|
||||
here:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
<ulink url='http://en.wikipedia.org/wiki/Open-source_license'>Open source license history</ulink>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<ulink url='http://en.wikipedia.org/wiki/Free_software_license'>Free software license history</ulink>
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In general, the Yocto Project is broadly licensed under the
|
||||
Massachusetts Institute of Technology (MIT) License.
|
||||
MIT licensing permits the reuse of software within proprietary
|
||||
software as long as the license is distributed with that software.
|
||||
MIT is also compatible with the GNU General Public License (GPL).
|
||||
Patches to the Yocto Project follow the upstream licensing scheme.
|
||||
You can find information on the MIT license
|
||||
<ulink url='http://www.opensource.org/licenses/mit-license.php'>here</ulink>.
|
||||
You can find information on the GNU GPL
|
||||
<ulink url='http://www.opensource.org/licenses/LGPL-3.0'>here</ulink>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
When you build an image using the Yocto Project, the build process
|
||||
uses a known list of licenses to ensure compliance.
|
||||
You can find this list in the
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#source-directory'>Source Directory</ulink>
|
||||
at <filename>meta/files/common-licenses</filename>.
|
||||
Once the build completes, the list of all licenses found and used
|
||||
during that build are kept in the
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#build-directory'>Build Directory</ulink>
|
||||
at <filename>tmp/deploy/licenses</filename>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If a module requires a license that is not in the base list, the
|
||||
build process generates a warning during the build.
|
||||
These tools make it easier for a developer to be certain of the
|
||||
licenses with which their shipped products must comply.
|
||||
However, even with these tools it is still up to the developer to
|
||||
resolve potential licensing issues.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The base list of licenses used by the build process is a combination
|
||||
of the Software Package Data Exchange (SPDX) list and the Open
|
||||
Source Initiative (OSI) projects.
|
||||
<ulink url='http://spdx.org'>SPDX Group</ulink> is a working group of
|
||||
the Linux Foundation that maintains a specification for a standard
|
||||
format for communicating the components, licenses, and copyrights
|
||||
associated with a software package.
|
||||
<ulink url='http://opensource.org'>OSI</ulink> is a corporation
|
||||
dedicated to the Open Source Definition and the effort for reviewing
|
||||
and approving licenses that conform to the Open Source Definition
|
||||
(OSD).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You can find a list of the combined SPDX and OSI licenses that the
|
||||
Yocto Project uses in the
|
||||
<filename>meta/files/common-licenses</filename> directory in your
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#source-directory'>Source Directory</ulink>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For information that can help you maintain compliance with various
|
||||
open source licensing during the lifecycle of a product created using
|
||||
the Yocto Project, see the
|
||||
"<ulink url='&YOCTO_DOCS_DEV_URL;#maintaining-open-source-license-compliance-during-your-products-lifecycle'>Maintaining Open Source License Compliance During Your Product's Lifecycle</ulink>"
|
||||
section in the Yocto Project Development Tasks Manual.
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
||||
<!--
|
||||
vim: expandtab tw=80 ts=4
|
||||
-->
|
||||
@@ -1,35 +0,0 @@
|
||||
<?xml version='1.0'?>
|
||||
<xsl:stylesheet
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:fo="http://www.w3.org/1999/XSL/Format"
|
||||
version="1.0">
|
||||
|
||||
<xsl:import href="http://downloads.yoctoproject.org/mirror/docbook-mirror/docbook-xsl-1.76.1/eclipse/eclipse3.xsl" />
|
||||
|
||||
<!--
|
||||
|
||||
<xsl:import href="../template/1.76.1/docbook-xsl-1.76.1/eclipse/eclipse3.xsl" />
|
||||
|
||||
<xsl:import
|
||||
href="http://docbook.sourceforge.net/release/xsl/1.76.1/eclipse/eclipse3.xsl" />
|
||||
|
||||
-->
|
||||
|
||||
<xsl:param name="chunker.output.indent" select="'yes'"/>
|
||||
<xsl:param name="chunk.quietly" select="1"/>
|
||||
<xsl:param name="chunk.first.sections" select="1"/>
|
||||
<xsl:param name="chunk.section.depth" select="10"/>
|
||||
<xsl:param name="use.id.as.filename" select="1"/>
|
||||
<xsl:param name="ulink.target" select="'_self'" />
|
||||
<xsl:param name="base.dir" select="'html/getting-started/'"/>
|
||||
<xsl:param name="html.stylesheet" select="'../book.css'"/>
|
||||
<xsl:param name="eclipse.manifest" select="0"/>
|
||||
<xsl:param name="create.plugin.xml" select="0"/>
|
||||
<xsl:param name="suppress.navigation" select="1"/>
|
||||
<xsl:param name="generate.index" select="0"/>
|
||||
<xsl:param name="chapter.autolabel" select="1" />
|
||||
<xsl:param name="appendix.autolabel" select="1" />
|
||||
<xsl:param name="section.autolabel" select="1" />
|
||||
<xsl:param name="section.label.includes.component.label" select="1" />
|
||||
</xsl:stylesheet>
|
||||
@@ -1,110 +0,0 @@
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
|
||||
[<!ENTITY % poky SYSTEM "../poky.ent"> %poky; ] >
|
||||
|
||||
<chapter id='overview-manual-intro'>
|
||||
|
||||
<title>The Getting Started With Yocto Project Manual</title>
|
||||
<section id='getting-started-welcome'>
|
||||
<title>Welcome</title>
|
||||
|
||||
<para>
|
||||
Welcome to the Getting Started With Yocto Project Manual!
|
||||
This manual introduces the Yocto Project by providing concepts,
|
||||
software overviews, best-known-methods (BKMs), and any other
|
||||
high-level introductory information suitable for a new Yocto
|
||||
Project user.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The following list describes what you can get from this manual:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
<emphasis><link linkend='overview-yp'>Introducing the Yocto Project</link>:</emphasis>
|
||||
This chapter provides an introduction to the Yocto
|
||||
Project.
|
||||
You will learn about features and challenges of the
|
||||
Yocto Project, the layer model, components and tools,
|
||||
development methods, the Poky reference distribution,
|
||||
the OpenEmbedded build system workflow, and some basic
|
||||
Yocto terms.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis><link linkend='overview-development-environment'>The Yocto Project Development Environment</link>:</emphasis>
|
||||
This chapter helps you get started understanding the
|
||||
Yocto Project development environment.
|
||||
You will learn about open source, development hosts,
|
||||
Yocto Project source repositories, workflows using Git
|
||||
and the Yocto Project, a Git primer, and information
|
||||
about licensing.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This manual does not give you the following:
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
<emphasis>Step-by-step Instructions for Development Tasks:</emphasis>
|
||||
Instructional procedures reside in other manuals within
|
||||
the Yocto Project documentation set.
|
||||
For example, the
|
||||
<ulink url='&YOCTO_DOCS_DEV_URL;'>Yocto Project Development Tasks Manual</ulink>
|
||||
provides examples on how to perform various development
|
||||
tasks.
|
||||
As another example, the
|
||||
<ulink url='&YOCTO_DOCS_SDK_URL;'>Yocto Project Application Development and the Extensible Software Development Kit (eSDK)</ulink>
|
||||
manual contains detailed instructions on how to install an
|
||||
SDK, which is used to develop applications for target
|
||||
hardware.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Reference Material:</emphasis>
|
||||
This type of material resides in an appropriate reference
|
||||
manual.
|
||||
For example, system variables are documented in the
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;'>Yocto Project Reference Manual</ulink>.
|
||||
As another example, the
|
||||
<ulink url='&YOCTO_DOCS_BSP_URL;'>Yocto Project Board Support Package (BSP) Developer's Guide</ulink>
|
||||
contains reference information on BSPs.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Detailed Public Information Not Specific to the
|
||||
Yocto Project:</emphasis>
|
||||
For example, exhaustive information on how to use the
|
||||
Source Control Manager Git is better covered with Internet
|
||||
searches and official Git Documentation than through the
|
||||
Yocto Project documentation.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='getting-started-overview-other-information'>
|
||||
<title>Other Information</title>
|
||||
|
||||
<para>
|
||||
Because this manual presents information for many different
|
||||
topics, supplemental information is recommended for full
|
||||
comprehension.
|
||||
For additional introductory information on the Yocto Project, see
|
||||
the <ulink url='&YOCTO_HOME_URL;'>Yocto Project Website</ulink>.
|
||||
You can find an introductory to using the Yocto Project by working
|
||||
through the
|
||||
<ulink url='&YOCTO_DOCS_QS_URL;'>Yocto Project Quick Start</ulink>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For a comprehensive list of links and other documentation, see the
|
||||
"<ulink url='&YOCTO_DOCS_REF_URL;#resources-links-and-related-documentation'>Links and Related Documentation</ulink>"
|
||||
section in the Yocto Project Reference Manual.
|
||||
For a paper showing how to set up and run a quick build using the
|
||||
Yocto Project, see the
|
||||
"<ulink url='&YOCTO_DOCS_BRIEF_URL;'>My First Yocto Project Build</ulink>"
|
||||
paper.
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
||||
<!--
|
||||
vim: expandtab tw=80 ts=4
|
||||
-->
|
||||
@@ -1,988 +0,0 @@
|
||||
/*
|
||||
Generic XHTML / DocBook XHTML CSS Stylesheet.
|
||||
|
||||
Browser wrangling and typographic design by
|
||||
Oyvind Kolas / pippin@gimp.org
|
||||
|
||||
Customised for Poky by
|
||||
Matthew Allum / mallum@o-hand.com
|
||||
|
||||
Thanks to:
|
||||
Liam R. E. Quin
|
||||
William Skaggs
|
||||
Jakub Steiner
|
||||
|
||||
Structure
|
||||
---------
|
||||
|
||||
The stylesheet is divided into the following sections:
|
||||
|
||||
Positioning
|
||||
Margins, paddings, width, font-size, clearing.
|
||||
Decorations
|
||||
Borders, style
|
||||
Colors
|
||||
Colors
|
||||
Graphics
|
||||
Graphical backgrounds
|
||||
Nasty IE tweaks
|
||||
Workarounds needed to make it work in internet explorer,
|
||||
currently makes the stylesheet non validating, but up until
|
||||
this point it is validating.
|
||||
Mozilla extensions
|
||||
Transparency for footer
|
||||
Rounded corners on boxes
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*************** /
|
||||
/ Positioning /
|
||||
/ ***************/
|
||||
|
||||
body {
|
||||
font-family: Verdana, Sans, sans-serif;
|
||||
|
||||
min-width: 640px;
|
||||
width: 80%;
|
||||
margin: 0em auto;
|
||||
padding: 2em 5em 5em 5em;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6,h7 {
|
||||
font-family: Arial, Sans;
|
||||
color: #00557D;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
text-align: left;
|
||||
padding: 0em 0em 0em 0em;
|
||||
margin: 2em 0em 0em 0em;
|
||||
}
|
||||
|
||||
h2.subtitle {
|
||||
margin: 0.10em 0em 3.0em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
font-size: 1.8em;
|
||||
padding-left: 20%;
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 2em 0em 0.66em 0em;
|
||||
padding: 0.5em 0em 0em 0em;
|
||||
font-size: 1.5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h3.subtitle {
|
||||
margin: 0em 0em 1em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
font-size: 142.14%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 1em 0em 0.5em 0em;
|
||||
padding: 1em 0em 0em 0em;
|
||||
font-size: 140%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin: 1em 0em 0.5em 0em;
|
||||
padding: 1em 0em 0em 0em;
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h5 {
|
||||
margin: 1em 0em 0.5em 0em;
|
||||
padding: 1em 0em 0em 0em;
|
||||
font-size: 110%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h6 {
|
||||
margin: 1em 0em 0em 0em;
|
||||
padding: 1em 0em 0em 0em;
|
||||
font-size: 110%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.authorgroup {
|
||||
background-color: transparent;
|
||||
background-repeat: no-repeat;
|
||||
padding-top: 256px;
|
||||
background-image: url("figures/getting-started-title.png");
|
||||
background-position: left top;
|
||||
margin-top: -256px;
|
||||
padding-right: 50px;
|
||||
margin-left: 0px;
|
||||
text-align: right;
|
||||
width: 740px;
|
||||
}
|
||||
|
||||
h3.author {
|
||||
margin: 0em 0me 0em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
font-weight: normal;
|
||||
font-size: 100%;
|
||||
color: #333;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.author tt.email {
|
||||
font-size: 66%;
|
||||
}
|
||||
|
||||
.titlepage hr {
|
||||
width: 0em;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.revhistory {
|
||||
padding-top: 2em;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.toc,
|
||||
.list-of-tables,
|
||||
.list-of-examples,
|
||||
.list-of-figures {
|
||||
padding: 1.33em 0em 2.5em 0em;
|
||||
color: #00557D;
|
||||
}
|
||||
|
||||
.toc p,
|
||||
.list-of-tables p,
|
||||
.list-of-figures p,
|
||||
.list-of-examples p {
|
||||
padding: 0em 0em 0em 0em;
|
||||
padding: 0em 0em 0.3em;
|
||||
margin: 1.5em 0em 0em 0em;
|
||||
}
|
||||
|
||||
.toc p b,
|
||||
.list-of-tables p b,
|
||||
.list-of-figures p b,
|
||||
.list-of-examples p b{
|
||||
font-size: 100.0%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.toc dl,
|
||||
.list-of-tables dl,
|
||||
.list-of-figures dl,
|
||||
.list-of-examples dl {
|
||||
margin: 0em 0em 0.5em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
.toc dt {
|
||||
margin: 0em 0em 0em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
.toc dd {
|
||||
margin: 0em 0em 0em 2.6em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
div.glossary dl,
|
||||
div.variablelist dl {
|
||||
}
|
||||
|
||||
.glossary dl dt,
|
||||
.variablelist dl dt,
|
||||
.variablelist dl dt span.term {
|
||||
font-weight: normal;
|
||||
width: 20em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.variablelist dl dt {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
.glossary dl dd,
|
||||
.variablelist dl dd {
|
||||
margin-top: -1em;
|
||||
margin-left: 25.5em;
|
||||
}
|
||||
|
||||
.glossary dd p,
|
||||
.variablelist dd p {
|
||||
margin-top: 0em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
|
||||
div.calloutlist table td {
|
||||
padding: 0em 0em 0em 0em;
|
||||
margin: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
div.calloutlist table td p {
|
||||
margin-top: 0em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
div p.copyright {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div.legalnotice p.legalnotice-title {
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 1.5em;
|
||||
margin-top: 0em;
|
||||
|
||||
}
|
||||
|
||||
dl {
|
||||
padding-top: 0em;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: solid 1px;
|
||||
}
|
||||
|
||||
|
||||
.mediaobject,
|
||||
.mediaobjectco {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
img {
|
||||
border: none;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding: 0em 0em 0em 1.5em;
|
||||
}
|
||||
|
||||
ul li {
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
ul li p {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
table {
|
||||
width :100%;
|
||||
}
|
||||
|
||||
th {
|
||||
padding: 0.25em;
|
||||
text-align: left;
|
||||
font-weight: normal;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0.25em;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
p a[id] {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
display: inline;
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: underline;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
pre {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
/*font-weight: bold;*/
|
||||
}
|
||||
|
||||
/* This style defines how the permalink character
|
||||
appears by itself and when hovered over with
|
||||
the mouse. */
|
||||
|
||||
[alt='Permalink'] { color: #eee; }
|
||||
[alt='Permalink']:hover { color: black; }
|
||||
|
||||
|
||||
div.informalfigure,
|
||||
div.informalexample,
|
||||
div.informaltable,
|
||||
div.figure,
|
||||
div.table,
|
||||
div.example {
|
||||
margin: 1em 0em;
|
||||
padding: 1em;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
|
||||
div.informalfigure p.title b,
|
||||
div.informalexample p.title b,
|
||||
div.informaltable p.title b,
|
||||
div.figure p.title b,
|
||||
div.example p.title b,
|
||||
div.table p.title b{
|
||||
padding-top: 0em;
|
||||
margin-top: 0em;
|
||||
font-size: 100%;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.mediaobject .caption,
|
||||
.mediaobject .caption p {
|
||||
text-align: center;
|
||||
font-size: 80%;
|
||||
padding-top: 0.5em;
|
||||
padding-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.epigraph {
|
||||
padding-left: 55%;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.epigraph p {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.epigraph .quote {
|
||||
font-style: italic;
|
||||
}
|
||||
.epigraph .attribution {
|
||||
font-style: normal;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
span.application {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.programlisting {
|
||||
font-family: monospace;
|
||||
font-size: 80%;
|
||||
white-space: pre;
|
||||
margin: 1.33em 0em;
|
||||
padding: 1.33em;
|
||||
}
|
||||
|
||||
.tip,
|
||||
.warning,
|
||||
.caution,
|
||||
.note {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
|
||||
}
|
||||
|
||||
/* force full width of table within div */
|
||||
.tip table,
|
||||
.warning table,
|
||||
.caution table,
|
||||
.note table {
|
||||
border: none;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
.tip table th,
|
||||
.warning table th,
|
||||
.caution table th,
|
||||
.note table th {
|
||||
padding: 0.8em 0.0em 0.0em 0.0em;
|
||||
margin : 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
.tip p,
|
||||
.warning p,
|
||||
.caution p,
|
||||
.note p {
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
padding-right: 1em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.acronym {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
b.keycap,
|
||||
.keycap {
|
||||
padding: 0.09em 0.3em;
|
||||
margin: 0em;
|
||||
}
|
||||
|
||||
.itemizedlist li {
|
||||
clear: none;
|
||||
}
|
||||
|
||||
.filename {
|
||||
font-size: medium;
|
||||
font-family: Courier, monospace;
|
||||
}
|
||||
|
||||
|
||||
div.navheader, div.heading{
|
||||
position: absolute;
|
||||
left: 0em;
|
||||
top: 0em;
|
||||
width: 100%;
|
||||
background-color: #cdf;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.navfooter, div.footing{
|
||||
position: fixed;
|
||||
left: 0em;
|
||||
bottom: 0em;
|
||||
background-color: #eee;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
div.navheader td,
|
||||
div.navfooter td {
|
||||
font-size: 66%;
|
||||
}
|
||||
|
||||
div.navheader table th {
|
||||
/*font-family: Georgia, Times, serif;*/
|
||||
/*font-size: x-large;*/
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
div.navheader table {
|
||||
border-left: 0em;
|
||||
border-right: 0em;
|
||||
border-top: 0em;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.navfooter table {
|
||||
border-left: 0em;
|
||||
border-right: 0em;
|
||||
border-bottom: 0em;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.navheader table td a,
|
||||
div.navfooter table td a {
|
||||
color: #777;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* normal text in the footer */
|
||||
div.navfooter table td {
|
||||
color: black;
|
||||
}
|
||||
|
||||
div.navheader table td a:visited,
|
||||
div.navfooter table td a:visited {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
|
||||
/* links in header and footer */
|
||||
div.navheader table td a:hover,
|
||||
div.navfooter table td a:hover {
|
||||
text-decoration: underline;
|
||||
background-color: transparent;
|
||||
color: #33a;
|
||||
}
|
||||
|
||||
div.navheader hr,
|
||||
div.navfooter hr {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.qandaset tr.question td p {
|
||||
margin: 0em 0em 1em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
|
||||
.qandaset tr.answer td p {
|
||||
margin: 0em 0em 1em 0em;
|
||||
padding: 0em 0em 0em 0em;
|
||||
}
|
||||
.answer td {
|
||||
padding-bottom: 1.5em;
|
||||
}
|
||||
|
||||
.emphasis {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
/************* /
|
||||
/ decorations /
|
||||
/ *************/
|
||||
|
||||
.titlepage {
|
||||
}
|
||||
|
||||
.part .title {
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/*
|
||||
h1 {
|
||||
border: none;
|
||||
}
|
||||
|
||||
h2 {
|
||||
border-top: solid 0.2em;
|
||||
border-bottom: solid 0.06em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
border-top: 0em;
|
||||
border-bottom: solid 0.06em;
|
||||
}
|
||||
|
||||
h4 {
|
||||
border: 0em;
|
||||
border-bottom: solid 0.06em;
|
||||
}
|
||||
|
||||
h5 {
|
||||
border: 0em;
|
||||
}
|
||||
*/
|
||||
|
||||
.programlisting {
|
||||
border: solid 1px;
|
||||
}
|
||||
|
||||
div.figure,
|
||||
div.table,
|
||||
div.informalfigure,
|
||||
div.informaltable,
|
||||
div.informalexample,
|
||||
div.example {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.tip,
|
||||
.warning,
|
||||
.caution,
|
||||
.note {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.tip table th,
|
||||
.warning table th,
|
||||
.caution table th,
|
||||
.note table th {
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
|
||||
.question td {
|
||||
border-top: 1px solid black;
|
||||
}
|
||||
|
||||
.answer {
|
||||
}
|
||||
|
||||
|
||||
b.keycap,
|
||||
.keycap {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
|
||||
div.navheader, div.heading{
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
|
||||
|
||||
div.navfooter, div.footing{
|
||||
border-top: 1px solid;
|
||||
}
|
||||
|
||||
/********* /
|
||||
/ colors /
|
||||
/ *********/
|
||||
|
||||
body {
|
||||
color: #333;
|
||||
background: white;
|
||||
}
|
||||
|
||||
a {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
background-color: #dedede;
|
||||
}
|
||||
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
h7,
|
||||
h8 {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
hr {
|
||||
border-color: #aaa;
|
||||
}
|
||||
|
||||
|
||||
.tip, .warning, .caution, .note {
|
||||
border-color: #fff;
|
||||
}
|
||||
|
||||
|
||||
.tip table th,
|
||||
.warning table th,
|
||||
.caution table th,
|
||||
.note table th {
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
|
||||
|
||||
.warning {
|
||||
background-color: #f0f0f2;
|
||||
}
|
||||
|
||||
.caution {
|
||||
background-color: #f0f0f2;
|
||||
}
|
||||
|
||||
.tip {
|
||||
background-color: #f0f0f2;
|
||||
}
|
||||
|
||||
.note {
|
||||
background-color: #f0f0f2;
|
||||
}
|
||||
|
||||
.glossary dl dt,
|
||||
.variablelist dl dt,
|
||||
.variablelist dl dt span.term {
|
||||
color: #044;
|
||||
}
|
||||
|
||||
div.figure,
|
||||
div.table,
|
||||
div.example,
|
||||
div.informalfigure,
|
||||
div.informaltable,
|
||||
div.informalexample {
|
||||
border-color: #aaa;
|
||||
}
|
||||
|
||||
pre.programlisting {
|
||||
color: black;
|
||||
background-color: #fff;
|
||||
border-color: #aaa;
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
.guimenu,
|
||||
.guilabel,
|
||||
.guimenuitem {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
|
||||
b.keycap,
|
||||
.keycap {
|
||||
background-color: #eee;
|
||||
border-color: #999;
|
||||
}
|
||||
|
||||
|
||||
div.navheader {
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
|
||||
div.navfooter {
|
||||
border-color: black;
|
||||
}
|
||||
|
||||
.writernotes {
|
||||
color: red;
|
||||
}
|
||||
|
||||
|
||||
/*********** /
|
||||
/ graphics /
|
||||
/ ***********/
|
||||
|
||||
/*
|
||||
body {
|
||||
background-image: url("images/body_bg.jpg");
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
.navheader,
|
||||
.note,
|
||||
.tip {
|
||||
background-image: url("images/note_bg.jpg");
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
.warning,
|
||||
.caution {
|
||||
background-image: url("images/warning_bg.jpg");
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
.figure,
|
||||
.informalfigure,
|
||||
.example,
|
||||
.informalexample,
|
||||
.table,
|
||||
.informaltable {
|
||||
background-image: url("images/figure_bg.jpg");
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
*/
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
h7{
|
||||
}
|
||||
|
||||
/*
|
||||
Example of how to stick an image as part of the title.
|
||||
|
||||
div.article .titlepage .title
|
||||
{
|
||||
background-image: url("figures/white-on-black.png");
|
||||
background-position: center;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
*/
|
||||
|
||||
div.preface .titlepage .title,
|
||||
div.colophon .title,
|
||||
div.chapter .titlepage .title,
|
||||
div.article .titlepage .title
|
||||
{
|
||||
}
|
||||
|
||||
div.section div.section .titlepage .title,
|
||||
div.sect2 .titlepage .title {
|
||||
background: none;
|
||||
}
|
||||
|
||||
|
||||
h1.title {
|
||||
background-color: transparent;
|
||||
background-repeat: no-repeat;
|
||||
height: 256px;
|
||||
text-indent: -9000px;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
h2.subtitle {
|
||||
background-color: transparent;
|
||||
text-indent: -9000px;
|
||||
overflow:hidden;
|
||||
width: 0px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*************************************** /
|
||||
/ pippin.gimp.org specific alterations /
|
||||
/ ***************************************/
|
||||
|
||||
/*
|
||||
div.heading, div.navheader {
|
||||
color: #777;
|
||||
font-size: 80%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
text-align: left;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
background: url('/gfx/heading_bg.png') transparent;
|
||||
background-repeat: repeat-x;
|
||||
background-attachment: fixed;
|
||||
border: none;
|
||||
}
|
||||
|
||||
div.heading a {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
div.footing, div.navfooter {
|
||||
border: none;
|
||||
color: #ddd;
|
||||
font-size: 80%;
|
||||
text-align:right;
|
||||
|
||||
width: 100%;
|
||||
padding-top: 10px;
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
|
||||
background: url('/gfx/footing_bg.png') transparent;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/****************** /
|
||||
/ nasty ie tweaks /
|
||||
/ ******************/
|
||||
|
||||
/*
|
||||
div.heading, div.navheader {
|
||||
width:expression(document.body.clientWidth + "px");
|
||||
}
|
||||
|
||||
div.footing, div.navfooter {
|
||||
width:expression(document.body.clientWidth + "px");
|
||||
margin-left:expression("-5em");
|
||||
}
|
||||
body {
|
||||
padding:expression("4em 5em 0em 5em");
|
||||
}
|
||||
*/
|
||||
|
||||
/**************************************** /
|
||||
/ mozilla vendor specific css extensions /
|
||||
/ ****************************************/
|
||||
/*
|
||||
div.navfooter, div.footing{
|
||||
-moz-opacity: 0.8em;
|
||||
}
|
||||
|
||||
div.figure,
|
||||
div.table,
|
||||
div.informalfigure,
|
||||
div.informaltable,
|
||||
div.informalexample,
|
||||
div.example,
|
||||
.tip,
|
||||
.warning,
|
||||
.caution,
|
||||
.note {
|
||||
-moz-border-radius: 0.5em;
|
||||
}
|
||||
|
||||
b.keycap,
|
||||
.keycap {
|
||||
-moz-border-radius: 0.3em;
|
||||
}
|
||||
*/
|
||||
|
||||
table tr td table tr td {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
hr {
|
||||
display: none;
|
||||
}
|
||||
|
||||
table {
|
||||
border: 0em;
|
||||
}
|
||||
|
||||
.photo {
|
||||
float: right;
|
||||
margin-left: 1.5em;
|
||||
margin-bottom: 1.5em;
|
||||
margin-top: 0em;
|
||||
max-width: 17em;
|
||||
border: 1px solid gray;
|
||||
padding: 3px;
|
||||
background: white;
|
||||
}
|
||||
.seperator {
|
||||
padding-top: 2em;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#validators {
|
||||
margin-top: 5em;
|
||||
text-align: right;
|
||||
color: #777;
|
||||
}
|
||||
@media print {
|
||||
body {
|
||||
font-size: 8pt;
|
||||
}
|
||||
.noprint {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.tip,
|
||||
.note {
|
||||
background: #f0f0f2;
|
||||
color: #333;
|
||||
padding: 20px;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.tip h3,
|
||||
.note h3 {
|
||||
padding: 0em;
|
||||
margin: 0em;
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.tip a,
|
||||
.note a {
|
||||
color: #333;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.footnote {
|
||||
font-size: small;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* Changes the announcement text */
|
||||
.tip h3,
|
||||
.warning h3,
|
||||
.caution h3,
|
||||
.note h3 {
|
||||
font-size:large;
|
||||
color: #00557D;
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
|
||||
[<!ENTITY % poky SYSTEM "../poky.ent"> %poky; ] >
|
||||
|
||||
<book id='getting-started-manual' lang='en'
|
||||
xmlns:xi="http://www.w3.org/2003/XInclude"
|
||||
xmlns="http://docbook.org/ns/docbook"
|
||||
>
|
||||
<bookinfo>
|
||||
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref='figures/getting-started-title.png'
|
||||
format='SVG'
|
||||
align='left' scalefit='1' width='100%'/>
|
||||
</imageobject>
|
||||
</mediaobject>
|
||||
|
||||
<title>
|
||||
Getting Started With Yocto Project
|
||||
</title>
|
||||
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Scott</firstname> <surname>Rifenbark</surname>
|
||||
<affiliation>
|
||||
<orgname>Scotty's Documentation Services, INC</orgname>
|
||||
</affiliation>
|
||||
<email>srifenbark@gmail.com</email>
|
||||
</author>
|
||||
</authorgroup>
|
||||
|
||||
<revhistory>
|
||||
<revision>
|
||||
<revnumber>2.5</revnumber>
|
||||
<date>April 2018</date>
|
||||
<revremark>The initial document released with the Yocto Project 2.5 Release.</revremark>
|
||||
</revision>
|
||||
</revhistory>
|
||||
|
||||
<copyright>
|
||||
<year>©RIGHT_YEAR;</year>
|
||||
<holder>Linux Foundation</holder>
|
||||
</copyright>
|
||||
|
||||
<legalnotice>
|
||||
<para>
|
||||
Permission is granted to copy, distribute and/or modify this document under
|
||||
the terms of the <ulink type="http" url="http://creativecommons.org/licenses/by-sa/2.0/uk/">
|
||||
Creative Commons Attribution-Share Alike 2.0 UK: England & Wales</ulink> as published by
|
||||
Creative Commons.
|
||||
</para>
|
||||
<note><title>Manual Notes</title>
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
This version of the
|
||||
<emphasis>Getting Started With Yocto Project Manual</emphasis>
|
||||
is for the &YOCTO_DOC_VERSION; release of the
|
||||
Yocto Project.
|
||||
To be sure you have the latest version of the manual
|
||||
for this release, use the manual from the
|
||||
<ulink url='&YOCTO_HOME_URL;/documentation'>Yocto Project documentation page</ulink>.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
For manuals associated with other releases of the Yocto
|
||||
Project, go to the
|
||||
<ulink url='&YOCTO_HOME_URL;/documentation'>Yocto Project documentation page</ulink>
|
||||
and use the drop-down "Active Releases" button
|
||||
and choose the manual associated with the desired
|
||||
Yocto Project.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
To report any inaccuracies or problems with this
|
||||
manual, send an email to the Yocto Project
|
||||
discussion group at
|
||||
<filename>yocto@yoctoproject.com</filename> or log into
|
||||
the freenode <filename>#yocto</filename> channel.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</note>
|
||||
</legalnotice>
|
||||
|
||||
</bookinfo>
|
||||
|
||||
<xi:include href="getting-started-intro.xml"/>
|
||||
|
||||
<xi:include href="getting-started-yp-intro.xml"/>
|
||||
|
||||
<xi:include href="getting-started-development-environment.xml"/>
|
||||
|
||||
</book>
|
||||
<!--
|
||||
vim: expandtab tw=80 ts=4
|
||||
-->
|
||||
@@ -21,7 +21,7 @@
|
||||
<para>
|
||||
Kernel Metadata exists in many places.
|
||||
One area in the Yocto Project
|
||||
<ulink url='&YOCTO_DOCS_GS_URL;#source-repositories'>Source Repositories</ulink>
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#source-repositories'>Source Repositories</ulink>
|
||||
is the <filename>yocto-kernel-cache</filename> Git repository.
|
||||
You can find this repository grouped under the "Yocto Linux Kernel"
|
||||
heading in the
|
||||
@@ -631,10 +631,8 @@
|
||||
<note>
|
||||
For BSPs supported by the Yocto Project, the BSP description
|
||||
files are located in the <filename>bsp</filename> directory
|
||||
of the
|
||||
<ulink url='&YOCTO_GIT_URL;/cgit/cgit.cgi/yocto-kernel-cache/tree/bsp'><filename>yocto-kernel-cache</filename></ulink>
|
||||
repository organized under the "Yocto Linux Kernel" heading
|
||||
in the
|
||||
of the <filename>yocto-kernel-cache</filename> repository
|
||||
organized under the "Yocto Linux Kernel" heading in the
|
||||
<ulink url='http://git.yoctoproject.org/cgit/cgit.cgi'>Yocto Project Source Repositories</ulink>.
|
||||
</note>
|
||||
</para>
|
||||
@@ -643,31 +641,27 @@
|
||||
This section overviews the BSP description structure, the
|
||||
aggregation concepts, and presents a detailed example using
|
||||
a BSP supported by the Yocto Project (i.e. BeagleBone Board).
|
||||
For complete information on BSP layer file hierarchy, see the
|
||||
<ulink url='&YOCTO_DOCS_BSP_URL;'>Yocto Project Board Support
|
||||
Package (BSP) Developer's Guide</ulink>.
|
||||
</para>
|
||||
|
||||
<section id='bsp-description-file-overview'>
|
||||
<title>Overview</title>
|
||||
|
||||
<para>
|
||||
For simplicity, consider the following root BSP layer
|
||||
For simplicity, consider the following top-level BSP
|
||||
description files for the BeagleBone board.
|
||||
These files employ both a structure and naming convention
|
||||
for consistency.
|
||||
Top-level BSP descriptions files employ both a structure
|
||||
and naming convention for consistency.
|
||||
The naming convention for the file is as follows:
|
||||
<literallayout class='monospaced'>
|
||||
<replaceable>bsp_root_name</replaceable>-<replaceable>kernel_type</replaceable>.scc
|
||||
<replaceable>bsp_name</replaceable>-<replaceable>kernel_type</replaceable>.scc
|
||||
</literallayout>
|
||||
Here are some example root layer BSP filenames for the
|
||||
Here are some example top-level BSP filenames for the
|
||||
BeagleBone Board BSP, which is supported by the Yocto Project:
|
||||
<literallayout class='monospaced'>
|
||||
beaglebone-standard.scc
|
||||
beaglebone-preempt-rt.scc
|
||||
</literallayout>
|
||||
Each file uses the root name (i.e "beaglebone") BSP name
|
||||
followed by the kernel type.
|
||||
Each file uses the BSP name followed by the kernel type.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
</literallayout>
|
||||
<note>
|
||||
The previous commands assume the
|
||||
<ulink url='&YOCTO_DOCS_GS_URL;#source-repositories'>Source Repositories</ulink>
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#source-repositories'>Source Repositories</ulink>
|
||||
(i.e. <filename>poky</filename>) have been cloned
|
||||
using Git and the local repository is named
|
||||
"poky".
|
||||
@@ -136,7 +136,7 @@
|
||||
Developer's Guide, respectively.
|
||||
For information on how to use the
|
||||
<filename>bitbake-layers create-layer</filename>
|
||||
command to quickly set up a layer, see the
|
||||
command, see the
|
||||
"<ulink url='&YOCTO_DOCS_DEV_URL;#creating-a-general-layer-using-the-bitbake-layers-script'>Creating a General Layer Using the <filename>bitbake-layers</filename> Script</ulink>"
|
||||
section in the Yocto Project Development Tasks
|
||||
Manual.
|
||||
@@ -303,7 +303,7 @@
|
||||
</literallayout>
|
||||
<note>
|
||||
The previous commands assume the
|
||||
<ulink url='&YOCTO_DOCS_GS_URL;#source-repositories'>Source Repositories</ulink>
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#source-repositories'>Source Repositories</ulink>
|
||||
(i.e. <filename>poky</filename>) have been cloned
|
||||
using Git and the local repository is named
|
||||
"poky".
|
||||
@@ -360,7 +360,7 @@
|
||||
Developer's Guide, respectively.
|
||||
For information on how to use the
|
||||
<filename>bitbake-layers create-layer</filename>
|
||||
command to quickly set up a layer, see the
|
||||
command, see the
|
||||
"<ulink url='&YOCTO_DOCS_DEV_URL;#creating-a-general-layer-using-the-bitbake-layers-script'>Creating a General Layer Using the <filename>bitbake-layers</filename> Script</ulink>"
|
||||
section in the Yocto Project Development Tasks
|
||||
Manual.
|
||||
@@ -489,8 +489,7 @@
|
||||
See the
|
||||
"<ulink url='&YOCTO_DOCS_DEV_URL;#creating-a-general-layer-using-the-bitbake-layers-script'>Creating a General Layer Using the <filename>bitbake-layers</filename> Script</ulink>"
|
||||
section in the Yocto Project Development Tasks Manual for
|
||||
information on how to use this script to quick set up a
|
||||
new layer.
|
||||
information on how to use this script.
|
||||
</note>
|
||||
</para>
|
||||
|
||||
@@ -1225,6 +1224,18 @@
|
||||
the
|
||||
"<link linkend='getting-ready-for-traditional-kernel-development'>Getting Ready for Traditional Kernel Development</link>"
|
||||
Section.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Although this example uses Git and shell commands to generate the
|
||||
patch, you could use the <filename>yocto-kernel</filename> script
|
||||
found in the <ulink url='&YOCTO_DOCS_REF_URL;#source-directory'>Source Directory</ulink>
|
||||
under <filename>scripts</filename> to add and manage kernel
|
||||
patches and configuration.
|
||||
See the "<ulink url='&YOCTO_DOCS_BSP_URL;#managing-kernel-patches-and-config-items-with-yocto-kernel'>Managing kernel Patches and Config Items with yocto-kernel</ulink>"
|
||||
section in the Yocto Project Board Support Packages (BSP)
|
||||
Developer's Guide for more information on the
|
||||
<filename>yocto-kernel</filename> script.
|
||||
<orderedlist>
|
||||
<listitem><para>
|
||||
<emphasis>Edit the Source Files</emphasis>
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
<para>
|
||||
You can find a web interface to the Yocto Linux kernels in the
|
||||
<ulink url='&YOCTO_DOCS_GS_URL;#source-repositories'>Source Repositories</ulink>
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#source-repositories'>Source Repositories</ulink>
|
||||
at
|
||||
<ulink url='&YOCTO_GIT_URL;'></ulink>.
|
||||
If you look at the interface, you will see to the left a
|
||||
@@ -239,9 +239,8 @@
|
||||
<ulink url='http://git-scm.com/documentation'></ulink>.
|
||||
You can also get an introduction to Git as it
|
||||
applies to the Yocto Project in the
|
||||
"<ulink url='&YOCTO_DOCS_GS_URL;#git'>Git</ulink>"
|
||||
section in the Getting Started With Yocto Project
|
||||
Manual.
|
||||
"<ulink url='&YOCTO_DOCS_REF_URL;#git'>Git</ulink>"
|
||||
section in the Yocto Project Reference Manual.
|
||||
The latter reference provides an overview of
|
||||
Git and presents a minimal set of Git commands
|
||||
that allows you to be functional using Git.
|
||||
@@ -382,7 +381,7 @@
|
||||
generic kernel just for conceptual purposes.
|
||||
Also keep in mind that this structure represents the Yocto
|
||||
Project
|
||||
<ulink url='&YOCTO_DOCS_GS_URL;#source-repositories'>Source Repositories</ulink>
|
||||
<ulink url='&YOCTO_DOCS_REF_URL;#source-repositories'>Source Repositories</ulink>
|
||||
that are either pulled from during the build or established
|
||||
on the host development system prior to the build by either
|
||||
cloning a particular kernel's Git repository or by
|
||||
|
||||
@@ -127,6 +127,18 @@
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Finally, while this document focuses on the manual creation of
|
||||
recipes, patches, and configuration files, the Yocto Project
|
||||
Board Support Package (BSP) tools are available to automate
|
||||
this process with existing content and work well to create the
|
||||
initial framework and boilerplate code.
|
||||
For details on these tools, see the
|
||||
"<ulink url='&YOCTO_DOCS_BSP_URL;#using-the-yocto-projects-bsp-tools'>Using the Yocto Project's BSP Tools</ulink>"
|
||||
section in the Yocto Project Board Support Package (BSP) Developer's
|
||||
Guide.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id='kernel-modification-workflow'>
|
||||
@@ -231,7 +243,11 @@
|
||||
|
||||
<para>Additionally, if you are working in a BSP layer
|
||||
and need to modify the BSP's kernel's configuration,
|
||||
you can use <filename>menuconfig</filename>.
|
||||
you can use the
|
||||
<ulink url='&YOCTO_DOCS_BSP_URL;#managing-kernel-patches-and-config-items-with-yocto-kernel'><filename>yocto-kernel</filename></ulink>
|
||||
script as well as <filename>menuconfig</filename>.
|
||||
The <filename>yocto-kernel</filename> script lets
|
||||
you interactively set up kernel configurations.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<emphasis>Rebuild the Kernel Image With Your Changes:</emphasis>
|
||||
|
||||
@@ -120,11 +120,11 @@
|
||||
(or tree) found at
|
||||
<ulink url='&YOCTO_GIT_URL;/cgit.cgi'></ulink> given the
|
||||
introduction of a new top-level kernel feature or BSP.
|
||||
The following actions effectively provide the Metadata
|
||||
and create the tree that includes the new feature, patch, or BSP:
|
||||
These are the actions that effectively provide the Metadata
|
||||
and create the tree that includes the new feature, patch or BSP:
|
||||
<orderedlist>
|
||||
<listitem><para>
|
||||
<emphasis>Pass Feature to the OpenEmbedded Build System:</emphasis>
|
||||
<emphasis>Pass Feature to Build Subsystem:</emphasis>
|
||||
A top-level kernel feature is passed to the kernel build
|
||||
subsystem.
|
||||
Normally, this feature is a BSP for a particular kernel
|
||||
@@ -138,10 +138,8 @@
|
||||
<listitem><para>
|
||||
The in-tree kernel-cache directories, which are
|
||||
located in the
|
||||
<ulink url='&YOCTO_GIT_URL;/cgit/cgit.cgi/yocto-kernel-cache/tree/bsp'><filename>yocto-kernel-cache</filename></ulink>
|
||||
repository organized under the "Yocto Linux Kernel"
|
||||
heading in the
|
||||
<ulink url='http://git.yoctoproject.org/cgit/cgit.cgi'>Yocto Project Source Repositories</ulink>.
|
||||
<filename>yocto-kernel-cache</filename>
|
||||
repository
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Areas pointed to by <filename>SRC_URI</filename>
|
||||
@@ -150,11 +148,9 @@
|
||||
</itemizedlist>
|
||||
For a typical build, the target of the search is a
|
||||
feature description in an <filename>.scc</filename> file
|
||||
whose name follows this format (e.g.
|
||||
<filename>beaglebone-standard.scc</filename> and
|
||||
<filename>beaglebone-preempt-rt.scc</filename>):
|
||||
whose name follows this format:
|
||||
<literallayout class='monospaced'>
|
||||
<replaceable>bsp_root_name</replaceable>-<replaceable>kernel_type</replaceable>.scc
|
||||
<replaceable>bsp_name</replaceable>-<replaceable>kernel_type</replaceable>.scc
|
||||
</literallayout>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
|
||||
@@ -86,11 +86,6 @@
|
||||
<date>October 2017</date>
|
||||
<revremark>Released with the Yocto Project 2.4 Release.</revremark>
|
||||
</revision>
|
||||
<revision>
|
||||
<revnumber>2.5</revnumber>
|
||||
<date>April 2018</date>
|
||||
<revremark>Released with the Yocto Project 2.5 Release.</revremark>
|
||||
</revision>
|
||||
</revhistory>
|
||||
|
||||
<copyright>
|
||||
|
||||
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 226 KiB |
|
Before Width: | Height: | Size: 13 KiB |