How to bitbake copy a prebuilt static library into the sdk - embedded-linux

Scenario:
I am working with yocto linux recipes. I am trying to make a recipe which simply copies a prebuilt MyLibrary.a and its headers available on the built linux image. So, I have a libMyLibrary.a which I want to copy to /usr/lib. And MyLibrary's headers files MyLibrary.h and MyLibrary.hpp into /usr/include. Note that MyLibrary is already built and I just want to copy the binary and headers into desired locations of the built linux image.
So following is the recipe:
SUMMARY = "Script to make a static library available in yocto linux image"
LICENSE = "CLOSED"
FILES_${PN} += "${libdir}"
SRC_URI = "file://libMyLibrary.a \
file://MyLibrary..hpp \
file://MyLibrary..h \
"
S = "${WORKDIR}"
do_install () {
install -d ${D}${libdir}
install -d ${D}${includedir}
install -m 0644 ${WORKDIR}/libMyLibrary.a ${D}${libdir}/
install -m 0644 ${WORKDIR}/MyLibrary.h ${D}${includedir}/
install -m 0644 ${WORKDIR}/MyLibrary.hpp ${D}${includedir}/
}
Initially I started with getting some errors in the do_install step. I resolved them but now the do_rootfs step is complaining about my bb file that is mylibrary_1.0.bb. I am pretty sure that the parent recipe that calls my recipe has no errors since it builds a lot of other recipes and mine is just additional to it. Also, the errors started to appear after I wrote the do_install step.
Question
Can someone point out what is wrong with my recipe above?
Or is there a simple example recipe which copies a .a and its headers into the desired location i.e. /usr/lib and /usr/include like I am doing above?

Explaining what the errors are would be useful. Note that because your recipe only ships a static library and headers it won't generate a mylibrary package, which is probably what the errors are about.

Related

I want to build my own operating system , but how install i686-elf-gcc in manjaro

