Cross compile package using crossscript in yocto for node-sqlite3? - node.js

my yocto setup has nodejs recipe. Which works properly. I'm trying to cross-compile node-sqlite3 package by adding new recipe. node-sqlite3 depends on node-gyp script. script uses command node(machine-image).
Build setup trying to use HOST path instead of machine image path.
node-sqlite3.bb
SUMMARY = "Asynchronous, non-blocking SQLite3 bindings for Node.js"
SECTION = "nodejs/module"
LICENSE = "MIT"
SRC_URI = "https://github.com/mapbox/node-sqlite3/archive/v${PV}.tar.gz"
LIC_FILES_CHKSUM = "file://LICENSE;md5=79558839a9db3e807e4ae6f8cd100c1c"
SRC_URI[md5sum] = "c17036d0db2d147d9af8d7b7057c8c8c"
SRC_URI[sha256sum] = "80d58f84073e524f7d4a39e2ec7b77908862a5629b9a4d882127c807cc093597"
S = "${WORKDIR}/node-sqlite3-${PV}"
DEPENDS = "nodejs node-gyp sqlite3"
inherit nodejs-arch
EXTRA_OECONF = "--with-node=${STAGING_BINDIR_CROSS}/node"
do_configure() {
export LD="${CXX}"
export GYP_DEFINES="sysroot=${STAGING_DIR_HOST}"
node-gyp --arch ${TARGET_ARCH} configure
}
do_compile() {
export LD="${CXX}"
export GYP_DEFINES="sysroot=${STAGING_DIR_HOST}"
node-gyp --arch ${TARGET_ARCH} build
}
do_install() {
install -d ${D}${libdir}/nodejs/sqlite3
install ${S}/build/Release/node_sqlite3.node ${D}${libdir}/nodejs/
install ${S}/lib/sqlite3.js ${D}${libdir}/nodejs/sqlite3/
install ${S}/lib/index.js ${D}${libdir}/nodejs/sqlite3/
install ${S}/lib/trace.js ${D}${libdir}/nodejs/sqlite3/
}
FILES_${PN} += "${libdir}/nodejs ${bindir}node-gyp"
cat node-gyp
#!/usr/bin/env sh
if [ "x$npm_config_node_gyp" = "x" ]; then
node "`dirname "$0"`/../../node_modules/node-gyp/bin/node-gyp.js" "$#"
else
"$npm_config_node_gyp" "$#"
fi
The following binary path should be considered for configuring, compiling.
node-gyp script is used from hosttools not from image directory.
/poky/build/tmp-glibc/hosttools/node-gyp
/poky/build/tmp-glibc/work/target-sdk/machine-image/1.0-r0/rootfs/usr/lib/node_modules/npm/bin/node-gyp-bin/node-gyp
node-gyp script uses node command to compile scipts, build recipe fails to point to image binary path.
build/tmp-glibc/work/target-sdk/machine-image/1.0-r0/rootfs/usr/bin/node
But I'm getting the following error.
| build/tmp-glibc/work/armv7ahf-neon-oe-linux-gnueabi/node-sqlite3/4.0.8-r0/recipe-sysroot
| /usr/bin/env: ‘node’: No such file or directory
How to fix above issues? What steps need to correct or include in node-sqlite3.bb recipe?

Related

Cross compile shared library for armv5te-unknown-linux-gnueabi Rust [Mindstorm Ev3dev]

