2015-03-20 03:45:30 +03:00
# Makefile for C source code
#
# Copyright (C) 2015 Colin Walters <walters@verbum.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
include Makefile-lib-defines.am
lib_LTLIBRARIES += librpmostree-1.la
librpmostreeincludedir = $(includedir)/rpm-ostree-1
librpmostreeinclude_HEADERS = $(librpmostree_public_headers)
librpmostree_1_la_SOURCES = \
2017-07-13 23:39:01 +03:00
src/lib/rpmostree.c \
2015-03-20 03:45:30 +03:00
src/lib/rpmostree-db.c \
2015-04-16 05:20:57 +03:00
src/lib/rpmostree-package.c \
2015-03-20 03:45:30 +03:00
$(NULL)
librpmostree_1_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/libglnx -I$(srcdir)/src/libpriv -I$(srcdir)/src/lib \
2015-04-14 04:25:05 +03:00
-fvisibility=hidden '-D_RPMOSTREE_EXTERN=__attribute((visibility("default"))) extern' \
2015-03-20 03:45:30 +03:00
$(PKGDEP_RPMOSTREE_CFLAGS)
2016-06-29 04:33:02 +03:00
librpmostree_1_la_LDFLAGS = $(AM_LDFLAGS) -version-number 1:0:0 -Bsymbolic-functions
2020-12-16 23:26:03 +03:00
librpmostree_1_la_LIBADD = $(PKGDEP_RPMOSTREE_LIBS) libglnx.la
EXTRA_librpmostree_1_la_DEPENDENCIES = libdnf.so.2
2015-03-20 03:45:30 +03:00
Makefile.am: Link with --enable-new-dtags
When g-ir-scanner runs, it uses a stub binary to help introspect the
target rpm-ostree library. That binary needs to link to the library, and
of course, transitively, to our bundled libdnf. Since we run the scanner
uninstalled, we use `LD_LIBRARY_PATH` to point the stub at the libdnf
from the build directory.
When we compile rpm-ostree, we use `-rpath` to point it at our libdnf,
which emits a `DT_RPATH` attribute. However, during dynamic linking at
runtime, it turns out that `LD_LIBRARY_PATH` has *lower* precedence than
`DT_RPATH`. This means that if there is already a libdnf at
`/usr/lib64/rpm-ostree`, it takes precedence.
This subtlety is mostly fine to ignore usually, because the stub doesn't
actually run any rpm-ostree business logic, so it doesn't really matter
that it runs against the "technically wrong" `libdnf.so.2`.
Where it becomes obvious something is off however is if we've just
built a new libdnf, and we have new code which references symbols from
the new libdnf that aren't in the stale libdnf at `$libdir/rpm-ostree`.
And this is exactly what was happening in CI (though it's of course
possible to reproduce this locally as well): we were using a new symbol,
`hy_goal_favor`, and building inside the cosa buildroot image, which
already has rpm-ostree installed, and so `ld.so` chose the bundled
libdnf of the installed rpm-ostree when loading the `g-ir-scanner` stub.
Thus why it failed with:
```
./tmp-introspectzh0n2cga/.libs/lt-RpmOstree-1.0: symbol lookup error: .libs/librpmostree-1.so.1: undefined symbol: hy_goal_favor
```
And of course, the root cause here has nothing to do with the stub in
itself. It's actually trivially easy to see the behaviour difference wrt
`LD_LIBRARY_PATH` on installed binaries. Using a shared object
from `python3-libdnf` which links to libdnf without using rpath, we can
see that `LD_LIBRARY_PATH` has an effect:
```
$ ldd /usr/lib64/python3.7/site-packages/libdnf/_transaction.so | grep libdnf
libdnf.so.2 => /lib64/libdnf.so.2 (0x00007fdde789e000)
$ LD_LIBRARY_PATH=./libdnf-build/libdnf ldd /usr/lib64/python3.7/site-packages/libdnf/_transaction.so | grep libdnf
libdnf.so.2 => ./libdnf-build/libdnf/libdnf.so.2 (0x00007fa615048000)
```
Whereas with rpm-ostree:
```
$ ldd /usr/bin/rpm-ostree | grep libdnf
libdnf.so.2 => /usr/lib64/rpm-ostree/libdnf.so.2 (0x00007f7da5271000)
$ LD_LIBRARY_PATH=./libdnf-build/libdnf ldd /usr/bin/rpm-ostree | grep libdnf
libdnf.so.2 => /usr/lib64/rpm-ostree/libdnf.so.2 (0x00007fc905dbd000)
```
And going further down the rabbit hole, `DT_RPATH` is in fact considered
deprecated for this reason; it makes it harder to run with uninstalled
libraries or whatever reason one has to want to override a library (one
can still use `LD_PRELOAD`, though the semantics are different, and it's
less commonly used than `LD_LIBRARY_PATH`). Instead, we should use
`DT_RUNPATH`, which does have lower precedence than `LD_LIBRARY_PATH`,
matching the usual behaviour.
To make the linker emit `DT_RUNPATH` attributes, we have to use the
`--enable-new-dtags` flag. This also then fixes the g-ir-scanner issue
described above.
2020-05-11 21:08:45 +03:00
# The g-ir-scanner creates a stub executable (to help introspect type information) which
# links to our stuff. We want to make sure it picks up our fresh libdnf and not a possibly
# stale one from a previously installed rpm-ostree's bundled libdnf.
2016-08-03 21:30:17 +03:00
INTROSPECTION_SCANNER_ENV = env LD_LIBRARY_PATH=$(top_builddir)/libdnf-build/libdnf
2016-06-29 04:33:02 +03:00
2019-03-18 19:11:14 +03:00
# XXX: work around clang being passed -fstack-clash-protection which it doesn't understand
# https://github.com/projectatomic/rpm-ostree/pull/1787#issuecomment-473971585
INTROSPECTION_SCANNER_ENV += CC=gcc
2015-03-20 03:45:30 +03:00
if BUILDOPT_INTROSPECTION
RpmOstree-1.0.gir: librpmostree-1.la Makefile
RpmOstree_1_0_gir_EXPORT_PACKAGES = rpm-ostree-1
RpmOstree_1_0_gir_INCLUDES = OSTree-1.0 Gio-2.0
RpmOstree_1_0_gir_CFLAGS = $(librpmostree_1_la_CFLAGS)
RpmOstree_1_0_gir_LIBS = librpmostree-1.la
RpmOstree_1_0_gir_SCANNERFLAGS = --warn-all --identifier-prefix=RpmOstree --symbol-prefix=rpm_ostree
RpmOstree_1_0_gir_FILES = $(librpmostreeinclude_HEADERS) $(filter-out %-private.h,$(librpmostree_1_la_SOURCES))
INTROSPECTION_GIRS += RpmOstree-1.0.gir
gir_DATA += RpmOstree-1.0.gir
typelib_DATA += RpmOstree-1.0.typelib
CLEANFILES += $(gir_DATA) $(typelib_DATA)
endif
pkgconfig_DATA += src/lib/rpm-ostree-1.pc