Difference between SRC_URI and FILESEXTRAPATHS_prepend in bitbake - yocto

Why do we need to give path of files in SRC_URI even though we are including the files path in FILESEXTRAPATHS_prepend variable? For example:
SUMMARY = "Simple Hello application"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
SRC_URI = "file://Hello_1.c \
file://Hello_2.c \
"
do_compile() {
oe_runmake
}
do_install() {
install -d ${D}${bindir}
install -m 0755 Hello ${D}${bindir}
}
In the "files" folder I have two files: hello1.c and hello2.c. When I remove SRC_URI it outputs the following error,
ERROR: Hello-1.0-r0 do_compile: oe_runmake failed
But if I remove
FILESEXTRAPATHS_prepend it is working fine.
What is the purpose of the variable FILESEXTRAPATHS_prepend?
Why error occurs when I remove SRC_URI even though I'm including my files path in FILESEXTRAPATHS_prepend?

Simple way let assume meta-layer/recipes-core/example
In above path created hello and hello.bb
Here hello is a directory having your source and other data and hello.bb is recipe.
Now
SRC_URI : The SRC_URI variable always checks the data in hello dir only.
FILESEXTRAPATHS_prepend := "${THISDIR}:" : if you add this line in your recipe, then the SRC_URI variable checks the data in present directory where the hello.bb file present.
In your case
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
The SRC_URI variable checks the data in files dir where the hello.bb is present.
Note: Most of the time people will use this FILESEXTRAPATHS variable in .bbappend files to apply patches and other files to the recipe.
For every .bb file, the SRC_URI variable is used to specify which files to fetch the source from - either from
an online repository or a local one, and the FILESEXTRAPATHS specifies where these files are looked for, and depends on your source
path.

BitBake uses the SRC_URI variable to point to source files
regardless of their location. Each recipe must have a SRC_URI
variable that points to the source.
SRC_URI = file:// Fetches files, which are usually files shipped
with the Metadata, from the local machine. The path is relative to the
FILESPATH variable. Thus, the build system searches, in order, from
the following directories, which are assumed to be a subdirectories of
the directory in which the recipe file (.bb) or append file
(.bbappend) resides:
FILESPATH: The default set of directories the OpenEmbedded build
system uses when searching for patches and files. During the build
process, BitBake searches each directory in FILESPATH in the specified
order when looking for files and patches specified by each file:// URI
in a recipe.
The default value for the FILESPATH variable is defined in the
base.bbclass class found in meta/classes in the Source Directory:
FILESPATH = "${#base_set_filespath(["${FILE_DIRNAME}/${BP}", \
"${FILE_DIRNAME}/${BPN}", "${FILE_DIRNAME}/files"], d)}"
Do not hand-edit the FILESPATH variable; The
default directories BitBake uses when it processes recipes are
initially defined by the FILESPATH variable. You can extend FILESPATH
variable by using FILESEXTRAPATHS.
> Best practices dictate that you accomplish this by using
FILESEXTRAPATHS from within a .bbappend file
FILESEXTRAPATHS: Extends the search path the OpenEmbedded build system
uses when looking for files and patches as it processes recipes and
append files. The default directories BitBake uses when it processes
recipes are initially defined by the FILESPATH variable.
If you want the build system to pick up files specified through a
SRC_URI statement from your append file, you need to be sure to extend
the FILESPATH variable by also using the FILESEXTRAPATHS variable from
within your append file.
http://www.yoctoproject.org/docs/2.1/ref-manual/ref-manual.html#var-FILESPATH
Back to your error, since each recipe MUST have a SRC_URI; it will not work if you delete it;
Since your recipe is not an .bbappend, adding FILESEXTRAPATHS is not appropriate and not necessary.

Related

how to get ${THISDIR} inside do_unpack_append in .bbappend file

