Yocto: BUILD_LDFLAGS set to build system libraries, not target - yocto

I've got a makefile recipe that builds a shared library (an alsa plugin). If I build the library outside if yocto everything works correctly and alsa will link to the library.
However if I build it with yocto, even though the log is error free, when I try and run alsa, I get an error "Cannot open shared library". The library is installed in location referenced by the error message and it's permissions are correct.
From within the recipe if I print out what BUILD_LDFLAGS is set to I notice the it's pointing to the x86_64-linux (build system) libraries instead of the 'MACHINE' libraries (example: -L//.build-yocto/tmp/sysroots/x86_64-linux/lib"
My questions are:
Is the BUILD_LDFLAGS the source of my problem?
If so how do I remedy it?
If not BUILD_LDFLAGS, any idea what is the problem.
Here is a copy of my recipe bb file:
SUMMARY = "..."
LICENSE = "CLOSED"
#Package release number
PR = "r0"
###################################################################
#The following lines tell yocto where to get the source code from
# This section is for git. Comment out ALL this section if
# you DO NOT want to pull from a git repo (local or remote).
# If pulling from git uncomment and modify paths.
###################################################################
#Uncomment following line to pull from REMOTE git repo
#SRC_URI = "git://gitpath;protocol=ssh;branch=master"
#Uncomment following line and modify path to pull from LOCAL git repo clone
##SRC_URI = "git:///localgitpath;protocol=file;branch=master"
#Change hash to match the commit you want yocto to use
##SRCREV="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
##S = "${WORKDIR}/git/"
# End of git section
###################################################################
#The following lines tell yocto where to use a local file system
# for the source. Uncomment all lines and modify paths
###################################################################
SRC_URI = ""
inherit externalsrc
EXTERNALSRC = "/home/<my_path>"
EXTERNALSRC_BUILD = "/home/<my_path>"
# End of local file system section
##################################################################
#END of where to get source code
##################################################################
#Ignore vendor ldflags checking and use ours
INSANE_SKIP_${PN} = "ldflags"
#Don't strip debug symbols
INHIBIT_PACKAGE_STRIP = "1"
INHIBIT_SYSROOT_STRIP = "1"
SOLIBS = ".so"
#Tell yocto that the .so files are real and not sym-links.
FILES_SOLIBSDEV = ""
#/usr/lib/alsa-lib
FILES_${PN} += "${libdir}/alsa-lib"
#/usr/<PATH>
FILES_${PN} += "${prefix}/<PATH>"
DEPENDS += "alsa-lib"
EXTRA_OEMAKE += "'CC=${CC}' 'RANLIB=${RANLIB}' 'AR=${AR}' 'CFLAGS=${CFLAGS} -I${S}/include' 'BUILDDIR=${S}' 'DESTDIR=${D}'"
TARGET_CFLAGS += "-DPIC -fPIC -Wall -Wextra -O2 -g -I./include -I<path> -I-I<path2> -I<path3> -lasound"
TARGET_LDFLAGS += "-shared -lasound"
do_configure() {
oe_runmake -f Makefile.yocto clean
}
do_compile() {
# unset LDFLAGS TARGET_LDFLAGS BUILD_LDFLAGS
echo " Werkdir ${WORKDIR}"
echo " Compiler ${CC}"
echo " BUILD_LDFLAGS ${BUILD_LDFLAGS}"
echo " LDFLAGS ${LDFLAGS}"
echo " TARGET_LDFLAGS ${TARGET_LDFLAGS}"
oe_runmake -f Makefile.yocto all 'CC=${CC}'
}
do_install() {
install -d ${D}${libdir}
install -d ${D}${libdir}/alsa-lib
install -d ${D}${bindir}
install -d ${D}${prefix}
install -d ${D}${prefix}/<PATH>
install -m 0644 <path_n>lib1.so ${D}${libdir}
install -m 0644 <path_n>lib2.so.so ${D}${libdir}
install -m 0644 <path_n>lib3.so.so ${D}${libdir}
install -m 0644 <path_n>lib4.so.so ${D}${libdir}
install -m 0644 <path_n>lib1pcm_plugin.so ${D}${libdir}/alsa-lib
install -m 0755 <path_n>app1 ${D}${bindir}
install -m 0755 <path_n>app2 ${D}${bindir}
install -m 0755 <path_n>app3 ${D}${bindir}
install -m 0755 <path_n>app4 ${D}${bindir}
install -m 0755 <path_n>app5 ${D}${bindir}
install -m 0755 <path_n>app6 ${D}${bindir}
install -m 0755 <path_n>app7 ${D}${bindir}
install -m 0755 <path_n>app8 ${D}${bindir}
}
Makefile:
# Makefile template for shared library
#Yocto will pass in the CC flag so this is commented out. Otherwise the correct compiler won't be used
#CC = gcc # C compiler
#These are here to allow a build outside of Yocto (testing the build). Yocto's CFLAGS
#and LDFLAGS will override these.
CFLAGS += -fPIC -Wall -Wextra -O2 -g -I<path1> -I<path2> -I<path2> # C flags
LDFLAGS = -shared # linking flags
RM = rm -f # rm command
TARGET_LIB = libasoundplugin.so # target lib
LIB1=lib1
PATH1=<path1>
LIB2=lib2
PATH2=<path2>
INCLUDE_FLAGS = -L$(PATH1) -l$(LIB1I) \
-L$(PATH2) -l$(LIB2) \
-lasound
SRCS = source.c
OBJS = $(SRCS:.c=.o)
.PHONY: all
all: ${TARGET_LIB}
$(TARGET_LIB): $(OBJS)
$(CC) ${LDFLAGS} ${INCLUDE_FLAGS} -o $# $^
$(SRCS:.c=.d):%.d:%.c
$(CC) $(CFLAGS) -MM $< >$#
include $(SRCS:.c=.d)
.PHONY: clean
clean:
-${RM} ${TARGET_LIB} ${OBJS} $(SRCS:.c=.d)
Thanks!

