I wrote a basic hello world recipe
DESCRIPTION = "Simple helloworld C application"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://userprog.c file://ReadMe.txt"
S = "${WORKDIR}"
do_compile() {
${CC} -DUSE_SYSCALL userprog.c ${LDFLAGS} -o userprog
}
do_install() {
install -d ${D}${bindir}
install -m 0755 userprog ${D}${bindir}
install -d ${D}${docdir}
install -m 0644 ReadMe.txt ${D}${docdir}
}
After, looking at the WORKDIR, the contents of 'package' and 'image' folder are same.
$ tree image/
image/
└── usr
├── bin
│ └── userprog
└── share
└── doc
└── ReadMe.txt
$ tree package
package
└── usr
├── bin
│ └── userprog
└── share
└── doc
└── ReadMe.txt
What is the difference between both folders, I know image folder is controlled in do_install task, what about in package folder?
images/ is for staging install dir, something like make install DESTDIR=<..>
package is for do_package task which is then further split into individual output packages in packages-split,
even though the content looks similar context is different, since it operates on PACKAGES and FILES variables, and if the files are not mentioned in these variables it won't copy those from image/ into package/ it is described in detail in Yocto project manual
Related
I have trouble creating a package with setuptools. I have a repository which I'm cleaning up to make it a package. The directory structure looks something like this
my-proj
├── setup.py
├── MANIFEST.in
├── MakeFile
├── README.rst
├── setup.py
└── myproj
├── __init__.py
├── my_code.py
├── templates
│ ├── template1.yaml
│ ├── template2.yaml
Initial version of "my_code.py" had code snippet which would directly reference the files withing templates folder to do some processing. If I package this using setup tools, I provide the following information in these files:
MANIFEST.in:
include README.rst
include requirements.txt
include LICENSE.txt
recursive-include myproj/templates *
setup.py:
setup(
name='myproj',
package_dir={'testbed_init': 'testbed_init'},
package_data={'templates': ['templates/*'], 'configs': ['configs/*']},
include_package_data=True,
)
My question is as follows. In "my_Code.py" I used to reference templates directly without any problem as I would run script from the myproj folder. If I package this, how can I make sure, I include the templates as part of package and when script runs, I need to open the templates relative to where the package is installed.
Code snippet from my_code.py:
if _type == "a":
temp_file = f"templates/template1.yaml"
else:
temp_file = f"templates/template2.yaml"
build_config(deploy_esx_file, output_file, data)
Code snippet of what happens in build_config:
def build_config(template_file, output_file, inputs):
templateLoader = jinja2.FileSystemLoader(searchpath="./")
templateEnv = jinja2.Environment(loader=templateLoader)
template = templateEnv.get_template(template_file)
outputText = template.render(inputs)
with open(output_file, 'w') as h:
h.write(outputText)
I am trying to copy two folders(containing some scripts) in my target rootfs. I have created a custom layer and a custom recipe inside it.
My directory structure is like this:
../sources/meta-company/recipes-bla_2.06/
└── bla
├── bla
│ ├── dir1
│ │ ├── dir
│ │ │ └── files.sh
│ └── dir2
│ ├── dir
│ │ ├── files.sql
│ ├── test.sh
└── bla_2.06.bb
My .bb file is as follows:
DESCRIPTION = " bla "
LICENSE = "CLOSED"
SRC_URI = "file://dir1/ \
file://dir2/ "
do_install() {
install -d ${D}/root/dir1
install -d ${D}/root/dir2
cp -r --no-dereference --preserve=mode,links -v ${S}/dir1/ ${D}/root/dir1
cp -r --no-dereference --preserve=mode,links -v ${S}/dir2/ ${D}/root/dir2/
}
FILE_$PN = "/root/"
The error I am getting:
> Log data follows: | DEBUG: Executing shell function do_install | cp:
> cannot stat
> '/home/amol/test/fsl-arm-yocto-bsp/build-cl-som-imx7-fsl-imx-x11/tmp/work/cortexa7hf-neon-poky-linux-gnueabi/bla/1.0-r0/bla-1.0/dir1':
> No such file or directory | WARNING: exit code 1 from a shell command.
> | ERROR: Function failed: do_install (log file is located at
> /home/amol/test/fsl-arm-yocto-bsp/build-cl-som-imx7-fsl-imx-x11/tmp/work/cortexa7hf-neon-poky-linux-gnueabi/seriald/1.0-r0/temp/log.do_install.49808)
> NOTE: recipe bla-1.0-r0: task do_install: Failed NOTE: Tasks Summary:
> Attempted 334 tasks of which 333 didn't need to be rerun and 1 failed.
I am new to yocto, is my .bb file correct?.Thanks in advance.
There are two problems in your do_install section,
${S} points to source directory, but SRC_URI copies your content in ${WORKDIR}. So you should be using ${WORKSIR} in your install section
You are trying to copy ${S}/dir1/ inside ${D}/root/dir1, this means your final structure is /root/dir1/dir1/. You may not want this.
So the modified version would look like,
do_install() {
install -d ${D}/root/dir1
install -d ${D}/root/dir2
cp -r --no-dereference --preserve=mode,links -v ${WORKDIR}/dir1/* ${D}/root/dir1/
cp -r --no-dereference --preserve=mode,links -v ${WORKDIR}/dir2/* ${D}/root/dir2/
}
Hi this is my layer tree
├── conf
│ └── layer.conf
├── COPYING.MIT
├── README
└── recipes-hello
├── helloworld
│ ├── helloworld-0.1
│ │ ├── helloworld.c
│ │ ├── helloworld.patch
│ │ └── newhelloworld.c
│ └── helloworld_0.1.bb
├── message
│ ├── message-0.1
│ │ └── message.txt
│ └── message_0.1.bb
└── service
├── service-0.1
│ ├── test_systemd.service
│ └── test_systemd.sh
└── service_0.1.bb
Here test_systemd.service is the service file which have to invoke test_systemd.sh, which I am trying to achieve using service_0.1.bb
# This recipe performs the following tasks
# 1) Install .sh file in /home/root/ and .sh script creates a random text file
# 2) Install the .service file in systemd directory
# 3) Invoke the .sh script via .service file
inherit systemd
SUMMARY = "Install and start a systemd service"
SECTION = "examples"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
#here we specify the source we want to build
SRC_URI = "file://test_systemd.sh"
SRC_URI += "file://test_systemd.service"
#here we specify the source directory, where we can do all the building and expect sources to be placed
S = "${WORKDIR}"
SYSTEMD_SERVICE_${PN} = "test_systemd.service"
#bitbake task
#created a directory /home/root for target install the script
do_install() {
install -d ${D}/home/root
install -m 0755 ${WORKDIR}/test_systemd.sh ${D}/home/root
install -d ${D}{systemd_system_unitdir}
install -m 0644 ${WORKDIR}/test_systemd.service ${D}{systemd_system_unitdir}
}
#Pack the path
FILES_${PN} += "/home/root"
FILES_${PN} += "/lib/systemd/system"
REQUIRED_DISTRO_FEATURES= "systemd"
The problem is when I try to bitbake system recipe, bitbake throws an error saying test_systemd.service not found.
I managed to install both the files in RFS with a previous attempt but when I include the systemd concept. I get the no such file error. What could be the reason ?
Error message
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
ERROR: service-0.1-r0 do_package: SYSTEMD_SERVICE_service value test_systemd.service does not exist
ERROR: service-0.1-r0 do_package: Function failed: systemd_populate_packages
ERROR: Logfile of failure stored in: /home/guest/yocto_practice/poky/build-beaglebone/tmp/work/cortexa8hf-neon-poky-linux-gnueabi/service/0.1-r0/temp/log.do_package.2860
ERROR: Task (/home/guest/yocto_practice/meta-testlayer/recipes-hello/service/service_0.1.bb:do_package) failed with exit code '1'
NOTE: Tasks Summary: Attempted 514 tasks of which 506 didn't need to be rerun and 1 failed.
Summary: 1 task failed:
/home/guest/yocto_practice/meta-testlayer/recipes-hello/service/service_0.1.bb:do_package
Summary: There were 2 ERROR messages shown, returning a non-zero exit code.
Also is this the correct way to write bb recipe for systemd and what is the significance of writing this
#Pack the path
FILES_${PN} += "/home/root"
FILES_${PN} += "/lib/systemd/system"
without this bitbake throws error.
SYSTEMD_SERVICE_${PN} += "file://test_systemd.service"
This should be:
SYSTEMD_SERVICE_${PN} = "test_systemd.service"
Other notes (unrelated to the error):
Installing things into /home is probably not a great idea (you could use e.g. ${libexecdir} for scripts that other scripts need.
there's no reason for having a do_install_append() in a bb file: you can just put everything in do_install()
If your Yocto is recent, using ${systemd_system_unitdir} instead of /lib/systemd/system is a good idea (in older releases ${systemd_unitdir}/system/ works)
In order to resolve this packaging error, I used the following install step
do_install() {
install -d ${D}${bindir}
install -m 0755 ${WORKDIR}/test_systemd.sh ${D}${bindir}
install -d ${D}${systemd_unitdir}/system
install -m 0644 ${WORKDIR}/test_systemd.service ${D}${systemd_unitdir}/system
}
I have a package (openssl) that must be built for the host and the target. It creates some .so and .a libraries that some other packages need for runtime and compilation time respectively.
When I compile this package for the target everything works fine and every file ends up in the place I tell it to go, but when I compile for the host (${PN}-native target) it just doesn't put the libraries in the host sysroot directory (./build/tmp/sysroot/x86_64-linux).
This is the recipe:
SUMMARY = "Secure Socket Layer"
SECTION = "libs/network"
LICENSE = "openssl"
LIC_FILES_CHKSUM = "file://LICENSE;md5=4004583eb8fb7f89"
branch = "yocto"
SRC_URI = "git://www.myserver.com/openssl.git;protocol=ssh;branch=${branch}"
SRCREV = "${AUTOREV}"
S = "${WORKDIR}/git"
BBCLASSEXTEND += "native nativesdk"
# This is because I am porting this package from other project and I can't modify it.
FILES_${PN} += "${libdir}/libssl.so ${base_libdir}/libcrypto.so"
FILES_SOLIBSDEV = ""
do_compile() {
${MAKE}
}
do_install() {
DESTDIR=${D} ${MAKE} install
}
Could anyone let me know what I am doing wrong? Thanks in advance
First, why are you writing your own recipe for openssl instead of using the one in oe-core?
Anyway the problem is that at no point do you tell the recipe what prefix to use. In native builds the prefix is what relocates the package correctly into the native sysroot.
Ok, I know what the problem is:
It seems like for native recipes, you have to install it using the full path to your host sysroot inside the image folder. This means that when compiling for the target, the image folder looks like this:
$ tree -d
/openssl/1.0.0-r0/image
├── lib
└── usr
├── include
│ └── openssl
└── lib
but for the host, it looks like this in my case:
$ tree -d
openssl-native/1.0.0-r0/image
└── home
└── xnor
└── yocto
└── build
└── tmp
└── sysroots
└── x86_64-linux
├── lib
└── usr
├── include
│ └── openssl
└── lib
EDIT
The right solution is to modify the Makefile to take ${prefix}, ${bindir}, ${libdir}, etc. from the environment instead of hardcoding those paths in the Makefile. In my case this is not possible because of the project requirements, so I have to do this:
SUMMARY = "Secure Socket Layer"
SECTION = "libs/network"
LICENSE = "openssl"
LIC_FILES_CHKSUM = "file://LICENSE;md5=4004583eb8fb7f89"
branch = "yocto"
SRC_URI = "git://www.myserver.com/openssl.git;protocol=ssh;branch=${branch}"
SRCREV = "${AUTOREV}"
S = "${WORKDIR}/git"
BBCLASSEXTEND += "native nativesdk"
# This is because I am porting this package from other project and I can't modify it.
FILES_${PN} += "${libdir}/libssl.so ${base_libdir}/libcrypto.so"
FILES_SOLIBSDEV = ""
do_compile() {
${MAKE}
}
do_install() {
# The change is here!
DESTDIR=${D}${base_prefix} ${MAKE} install
}
and as you can imagine, ${base_prefix} expands to "/home/xnor/yocto/build/tmp/sysroots/x86_64-linux/" for the host (openssl-native) recipe and to "" for the target (openssl).
I am having a weird RPM issue, I am new to it so bear with me... I have the spec file created and when I run to do the build I get an error:
/var/tmp/rpm-tmp.ajKra4: line 36: cd: hero-01: No such file or directory
error: Bad exit status from /var/tmp/rpm-tmp.ajKra4 (%prep)
Then I check that temp file and it is trying to CD to a directory that does not exist.. Should it be creating this in the spec file? if so where?
Here is my spec file:
Summary: Install Hero
Name: hero
Version: 01
Release: 1
Group: Billing reporting
Source: %{name}-%{version}.tar.gz
License: SLA
%description
Hero billing reports system
%prep
rm -rf %{_topdir}/BUILD/*
%setup
%install
mkdir -p /opt/%{name}
cp -r * /opt/%{name}
%post
find /opt/%{name} -type d -exec chmod 755 {} \;
find /opt/%{name} -type f -exec chmod 644 {} \;
chmod -R 755 /opt/%{name}/bin
%files
/opt/%{name}
%defattr(-,root,root,0755)
%clean
rm -rf $RPM_BUILD_ROOT
%postun
rm -rf /opt/%{name}
Perhaps I am missing something? Would not be the first lol, thanks
Here is also what that tmp file is outputting:
#!/bin/sh
RPM_SOURCE_DIR="/root/rpmbuild/SOURCES"
RPM_BUILD_DIR="/root/rpmbuild/BUILD"
RPM_OPT_FLAGS="-O2 -g"
RPM_ARCH="x86_64"
RPM_OS="linux"
export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS
RPM_DOC_DIR="/usr/share/doc"
export RPM_DOC_DIR
RPM_PACKAGE_NAME="hero"
RPM_PACKAGE_VERSION="01"
RPM_PACKAGE_RELEASE="1"
export RPM_PACKAGE_NAME RPM_PACKAGE_VERSION RPM_PACKAGE_RELEASE
LANG=C
export LANG
unset CDPATH DISPLAY ||:
RPM_BUILD_ROOT="/root/rpmbuild/BUILDROOT/hero-01-1.x86_64"
export RPM_BUILD_ROOT
PKG_CONFIG_PATH="/usr/lib64/pkgconfig:/usr/share/pkgconfig"
export PKG_CONFIG_PATH
set -x
umask 022
cd "/root/rpmbuild/BUILD"
rm -rf /root/rpmbuild/BUILD/*
cd '/root/rpmbuild/BUILD'
rm -rf 'hero-01'
/usr/bin/gzip -dc '/root/rpmbuild/SOURCES/hero-01.tar.gz' | /bin/tar -xvvf -
STATUS=$?
if [ $STATUS -ne 0 ]; then
exit $STATUS
fi
cd 'hero-01'
/bin/chmod -Rf a+rX,u+w,g-w,o-w .
exit 0
Check out http://www.rpm.org/max-rpm/s1-rpm-inside-macros.html, specifically the "-n — Set Name of Build Directory" section.
The %setup macro is expecting that after untaring the tar.gz, there will be a hero-01 directory available, but your hero-01.tar.gz probably creates some other directory name, probably one without the version included in the name.
So, for example, if there's a 'hero' directory instead of a 'hero-01' directory in /root/rpmbuild/BUILD after the untarring, then update the spec file to use '%setup -n hero' instead of just '%setup'.
Also noteworthy is that some tarballs will not create themselves as a parent directory to the install paths. I.e., my tarball has the tree:
usr
├── bin
│ ├── check_for_incorrect_quotes
│ └── check_for_incorrect_quotes.py
└── lib
└── python2.6
└── site-packages
├── incorrectquotes
│ ├── check_for_incorrect_quotes.py
│ ├── check_for_incorrect_quotes.pyc
│ ├── __init__.py
│ ├── __init__.pyc
│ └── test
│ ├── __init__.py
│ └── __init__.pyc
└── IncorrectQuotes-0.2.0-py2.6.egg-info
├── dependency_links.txt
├── entry_points.txt
├── PKG-INFO
├── requires.txt
├── SOURCES.txt
└── top_level.txt
Because this is where it wants to install these packages
To make this work, you can just change setup -n to setup -c to create and move to that directory before untarring (You'll want to ctrl+f for "create directory (and change to it)")
TL;DR: setup -n -> setup -c might help
In your rpmbuild folder, go to SOURCES and rename your source folder this way:
mypackage-1.0
then create the tarball:
mypackage-1.0.tar.gz
And it should work.
What happens is that after untarring the archive, rpmbuild expects a folder named mypackage-1.0 and not mypackage or mypackage-something else.
Respect naming conventions. Check Guidelines