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: Simon McVittie's avatarSimon McVittie <smcv@collabora.com>
parent f367076b
......@@ -10,6 +10,7 @@ Depends:
libcapsule-tests,
libcapsule-tools,
libipc-run-perl,
libglib2.0-0,
libjpeg62 (>= 6b1) | libjpeg62-turbo,
libtool,
perl,
......
......@@ -165,6 +165,101 @@ run_ok([qw(bwrap --ro-bind / / --ro-bind /), $host,
"--dest=$libdir", "--provider=$host",
'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 "not on Linux? Good luck!", 1 unless $^O eq 'linux';
my $stdout;
......
......@@ -163,6 +163,10 @@ static void usage (int code)
"\tCapture every library in ld.so.cache that matches\n"
"\ta shell-style glob (which will usually need to be\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"
"\tCapture PATTERN, but don't fail if nothing matches\n" );
fprintf( fh, "even-if-older:PATTERN\n"
......@@ -180,6 +184,8 @@ typedef enum
CAPTURE_FLAG_NONE = 0,
CAPTURE_FLAG_EVEN_IF_OLDER = (1 << 0),
CAPTURE_FLAG_IF_EXISTS = (1 << 1),
CAPTURE_FLAG_LIBRARY_ITSELF = ( 1 << 2 ),
CAPTURE_FLAG_DEPENDENCIES = ( 1 << 3 ),
} capture_flags;
static bool
......@@ -254,6 +260,21 @@ capture_one( const char *soname, capture_flags flags,
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 );
if( fstatat( dest_fd, its_basename, &statbuf,
......@@ -529,6 +550,17 @@ capture_pattern( const char *pattern, capture_flags flags,
{
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:" ) )
{
return capture_one( pattern + strlen( "soname:" ),
......@@ -555,6 +587,20 @@ capture_pattern( const char *pattern, capture_flags flags,
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 )
{
// Useful information:
......@@ -650,7 +696,8 @@ capture_patterns( const char * const *patterns, capture_flags flags,
int
main (int argc, char **argv)
{
capture_flags flags = CAPTURE_FLAG_NONE;
capture_flags flags = (CAPTURE_FLAG_LIBRARY_ITSELF |
CAPTURE_FLAG_DEPENDENCIES);
int code = 0;
char *message = NULL;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment