Reputation: 99
I need to figure out how to manage a recipe for a package based on CMake creating a very simple shared library. The goal is to provide the .so library into the Yocto build system in an atomic way, so can be used by other recipes managing application level.
This is the simple cpp code
#include <iostream>
#include "Student.h"
using namespace std;
Student::Student(string name):name(name){}
void Student::display(){
cout << "A student with name " << this->name << endl;
}
This is kind of CMakeList.txt
cmake_minimum_required(VERSION 2.8.9)
project(directory_test)
set(CMAKE_BUILD_TYPE Release)
#Bring the headers, such as Student.h into the project
include_directories(include)
#However, the file(GLOB...) allows for wildcard additions:
file(GLOB SOURCES "*.cpp")
#Generate the shared library from the sources
add_library(testStudent SHARED ${SOURCES})
#Set the location for library installation
install(TARGETS testStudent DESTINATION lib)
install(FILES student.h DESTINATION include)
This is the recipe studentlib_0.1.bb
SUMMARY = "Cmake application - creates a library"
SECTION = "examples"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "\
file://CMakeLists.txt \
file://student.cpp \
file://student.h \
"
S = "${WORKDIR}"
inherit cmake
EXTRA_OECMAKE = ""
The problem is when I build the specific recipe studentlib
$ bitbake studentlib
...
Build Configuration:
BB_VERSION = "1.38.0"
BUILD_SYS = "x86_64-linux"
NATIVELSBSTRING = "universal"
TARGET_SYS = "arm-poky-linux-gnueabi"
MACHINE = "qemuarm"
DISTRO = "poky"
DISTRO_VERSION = "2.5.2"
TUNE_FEATURES = "arm armv5 thumb dsp"
TARGET_FPU = "soft"
...
NOTE: Executing RunQueue Tasks
ERROR: studentlib-0.1-r0 do_package_qa: QA Issue: -dev package contains non-symlink .so: studentlib-dev path '/work/armv5e-poky-linux-gnueabi/studentlib/0.1-r0/packages-split/studentlib-dev/usr/lib/libtestStudent.so' [dev-elf]
ERROR: studentlib-0.1-r0 do_package_qa: QA run found fatal errors. Please consider fixing them.
ERROR: studentlib-0.1-r0 do_package_qa: Function failed: do_package_qa
ERROR: Logfile of failure stored in: /home/me/yocto-qemuarm-sumo/poky/build/tmp/work/armv5e-poky-linux-gnueabi/studentlib/0.1-r0/temp/log.do_package_qa.21681
ERROR: Task (/home/me/yocto-qemuarm-sumo/poky/meta-me/recipes-cmake/studentlib/studentlib_0.1.bb:do_package_qa) failed with exit code '1'
How can I solve this Issue? I can't find any example for explanation.
Thanks
Upvotes: 4
Views: 6101
Reputation: 875
You should read the answer from qschulz to understand what's happening and why.
Still, here are my practical recommendations:
inherit cmake
, Bitbake works out of the box, if you follow the conventions, e.g.:TARGETS
you install()
in cmake. The filename sets the PN (package name) variable, which sets PROVIDES, see qschulzproject()
statementset_target_properties(some_target PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR})
do_install()
etc. in bitbakeUpvotes: 0
Reputation: 1763
In Yocto, files (which are installed in ${D} either manually in do_install or by the make, cmake, autotools, etc... in e.g. do_compile) are put in a package when they match one of the regular expression (or glob, not entirely sure about that) contained in FILES_foo.
One recipe can (and usually does) provide multiple packages. So you'd have multiple FILES_foo1 with their own paths to match.
In Yocto, the file is put in the first package where one of the paths in its FILE_foo matches the file. Even if the file matches the paths of other packages, it'll ever be in only one package, the first one.
FWIW, packages are created from leftmost to rightmost in PACKAGES variable in the recipe. By default, the PACKAGES variable is ${PN}-src ${PN}-dbg ${PN}-staticdev ${PN}-dev ${PN}-doc ${PN}-locale ${PACKAGE_BEFORE_PN} ${PN} (c.f. http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n292).
The default FILES_* variables are defined in bitbake.conf as well, c.f. http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf. Look for everything starting with FILES_.
In there, you can see that by default, FILES_${PN} has ${libdir}/lib*${SOLIBS} (c.f. http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n296) packaged. SOLIBS is, by default, .so.* (c.f. http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n280), which means only dot versions of libraries are packaged in the ${PN} package (if they are not matched by another package before). FILES_${PN}-dev on the other hand packages ${FILES_SOLIBSDEV} which defaults to ${base_libdir}/lib*${SOLIBSDEV} ${libdir}/lib*${SOLIBSDEV}, with SOLIBSDEV in turns defaults to .so (c.f. http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n313, http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n314 and http://git.yoctoproject.org/cgit.cgi/poky/tree/meta/conf/bitbake.conf#n283). Please note that library filenames should all start with lib to be able to be matched by the default FILES_*.
TL;DR: By default, lib*.so.* in FILES_${PN} and lib*.so in FILES_${PN}-dev.
That's the background needed to understand what is expected in which package. The issue is that -dev package should only contain lib*.so symlinks to versioned libraries (i.e. lib*.so.*). People usually expect versioned libraries so it's easy to know which version is installed and against which version a particular software should be linked against. If the version does not matter or if the major version only matters, those will then link to the unversioned or major versioned symlinks to the versioned library. Best practice dictates that behavior.
Two possible cases, either you only provide the unversioned library in which case the solution is to version your library in your cmake or in your recipe. Then everything works out of the box. Or you have a copy of your versioned library named as an unversioned library, in which case you should delete your copy and just make a symlink to the versioned library.
If that is not an option (but please really consider it), you can try to find a way so that ${PN}-dev does not have this library. There are multiple options: add lib*.so to FILES_${PN} and either remove the ${PN}-dev from the PACKAGES, remove lib*.so from FILES_${PN}-dev, unset FILES_${PN}-dev, ...
Upvotes: 5