BitBake: example not found in the base feeds - package

I have a BitBake recipe (example_0.1.bb) with a do_install task where I attempt to install a .so file:
do_install() {
install -d ${D}${libdir}
install -m 0644 ${S}/example.so ${D}${libdir}
}
FILES_${PN} += "${libdir}/example.so"
This fails during the build process and returns:
ERROR: example not found in the base feeds
However, if I add a test file to the package, both the .so file and the test file are added to the rootfs.
do_install() {
install -d ${D}${libdir}
install -m 0644 ${S}/example.so ${D}${libdir}
echo "bar" >> ${TOPDIR}/foo
install -m 0644 ${TOPDIR}/foo ${D}${libdir}
}
FILES_${PN} += "${libdir}/libceill.so"
FILES_${PN} += "${libdir}/foo"
How can I add only the .so file without the junk test file?

So you've got a library that is non-standard in that it's not installing a versioned library (libfoo.so.1.2.3, maybe symlinks such as libfoo.so.1 -> libfoo.so.1.2.3), and then an unversioned symlink for compilation time (libfoo.so -> libfoo.so.1). The default packaging rules assume standard libraries.
What's happening is that packages are populated by their order in PACKAGES, which has PN-dev before PN. FILES_PN-dev by default contains /usr/lib/lib*.so, and FILES_PN contains /usr/lib/lib*.so.. When you add /usr/lib/lib.so to FILES_PN what you want to happen isn't happening because PN-dev has already taken the files.
If your library doesn't come with any development files at all (e.g. no headers) then you can set FILES_${PN}-dev = "" to empty that package, and then your addition of lib*.so to FILES_${PN} will work as expected.
Yes, this is something that we should make easier (I've been thinking about a small class for libraries like this) and warn in sanity checks when it happens.
Oh and I'm surprised that the library ends up in the image in your second example, as example will contain /usr/lib/foo and example-dev will contains /usr/lib/libceill.so. Unless of course you've got dev-pkgs enabled, which will automatically install example-dev if you've got example in an image.

Add the line
FILES_SOLIBSDEV = ""
An explanation from the Yocto mailing list:
I had FILES_${PN} += “${libdir}/.so” in there and that didn't work.
Maybe it was because I was missing the FILES_SOLIBSDEV = “" you mentioned.
I'll play with it some more and see what happens. I first started out with
FILES_${PN} += “${libdir}/.so” and when that didn't work I tried other
things in the FILES_${PN} = line to try and get it picked up. When I
couldn't get any of it to work and then saw others (well, at least the link
I provided) were seeing the same thing I figured it was time to quit
spinning my wheels and consult the big guns :)
Heh :) The issue there is that the patterns are matched in the order of the
PACKAGES variable. The first package to include a file gets it, and
${PN}-dev is in PACKAGES before ${PN}. By emptying FILES_SOLIBSDEV, that’ll
remove the .so from FILES_${PN}-dev, letting the ${PN} package get it
instead.

Add the line:
FILES_${PN}_dev_remove="${FILES_SOLIBDEV} "
It will move out the package for development path.

Related

How to build a debuginfo RPM without source code?

