Create a recipe for a QT5 application - yocto

I have been struggling for too long, so I need help :)
I made a big QT5.8 application and usually when I want to compile it with my PC I just have to run the following command: qmake -qt=5.9 -spec linux-arm-gnueabihf-g++ -config configuration_name.
With this command, I can cross compile my source code for the armhf architecture using linux-arm-gnueabihf-g++ toolchain.
But now, as can easily create a yocto image for my target (Raspberry pi), I want to make a recipe in order to compile my qt software and put it into my image.
For now, I achieved to perform these following task in my recipe without errors:
do_fetch -> Yocto fetch the source from git repo (OK)
do_unpack -> OK
After that I want to perform a qmake command in order to generate my makefile, but here is my problem :/
First, I included the qmake5 class in my recipe using
require recipes-qt/qt5/qt5.inc
Then I tried a lot of things..
writing "qmake" into the do_configure task doesn't work. Last thing I tried was: '${OE_QMAKE_QMAKE} ${S}/my_software.pro -config my_config' but still the same error:
Could not find qmake spec 'linux-oe-g++'
I don't know what to do and I can't find any recipe exemple doing the things that I want to do.
If somebody already experienced this issue or have experience compiling qt5 software with a yocto recipe I would like your help :)
my recipe:
LICENSE = "CLOSED"
LIC_FILES_CHKSUM = " "
USERNAME = "****"
PASSWORD = "*****"
S = "${WORKDIR}/git"
require recipes-qt/qt5/qt5.inc
do_fetch(){
git clone http://${USERNAME}:${PASSWORD}#gitlab.....
}
do_configure () {
${OE_QMAKE_QMAKE} ${S}/my_software.pro -config my_config
}
Thanks

Short answer
Add "inherit qmake5" and let Yocto take care of it :)
Long answer
Here's an example of how I added a QT project. It is not using git, it is using local files. However for getting one step further I suggest:
Use my way as a test. Copy the QT project to /yocto/local_sources/Myproject/
and make this known to Yocto by using FILESEXTRAPATHS_prepend_ (as shown below).
If this works on your environment, adapt it to your needs (e.g. build from git instead of local_source, which is better off course.)
This way is tested and works also well for later remote-debugging with qt-creator and the yocto SDK by the way. Stick to Yocto, it's worth it in the end.
Here's my .bb file:
#
# Build QT xyz application
#
SUMMARY = "..."
SECTION = "Mysection"
LICENSE = "CLOSED"
#Add whatever you need here
DEPENDS += "qtbase qtmultimedia qtsvg"
#Add here your .pro and all other relevant files (if you use git later this step will be less tedious ...)
SRC_URI += "file://Myproject.pro"
SRC_URI += "file://*.h"
SRC_URI += "file://*.cpp"
SRC_URI += "file://subdir1/*.h"
SRC_URI += "file://subdir1/*.cpp"
SRC_URI += "file://subdir2/*.h"
SRC_URI += "file://subdir2/*.cpp"
SRC_URI += "file://subdir2/subdir3/*.h"
SRC_URI += "file://subdir2/subdir3/*.cpp"
#If you need autostart:
#SRC_URI += "file://myproject.service"
#Register for root file system aggregation
FILES_${PN} += "${bindir}/Myproject"
#RBE todo: both needed ?
FILESEXTRAPATHS_prepend_${PN} := "/yocto/local_sources/Myproject/Src:"
FILESEXTRAPATHS_prepend := "/yocto/local_sources/Myproject/Src:"
S = "${WORKDIR}"
#If you want to auto-start this add:
#SYSTEMD_SERVICE_${PN} = "Myproject.service"
FILES_${PN} = "${datadir} ${bindir} ${systemd_unitdir}"
FILES_${PN}-dbg = "${datadir}/${PN}/.debug"
FILES_${PN}-dev = "/usr/src"
#Check what's needed in your case ...
RDEPENDS_${PN} += "\
qtmultimedia-qmlplugins \
qtvirtualkeyboard \
qtquickcontrols2-qmlplugins \
gstreamer1.0-libav \
gstreamer1.0-plugins-base-audioconvert \
gstreamer1.0-plugins-base-audioresample \
gstreamer1.0-plugins-base-playback \
gstreamer1.0-plugins-base-typefindfunctions \
gstreamer1.0-plugins-base-videoconvert \
gstreamer1.0-plugins-base-videoscale \
gstreamer1.0-plugins-base-volume \
gstreamer1.0-plugins-base-vorbis \
gstreamer1.0-plugins-good-autodetect \
gstreamer1.0-plugins-good-matroska \
gstreamer1.0-plugins-good-ossaudio \
gstreamer1.0-plugins-good-videofilter \
"
do_install_append () {
# Install application
install -d ${D}${bindir}
install -m 0755 Myproject ${D}${bindir}/
# Uncomment if you want to autostart this application as a service
#install -Dm 0644 ${WORKDIR}/myproject.service ${D}${systemd_system_unitdir}/myproject.service
# Install resource files (example)
#install -d ${D}${datadir}/${PN}/Images
#for f in ${S}/Images/*; do \
# install -Dm 0644 $f ${D}${datadir}/${PN}/Images/
#done
}
#Also inherit "systemd" if you need autostart
inherit qmake5