Is the BUILD_LDFLAGS the source of my problem?
No. BUILD_LDFLAGS is used to build native packages, while you build a target package. In your case TARGET_LDFLAGS variable will be used as LDFLAGS source.
Here is a copy of my recipe bb file
Where does it come from? Did you write it from a template?
As I can see there is a recipe for alsa plugins, maybe you can add your plugin to this recipe?
You can also take as example the recipe for a2jmidid, it is close to what you are trying to do as I understand. It does nothing special, except for setting dependencies, getting sources, adding certain ld flags and passing resulting files to the package.
Regarding the Makefile (I suppose it is also your recipe):
First of all there is no need to have a separate Makefile for yocto.
#Yocto will pass in the CC flag so this is commented out. Otherwise the correct compiler won't be used
#CC = gcc # C compiler
You are passing CC from your .bb recipe (even twice: via EXTRA_OEMAKE and in do_compile). There is no need to comment out CC variable, as definitions inside Makefile have lower priority compared to definitions passed as command line arguments.
Why do you need INCLUDE_FLAGS variable? I don't understand what does it do (except for passing to gcc some flags for the third time).
Ultimately, you can go to the workdir, open file temp/log.do_compile and you will see which commands were executed to compile your plugin. Compare it to the settings you use to compile it manually, and you will see what is the difference between successful and unsuccessful builds.

Related

Bitbake service file organization

