This adds a few necessary feature, and a future one to discuss.
What this does is activate -S in a "smart way".
Namely, the variable substitutions happen in order, so the COMPILER_LIBCXX
will be preferred to LIBCXX and LIBECXX. This also removes the >= part so
that it actually works.
There's also a new option, -F missing, which I'm not using yet (commented
out), to simplify the mess that pthread is bound to become.
The idea is to be able to ignore a library while backsubstituting, and to
not show it as extra.
Note the may_be_missing / cant_be_extra dance.
The problem here is that clang uses 'c++ c++abi pthread'
as its C++ wantlib list. This will effectively swallow pthread on
clang architectures.
The solution I'm proposing is to add pthread to LIBCXX and LIBECXX,
so that effectively, any C++ port will have pthread in its wantlib.
It's obviously not always correct, but it only errs on the side of
caution. If libpthread gets bumped, a few more packages will notice and
update.
The extra apparatus is just there so that this should be transparent.
Does this look reasonable to you ?
Anyway, first step is to verify that this does perform as advertized.
Which is what I want to do with this diff first.
Adding pthread to LIBCXX/LIBECXX will require a few bumps.
Index: bin/check-lib-depends
===================================================================
RCS file: /cvs/ports/infrastructure/bin/check-lib-depends,v
retrieving revision 1.40
diff -u -p -r1.40 check-lib-depends
--- bin/check-lib-depends 11 Apr 2017 16:02:15 -0000 1.40
+++ bin/check-lib-depends 19 Jul 2017 09:48:25 -0000
@@ -195,6 +195,24 @@ sub depwalk
package CheckLibDepends::State;
our @ISA = qw(OpenBSD::AddCreateDelete::State);
+sub parse_variable
+{
+ my ($state, $opt) = @_;
+ # this looks a bit like the subst module, but goes much further
+ if ($opt =~ m/^([^=]+)\=(.*)$/o) {
+ my ($k, $v) = ($1, $2);
+ $v =~ s/^\'(.*)\'$/$1/;
+ $v =~ s/^\"(.*)\"$/$1/;
+ my @list = split(/\s+/, $v);
+ for my $l (@list) {
+ $l =~ s/\>\=\d.*//; # zap extra version req
+ }
+ # the order matters!
+ push(@{$state->{possibilities}}, [$k, \@list]);
+ } else {
+ $state->usage("Incorrect -S option");
+ }
+}
sub handle_options
{
@@ -202,10 +220,14 @@ sub handle_options
$state->{opt}{i} = 0;
$state->{opt}{S} = sub {
- $state->{subst}->parse_option(shift);
+ $state->parse_variable(shift);
};
- $state->SUPER::handle_options('oid:D:fB:qS:s:O:',
- '[-fiomqx] [-B destdir] [-d pkgrepo] [-O dest] [-S var=value]
[-s source]');
+ $state->{opt}{F} = sub {
+ my $v = shift;
+ $state->{may_be_missing}{$v} = 1;
+ };
+ $state->SUPER::handle_options('oid:D:fF:B:qS:s:O:',
+ '[-fiomqx] [-B destdir] [-d pkgrepo] [-F fuzz] [-O dest] [-S
var=value] [-s source]');
$state->{destdir} = $state->opt('B');
if ($state->opt('O')) {
@@ -458,8 +480,11 @@ sub report_lib_issue
sub has_all_libs
{
- my ($self, $libs, $list) = @_;
+ my ($self, $absent, $libs, $list) = @_;
for my $l (@$list) {
+ if ($absent->{$l}) {
+ next;
+ }
if (!defined $libs->{$l}) {
return 0;
}
@@ -470,19 +495,18 @@ sub has_all_libs
sub backsubst
{
my ($self, $h, $state) = @_;
- my $doit = {};
- # try backsubsting each list
- while (my ($k, $v) = each %{$state->{subst}->hash}) {
- my @l = split(/\s+/, $v);
- if ($self->has_all_libs($h, \@l)) {
- $doit->{$k} = \@l;
- }
- }
- while (my ($k, $list) = each %$doit) {
+ return unless defined $state->{possibilities};
+ for my $p (@{$state->{possibilities}}) {
+ my ($v, $list) = @$p;
+ next unless $self->has_all_libs($h, $state->{may_be_missing},
+ $list);
for my $l (@$list) {
+ if ($state->{may_be_missing}{$l}) {
+ $state->{cant_be_extra} = 1;
+ }
delete $h->{$l};
}
- $h->{'${'.$k.'}'} = 1;
+ $h->{'${'.$v.'}'} = 1;
}
}
@@ -493,8 +517,6 @@ sub print_list
$self->backsubst($h, $state);
my $line = "";
for my $k (sort keys %$h) {
- next if $k eq 'c++abi';
- $k =~ s/^(std)?c\+\+$/\${LIBCXX}/;
if (length $line > 50) {
$state->say_with_context("#1#2", $head, $line);
$line = "";
@@ -571,6 +593,9 @@ sub analyze
for my $k (keys %$has_libs) {
my $v = $has_libs->{$k};
next if $v == 2;
+ my $l = $k;
+ $l =~ s/\.\d+//;
+ next if defined $state->{cant_be_extra}{$l};
$extra->{$k} = 1;
}
unless ($state->{quiet} && keys %{$r->{wantlib}} == 0) {
Index: man/man1/check-lib-depends.1
===================================================================
RCS file: /cvs/ports/infrastructure/man/man1/check-lib-depends.1,v
retrieving revision 1.7
diff -u -p -r1.7 check-lib-depends.1
--- man/man1/check-lib-depends.1 11 Apr 2017 16:00:53 -0000 1.7
+++ man/man1/check-lib-depends.1 19 Jul 2017 09:48:25 -0000
@@ -26,6 +26,7 @@
.Op Fl B Ar destdir
.Op Fl d Ar pkgrepo
.Op Fl D Ar directory
+.Op Fl F Ar missing
.Op Fl O Ar dest
.Op Fl S Ar VAR Ns = Ns Ar value
.Op Fl s Ar source
@@ -75,6 +76,17 @@ that show in more details the run of
.Xr objdump 1 .
.It Fl f
Give full reports of every file that requires a missing library.
+.It Fl F Ar missing
+Works in tandem with
+.Fl S .
+Allow backsubstituting even if the
+.Ar missing
+library
+is actually not part of the actual
+.Ev WANTLIB
+of the package.
+Mostly used to waive the presence of
+.Ar pthread .
.It Fl i
Read packing-list from standard input.
.It Fl m
@@ -98,14 +110,18 @@ wantlibs unless there's also an actual p
recognize list of libraries listed in a variable, and replace said list
with variable value.
For instance,
-.Fl S Ar LIBCXX Ns = Ns Ar stdc++
+.Fl S Ar COMPILER_LIBCXX Ns = Ns Ar stdc++
will replace
.Sq stdc++
with
-.Sq ${LIBCXX}
+.Sq ${COMPILER_LIBCXX}
in
.Ev WANTLIB
lists for compatibility with both clang and gcc.
+Order matters.
+The first
+.Fl S
+option will be handled first.
.It Fl s Ar src
Don't scan, directly read result of first stage from file
.Ar src .
Index: mk/bsd.port.mk
===================================================================
RCS file: /cvs/ports/infrastructure/mk/bsd.port.mk,v
retrieving revision 1.1359
diff -u -p -r1.1359 bsd.port.mk
--- mk/bsd.port.mk 13 Jul 2017 11:43:55 -0000 1.1359
+++ mk/bsd.port.mk 19 Jul 2017 09:48:25 -0000
@@ -1833,6 +1833,10 @@ _check_lib_depends =:
_CHECK_LIB_DEPENDS = PORTSDIR=${PORTSDIR} ${_PERLSCRIPT}/check-lib-depends
_CHECK_LIB_DEPENDS += -d ${_PKG_REPO} -B ${WRKINST}
+_CHECK_LIB_DEPENDS += -S COMPILER_LIBCXX="${COMPILER_LIBCXX}"
+_CHECK_LIB_DEPENDS += -S LIBECXX="${LIBECXX}"
+_CHECK_LIB_DEPENDS += -S LIBCXX="${LIBCXX}"
+#_CHECK_LIB_DEPENDS += -F pthread
.for _s in ${MULTI_PACKAGES}
. if ${STATIC_PLIST${_s}:L} == "no"