diff --git a/bin/meson.build b/bin/meson.build index da4f5b95032bb960af383ab58f4c98db2af90c65..8761bde2f682be618c6971921dc426b9311cda61 100644 --- a/bin/meson.build +++ b/bin/meson.build @@ -26,6 +26,10 @@ executable( 'system-info.c', dependencies : [glib, libsteamrt_dep, json_glib], install : true, + # Use the adjacent libsteam-runtime-tools and json-glib, ignoring + # LD_LIBRARY_PATH even if set + build_rpath : bin_rpath, + install_rpath : bin_rpath, ) if get_option('man') diff --git a/debian/control b/debian/control index a22c249a291a897e36912983b1702c5c87f13cdf..6cb6000f2559ca8cdeba61094836f63c7a4c9a0e 100644 --- a/debian/control +++ b/debian/control @@ -8,6 +8,7 @@ Build-Depends: g++ (>= 4:4.8) | g++-4.8, glslang-tools, gtk-doc-tools <!nodoc>, + libcapsule-tools, libglib2.0-dev, libjson-glib-dev (>= 1.0), libtheora0 <!nocheck>, diff --git a/debian/libsteam-runtime-tools-0-helpers.install b/debian/libsteam-runtime-tools-0-helpers.install index 4d24bb6e601f5ae39446eb84d572b5f5947a1614..4f58c509f4b15622ce24b6c0b13e02fa2b63f0b7 100644 --- a/debian/libsteam-runtime-tools-0-helpers.install +++ b/debian/libsteam-runtime-tools-0-helpers.install @@ -1 +1,2 @@ +usr/lib/*/steam-runtime-tools-0/* usr/libexec/steam-runtime-tools-0/* diff --git a/debian/rules b/debian/rules index 506e949aad2cc4ba049bd86181db704c3f334d44..e8200469bc50201641ac386f46de5c2910c85f42 100755 --- a/debian/rules +++ b/debian/rules @@ -40,10 +40,17 @@ override_dh_auto_clean: rm -fr builddir rm -fr debian/locales +libexecdir := libexec +pkglibexecdir := $(libexecdir)/steam-runtime-tools-0 +libdir := lib/$(DEB_HOST_MULTIARCH) +pkglibdir := $(libdir)/steam-runtime-tools-0 +DESTDIR := $(CURDIR)/debian/tmp + override_dh_auto_configure: meson builddir \ --prefix=/usr \ - --libexecdir=/usr/libexec \ + --libexecdir=$(libexecdir) \ + --libdir=$(libdir) \ -Dgtk_doc=$(gtk_doc_has_cflags) \ -Dintrospection=false \ -Dmultiarch_tuple=$(DEB_HOST_MULTIARCH) \ @@ -61,19 +68,46 @@ ifeq ($(filter nocheck,$(DEB_BUILD_OPTIONS)),) endif override_dh_auto_install: - DESTDIR=$(CURDIR)/debian/tmp ninja -C builddir install + DESTDIR=$(DESTDIR) ninja -C builddir install ln -s ../../bin/$(DEB_HOST_MULTIARCH)-vulkaninfo \ - debian/tmp/usr/libexec/steam-runtime-tools-0/ + $(DESTDIR)/usr/$(pkglibexecdir)/ ln -s ../../bin/$(DEB_HOST_MULTIARCH)-wflinfo \ - debian/tmp/usr/libexec/steam-runtime-tools-0/ - for x in debian/tmp/usr/libexec/installed-tests/steam-runtime-tools-0/*; do \ + $(DESTDIR)/usr/$(pkglibexecdir)/ + set -e; for x in $(DESTDIR)/usr/libexec/installed-tests/steam-runtime-tools-0/*; do \ if [ -f "$$x" ] \ && cmp -s "$$x" \ - debian/tmp/usr/libexec/steam-runtime-tools-0/$(DEB_HOST_MULTIARCH)-true; \ + $(DESTDIR)/usr/libexec/steam-runtime-tools-0/$(DEB_HOST_MULTIARCH)-true; \ then \ - ln -fns ../../steam-runtime-tools-0/$(DEB_HOST_MULTIARCH)-true "$$x"; \ + ln -fnsv ../../steam-runtime-tools-0/$(DEB_HOST_MULTIARCH)-true "$$x"; \ fi; \ done + install -d $(DESTDIR)/usr/$(pkglibdir) + ln -fnsv ../libsteam-runtime-tools-0.so.0 $(DESTDIR)/usr/$(pkglibdir)/ + LD_LIBRARY_PATH='$(DESTDIR)/usr/$(libdir)' \ + $(DEB_HOST_MULTIARCH)-capsule-capture-libs \ + --container / \ + --dest $(DESTDIR)/usr/$(pkglibdir) \ + --link-target / \ + --no-glibc \ + --provider / \ + only-dependencies:path:$(DESTDIR)/usr/bin/steam-runtime-system-info \ + only-dependencies:path:$(DESTDIR)/usr/$(pkglibexecdir)/$(DEB_HOST_MULTIARCH)-check-locale \ + $(NULL) + +override_dh_link: + dh_link + # Make the links in $(pkglibdir) relative. This is contrary + # to Debian policy, but is what we need for the LD_LIBRARY_PATH + # Steam Runtime, where GLib is in /lib. + set -e; for link in debian/libsteam-runtime-tools-0-helpers/usr/$(pkglibdir)/lib*; do \ + target="$$(readlink -v "$$link")"; \ + echo "before: $$link -> $$target"; \ + case "$$target" in \ + (/*) \ + ln -fnsv "../../../..$${target}" "$${link}"; \ + ;; \ + esac; \ + done override_dh_missing: dh_missing --fail-missing diff --git a/helpers/meson.build b/helpers/meson.build index b709726c3b63982ff5aa16fed05d6385b068f454..65eed6ed89972bc232c8e25d2b89f523ebdd3dfb 100644 --- a/helpers/meson.build +++ b/helpers/meson.build @@ -27,6 +27,8 @@ executable( include_directories : project_include_dirs, install : true, install_dir : pkglibexecdir, + # Deliberately no RPATH/RUNPATH here: it's unnecessary because this + # executable has no dependencies. ) executable( @@ -36,6 +38,9 @@ executable( dependencies : [json_glib, glib], install : true, install_dir : pkglibexecdir, + # Use json-glib and GLib from the adjacent libdir, ignoring LD_LIBRARY_PATH + build_rpath : pkglibexec_rpath, + install_rpath : pkglibexec_rpath, ) executable( @@ -45,6 +50,8 @@ executable( include_directories : project_include_dirs, install : true, install_dir : pkglibexecdir, + # Deliberately no RPATH/RUNPATH here: we want to determine whether + # a game with no special linking would be able to load a library. ) executable( @@ -57,7 +64,10 @@ executable( get_option('libexecdir'), 'steam-runtime-tools-' + api_major, ) -) + # Deliberately no RPATH/RUNPATH here: we want to determine whether + # a game with no special linking would be able to use libvulkan + # and its associated drivers successfully. +) custom_target( 'frag.spv', diff --git a/meson.build b/meson.build index a70c8dd9aac9bbbaf17de2e7e8b6a8751ec65cc2..13bd831d069b59cc8b43635a58ff8358a51e1d9b 100644 --- a/meson.build +++ b/meson.build @@ -134,6 +134,19 @@ foreach flag : no_warning_cxxflags add_project_arguments(supported_no_warning_cxxflags, language : 'cpp') endforeach +add_project_link_arguments( + c_compiler.get_supported_link_arguments( + '-Wl,-z,origin', + # Generate RPATH in preference to RUNPATH, even if RUNPATH is the + # linker's default. We want RPATH here, because it's used recursively + # for both direct and indirect dependencies: in particular we need + # to pick up the whole GLib family (GLib, GObject, GIO) from the same + # location. (It also bypasses LD_LIBRARY_PATH.) + '-Wl,-z,--disable-new-dtags', + ), + language : 'c', +) + conf_data = configuration_data() conf_data.set('_GNU_SOURCE', '1') conf_data.set_quoted('VERSION', meson.project_version()) @@ -181,11 +194,30 @@ libdl = c_compiler.find_library('dl', required : false) project_include_dirs = include_directories('.') +# Relative path from get_option('prefix') to our private library directory +pkglibdir = join_paths( + get_option('libdir'), + 'steam-runtime-tools-' + api_major, +) + +# RPATH for executables installed in get_option('bindir'). +# This assumes that bindir is a single directory component (normally +# 'bin'), so that ../ gets us from get_option('bindir') to the prefix, +# and that libdir is relative. +bin_rpath = '${ORIGIN}/../' + pkglibdir + +# Relative path from get_option('prefix') to our private libexec directory pkglibexecdir = join_paths( get_option('libexecdir'), 'steam-runtime-tools-' + api_major, ) +# RPATH for executables installed in pkglibexecdir. +# This assumes that libexecdir is a single directory component (normally +# 'libexec'), so that ../../ gets us from pkglibexecdir to the prefix, +# and that libdir is relative +pkglibexec_rpath = '${ORIGIN}/../../' + pkglibdir + if get_option('multiarch_tuple') != '' multiarch = get_option('multiarch_tuple') elif host_machine.cpu_family() == 'x86_64' diff --git a/steam-runtime-tools/utils.c b/steam-runtime-tools/utils.c index c3bb136320ba45f832e832f03b0dd0ef7ffbdf91..1c2b95bcd2370906b3f8a3669469e158fa7bb255 100644 --- a/steam-runtime-tools/utils.c +++ b/steam-runtime-tools/utils.c @@ -146,6 +146,11 @@ _srt_check_not_setuid (void) return !is_setuid; } +#define MULTIARCH_LIBDIR \ + "/lib/" _SRT_MULTIARCH +#define RELOCATABLE_PKGLIBDIR \ + MULTIARCH_LIBDIR "/steam-runtime-tools-" _SRT_API_MAJOR + G_GNUC_INTERNAL const char * _srt_find_myself (const char **helpers_path_out, GError **error) @@ -177,8 +182,10 @@ _srt_find_myself (const char **helpers_path_out, g_debug ("Found _srt_find_myself() in %s", map->l_name); dir = g_path_get_dirname (map->l_name); - if (g_str_has_suffix (dir, "/lib/" _SRT_MULTIARCH)) - dir[strlen (dir) - strlen ("/lib/" _SRT_MULTIARCH)] = '\0'; + if (g_str_has_suffix (dir, RELOCATABLE_PKGLIBDIR)) + dir[strlen (dir) - strlen (RELOCATABLE_PKGLIBDIR)] = '\0'; + else if (g_str_has_suffix (dir, MULTIARCH_LIBDIR)) + dir[strlen (dir) - strlen (MULTIARCH_LIBDIR)] = '\0'; else if (g_str_has_suffix (dir, "/lib64")) dir[strlen (dir) - strlen ("/lib64")] = '\0'; else if (g_str_has_suffix (dir, "/lib"))