I'm working with a proprietary code base where the owner would like users to get useful stack traces but not be able to view the source code. Generating Debian dbg packages with debug symbols but no source code is straightforward but the Redhat debuginfo RPMs are automatically created with source code.
Is there a way of configuring rpmbuild to build a debuginfo RPM without source code?
If not, what's the best way to remove the source code from a debuginfo package? Does anyone have a script to do it?
A -debuginfo package is just a sub-package, and can be created manually without source code. The automatic generation adds the necessary syntax to a spec file, but you can also do this manually, adding a debug info package in the spec file.
Disable automagic generation of *-debuginfo.rpm, run find-debuginfo.sh at the end of %install, and then remove the source files.
Another (and easier/cleaner) means to remove source files overrides this macro
%__debug_install_post \
%{_rpmconfigdir}/find-debuginfo.sh %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\
%{nil}
in the spec file, replacing %{_rpmconfigdir}/find-debuginfo.sh with a modified/customized find-debuginfo.sh script.
Include the modified script in the spec file like
SourceN: my-find-debuginfo.sh
and then use the macro
%{SOURCEn}
(where N == n, some small appropriate integer) instead of the default to generate debugging symbols without source code.
Just finished a round of testing and in the end we inserted the following into the .spec file somewhere above the %description tag:
# Override the macro that invokes find-debuginfo.sh to remove
# the source files before the debuginfo pkg is assembled.
# It would be nice to remove the entire /usr/src tree but
# rpmbuild is running a check-files utility that fails the
# build if /usr/src/debug/%{name} isn't there. Tried to
# just delete the contents but it's tricky getting an
# asterisk to expand properly so we remove the entire
# directory and then restore an empty one. Sigh!
%define __debug_install_post \
%{_rpmconfigdir}/find-debuginfo.sh %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}";\
rm -rf "${RPM_BUILD_ROOT}/usr/src/debug/%{name}"; \
mkdir "${RPM_BUILD_ROOT}/usr/src/debug/%{name}"; \
%{nil}
This works for RHEl 6 and 7 but results in a bash error in RHEl 5 so we avoid building a debuginfo package for the latter by not installing the redhat-rpm-config package.
We decided to avoid creating a modified find-debuginfo.sh script as suggested because there are already differences between different platforms and we preferred a single patch that would work for all targets including future new ones. This isn't perfect but is as close as we came up with.
CentOS 7 needed a slight modification of Guy's solution. Here's what I'm using successfully:
# Remove source code from debuginfo package.
%define __debug_install_post \
%{_rpmconfigdir}/find-debuginfo.sh %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"; \
rm -rf "${RPM_BUILD_ROOT}/usr/src/debug"; \
mkdir -p "${RPM_BUILD_ROOT}/usr/src/debug/%{name}-%{version}"; \
%{nil}
The following can be used to verify the source code is no longer contained within the RPM:
rpm -qpl xxx-debuginfo-1.0.0-1.el7.x86_64.rpm

Autotools suite misplaces "man" file leading to installation failure