Parameters:
source = x86_x64 windows 10 or x86_x64 linux (ubuntu wsl)
target = armv5te linux
target_type = cdylib
target_glibc = 2.24
language = rust
build_tool = cargo
compiler = rustc
(The target is a Lego Mindstorm running a linux image from Ev3dev)
Cargo Configuration:
[package]
name = "ev3"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
jni = "0.19"
ev3dev-lang-rust = { version = "0.12.1", features=["screen"]}
jni_proc_macro= {path= "./jni_proc_macro"}
[lib]
crate-type= ["cdylib"]
[workspace]
members= ["jni_proc_macro"]
Build Configuration:
[build]
target = "armv5te-unknown-linux-gnueabi"
[target.armv5te-unknown-linux-gnueabi]
linker = "rust-lld"
Build Error:
error: linking with `rust-lld` failed: exit code: 1
|
= note: {...}
= note: rust-lld: error: unable to find library -lgcc_s
rust-lld: error: unable to find library -lutil
rust-lld: error: unable to find library -lrt
rust-lld: error: unable to find library -lpthread
rust-lld: error: unable to find library -lm
rust-lld: error: unable to find library -ldl
rust-lld: error: unable to find library -lc
error: could not compile `ev3` due to previous error
As the error suggests the linker is missing libraries. I found no clear solution where I can download and or provide these dependencies.
My question is, A is there a diffrent way to build this successfully or B how do I solve these dependencies.
The result needs to be a shared library (.so) for linux and armv5te
Requirements
wsl or linux installed
cargo and rustc installed
(everthing is done in wsl/linux)
Prep/Build
Install cross on cargo
cargo install cross --git https://github.com/cross-rs/cross
Install docker
Clone the cross repository
Navigate into the docker folder
Create a new file with the name "Dockerfile.armv5te-unknown-linux-gnueabi-cross"
Paste this in the new file:
FROM ubuntu:16.04
ARG DEBIAN_FRONTEND=noninteractive
COPY common.sh lib.sh /
RUN /common.sh
COPY cmake.sh /
RUN /cmake.sh
COPY xargo.sh /
RUN /xargo.sh
RUN apt-get update && apt-get install --assume-yes --no-install-recommends \
g++-arm-linux-gnueabi \
crossbuild-essential-armel \
libc6-dev-armel-cross
COPY deny-debian-packages.sh /
RUN TARGET_ARCH=armel /deny-debian-packages.sh \
binutils \
binutils-arm-linux-gnueabi
# Qemu is disabled since we've changed the scripts to require newer Python versions.
#COPY qemu.sh /
#RUN /qemu.sh arm
COPY qemu-runner base-runner.sh /
ENV CROSS_TOOLCHAIN_PREFIX=arm-linux-gnueabi-
ENV CROSS_SYSROOT=/usr/arm-linux-gnueabi
ENV CARGO_TARGET_ARMV5TE_UNKNOWN_LINUX_GNUEABI_LINKER="$CROSS_TOOLCHAIN_PREFIX"gcc \
CARGO_TARGET_ARMV5TE_UNKNOWN_LINUX_GNUEABI_RUNNER="/qemu-runner arm" \
AR_armv5te_unknown_linux_gnueabi="$CROSS_TOOLCHAIN_PREFIX"ar \
CC_armv5te_unknown_linux_gnueabi="$CROSS_TOOLCHAIN_PREFIX"gcc \
CXX_armv5te_unknown_linux_gnueabi="$CROSS_TOOLCHAIN_PREFIX"g++ \
BINDGEN_EXTRA_CLANG_ARGS_armv5te_unknown_linux_gnueabi="--sysroot=$CROSS_SYSROOT" \
QEMU_LD_PREFIX="$CROSS_SYSROOT" \
RUST_TEST_THREADS=1 \
PKG_CONFIG_PATH="/usr/lib/arm-linux-gnueabi/pkgconfig/:${PKG_CONFIG_PATH}"
Make sure the project uses "LF" newlines. if not this fixes it.
Compile the custom cross/docker build using the following command in the root of the cloned repository:
cargo build-docker-image armv5te-unknown-linux-gnueabi-cross
This will create a new docker image that will be used to compile the rust code.
Then navigate to your target project folder and run:
export CROSS_TARGET_ARMV5TE_UNKNOWN_LINUX_GNUEABI_IMAGE=ghcr.io/cross-rs/armv5te-unknown-linux-gnueabi-cross:local
(Do not close this terminal)
Now add the following to the Cargo.toml file:
[package.metadata.cross.build]
default-target = "armv5te-unknown-linux-gnueabi"
now you can run:
cross build
Many cargo options like "--release" can be used (for more info have a look at cross in the credits)
Credits
MeetTitan(Stackoverflow) who recomended me to use cross
Cross project(GitHub) which powers the whole solution
Custom cross version discussion(Cross Github)
Alexhuszagh(Cross Github) who showed me how to build a custom cross version
Emilgardis(Cross Github) who explained the newline bug