I have a service created and working. However my current bitbake file makes my folder structure very ugly. To have it work I have to have all of my configuration files in my src folder. I would like to have two folders, src and configfiles.
If my tree is as follows
How can I edit my bb file to pull in my src directory and my configfiles?
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://src"
S = "${WORKDIR}/src"
CF = "${WORKDIR}/configfiles"
inherit systemd autotools
SYSTEMD_SERVICE_${PN} = "helloworld.service"
do_install_append () {
echo "look at this PN ${PN}"
echo "look at this D ${D}"
echo "look at this S ${S}"
echo "look at this CF ${CF}"
install -d ${D}${systemd_system_unitdir}
install -m 0644 ${CF}/helloworld.service ${D}${systemd_system_unitdir}
sed -i -e 's,#BINDIR#,${bindir},g' ${D}${systemd_system_unitdir}/helloworld.service
}
Update 1:
I added a CF variable. Using bitbake -e helloworld > log.txt I can echo the values of variables and noticed we are not pointing to the config files.
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://src"
S = "${WORKDIR}/src"
CF = "${WORKDIR}/configfiles"
inherit systemd autotools
SYSTEMD_SERVICE_${PN} = "helloworld.service"
do_install_append () {
echo "look at this PN ${PN}"
echo "look at this D ${D}"
echo "look at this S ${S}"
echo "look at this CF ${CF}"
install -d ${D}${systemd_system_unitdir}
install -m 0644 ${CF}/helloworld.service ${D}${systemd_system_unitdir}
sed -i -e 's,#BINDIR#,${bindir},g' ${D}${systemd_system_unitdir}/helloworld.service
}
Bitbake still can not find my makefile.
Update 2:
The solution given works but I have one more question.
My makefile is very basic:
ACLOCAL_AMFLAGS = -I m4
AUTOMAKE_OPTIONS = foreign
SUBDIRS = app
CFLAGS = -Wall -pedantic
include_HEADERS = helloworld.h
bin_PROGRAMS = helloworld
helloworld_SOURCES = helloworld.c
I want to separate my files by folder. I want my main application in a folder /src/app. I edited my makefile to point to app/helloworld.h and app/helloworld.c However this does not find the files. My updated bb file follows
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
FILESEXTRAPATHS:prepend := "${THISDIR}/files/src:${THISDIR}/files/src/app:${THISDIR}/files/services:"
SRC_URI = "file://src \
file://src/app \
"
SRC_URI += "file://helloworld.service \
file://autogen.sh \
file://configure.ac \
file://Makefile.am"
S = "${WORKDIR}/src"
inherit systemd autotools
SYSTEMD_SERVICE_${PN} = "helloworld.service"
do_install_append () {
install -d ${D}${systemd_system_unitdir}
install -m 0644 ${WORKDIR}/helloworld.service ${D}${systemd_system_unitdir}
sed -i -e 's,#BINDIR#,${bindir},g' ${D}${systemd_system_unitdir}/helloworld.service
}
I understand the makefile should be packaged with the code, This just does not work when creating larger applications.
You need to let bitbake know where to look for files, it sounds like you want to keep the Makefile in a separate directory but in most cases the Makefile should be with the source files, feel free to play around with this, the concept is still the same as explained below.
Either way, your directory structure should look something like this:
recipes-core/
helloworld/
helloworld_0.1.bb
files/
configfiles/
helloworld.service
src/
autogen.sh
configure.ac
helloworld.c
helloworld.h
Makefile.am
And to let bitbake know where to pull files you use the FILESESXTRAPATHS variable [1]:
FILESEXTRAPATHS:prepend := "${THISDIR}/files/src:${THISDIR}/files/configfiles:"
At this point bitbake knows WHERE to pull the files from, but it doesn't know which files to pull, for this you use the SRC_URI variable (specifically the file:// fetcher) [2]:
SRC_URI += "file://helloworld.service \
file://autogen.sh \
file://configure.ac \
file://helloworld.c \
file://helloworld.h \
file://Makefile.am"
This assumes your Makefile will try to find files in the same directory.
The rest of your recipe is fine, the CF variable is no longer necessary, and you just need to change where you're installing the service file from, since SRC_URI[1] will pull it to ${WORKDIR}:
install -m 0644 ${WORKDIR}/helloworld.service ${D}${systemd_system_unitdir}
[1] https://docs.yoctoproject.org/singleindex.html#term-FILESEXTRAPATHS
[2] https://docs.yoctoproject.org/bitbake/singleindex.html#term-SRC_URI

yocto recipe how to install file to rootfs

sorry I am a little new to syntax of yocto, this is how I have modified my recipe:
LICENSE = "LGPLv2.1"
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
SRC_URI = "file://myscript.sh"
FILES_${PN} += "${sysconfdir}/init.d/myscript.sh"
do_install() {
install -d ${D}${sysconfdir}/init.d
install -m 0755 ${WORKDIR}/myscript.sh ${D}${sysconfdir}/init.d/
}
The recipe is added to the build, because if I remove the LICENSE line the yocto image will not be baked.
The folder where the recipe is kept is named "customssh", inside this folder I have the recipe named customssh_0.1.bb and a subfolder named "files" where the myscript.sh is kept.
After I have baked the image, I run this command to see if the myscript.sh has been placed in the rootfs:
find . -name 'myscript*'
which will return where the file is held:
./meta-swi/common/recipes-core/customssh/files/myscript.sh
In the recipe, is this line correct?
install -m 0755 ${WORKDIR}/myscript.sh ${D}${sysconfdir}/init.d/
If this is the root recipe and not a bbappend one use do_install instead of do_install_append
Make sure that ${D}${sysconfdir}/init.d is created before copying to it
do_install(){
install -d ${D}${sysconfdir}/init.d
install -m 0755 ${WORKDIR}/myscript.sh ${D}${sysconfdir}/init.d/
}
Now, make sure to specify the file you installed so that the do_package will not fail
FILES_${PN} += "${sysconfdir}/init.d/myscript.sh"