Related

Petalinux--ERROR:conflicts between attempted installs

I am trying to modify /etc/inittab file to add a restart function. To check whether I can add a line in inittab, I created a demo. I created a .bb file under proect-spec/meta-user/recipes-apps:
#
# This is the GPIO-DEMO apllication recipe
#
#
SUMMARY = "automatic-restart application"
SECTION = "PETALINUX/apps"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://* \
"
S = "${WORKDIR}"
FILESEXTAPATHS_preprend := "${THISDIR}/files:"
#inherit update-rc.d
INITSCRIPT_NAME = "hello"
INITSCRIPT_PARAMS = "start 98 5 ."
do_install() {
install -d ${D}${sysconfdir}/init.d
install -m 0755 ${S}/hello ${D}${sysconfdir}/init.d/hello
install -d ${D}/opt/hello
cp ${S}/hello.elf ${D}/opt/hello/
}
do_install_append(){
echo "adding a line" >> ${D}${sysconfdir}/inittab
}
FILES_${PN} += "${sysconfdir}/*"
FILES_${PN} += "/opt/hello/"
By the way, this file is used firsly put an .elf file under /etc/init.d and it worked.
However, when I was adding these below code block to check whether I can modify "inittab" :
do_install_append(){
echo "adding a line" >> ${D}${sysconfdir}/inittab
}
then building the petalinux project, I encountered with this error:
"file /etc/inittab conflicts between attempted installs of hello-1.0-r0.cortexa9hf_neon and sysvinit-inittab-2.88dsf-r10.plnx_zynq7"
This is a well known issue in Yocto which is you cannot ship two packages(recipes) that are installing the same file in the final rootfs.
So, either you remove one of hello or sysvinit-inittab from the image, or use update-alternatives class as mentioned in this question.

Yocto: Create a New Directory in etcdir

