Skip to content
Snippets Groups Projects
Commit f6642d9d authored by Simon McVittie's avatar Simon McVittie
Browse files

capture-libs: Decouple capture of dependencies and the library itself


For Mesa DRI drivers, we will need to capture the dependencies but
not the driver itself, because we load the driver itself by setting
LIBGL_DRIVERS_PATH instead.

I don't have a concrete use-case for no-dependencies:, which is
implemented for symmetry.

Signed-off-by: default avatarSimon McVittie <smcv@collabora.com>
parent f367076b
No related branches found
No related tags found
1 merge request!311Build capsule-capture-libs from a bundled copy of libcapsule
...@@ -10,6 +10,7 @@ Depends: ...@@ -10,6 +10,7 @@ Depends:
libcapsule-tests, libcapsule-tests,
libcapsule-tools, libcapsule-tools,
libipc-run-perl, libipc-run-perl,
libglib2.0-0,
libjpeg62 (>= 6b1) | libjpeg62-turbo, libjpeg62 (>= 6b1) | libjpeg62-turbo,
libtool, libtool,
perl, perl,
......
...@@ -165,6 +165,101 @@ run_ok([qw(bwrap --ro-bind / / --ro-bind /), $host, ...@@ -165,6 +165,101 @@ run_ok([qw(bwrap --ro-bind / / --ro-bind /), $host,
"--dest=$libdir", "--provider=$host", "--dest=$libdir", "--provider=$host",
'if-exists:soname-match:this*library*does?not?exist']); 'if-exists:soname-match:this*library*does?not?exist']);
# libgobject-2.0.so.0 depends on libglib-2.0.so.0 so normally,
# capturing GObject captures GLib
ok(! system('rm', '-fr', $libdir));
mkdir($libdir);
run_ok([qw(bwrap --ro-bind / / --ro-bind /), $host,
'--bind', $libdir, $libdir,
qw(--dev-bind /dev /dev),
$CAPSULE_CAPTURE_LIBS_TOOL, '--link-target=/',
"--dest=$libdir", "--provider=$host",
'soname:libgobject-2.0.so.0']);
{
opendir(my $dir_iter, $libdir);
foreach my $symlink (readdir $dir_iter) {
next if $symlink eq '.' || $symlink eq '..';
diag "- $symlink -> ".readlink("$libdir/$symlink");
}
closedir $dir_iter;
}
like(readlink "$libdir/libgobject-2.0.so.0",
qr{^$LIBDIR/libgobject-2\.0\.so\.0(?:[0-9.]+)$},
'$libdir/libgobject-2.0.so.0 is captured');
like(readlink "$libdir/libglib-2.0.so.0",
qr{^$LIBDIR/libglib-2\.0\.so\.0(?:[0-9.]+)$},
'$libdir/libglib-2.0.so.0 is captured as a dependency');
# only-dependencies: captures the dependency, GLib but not the
# dependent library, GObject
ok(! system('rm', '-fr', $libdir));
mkdir($libdir);
run_ok([qw(bwrap --ro-bind / / --ro-bind /), $host,
'--bind', $libdir, $libdir,
qw(--dev-bind /dev /dev),
$CAPSULE_CAPTURE_LIBS_TOOL, '--link-target=/',
"--dest=$libdir", "--provider=$host",
'only-dependencies:soname:libgobject-2.0.so.0']);
{
opendir(my $dir_iter, $libdir);
foreach my $symlink (readdir $dir_iter) {
next if $symlink eq '.' || $symlink eq '..';
diag "- $symlink -> ".readlink("$libdir/$symlink");
}
closedir $dir_iter;
}
ok(! -e "$libdir/libgobject-2.0.so.0",
'only-dependencies: does not capture the library itself');
like(readlink "$libdir/libglib-2.0.so.0",
qr{^$LIBDIR/libglib-2\.0\.so\.0(?:[0-9.]+)$},
'$libdir/libglib-2.0.so.0 is captured as a dependency');
# no-dependencies: captures the dependent library, GObject but not the
# dependency, GLib (not amazingly useful)
ok(! system('rm', '-fr', $libdir));
mkdir($libdir);
run_ok([qw(bwrap --ro-bind / / --ro-bind /), $host,
'--bind', $libdir, $libdir,
qw(--dev-bind /dev /dev),
$CAPSULE_CAPTURE_LIBS_TOOL, '--link-target=/',
"--dest=$libdir", "--provider=$host",
'no-dependencies:soname:libgobject-2.0.so.0']);
{
opendir(my $dir_iter, $libdir);
foreach my $symlink (readdir $dir_iter) {
next if $symlink eq '.' || $symlink eq '..';
diag "- $symlink -> ".readlink("$libdir/$symlink");
}
closedir $dir_iter;
}
like(readlink "$libdir/libgobject-2.0.so.0",
qr{^$LIBDIR/libgobject-2\.0\.so\.0(?:[0-9.]+)$},
'$libdir/libgobject-2.0.so.0 is captured');
ok(! -e "$libdir/libglib-2.0.so.0",
'no-dependencies: does not capture libglib-2.0.so.0');
# only-dependencies:no-dependencies: (either way round) is completely useless
ok(! system('rm', '-fr', $libdir));
mkdir($libdir);
my $result = run_verbose([qw(bwrap --ro-bind / / --ro-bind /), $host,
'--bind', $libdir, $libdir,
qw(--dev-bind /dev /dev),
$CAPSULE_CAPTURE_LIBS_TOOL, '--link-target=/',
"--dest=$libdir", "--provider=$host",
'only-dependencies:no-dependencies:libglib-2.0.so.0'],
'>&2');
ok(! $result, 'only-dependencies:no-dependencies: is useless');
ok(! system('rm', '-fr', $libdir));
mkdir($libdir);
my $result = run_verbose([qw(bwrap --ro-bind / / --ro-bind /), $host,
'--bind', $libdir, $libdir,
qw(--dev-bind /dev /dev),
$CAPSULE_CAPTURE_LIBS_TOOL, '--link-target=/',
"--dest=$libdir", "--provider=$host",
'no-dependencies:only-dependencies:libglib-2.0.so.0'],
'>&2');
ok(! $result, 'no-dependencies:only-dependencies: is useless');
SKIP: { SKIP: {
skip "not on Linux? Good luck!", 1 unless $^O eq 'linux'; skip "not on Linux? Good luck!", 1 unless $^O eq 'linux';
my $stdout; my $stdout;
......
...@@ -163,6 +163,10 @@ static void usage (int code) ...@@ -163,6 +163,10 @@ static void usage (int code)
"\tCapture every library in ld.so.cache that matches\n" "\tCapture every library in ld.so.cache that matches\n"
"\ta shell-style glob (which will usually need to be\n" "\ta shell-style glob (which will usually need to be\n"
"\tquoted when using a shell)\n" ); "\tquoted when using a shell)\n" );
fprintf( fh, "only-dependencies:PATTERN\n"
"\tCapture the dependencies of each library matched by\n"
"\tPATTERN, but not the library matched by PATTERN itself\n"
"\t(unless a match for PATTERN depends on another match)\n" );
fprintf( fh, "if-exists:PATTERN\n" fprintf( fh, "if-exists:PATTERN\n"
"\tCapture PATTERN, but don't fail if nothing matches\n" ); "\tCapture PATTERN, but don't fail if nothing matches\n" );
fprintf( fh, "even-if-older:PATTERN\n" fprintf( fh, "even-if-older:PATTERN\n"
...@@ -180,6 +184,8 @@ typedef enum ...@@ -180,6 +184,8 @@ typedef enum
CAPTURE_FLAG_NONE = 0, CAPTURE_FLAG_NONE = 0,
CAPTURE_FLAG_EVEN_IF_OLDER = (1 << 0), CAPTURE_FLAG_EVEN_IF_OLDER = (1 << 0),
CAPTURE_FLAG_IF_EXISTS = (1 << 1), CAPTURE_FLAG_IF_EXISTS = (1 << 1),
CAPTURE_FLAG_LIBRARY_ITSELF = ( 1 << 2 ),
CAPTURE_FLAG_DEPENDENCIES = ( 1 << 3 ),
} capture_flags; } capture_flags;
static bool static bool
...@@ -254,6 +260,21 @@ capture_one( const char *soname, capture_flags flags, ...@@ -254,6 +260,21 @@ capture_one( const char *soname, capture_flags flags,
continue; continue;
} }
if( i == 0 && !( flags & CAPTURE_FLAG_LIBRARY_ITSELF ) )
{
DEBUG( DEBUG_TOOL, "Not capturing \"%s\" itself as requested",
provider.needed[i].name );
continue;
}
if( i > 0 && !( flags & CAPTURE_FLAG_DEPENDENCIES ) )
{
DEBUG( DEBUG_TOOL,
"Not capturing dependencies of \"%s\" as requested",
provider.needed[0].name );
break;
}
its_basename = my_basename( provider.needed[i].name ); its_basename = my_basename( provider.needed[i].name );
if( fstatat( dest_fd, its_basename, &statbuf, if( fstatat( dest_fd, its_basename, &statbuf,
...@@ -529,6 +550,17 @@ capture_pattern( const char *pattern, capture_flags flags, ...@@ -529,6 +550,17 @@ capture_pattern( const char *pattern, capture_flags flags,
{ {
DEBUG( DEBUG_TOOL, "%s", pattern ); DEBUG( DEBUG_TOOL, "%s", pattern );
if ( ( flags & ( CAPTURE_FLAG_LIBRARY_ITSELF |
CAPTURE_FLAG_DEPENDENCIES ) ) == 0 )
{
_capsule_set_error( code, message, EINVAL,
"combining no-dependencies: with "
"only-dependencies: is meaningless, "
"so \"%s\" is invalid",
pattern );
return false;
}
if( strstarts( pattern, "soname:" ) ) if( strstarts( pattern, "soname:" ) )
{ {
return capture_one( pattern + strlen( "soname:" ), return capture_one( pattern + strlen( "soname:" ),
...@@ -555,6 +587,20 @@ capture_pattern( const char *pattern, capture_flags flags, ...@@ -555,6 +587,20 @@ capture_pattern( const char *pattern, capture_flags flags,
code, message ); code, message );
} }
if( strstarts( pattern, "only-dependencies:" ) )
{
return capture_pattern( pattern + strlen( "only-dependencies:" ),
flags & ~CAPTURE_FLAG_LIBRARY_ITSELF,
code, message );
}
if( strstarts( pattern, "no-dependencies:" ) )
{
return capture_pattern( pattern + strlen( "no-dependencies:" ),
flags & ~CAPTURE_FLAG_DEPENDENCIES,
code, message );
}
if( strcmp( pattern, "gl:" ) == 0 ) if( strcmp( pattern, "gl:" ) == 0 )
{ {
// Useful information: // Useful information:
...@@ -650,7 +696,8 @@ capture_patterns( const char * const *patterns, capture_flags flags, ...@@ -650,7 +696,8 @@ capture_patterns( const char * const *patterns, capture_flags flags,
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
capture_flags flags = CAPTURE_FLAG_NONE; capture_flags flags = (CAPTURE_FLAG_LIBRARY_ITSELF |
CAPTURE_FLAG_DEPENDENCIES);
int code = 0; int code = 0;
char *message = NULL; char *message = NULL;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment