recipe also produces -native output that needs packaging - yocto

I have a recipe which successfully invokes a legacy build command to cross-compile a target.
As a side effect it produces some custom native tools that are used in the build.
I want to reap those tools into a -tools-native package to allow other recipes to depend the main package to access the artifacts, and use the -tools-native package to further process those artifacts.
I can build such a native package as simply as adding:
PROVIDES = "${PN} ${PN}-tools-native"
SYSROOT_DIRS += "/"
PACKAGES += "${PN}-tools-native"
FILES_${PN}-tools-native += "/native-bin/*"
and having the install section install the native tools to /native-bin/
but yet it somehow isn't a real native package, and when DEPENDS'd by an additional recipe the native-bin artifacts are installed inrecipe-sysrootinstead ofrecipe-sysroot-native`
I also have to install the tools 0644 or bitbake tries to strip them (and fails, as they are native build).
Because the native tools are already generated by the legacy build commands, I don't need to actually invoke as a -native recipe variant.
It's a long process, I don't want to run it twice, either.
Currently I work around it by having the other recipes DEPEND on recipe-native-tools and fixup the permissions and PATH
But what's the proper way to do this?

This is generally handled by separate recipes. There is no mechanism to share native binaries from target recipes as their task hashes have the wrong kinds of information in them (they change depending on the target architecture).
Target recipes don't install their bindir/sbindir into the sysroot since we can't run them and as you mention, they're the wrong architecture so they confuse strip and so on.
You could try having a native recipe which depended upon this target recipe and which installs the binaries saved by the target recipe somewhere into its ${D} at do_install. That may well give some warnings since in general native recipes shouldn't depend on target recipes but is probably your best option if you can't build twice.

Related

Yocto deploy Debug or Release prebuild?

I am writing a bitbake recipe to deploy a third party pre-built tool, similar to this wiki page: https://wiki.yoctoproject.org/wiki/TipsAndTricks/Packaging_Prebuilt_Libraries
However, I have a Release and Debug pre-build versions of the tool available as *.so files. How do I distinguish inside the recipe which one of both build types I shall deploy?
Thanks and regards,
Martin
You can have two different virtual recipes each with their own .so file. This then warrants a selection in a configuration file (with PREFERRED_PROVIDER_virtual/my-recipe), so either in a machine or distro configuration file. This is probably preferred if you consider having release and debug distros.
A second option is to install the libraries in two different paths, in two different PACKAGES (use FILES_my-package for that) and make them RCONFLICTS_my-package each other to be sure they can't both be in the rootfs. After that, you could write a pkg_postinst_my-package() task specific to each package that actually move the library from the "different" path to the intended one. This will be run both at build time when creating the rootfs and at runtime on first boot, so you need to make sure to exclude one or the other (it's usually done by checking if ${D} exists, which does at build time but not runtime).
c.f.: http://docs.yoctoproject.org/dev-manual/dev-manual-common-tasks.html#post-installation-scripts
If you can manage to have both libraries installed in your rootfs and select the one you want with the LIBRARY_PATH environment variable, a simple recipe, with two packages with each library in a different location, will be sufficient.

Library built but not part of rootfs

I have built images using yocto(core-image-minimal). I need "libtinfo" library to run my application, but it is not part of rootfs.
I could see the library was built and available under "cortexa7hf-neon-poky-linux-gnueabi" folder, but it is not available in rootfs. I have added using IMAGE_INSTALL_append.
My doubt here is, if the library is not required for rootfs(core-image-minimal) then it should not built.
Why the yocto built that library? similar behavior was observed with libudev library also.
Before answering your question, if you have an application which depends on "libtinfo" and your application is also build using yocto (say sample_app.bb), then you should use
DEPENDS += "libtinfo"
RDEPENDS_${PN} += "libtinfo"
This will instruct yocto to include the library in rootfs as your application needs it for runtime.
My doubt here is, if the library is not required for
rootfs(core-image-minimal) then it should not built.
Assume you have source for a package which produces binary and also library i.e for example source for kmod produces libkmod and also modprobe, insmod, rmmod. In such cases recipes are written in such a way to produce two different package (based on configuration you can see *.rpm or *.ipk) files i.e kmod_*.ipk/rpm and libkmod2_*.ipk/rpm.
Based on your real requirement of application you can either use kmod or libkmod in RDEPENDS.
In your case, libtinfo is build inside ncurses package which may not be required in rootfs by any package.
Why the yocto built that library? similar behavior was observed with
libudev library also.
By default the recipe for the source component ncurses or systemd includes the configuration (do_configure) for libtinfo and libudev respectively. But it is not included in rootfs, as none of the software needs it during runtime.
You can always check the dependency graph using
bitbake -g <recipe name>
as mentioned here.

Yocto recipes’ dependencies

I’m quite new to Yocto build system and I’m struggling on something I don’t understand. Actually, what’s the difference between :
DEPENDS= “foo”
and
DEPENDS=“foo-native”
I mean, I know the suffix -native indicates that the component foo will be built to run on the native host machine, but what are the consequences for the target machine ?
What does it change to switch a dependency to a -native dependency ?
As, in any case, everything is pre-built and pre-packaged on the host machine, where is the difference ?
DEPENDS are build time dependencies which allow you to specify which packages need to exist prior to building your recipe. So DEPENDS = "foo" would explicity state that the foo package needs to be successfully built and installed prior to my package starting it's do_configure (it might just be a dependency for do_compile, but I think it's do_configure) process. Using a -native for DEPENDS says that packages native components need to exist as well. A good example of this is the Google protobuf package. It has both native and target components, and you generally need both to use it. The protobuf-native package would include creating the protoc compiler, which would be required to build a pacakage that needs the protoc compiler to generate content. It would also need the protbuf package for it's runtime components as well to link against.
Generally, there are no consequences so to speak. The protoc in my example above doesn't exist on the target. That answer may depend on the package though, so it's not so simple to say it has none. Generally though, use -native if you need a native tool to help you build a target object.

How can I make a FindMyPackage.cmake module fall back to downloading?

I have a simple CMake find module I've written, for a library of mine used by other projects. It's pretty simplistic, with its full text available here. Mainly there's one find_path() and one find_library(), and then some variables are set.
Now, I want CMake, when trying to find my package, to fall back on:
git-cloning or downloading the package/library from its GitHub repository,
Unpacking the archive, if it was a download
Building the package, either be using the running CMake itself somehow (the package has its own CMakeLists.txt), or by running an arbitrary shell command in the directory into which the packages was downloaded/cloned
The specifics of what happens post-download are less important to me than actually having a download fall-back.
How can I / how should I make this happen?
Notes:
Of course if the download/git clone fails, than finding the package has failed.
No need to worry about specific versions at the repo, although you can if you want to.

Cross-compiling Makefile: dealing with test programs

I'm trying to cross-compile several libraries from OSX to iOS. I've successfully cross-compiled libjpeg and libogg.
But I can't compile libvorbis because configure insists on creating and running a small test program. This obviously fails, because it creates an armv7 binary, fails to run it, and then interprets this as missing ogg libraries.
How do you usually deal with this kind of problem? I'm tempted to hack the configure script to work around these issues, but because of this kind of failure some features may be disabled. I'm also thinking of letting configure generate a native Makefile and then convert it to use the iOS toolchain, but this seems too error prone.
Any advice?
If you are cross-compiling anything that has more dependencies than libc (glibc) it becomes much more complicated. You need to have already cross-compiled all the dependencies. And the cross-compiler toolchain and all helper build programs and scripts need to know how to find those dependencies (the cross-compiled libraries and headers).
You need to have already cross-compiled libogg (and its dependencies) and installed them into the cross-compile root directory. The headers and libraries from your build system can't be used for the host (arm7) system. They must be kept separate.
Also, if you want to have shared object libraries (*.so) and not just static libraries then there is a whole new set of complications. For example, while a cross-compiler toolchain contains a cross-compiled libc as part of the toolchain, you still need a libc for the host system. The libc that is part of the toolchain can be used for this, but the way it is structured is different than on the host system. Sometimes people copy and re-arrange the files, but often people just compile and install a new glibc for the root.
Anyways, all that to say, the two errors you are seeing are because the configure script is not able to find a cross-compiled libogg library. If you haven't already, you need to cross-compile libogg (and dependencies) and install them into your target root. Then you need to tell the configure script where your cross-compiled headers (yes, header are architecture specific) and libraries are in your target root. Usually using CFLAGS, LDFLAGS, CXXFLAGS, etc (NOT --prefix) but there may be other environment variables you need to set also to affect things like pkg-config, etc. After you have built each dependency, then you need to get the makefile to install the dependency to the root. Usually this is done with make DESTDIR=[root] install but some makefiles have their own mechanism (or no proper alternate install mechanism).
You may also need to override certain configure checks (using environment variables) that are poorly written and don't have good cross-compile defaults. These variables usually start with ac_cv_*
So the basic process is to do this for packages that you need (in dependency order):
export CFLAGS=-I[root]/usr/include LDFLAGS=-L[root]/usr/lib CXXFLAGS=-I[root]/usr/include
export ac_cv_[test1]=[yes|no] ac_cv_[test2]=[yes|no] ...
./configure --host=[arm7-blah-blah]
make
make DESTDIR=[root] install
Good luck. Once you feel comfortable with standard cross-compiling, then you will be ready to take on the real black art, the Canadian cross ;-)
I finally figured it out. I tricked configure by explicitly making it link with ogg (LDFLAGS="/usr/local/ios/lib/libogg-armv7.a" ./configure ...) and then removed the explicit reference to the library from the generated makefile.