Old version of library is included in image after updating bitbake file

After updating dotnet-runtime in our Yocto based Linux distribution to version 2.1.12, I saw that the resulting image had increased significantly in size. On closer inspection i found that the image contained both the new 2.1.12 version and the older 2.1.11 version of the dotnet-runtime library. How can I ensure that older version are not included in the image? Do I have to change more that just the SRC_URI and checksum?
Here is the content of dotnet-runtime.bb
DESCRIPTION = ".NET Core Runtime, SDK & CLI tools"
HOMEPAGE = "https://www.microsoft.com/net/core"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=42b611e7375c06a28601953626ab16cb"
COMPATIBLE_HOST ?= "x86_64.*-linux"
RDEPENDS_${PN} = "glibc zlib libunwind icu libcurl openssl krb5 libgssglue"
INSANE_SKIP_${PN} += "already-stripped staticdev file-rdeps libdir"
INHIBIT_PACKAGE_STRIP = "1"
INHIBIT_SYSROOT_STRIP = "1"
INHIBIT_PACKAGE_DEBUG_SPLIT = "1"
SRC_URI = "https://download.visualstudio.microsoft.com/download/pr/c1b620fe-7d8e-4685-b6ae-82b444dbc7a7/3d5610f0607da49ee014c61c6cd4e9af/aspne
tcore-runtime-2.1.12-linux-x64.tar.gz"
SRC_URI[sha256sum] = "cdb8816a437de168b25500b14ea32169abe610675ced08ca31f77f9542c2149a"
S = "${WORKDIR}"
do_install() {
install -d ${D}${bindir}
install -d ${D}${datadir}/dotnet
install -d ${D}${datadir}/dotnet/host/
install -d ${D}${datadir}/dotnet/shared/
install -m 0755 ${S}/dotnet ${D}${datadir}/dotnet
install -m 0644 ${S}/LICENSE.txt ${D}${datadir}/dotnet
install -m 0644 ${S}/ThirdPartyNotices.txt ${D}${datadir}/dotnet
cp -r --no-preserve=ownership ${S}/host/ ${D}${datadir}/dotnet/
cp -r --no-preserve=ownership ${S}/shared/ ${D}${datadir}/dotnet/
# Symlinks
cd ${D}${bindir}
ln -s ../../${datadir}/dotnet/dotnet dotnet || true
}
FILES_${PN} = "\
${bindir}/dotnet \
${datadir}/dotnet/ \
"
You might need to clean the cache of the recipe.
Just run:
$ bitbake -c clean {recipe name}
Then build your image again.
Hope it helps.
Adding the version number to the bitbake file, dotnet-runtime_2.1.12.bb instead of dotnet-runtime.bb, solved the issue.
Info about recipe naming http://www.embeddedlinux.org.cn/OEManual/recipes_versioning.html

Yocto: Create a directory after mount

I have a Yocto bitbake recipe in my layer - base-files_%.bbappend. It creates mount points:
do_install_append() {
mknod -m 622 ${D}/dev/console c 5 1
install -m 0755 -d ${D}/boot/EFI
install -m 0755 -d ${D}/data
}
The /data/ directory is later mounted to the internal SD card.
I would like to create a directory ${D}/data/test. What is the best way to do it? I've added a line install -m 0755 -d ${D}/data/test to this function but it didn't do it.
Thanks so much.
You have to ship those installed files by adding to your recipe:
FILES_${PN} += "/data/test"
Another solution is to add in your image recipe:
create_dirs() {
mkdir -p ${IMAGE_ROOTFS}/data/test
}
ROOTFS_POSTPROCESS_COMMAND += "create_dirs ; "
In your do_install function
do_install(){
mkdir -d ${D}/data/test
}
-d option creates the dir in your rootfs, and if you want to copy files, use below command in do_install function.
install -m 0777 ${s}/your files ${D}/data/test
The QA packaging process verification should be informed :
FILES_${PN} += "/data/test"

