Yocto: closed source library with separated packages for library and header - embedded-linux

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

Related

CMake get dependent header files like gcc -M

I'm analyzing a CMake project and I want to get all the header files that a source file depends on. Is there a tool or a command like gcc -M or g++ -M to list all the dependencies of one file in the CMake project? It would be better if I could also get which Target each header file belongs to.
Of course I can’t use g++ -M directly because it can’t find some dependencies organized by CMakeLists.txt.
Since the cmake command will generate MakeFile, a tool or command for Make may may also work for me.
Check the build folder for your CMake project. For each target, CMake should generate a file called C.includecache. This file contains the include dependency information.
If, for example, you have a main.c file which is including the stdio.h and math.h headers. The C.includecache file will contain an entry like:
/path/to/main.c
stdio.h
-
math.h
-

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.

How to bitbake copy a prebuilt static library into the sdk

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.

"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