In a software I have to tweak, the man file is located under doc/ along with a simple Makefile.am file:
man_MANS = software.1
EXTRA_DIST = $(man_MANS)
Upon installation, I expect make install to copy the manual under /usr/local/share/man/, but the script - instead - will try to install the man under /usr/local/share/man/man1 - which does not exist - throwing an error and stopping the process.
I would expect a similar behavior if I assigned software.1 to man1_MANS, though.
What is going on ? How is this possible that automake does not create non-existing folders ?
man_MANS will try to figure out in which section to put the manual depending on the extension you gave it, so it is correct in this case that it would install into ${mandir}/man1.
Since you say that MKDIR_P is empty in your output, try to ensure that AC_PROG_MKDIR_P is being called in your configure.ac (it should be automatically called by AM_INIT_AUTOMAKE but since you said it's old it might have some issues).

Makefile - Just make install (copy files), no target to build

I have a simple makefile project where I just want make install to copy files to a target folder, ie:
all:
#echo "Nothing to build"
install:
cp ./*.wav /usr/share/snd
my_custom_target:
#echo "For testing purposes"
However, whenever I try to build any targets (ie: clean, all, install, my_custom_target, etc), every single one just echos "Nothing to be done for 'clean'", "Nothing to be done for 'all'", etc. My guess is that a makefile project is expecting at least something being built (ie: C/C++ file, etc).
Does anyone have any suggestions on how to proceed with this?
Thank you.
This seems to indicate that make is not able to find, or not able to correctly parse, your Makefile. What is the file named?
Also, ensure that the commands in each rule (like the cp ./*.wav /usr/share/snd) are prefixed by an actual tab character, not spaces. In the sample that you pasted in, they are prefixed simply by three spaces, but for make to parse it properly, they need to be prefixed by an actual tab character.
One more thing to check is whether there are files named all, install, or my_custom_target. Make does not care about whether some C or C++ file is built; the rules can do anything that you want. But it does check to see if there is a file named the same as the rule, and whether it is newer than the dependencies of the rule. If there is a file, and it is newer than all dependencies (or there are no dependencies, like in this example), then it will decide that there is nothing to do. In order to avoid this, add a .PHONY declaration to indicate that these are phony targets and don't correspond to actual files to be built; then make will always run these recipes, whether or not there is an up-to-date file with the same name.
.PHONY: all install my_custom_target

Installing a new library in Linux, and accessing it from my C code

I am working on a project which requires me to download and use this. Inside the downloaded folder, when extracted I am presented with three things:
A folder called "include"
A folder called "src"
A file called "Makefile"
After some research, I found out that I have to navigate to the directory which contains these files, and just type in the command make.
It seemed to install the library in my system. So I tried a sample bit of code which should use the library:
csp_conn_t * conn;
csp_packet_t * packet;
csp_socket_t * socket = csp_socket(0);
csp_bind(socket, PORT_4);
csp_listen(socket, MAX_CONNS_IN_Q);
while(1) {
conn = csp_accept(socket, TIMEOUT_MAX);
packet = csp_read(conn, TIMEOUT_NONE);
printf(“%S\r\n”, packet->data);
csp_buffer_free(packet);
csp_close(conn);
}
That's all that was given for the sample server end of the code. So I decided to add these to the top:
#include <csp.h>
#include <csp_buffer.h>
#include <csp_config.h>
#include <csp_endian.h>
#include <csp_interface.h>
#include <csp_platorm.h>
Thinking I was on the right track, I tried to compile the code with gcc, but I was given this error:
csptest_server.c:1: fatal error: csp.h: No such file or directory
compilation terminated.
I thought I may not have installed the library correctly after all, but to make sure, I found out I could check by running this command, and getting this result:
find /usr -iname csp.h
/usr/src/linux-headers-2.6.35-28-generic/include/config/snd/sb16/csp.h
/usr/src/linux-headers-2.6.35-22-generic/include/config/snd/sb16/csp.h
So it seems like the csp.h is installed, maybe I am referencing it incorrectly in the header include line? Any insight? Thanks a lot.
The make command is probably only building the library, but not installing it. You could try sudo make install. This is the "common" method, but I recommend you to check the library's documentation, if any.
The sudo command is only necessary if you have no permissions to write the system's include and library directories, which may be your case.
Another possibility (instead of installing the library) is telling GCC the location of the library's source code and generated binaries (by means of the -I and -L options of the gcc command.
That Makefile will not install anything, just translate the source into a binary format.
The csp.h in the Linux kernel has nothing to do with your project, it's just a naming collision, likely to happen with three letter names.
In your case, I would presume you need to add the include directory to the compilation flags for your server, like gcc -I/path/to/csp/include/csp csptest_server.c.
(Next, you'll run into linker errors because you'll also want to specify -L/path/to/csp -lcsp so that the linker can find the binary code to link to.)

Injecting mercurial changeset as version information in a C executable

I would like the executables for a project I am working on to have the latest mercurial changeset recorded so that when a user complains about buggy behavior, I can track which version they are using. Some of my executables are Python and others are compiled C. Is there a way to automate this, or can you point me to projects that exhibit solutions that I can look at?
I am using autoconf in my project... in case that makes the solution easier.
Thanks!
Setjmp
A common way to do this is with m4_esyscmd. For example, autoconf distributes a script in build-aux which generates a version number from the git repo and invokes AC_INIT as:
AC_INIT([GNU Autoconf], m4_esyscmd([build-aux/git-version-gen .tarball-version]),
[bug-autoconf#gnu.org])
You can often get away without distributing the script and do something simple like:
AC_INIT([Package name], m4_esyscmd([git describe --dirty | tr -d '\012']),
[bug-report-address])
Instead of git-describe, use whatever command you want to generate the version number. One important detail is that it should not have a trailing newline (hence the tr following git-describe).
A major drawback with this technique is that the version number is only generated when you run autoconf.
Add this to configure.ac:
AM_CONDITIONAL([IS_HG_REPO], [test -d "$srcdir/.hg"])
Add the following lines to Makefile.am:
if IS_HG_REPO
AM_CPPFLAGS = -DHGVERSION="\"$(PACKAGE) `hg parents --template 'hgid: {node|short}'`\""
else
AM_CPPFLAGS = -DHGVERSION=PACKAGE_STRING
endif
This will define HGVERSION as a string of the form APPNAME hgid: 24d0921ee4bd or APPNAME VERSION, if building from a release tarball.
See wiki page on versioning with make

Resources