I'm attempting to replace a file from another layer with a .bbappend file. My goal is to overwrite a specific configuration file with a customized one during the unpack stage.
In my .bbappend I'm attempting to append the do_unpack to copy a file from the same directory as the .bbappend file into the working directory ${WORKDIR} The problem is: When inside do_unpack_append, ${THISDIR} is returning the directory of the original .bb recipe, rather than the directory of .bbappend
Here's an example:
The original recipe resides in: meta-origLayer/recipe.bb
My *.bbappend resides in: meta-newLayer/recipe.bbappend
recipe.bbappend:
`FILESEXTRAPATHS_prepend := "${THISDIR}:"`
do_unpack_append(){
bb.build.exec_func('replace_file', d)
}
replace_file(){
cp -f ${THISDIR}/fileToBeReplaced ${WORKDIR}/fileToBeReplaced
echo ${THISDIR} > ${WORKDIR}/shouldContain_meta-newLayer
}
There are two issues with recipe.bbappend:
I would expect the file shouldContain_meta-newLayer to contain meta-newLayer, but instead it contains meta-origLayer.
I'd primarily like to understand why ${THISDIR} behaves differently when placed inside do_unpack_append() from when it is used for prepending FILESEXTRAPATHS
When running bitbake, the recipe fails, producing the following error:
cp: cannot stat '/fileToBeReplaced': No such file or directory
This error occurs because fileToBeReplaced resides in a subdirectory of meta-origLayer (i.e. meta-origLayer/machine1/fileToBeReplaced) and the .bbappend expects to find the file in /fileToBeReplaced
My Question. . .
I have assumed ${THISDIR} would behave consistently within the same .bbappend, but it doesn't appear to. What is the best way to reference meta-newLayer/fileToBeReplaced from within do_unpack_append()?
This *.bbappend correctly overwrites fileToBeReplaced in the working directory during the unpack task:
FILESEXTRAPATHS_prepend := "${THISDIR}:"
SRC_URI_append += " file://fileToBeReplaced "
SAVED_DIR := "${THISDIR}"
do_unpack_append(){
bb.build.exec_func('replace_file', d)
}
replace_file(){
cp -f ${SAVED_DIR}/fileToBeReplaced ${WORKDIR}/fileToBeReplaced
}
Thanks for the explanation between bbappend parsing and execution johannes-schaub-ltb

Stripping base path off the unpacked source tree with bitbake SRC_URI file:// fetcher