I am new to Yocto,
I want to create a directory in /etc and copy my server certificates into that directory. I tried doing below, But it it not creating any directory in /etc, however i am not getting any compilation error:
DESCRIPTION = "OC sample service"
SUMMARY = "Install and start a systemd service and copy server certificates"
LICENSE = "MIT"
SRC_URI = "file://service.tar.gz"
inherit systemd
S = "${WORKDIR}/service"
SYSTEMD_PACKAGES = "${PN}"
SYSTEMD_SERVICE_${PN} = "sample.service"
SYSTEMD_AUTO_ENABLE = "enable"
INSANE_SKIP_${PN} += "installed-vs-shipped"
do_configure() {
:
}
do_compile() {
:
}
do_install() {
install -d ${D}${systemd_unitdir}/system
install -m 0755 ${S}/sample.service ${D}${systemd_unitdir}/system
mkdir -p ${D}${etcdir}/oc_certs
install -m 0755 ${S}/certs/* ${D}${etcdir}/oc_certs
}
FILES_${PN} = "${systemd_unitdir}/system
"
Now the problem is, sample.service is successfully being placed to the location but /etc/oc_certs is not being created.
In addition to LetoThe2nd's answer: the ${etcdir} variable is usually empty. If you want a variable for /etc, it is ${sysconfdir}. So your files are probably installed to root directory.
Check output of bitbake -e <your_recipe> and try to find etcdir to verify.
Also drop INSANE_SKIP_${PN} += "installed-vs-shipped" which hides the error your are trying to find (you will see what is installed where but not shipped).
BTW LetoThe2nd's answer is also needed, because you are overwriting (instead of appending FILES_${PN}, otherwise it wouldn't be needed. The ${sysconfdir} is already part of FILES_${PN}.
"Not working" is a rather bad error description, but the most probable issue is that it does not get included in the image. This is because bitbakes packaging mechanisms do not know about that directory, so add it with:
FILES_${PN} += "${etcdir}/oc_certs"
If you need further assistance, please extend your question with a precise error description, respectively the corresponding log.
You are missing a / after ${D}. To create a directory say mydir in your /etc folder, just add the following code in the do_install() of your recipe.
do_install() {
install -d ${D}/etc/mydir
}

In Yocto, how to include header files from another recipes

My program depends on the poco recipes, which provides both the header files and shared libraries. However, I cannot make use of the header files from poco in my recipe, which leads to the error Poco/Delegate.h: No such file for directory.
How do I make the header available at build time for my software package?
Here is an example recipe:
SUMMARY = ""
DESCRIPTION = ""
AUTHOR = ""
LICENSE = "CLOSED"
LIC_FILES_CHKSUM = ""
HOMEPAGE = ""
BUGTRACKER = ""
S = "${WORKDIR}"
SRC_URI = " file://foo.cpp \
file://CMakeLists.txt \
"
inherit pkgconfig cmake
DEPENDS_foo = "poco"
RDEPENDS_foo = "poco"
do_install() {
install -d ${D}/${bindir}
install -m 755 ${S}/foo ${D}/${bindir}
}
FILES_${PN} = "${bindir}/foo"
We can use provider and user to illustrate this case, the package (recipe) provides a header file to be used by another package (recipe) is the provider, the package (recipe) use a header file from another package (recipe) is the user.
First we change the provider's recipe (myprovider.bb) to export the header file -- myapi.h,
...
do_install() {
install -d ${D}/${bindir}
install -m 755 ${B}/hello_provider ${D}/${bindir}
install -d ${D}${libdir}/lib_myprovider/
install -m 0755 ${WORKDIR}/myapi.h ${STAGING_DIR_TARGET}${libdir}/lib_myprovider/
}
...
Secondly we change the user's recipe (myuser.bb) to refer the header file -- myapi.h
...
do_compile () {
${CC} ${WORKDIR}/main.c -o hello_user ${CFLAGS} ${LDFLAGS} -I${STAGING_DIR_TARGET}/${libdir}/lib_myprovider/
}
# file dependency declaration
FILES_${PN} = "${libdir}/lib_myprovider"
# package dependency declaration
DEPENDS += "myprovider"
...
At last, rebuild myprovider.bb and myuser.bb recipes, it should work.
Manual recommends:
Recipes should never populate the sysroot directly:
Recommended way is (poco recipe should do something similar):
Files should be installed into standard locations:
...
do_install() {
...
install -d ${D}${includedir}
install -m 0755 ${S}/myapi.h ${D}${includedir}/
...
}
...
Than, include poco recipe as a build dependency of foo.bb :
DEPENDS += "poco"
And compile normally.
You could use DEPENDS to have dependency with "poco" recipe and it would build and populate "poco" recipe's headers and libs into your recipe's sysroot.
Similar way you have to mention the export paths in the provider's recipe with FILES_*( * - package type)

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.

How to install only a subset of the packages listed in a packagegroup?

I have written the following packagegroup called packagegroup-amatek.bb for testing purposes :
# Copyright (C) 2012-2013 Freescale Semiconductor
# Released under the MIT license (see COPYING.MIT for the terms)
DESCRIPTION = "Example package group"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COREBASE}/LICENSE;md5=3f40d7994397109285ec7b81fdeb3b58 \
file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"
PR = "r5"
inherit packagegroup
PROVIDES = "${PACKAGES}"
PACKAGES += " \
${PN}-package1 \
${PN}-package2 \
"
RDEPENDS_${PN}-package1 = " \
package1-depend1 \
"
RDEPENDS_${PN}-package2 = " \
package2-depend2 \
"
PACKAGE_ARCH = "${MACHINE_ARCH}"
If in my custom image file (amatek-image) I include only packagegroup-amatek-package1:
IMAGE_INSTALL = "packagegroup-amatek-package1"
I would expect that package2-depend2 is not installed because it is a dependency of the package packagegroup-amatek-package2 which is not installed.
However, bitbake amatek-image -g -u depexp shows that package2-depend2 is installed as well:
Is this the expected behaviour?
The dependency explorer will show what is built, not what is installed. If you build the above image, you will find that only packagegroup-amatek-package1 is installed as you'd expect. There is a difference between what the system has to build and what is installed at runtime. It has to build packagegroup-amatek-package2 since its part of the same recipe as packagegroup-amatek-package1 and the system doesn't partially build recipes, it either does or does not.