Yocto - adding out of tree kernel module

I would like to add a wifi out-of-tree kernel module to my Yocto project. I found a layer on Open Embedded Layer Index with the driver that I need (https://layers.openembedded.org/layerindex/branch/master/layer/meta-rtlwifi/). I cannot build an image because I get the following error from bitbake:
install: cannot stat
'build/tmp/work/<machine_dir>/rtl8821cu/5.8.1.2-git-r0/git/8821cu.ko': No
such file or directory WARNING: exit code 1 from a shell command.
This file should be created by Makefile, but I have no errors generating by make.
The recipe for the driver is as follows:
SUMMARY = "RTL8821CU kernel driver (wifi)"
DESCRIPTION = "RTL8821CU kernel driver"
LICENSE = "GPLv2"
LIC_FILES_CHKSUM = "file://LICENSE;md5=b234ee4d69f5fce4486a80fdaf4a4263"
SRCREV = "2dace83e5f4cada52bbe3930b864c3eb82390b1f"
SRC_URI = "git://github.com/spriteguard/rtl8821CU;protocol=https "
S = "${WORKDIR}/git"
PV = "5.8.1.2-git"
DEPENDS = "virtual/kernel"
inherit module
#This is the only line added by me to this recipe because sh wasn't able to find `bc`
EXTRA_OEMAKE += "-I${S}/usr/bin' "
EXTRA_OEMAKE += "ARCH=${ARCH}"
EXTRA_OEMAKE += "KSRC=${STAGING_KERNEL_BUILDDIR}"
MODULES_INSTALL_TARGET="install"
do_install () {
install -d ${D}${nonarch_base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/net/wireless
install -m 0644 ${B}/8821cu.ko ${D}${nonarch_base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/net/wireless/rtl8821cu.ko
}
FILES_${PN} += "${nonarch_base_libdir}/modules/${KERNEL_VERSION}/kernel/drivers/net/wireless/rtl8821cu.ko"
RPROVIDES_${PN} += "kernel-module-${PN}-${KERNEL_VERSION}"
I have tried to add the following task:
do_compile () {
oe_runmake
}
But it changed nothing. I needed to add one line to this recipe: EXTRA_OEMAKE += "-I${S}/usr/bin' " because sh wasn't able to find bc. Maybe bitbake doesn't see one more file/library?
When I cloned the repo on my PC and just run make, the file *.ko was created. What can cause problems in Yocto with creating this module? I use the official layer and recipe so I suppose it should works.
You have to replace SRCREV. Because as far as I can see, the SRCREV of the above recipe is using the old version. You can check "git log" and choose the latest commit.
I used master branch and bitbake successfully.

Yocto install a script along with a kernel module

I want to install a script into target rootfs that will help set up a driver. I tried doing something like this (as I wanted it to be installed along the kernel module):
SUMMARY = "Kernel module with script"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "\
file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
inherit module
SRC_URI = "file://Makefile"
SRC_URI += "file://char-drv-ll.c"
SRC_URI += "file://start-char-drv-ll.sh"
S = "${WORKDIR}"
# The inherit of module.bbclass will automatically name module packages with
# "kernel-module-" prefix as required by the oe-core build environment.
RPROVIDES_${PN} += "kernel-module-char-drv-ll"
do_install_append() {
install -d ${D}${bindir}
install -m 0755 ${S}/start-char-drv-ll.sh ${D}${bindir}
}
RDEPENDS_${PN} += "bash"
FILES_${PN} += "${bindir}/start-char-drv-ll.sh"
However, after running the image in QEMU, I see that module is installed, but the script is nowhere to be found.
Where am I wrong in my reasoning?

Yocto build for a static library fails with error "No Match Found"

I am trying to include a Yocto recipe in the image which I wrote for static library.
Created recipes-test/static folder in my own layer .
Created 'static_0.1.bb' file in this folder
Created 'files' folder inside the 'recipes-test/static' folder
Copied the below files.
hello.c
char * hello (void)
{
return "Hello";
}
world.c
char *world(void)
{
return "World";
}
helloworld.h
#ifndef HELLOWORLD_H
#define HELLOWORLD_H
char * hello (void);
char * world (void);
#endif
Created recipe with the following content:
DESCRIPTION = "Simple helloworld example static library"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = " file://hello.c \
file://world.c \
file://helloworld.h "
S = "${WORKDIR}"
do_compile() {
${CC} -c hello.c world.c
${AR} -cvq libhelloworld.a hello.o world.o
}
do_install() {
install -d ${D}${includedir}
install -d ${D}${libdir}
install -m 0755 helloworld.h ${D}${includedir}
install -m 0755 libhelloworld.a ${D}${libdir}
}
When i say bitbake static , static library is created in the tmp/work folder
When i included it in conf/local.conf file with the following line:
IMAGE_INSTALL_append = " static"
The build fails at the root file creating stage with the following error:
not found other for:
not found modules for:
not found deltainfo for:
not found updateinfo for:
oe-repo: using metadata from Tue 02 Jul 2019 03:54:50 AM UTC.
No module defaults found
No match for argument: static
Error: Unable to find a match
Can you please help me to resolve the error
Update: After changing IMAGE_INSTALL_append = " static-staticdev", i get the following error:
No module defaults found
--> Starting dependency resolution
--> Finished dependency resolution
Error:
Problem: package static-staticdev-0.1-r0.cortexa7t2hf_neon_vfpv4 requires static-dev = 0.1-r0, but none of the providers can be installed
- conflicting requests
- nothing provides static = 0.1-r0 needed by static-dev-0.1-r0.cortexa7t2hf_neon_vfpv4
(try to add '--skip-broken' to skip uninstallable packages or '--nobest' to use not only best candidate packages)
Yocto will automatically split up the files installed in ${D} into different packages. In your case the helloworld.h will go into ${PN}-dev (${PN} equals static in your case, but I write ${PN} to avoid confusion) and libhelloworld.a will go into ${PN}-staticdev, but since there's no other files there will not be a package called ${PN} since it would be empty.
If you really want the static library to end up in the image, use IMAGE_INSTALL_append = "static-staticdev"
There's also a problem that there is no file that will be included in the plain ${PN} package, which with the default settings means that no such package will be created. This is a problem since the ${PN}-dev package has a runtime dependency on ${PN}. This can be solved by allowing the creation of ${PN} even if it's empty, enable this by adding ALLOW_EMPTY_${PN} = "1"

Bitbake recipe to have pre and post install action

I am writing an custom recipe for the Bitbake for an Makefile based project. We are able to create the RPMs with all the files place in the package but we are not able to find a way for pre and post install action.
As the application runs as service we want to stop it in pre-install step and then start it in post-install step.
But I am not able to find the same so any thoughts to achieve it.
Below is the sample recipe we written for it.
DESCRIPTION = "Simple helloworld application"
SECTION = "examples"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
PR = "r0"
SRC_URI = "file://helloworld.c"
DEPENDS = "boost"
S = "${WORKDIR}"
do_compile() {
${CC} helloworld.c -o helloworld
}
PACKAGES = "helloworld"
do_install() {
install -d ${D}${bindir}
install -m 0755 helloworld ${D}${bindir}
install -d ${D}${sysconfig}/init.d
install -m 0755 ${S}/service ${D}${sysconfig}/init.d
}
I do see INITSCRIPT_PACKAGES and INITSCRIPT_PARAMS but their description doesn't talk about being pre and post action.
So any thoughts for putting %pre and %post (in terms of RPM spec) for this purpose.
You can add post install scripts in your .bb:
pkg_postinst_PACKAGENAME() {
#!/bin/sh -e
# Commands to carry out
}
Reference: Section 5.3.16 http://www.yoctoproject.org/docs/1.7.1/mega-manual/mega-manual.html
According to the documentation the examples only runs during image creation time. There is also another function that will only run on the first boot (and never after it). It uses the meta/recipes-devtools/run-postinsts recipe to accomplish this.
I ran into the same issue. See this post for how I did the post install script. Hopefully you can glean from that answer enough to modify it for your script.

Resources