I want to build my own operating system , but how install i686-elf-gcc in manjaro
i I found a tool(https://github.com/lordmilko/i686-elf-tools), but it can only be run in ubuntu
A simple solution would be to build the compiler yourself. I went through the same thing recently. If you are into operating system development, you won't be able to avoid looking at the compiler in more detail and building cross compilation tools anyway.
Building your own compiler
The build process can be roughly divided into 4 steps:
Install all dependencies necessary for the build. If I remember correctly, you can get everything from the official package sources in Arch Linux. Make sure that these packages/tools are present: make, bison, flex, gmp, mpc, mpfr, texinfo, libisoburn, mtools.
Download the source code of binutils (GNU's assembler and binary tools) and gcc (the GNU compiler collection). I recommend using the newest versions at the bottom of the respective pages.
Decide where your new compiler should be installed. Although it sounds tempting, it should not end up in any system directory, rather somewhere in your home folder. I used $HOME/tools/crc to store my cross-compilation tools. You can at it to your $PATH lateron for convenience.
Do the actual build. First of all: The build takes a while and needs one or the other command line switch. Do not omit any of them. The build may pass and problems may occur later. Just follow the instructions below.
The actual build process
The first thing to do is to compile binutils, because it is needed for the gcc build. For convenience set a few shell variables to minimize error sources:
# This is where the tools will end up
export PREFIX="$HOME/tools/crc"
# Prefix of the produced assemblies (for example i686-elf-gcc)
export TARGET=i686-elf
# Add the new installation to the PATH variable temporarily
# since it is required for the gcc build
export PATH="$PREFIX/bin:$PATH"
Now create a new directory somewhere and extract both the gcc and binutils source code archives in there. You should end up with two subdirectories like yourdir/binutils-x.y.z and yourdir/gcc-x.y.z. It is recommended to do the build in an empty directory, so create yourdir/build-binutils and yourdir/build-gcc as well. Notice: These directories are not placed inside the source directories!
Building binutils
cd into the yourdir/build-binutils directory and run the following commands. Replace the x.y.z part with your version.
../binutils-x.y.z/configure \
--target=$TARGET \
--prefix="$PREFIX" \
--with-sysroot \
--disable-nls \
--disable-werror
make
make install
Now check the installation with which -- $TARGET-as. This will return the location of i686-elf-as, which is the assembler we just build.
Building gcc
cd into the yourdir/build-gcc directory. The process is pretty much the same as with binutils above:
../gcc-x.y.z/configure \
--target=$TARGET \
--prefix="$PREFIX" \
--disable-nls \
--enable-languages=c,c++ \
--without-headers
make all-gcc
make all-target-libgcc
make install-gcc
make install-target-libgcc
Verify the build
Check the installation by invoking i686-elf-gcc --version. If you used the same values as I, this can be done with $HOME/tools/crc/bin/$TARGET-gcc --version.

Yocto: closed source library with separated packages for library and header

I have my own .so closed source library and provide header file. My .so library file should be inside the yocto image, but header file should be used during another projects compilation only.
Here is yocto receipt:
SUMMARY = "foo library"
LICENSE = "CLOSED"
SECTION = "libs"
SRC_URI = "file://usr/lib/libfoo.so \
file://usr/include/foo.h "
S = "${WORKDIR}"
inherit autotools pkgconfig
do_compile() {
}
do_install() {
install -d ${D}/usr/lib
install -m 0755 ${WORKDIR}/usr/lib/libfoo.so ${D}/usr/lib/libfoo.so.1
ln -s /usr/lib/libfoo.so.1 ${D}/usr/lib/libfoo.so
install -d ${D}/usr/include
install -m 0644 ${WORKDIR}/usr/include/foo.h ${D}/usr/include/
}
FILES_${PN}-dev += "${includedir} "
FILES_${PN} += "/usr/lib/libfoo.so \
/usr/lib/libfoo.so.1"
PROVIDES += "libfoo"
I expect ${PN} package has libfoo.so and libfoo.so.1 and ${PN}-dev package has only one header file. But yocto bitbake copies only libfoo.so.1 in ${PN} and libfoo.so is in ${PN}-dev packet.
Could you please help me how to move so file into ${PN} package?
The behavior is correct here. Non-versioned .so files are installed in the -dev package because packages in the system should link against versioned files.
It is pretty uncommon to need to install a -dev package in an image, so effectively, only your versioned so file will make it.
As you saw already, the header is in the -dev package so won't make it to the image except if the -dev package is explicitly added to the image.
Because your header file is in includedir which is one of the directories used for the sysroot of other recipes (c.f. SYSROOT_DIRS), it'll be available to other recipes at build time. Same for your library as it's installed in lib_dir (also in aforementioned variable).
So the current behavior is expected. It is not clear why exactly you want your non-versioned symlink in the main package too.
If for some reason it's really what you want to do, you just need to add the following to your recipe:
SOLIBS = ".so"
FILES_SOLIBSDEV = ""
c.f. https://wiki.yoctoproject.org/wiki/TipsAndTricks/Packaging_Prebuilt_Libraries#Non-versioned_Libraries

how to avoid to include header files and static libs in bitbake package or image

When I tried to bitbake my image from my recipe file, I don't want to include header file and static libs in the image, but they are always packaged in *.ipk, then installed in the image.
Here is my recipe
FILES_{PN} += "${libdir}/*.so"
do_install () {
install -m 0444 ${S}/lib/*.so ${D}{libdir}
install -m 0444 ${S}/lib/*.a ${D}${libdir}/local/lib
install -m 0444 ${S}/include/*.h ${D}${libdir}/local/include
}
I include shared libs only, and add headers and static lib to system root to build my app, but not want them in the package.
Any idea?

Why am I getting `undefined reference to xxx` errors when all libraries and references needed are accounted for? [duplicate]

This question already has answers here:
Why does the order in which libraries are linked sometimes cause errors in GCC?
(9 answers)
Closed 2 years ago.
Essentially I am trying to use the redland rdf libraries but I cannot link to them. When I try a simple basic program which uses the redland libraries I get these errors:
/usr/local/lib/librdf.a(rdf_init.o): In function `librdf_free_memory':
/home/ciaran/Software/redland/redland-1.0.17/src/rdf_init.c:671: undefined reference to `raptor_free_memory'
/usr/local/lib/librdf.a(rdf_init.o): In function `librdf_alloc_memory':
/home/ciaran/Software/redland/redland-1.0.17/src/rdf_init.c:689: undefined reference to `raptor_alloc_memory'
/usr/local/lib/librdf.a(rdf_init.o): In function `librdf_calloc_memory':
/home/ciaran/Software/redland/redland-1.0.17/src/rdf_init.c:707: undefined reference to `raptor_calloc_memory'
At first glance, you might just think I have a missing link library, which is what I thought until I inspected further (see below), however, the libraries are all accounted for.
A proper minimal working example is difficult in this instance because it requires getting and building the libraries that I'm trying to use. However, I've created a GitHub repository
$ git clone git#github.com:CiaranWelsh/RedlandBuildTest.git
that contains the source files necessary for building the Redland libraries as well as the example code I'm using (which breaks).
In order to build the libraries, you will also need
$ sudo apt install automake autoconf libtool gtk-doc-tools
$ sudo apt install libxml2 libxml2-dev libxslt libxslt-dev libcurl4-openssl-dev libltdl-dev
Note, I'm working on Ubuntu-18.04 on windows subsystem for Linux.
To get, build and install the libraries I'm using these terminal commands:
#raptor2
wget "http://download.librdf.org/source/raptor2-2.0.15.tar.gz"
tar -xvf raptor2-2.0.15.tar.gz
cd raptor2-2.0.15
./autogen.sh
make
sudo make install
# redland (librdf)
wget "http://download.librdf.org/source/redland-1.0.17.tar.gz"
tar -xvf redland-1.0.17.tar.gz
cd redland-1.0.17
./autogen.sh
make
sudo make install
# rasqal
wget "http://download.librdf.org/source/rasqal-0.9.33.tar.gz"
tar -xvf rasqal-0.9.33.tar.gz
cd rasqal-0.9.33
./autogen.sh
make
sudo make install
Which are available in the github repository as shell scripts (get-raptor.sh, get-rasqal.sh and get-librdf.sh).
And my minimal CMake script (also in the repository):
cmake_minimum_required(VERSION 3.15)
project(RedlandBuildTest)
set(CMAKE_CXX_STANDARD 14)
find_library(RAPTOR2_STATIC_LIBRARY
NAMES libraptor2.a
PATHS /usr/local/lib
)
find_path(RAPTOR2_INCLUDE_DIR
NAMES raptor2.h
PATHS /usr/local/include/raptor2
)
find_library(RASQAL_STATIC_LIBRARY
NAMES librasqal.a
PATHS /usr/local/lib
)
find_path(RASQAL_INCLUDE_DIR
NAMES rasqal.h
PATHS /usr/local/include/rasqal
)
find_library(LIBRDF_STATIC_LIBRARY
NAMES librdf.a
PATHS /usr/local/lib
)
find_path(LIBRDF_INCLUDE_DIR
NAMES librdf.h
PATHS /usr/local/include
)
add_executable(RedlandBuildTest main.c)
target_include_directories(RedlandBuildTest PRIVATE
${RAPTOR2_INCLUDE_DIR}
${RASQAL_INCLUDE_DIR}
${LIBRDF_INCLUDE_DIR}
)
target_link_libraries(RedlandBuildTest PRIVATE
${RAPTOR2_STATIC_LIBRARY}
${RASQAL_STATIC_LIBRARY}
${LIBRDF_STATIC_LIBRARY}
curl
xml2
xslt
ltdl
)
get_target_property(LINK_LIBRARIES RedlandBuildTest LINK_LIBRARIES)
get_target_property(INCLUDE_DIRECTORIES RedlandBuildTest INCLUDE_DIRECTORIES)
message(STATUS "
LINK_LIBRARIES ${LINK_LIBRARIES}
INCLUDE_DIRECTORIES ${INCLUDE_DIRECTORIES}
")
message(STATUS "
RAPTOR2_STATIC_LIBRARY ${RAPTOR2_STATIC_LIBRARY}
RAPTOR2_INCLUDE_DIR ${RAPTOR2_INCLUDE_DIR}
RASQAL_STATIC_LIBRARY ${RASQAL_STATIC_LIBRARY}
RASQAL_INCLUDE_DIR ${RASQAL_INCLUDE_DIR}
LIBRDF_STATIC_LIBRARY ${LIBRDF_STATIC_LIBRARY}
LIBRDF_INCLUDE_DIR ${LIBRDF_INCLUDE_DIR}
")
And the output of the CMake command:
#(looks good)
LINK_LIBRARIES /usr/local/lib/libraptor2.a;/usr/local/lib/librasqal.a;/usr/local/lib/librdf.a;curl;xml2;xslt;ltdl
INCLUDE_DIRECTORIES /usr/local/include/raptor2;/usr/local/include/rasqal;/usr/local/include
RAPTOR2_STATIC_LIBRARY /usr/local/lib/libraptor2.a
RAPTOR2_INCLUDE_DIR /usr/local/include/raptor2
RASQAL_STATIC_LIBRARY /usr/local/lib/librasqal.a
RASQAL_INCLUDE_DIR /usr/local/include/rasqal
LIBRDF_STATIC_LIBRARY /usr/local/lib/librdf.a
LIBRDF_INCLUDE_DIR /usr/local/include
To build, I'm using CLion which just does this in the background:
mkdir build && cd build
CMake ..
make
Thus giving me linker errors. I have dug a little deeper by using nm to inspect the contents of the Redland libraries.
$nm -A librdf.a > librdf.a.nmoutput.txt
$nm -A libraptor2.a > libraptor2.a.nmoutput.txt
$nm -A librasqal.a > librasqal.a.nmoutput.txt
The first offending undfined reference error
/usr/local/lib/librdf.a(rdf_init.o): In function `librdf_free_memory':
/home/ciaran/Software/redland/redland-1.0.17/src/rdf_init.c:671: undefined reference to `raptor_free_memory'
is in function librdf_free_memory, which is a defined reference inside librdf.a
# librdf.a.nmoutput.txt
...
librdf.a:rdf_init.o:0000000000000740 T librdf_free_memory
...
When we look for the undefined reference to raptor_free_memory, we se that it is indeed undefined inside librdf.a..
#librdf.a.nmoutput.txt
...
librdf.a:rdf_init.o: U raptor_free_memory
...
But this should be in libraptor2.a anyway, and if we look we see that it is indeed there and defined as it should be:
# libraptor2.a.nmoutput.txt
...
libraptor2.a:raptor_general.o:0000000000000863 T raptor_free_memory
...
My understanding is that the process of linking should essentially fill the undefined reference inside librdf.a with the definition inside libraptor.a, but this clearly is not happening.
Why is this happening?
When your static libraries have dependencies on each other, the link order matters (see this response).
If librdf depends on the libraptor library (as indicated by the link error), the libraptor library should be listed after librdf when specified to the linker. Try re-arranging the list of libraries in your target_link_libraries() command to adhere to this ordering, based on your library dependencies.

"File format not recognized" when building Petalinux app

I am using Petalinux 2017.2 and the included tools to build a Linux image for a Zynq ZC702 board. I am trying to add a pre-compiled executable to my rootfs with a bitbake recipe.
SUMMARY = "Demo on ARM-Linux"
SECTION = "PETALINUX/apps"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = " \
file://Demo1.out \
"
FILES_${PN} = " \
/home/root/Demo/ \
/home/root/Demo/Demo1.out \
"
S = "${WORKDIR}"
do_install() {
install -d ${D}/home/root/Demo
install -m 0755 ${S}/Demo1.out ${D}/home/root/Demo
}
When I attempt to build the rootfs with my app included I get this error:
ERROR: demo-1.0-r0 do_package: objcopy failed with exit code 1 (cmd was 'arm-xilinx-linux-gnueabi-objcopy' --only-keep-debug '/home/common/peta_proj_2017.2_secure/build/tmp/work/cortexa9hf-neon-xilinx-linux-gnueabi/demo/1.0-r0/package/home/root/Demo/Demo1.out' '/home/common/peta_proj_2017.2_secure/build/tmp/work/cortexa9hf-neon-xilinx-linux-gnueabi/demo/1.0-r0/package/home/root/Demo/.debug/Demo1.out'):
arm-xilinx-linux-gnueabi-objcopy:/home/common/peta_proj_2017.2_secure/build/tmp/work/cortexa9hf-neon-xilinx-linux-gnueabi/demo/1.0-r0/package/home/root/Demo/Demo1.out: File format not recognized
ERROR: demo-1.0-r0 do_package: Function failed: split_and_strip_files
I assume objcopy has an issue with my file having been compiled for arm-linux-gnueabihf, but I already know it works since I've tried copying it to the rootfs manually after Linux is booted and tested it. I would try to recompile it with the arm-xilinx-linux-gnueabi toolchain but it's missing some of the libraries I need. I don't know why objcopy is being called for this operation anyway. All I want is for it to move the file to the rootfs, but for some reason it's doing all this extra work on it. Is there a way I can make bitbake ignore the file's format?
looks like the problem is that objcopy is trying to strip symbols, and as you said, the toolchain used is not the same as the one it was used to build it.
You can try to setting:
INHIBIT_PACKAGE_STRIP="1"
somewhere (perhaps in your local.conf).
It should skip the step on which the build system tries to strip debug symbols from binaries hence will probably not invoke objcopy.
1 [https://www.yoctoproject.org/docs/current/mega-manual/mega-manual.html#var-INHIBIT_PACKAGE_STRIP]1

Resources