The manual here says that there is a basepath option to SRC_URI that should "strip the specified directories from the source path when unpacking".
I'm trying to fetch the sources from a local directory, say /src/someproject.
For that purpose I configured my recipe as follows:
SRC_URI="file:///src/someproject;subdir=source;basepath=/src/someproject"
The intention was to have the sources taken from /src/someproject directory and put into build/tmp/work/target/someproject/1.0-r1/source/. Instead, I'm getting the sources under build/tmp/work/target/someproject/1.0-r1/source/src/someproject.
Is there a way to get rid of /src/someproject subdirectory inside source ?
The documentation you point to is for yocto 1.6, release April 2014. The basepath parameter appears to have been removed in later releases, with no fanfare and no apparent replacement.
Instead you can do something like:
SRCDIR = "/path/to/your/files"
SRC_URI = "file://${SRCDIR}/contents/;subdir=src"
S = "${WORKDIR}/src"
Then you can access your files under ${S}/${SRCDIR}.
If you find using the ${SRCDIR} part too cumbersome, you can hook onto the do_patch target, which need the prefunc mechanism and not _prepend if you want to use shell scripting, as do_patch is otherwise written in python:
relocate_source() {
mv ${S}/${SRCDIR}/* ${S}/
rmdir ${S}/${SRCDIR}
}
do_patch[prefunc] += "relocate_source"
This will reorganise your source before applying any patch you can add to SRC_URI.
Also note that a file:// URI does not get cached in ${DL_DIR}, so there is no name-conflict to handle (the way we would need to use downloadfilename= in an http:// URI).

Yocto: Install different config files based on MACHINE type or target image

I've got a couple of HW platforms (same cpu, etc.) that require different asound.conf files.
The way that I'm controlling the target platform is via the MACHINE variable and target image (i.e., MACHINE=machine_1 nice bitbake machine-1-bringup-image)
Normally, if just replacing the conf file I'd just create an alsa-state.bbappend and create a do_install_append function to replace it.
However since the different HW platforms require differ conf files I'm unsure how to handle it.
I've tried putting some logic into the append file do_install_append function but it's not working out. It's not always picking up the correct file (like it thinks that nothing has changed so that it uses the previous cached conf?)
Here's an example of one of the append files that I've tried:
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
SRC_URI += " \ file://asound_MACHINE1.conf \
file://asound_MACHINE2.conf \ "
do_install_append() {
echo " alsa-state.bbappend MACHINE: ${MACHINE}"
if [ "${MACHINE}" = "machine_1" ]; then
echo " machine_1"
echo " installing ${WORKDIR}/asound_MACHINE1.conf to ${D}${sysconfdir}/asound.conf"
install -m 644 ${WORKDIR}/asound_MACHINE1.conf {D}${sysconfdir}/asound.conf
else
echo " installing ${WORKDIR}/asound_MACHINE2.conf to ${D}${sysconfdir}/asound.conf"
install -m 644 ${WORKDIR}/asound_MACHINE2.conf ${D}${sysconfdir}/asound.conf
fi
}
I can see the correct echoes in the logs per the logic.
At any rate I don't think that the path I'm going down is the best way to deal with this.
Is there a 'standard' way to have different files installed based on either the target image or MACHINE variable?
do_install_append () {
// install common things here
}
do_install_append_machine-1 () {
// install machine-1 specific things here
}
do_install_append_machine-2 () {
// install machine-2 specific things here
}
The value of MACHINE is automatically added to OVERRIDES, which can be used at the end of a function append to have a MACHINE-specific addition to a function.
Maybe useful: https://www.yoctoproject.org/docs/2.4/mega-manual/mega-manual.html#var-OVERRIDES
You can have configuration files in machine specific directories in your particular case (just a specific configuration file for each machine). OpenEmbedded will fetch the most specific one. The directory structure in your recipe directory will look like:
files/<machine1>/asound.conf
files/<machine2>/asound.conf
And your alsa-state.bbappend will contain just one line (you don't need to change do_install because alsa-state.bb already installs asound.conf):
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
BTW: We are using that setup to have specific asound.state file per machine in our project.
Moreover, OpenEmbedded will detect that SRC_URI contains machine specific file and change the PACKAGE_ARCH accordingly, see: https://www.yoctoproject.org/docs/2.5/mega-manual/mega-manual.html#var-SRC_URI_OVERRIDES_PACKAGE_ARCH
Few more words on machine, distro or arch specific files: OE is trying to fetch the most specific file in file:// fetcher. It searches also in the directories named by distro (e.g files/<distro>/asound.conf) and architecture (e.g. armv7a, arm). It might be useful if you want to have file specific for some set of devices. More information: https://www.yoctoproject.org/docs/2.5/mega-manual/mega-manual.html#var-FILESOVERRIDES and also https://www.yoctoproject.org/docs/2.5/mega-manual/mega-manual.html#best-practices-to-follow-when-creating-layers (section "Place Machine-Specific Files in Machine-Specific Locations")
The above answer by clsulliv worked better than advertised. For future reference below is the append file I used:
FILESEXTRAPATHS_prepend:= "${THISDIR}/${PN}:"
SRC_URI += " \
file://machine1_asound.conf \
file://machine2_asound.conf \
"
do_install_append_machine1() {
echo " machine1"
echo " installing ${WORKDIR}/machine1_asound.conf to ${D}${sysconfdir}/asound.conf"
install -m 644 ${WORKDIR}/machine1_asound.conf ${D}${sysconfdir}/asound.conf
}
do_install_append_machine2() {
echo " machine2"
echo " installing ${WORKDIR}/machine2_asound.conf to ${D}${sysconfdir}/asound.conf"
install -m 644 ${WORKDIR}/machine2_asound.conf ${D}${sysconfdir}/asound.conf
}
Thanks for the help!

How do I add script files to a Raspberry Pi filesystem using a custom Yocto recipe?

I have a working Yocto image for a RaspberryPi3. I want to add 3 script files /etc/ppp/peers/. I would have thought that adding non-compiled files to the root file-system was a fairly generic thing to do but the only examples I can find are using compiled files and inheriting the autotools recipe.
Is there an example of how to add text files or script files to a Yocto root filesystem this somewhere?
Either a How To write up or an existing recipe that takes a set of text files and places them onto the target's rootfs.
I must be missing something because I cannot get the file files onto the system.
I tried using do_deploy, but that puts files into my ../tmp/deploy/images/raspberrypi3/etc/ppp/ which would be helpful for scripts to aid in image deployment. It is not what I want though as the scripts need to be on the target.
Running a do_install() with or without a blank do_compile() has not resulted in things getting onto the target either. Unless there is something about using ${sysconfdir} or ${IMAGE_ROOTFS} or ${S} or ${D} or ${DEPLOYDIR} or ${WORKDIR} which is particular to the Pi. I'd provide an example of my script but having changed it so many times in the last two days there is not much worth of sharing just one iteration.
Anything that resembles the following with;
${IMAGE_ROOTFS} possibly substituted for ${D} or missing
do_install replaced with do_deploy.
There are probably other permutations that I have tried.
#
# Copy the ppp script files for <vendor> chips to the target filesystem
# These files are based on the details provided in
#
SUMMARY = "PPP Scripts for ..."
SECTION = "net"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
DESCRIPTION = "A set of Linux PPP scripts blar blar"
RDEPENDS_${PN} = "ppp"
SRC_URI += "file://<provider>-ppp"
SRC_URI += "file://<provider>-chat-connect"
SRC_URI += "file://<provider>-chat-disconnect"
S = "${WORKDIR}"
#PACKAGES =+ "${PN} ${PN}-staticdev"
#DEPLOYDIR = "${WORKDIR}/deploy-${PN}"
#D = "${DEPLOYDIR}"
inherit allarch
# Install script on target's root file-system
do_install () {
# Install init script and default settings
install -d ${IMAGE_ROOTFS}${sysconfdir}
install -d ${IMAGE_ROOTFS}${sysconfdir}/ppp/
install -d ${IMAGE_ROOTFS}${sysconfdir}/ppp/peers/
install -m 0755 ${S}/<provider>-ppp ${IMAGE_ROOTFS}${sysconfdir}/ppp/peers/
install -m 0755 ${S}/<provider>-chat-connect ${IMAGE_ROOTFS}${sysconfdir}/ppp/peers/
install -m 0755 ${S}/<provider>-chat-disconnect ${IMAGE_ROOTFS}${sysconfdir}/ppp/peers/
}
# Mark the files which are part of this package
FILES_${PN} += "${sysconfdir}/ppp/"
FILES_${PN} += "${sysconfdir}/ppp/peers/"
FILES_${PN} += "${sysconfdir}/ppp/peers/<provider>-ppp"
FILES_${PN} += "${sysconfdir}/ppp/peers/<provider>-chat-connect"
FILES_${PN} += "${sysconfdir}/ppp/peers/<provider>-chat-disconnect"
I can find a lot of helloworld.c and automate examples. There must be some basic ones for adding scripts somewhere? My googlefu is very weak, I blame a lingering cold.
You should be using install -m 0755 ${WORKDIR}/<provider>-ppp ${D}${sysconfdir}/ppp/peer in your recipe. Have you added the resulting package to your image recipe? You could look at ${WORKDIR}/packages-split/${PN} to confirm that your files have been properly packaged.

bitbake recipe - doing a simple copy of the image

I am attempting to write a recipe that would simple copy two files (MyfileA , MyfileB) to a specific directory when the overall image is built. This is what my directory structure looks like:
MyDir/MyRecipe.bb
MyDir/files/MyfileA
MyDir/files/MyfileB
I would like the two files to be copied to a folder in home (which would not exist initially hence the directories should be created)The folder lets say is called "Testfolder"
This is what my bitbake file looks like
DESCRIPTION = "Testing Bitbake file"
PR = "r0"
SRC_URI = "file://MyfileA \
file://MyfileB "
do_install() {
install -d MyfileA ~/TestFolder/
}
Kindly let me know if I am doing something wrong here?
When i run bitbake on this I get the following
The BBPATH variable is not set and bitbake did not find a conf/bblayers.conf file in the expected location.
Maybe you accidentally invoked bitbake from the wrong directory?
DEBUG: Removed the following variables from the environment: LANG, LS_COLORS, LESSCLOSE, XDG_RUNTIME_DIR, SHLVL, SSH_TTY, OLDPWD, LESSOPEN, SSH_CLIENT, MAIL, SSH_CONNECTION, XDG_SESSION_ID, _, BUILDDIR
Any help in this regard would be appreciated.
First of all, to create your own meta-layer, you should run command yocto-layer create MyRecipe in your Yocto Environment. This is to make sure that you have all the necessary element in your meta layer. Make sure to put the new meta-layer into conf/bblayers.conf
Creating HelloWorld Recipe Video can be found here
Second, to copy a file from one to another directories.
DESCRIPTION = "Testing Bitbake file"
SECTION = "TESTING"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
PR = "r0"
SRC_URI = "file://MyfileA \
file://MyfileB "
#specify where to get the files
S = "${WORKDIR}"
inherit allarch
#create the folder in target machine
#${D} is the directory of the target machine
#move the file from working directory to the target machine
do_install() {
install -d ${D}/TestFolder
install -m ${WORKDIR}/MyfileA ${D}/TestFolder
}
To get more in details, this is my understanding of how the files move around in Yocto.
You have a directory that stored metadata in /sourced/meta-mylayer/recipes-myRecipe/. In that directory, there would be a folder with the same name as the recipe. I.E. myRecipe/ myRecipe_001.bb.
You would store the files that are related to myRecipe.bb (usually it is a patch) in myRecipe/ so that SRC_URI will get into that myRecipe/ directory to grab files. I.E. myFileA, myFileB
Then, you specify the S. This is the location in the Build Directory where unpacked recipe source code resides. By that mean, myFileA and myFileB are moved/copied to there when myRecipe builds.
Usually, S is equal to ${WORKDIR}, this is equivalent to ${TMPDIR}/work/${MULTIMACH_TARGET_SYS}/${PN}/${EXTENDPE}${PV}-${PR}
The actual directory depends on several things:
TMPDIR: The top-level build output directory
MULTIMACH_TARGET_SYS: The target system identifier
PN: The recipe name
EXTENDPE: The epoch - (if PE is not specified, which is usually the case for most recipes, then EXTENDPE is blank)
PV: The recipe version
PR: The recipe revision
After that, we inherit allarch. This class is used for architecture independent recipes/data files (usually scripts).
Then, the last thing we have to do is copy the files.
${D} is the location in the Build Directory where components are installed by do_install task. This location defaults to ${WORKDIR}/image
${WORKDIR}/image can also be described as the / directory in the target system.
Go to ${D} directory and create a folder call TestFolder
Then, copy myFileA from ${WORKDIR} to the ${D}/TestFolder
P.S. Please add comment to fix. There might be mistaken information here, cause I learned all this by myself.