Yocto build not including files in sdcard image

I am trying to build an SDK into my sysroot on my yocto build. However when i compile my build i get no errors and everything appears to have worked fine.
When i flash my SD card and run it on my board and go to look for my files, they arent there.
here is my .bb file which is used to install the SDK i want to use.
giffgaff-connectDESCRIPTION = "azure"
HOMEPAGE = "https://github.com/Azure/azure-iot-sdk-c"
LICENSE = "MIT"
SECTION = "applications"
PRIORITY = "optional"
DEPENDS = "mono"
LIC_FILES_CHKSUM = "file://${WORKDIR}/git/LICENSE;md5=4283671594edec4c13aeb073c219237a"
SRCREV = "${AUTOREV}"
SRC_URI = "git://git#bitbucket.org/condecosoftware/azure-iot-sdk-c;protocol=ssh;branch=master"
COMPATIBLE_MACHINE = "imx6qsabresd"
S = "${WORKDIR}"
ALLOW_EMPTY_${PN} = "1"
do_compile() {
echo libdir: ${libdir}
echo Files : FILES_${PN}
echo "compiler: ${CC}"
echo "sysroot: ${STAGING_DIR_TARGET}"
export SYSROOT=${STAGING_DIR_TARGET}
cd ${WORKDIR}/git/build_all/linux/
./build.sh --toolchain-file toolchain-yocto.cmake -cl --sysroot=${STAGING_DIR_TARGET} --install-path-prefix ${STAGING_DIR_TARGET}
cd ../..
cmake -P cmake/iotsdk_linux/cmake_install.cmake
}
do_install() {
cd git
pwd
echo ${D}
echo ${libdir}
install -d 0755 ${D}${libdir}
install -m 0755 ./cmake/iotsdk_linux/umqtt/libumqtt.a ${D}${libdir}/
install -m 0755 ./cmake/iotsdk_linux/uamqp/libuamqp.a ${D}${libdir}/
install -m 0755 ./cmake/iotsdk_linux/c-utility/libaziotsharedutil.a ${D}${libdir}/
install -m 0755 ./cmake/iotsdk_linux/iothub_client/libiothub_client_http_transport.a ${D}${libdir}/
install -m 0755 ./cmake/iotsdk_linux/iothub_client/libiothub_client.a ${D}${libdir}/
install -m 0755 ./cmake/iotsdk_linux/iothub_client/libiothub_client_amqp_ws_transport.a ${D}${libdir}/
install -m 0755 ./cmake/iotsdk_linux/iothub_client/libiothub_client_amqp_transport.a ${D}${libdir}/
install -m 0755 ./cmake/iotsdk_linux/iothub_client/libiothub_client_mqtt_transport.a ${D}${libdir}/
install -m 0755 ./cmake/iotsdk_linux/iothub_client/libiothub_client_mqtt_ws_transport.a ${D}${libdir}/
install -m 0755 ./cmake/iotsdk_linux/serializer/libserializer.a ${D}${libdir}/
install -m 0755 ./cmake/iotsdk_linux/iothub_service_client/libiothub_service_client.a ${D}${libdir}/
}
do_fetch_extra(){
cd ${WORKDIR}/git/
git submodule update --init --recursive
}
addtask fetch_extra after do_unpack before do_patch
Any help would be great appreciated. Thanks
Have you tried ${WORKDIR} variable? This variable holds the pathname of the work directory of recipe being build. So every file fetched from git can be accessed from there, I presume. For example:
install -m 0755 ${WORKDIR}/cmake/iotsdk_linux/umqtt/libumqtt.a ${D}${libdir}/
Please let me know if it works.
You will probably need to add
PACKAGES =+ "${PN}-staticdev"
FILES_${PN}-staticdev += "${libdir}/*.a"
to ship every files you installed into your image.
You can also add every files one by one instead of wildcard.
Some remarks:
For git submodules, you can use gitsm:// url, it will initialize every submodules.
You can also put the following instruction to avoid doing some change dir in recipe.
S = "${WORKDIR}/git"
By the way, you can look this OE recipe for Azure from Intel meta-iot-cloud layer. It is python recipe, but it depends on C iot sdk, it can be inspiring:
https://github.com/intel-iot-devkit/meta-iot-cloud/blob/master/recipes-azure/azure-iot-sdk/azure-iot-sdk_1.1.23.bb