From: Eric Wong Date: Tue, 12 Sep 2023 10:48:29 +0000 (+0000) Subject: xap_helper_cxx: detect libxapian version changes X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c24a54870a2bde13b5e4a4cf5778c55c19abef39;p=thirdparty%2Fpublic-inbox.git xap_helper_cxx: detect libxapian version changes As with libgit2, Xapian can be upgraded and break linkage with the xap_helper binary. For now, save the result of `pkg-config --modversion xapian-core' to a file and compare it with the current output. Perhaps portable some make(1) can be used for this... --- diff --git a/lib/PublicInbox/XapHelperCxx.pm b/lib/PublicInbox/XapHelperCxx.pm index 1c9a314f8..5157fb35c 100644 --- a/lib/PublicInbox/XapHelperCxx.pm +++ b/lib/PublicInbox/XapHelperCxx.pm @@ -7,8 +7,9 @@ # The resulting executable is not linked to Perl in any way. package PublicInbox::XapHelperCxx; use v5.12; -use PublicInbox::Spawn; +use PublicInbox::Spawn qw(popen_rd); use PublicInbox::Search; +use Fcntl qw(SEEK_SET); my $dir = ($ENV{PERL_INLINE_DIRECTORY} // die('BUG: PERL_INLINE_DIRECTORY unset')) . '/cxx'; my $bin = "$dir/xap_helper"; @@ -20,11 +21,33 @@ $ldflags .= ' -Wl,--compress-debug-sections=zlib' if $^O ne 'openbsd'; my $xflags = ($ENV{CXXFLAGS} // '-Wall -ggdb3 -O0') . ' ' . ($ENV{LDFLAGS} // $ldflags) . qq{ -DTHREADID=}.PublicInbox::Search::THREADID; +my $xap_modversion; -sub xflags_chg () { +sub xap_cfg (@) { + open my $err, '+>', undef or die "open(undef): $!"; + my $cmd = [ $ENV{PKG_CONFIG} // 'pkg-config', @_, 'xapian-core' ]; + my $rd = popen_rd($cmd, undef, { 2 => $err }); + chomp(my $ret = do { local $/; <$rd> }); + return $ret if close($rd); + seek($err, 0, SEEK_SET) or die "seek: $!"; + $err = do { local $/; <$err> }; + die <); - $prev ne $xflags; + return 1 if $prev ne $xflags; + + open $fh, '<', "$dir/xap_modversion" or return 1; + chomp($prev = <$fh>); + $prev or return 1; + + $xap_modversion = xap_cfg('--modversion'); + $xap_modversion ne $prev; } sub build () { @@ -37,7 +60,6 @@ sub build () { require File::Temp; require PublicInbox::CodeSearch; my ($prog) = ($bin =~ m!/([^/]+)\z!); - my $pkg_config = $ENV{PKG_CONFIG} // 'pkg-config'; my $tmp = File::Temp->newdir(DIR => $dir) // die "newdir: $!"; my $src = "$tmp/$prog.cpp"; open my $fh, '>', $src; @@ -51,9 +73,9 @@ sub build () { print $fh PublicInbox::CodeSearch::generate_cxx(); close $fh; - my $cmd = "$pkg_config --libs --cflags xapian-core"; - chomp(my $fl = `$cmd`); - die "$cmd failed: \$?=$?" if $?; + # xap_modversion may be set by needs_rebuild + $xap_modversion //= xap_cfg('--modversion'); + my $fl = xap_cfg(qw(--libs --cflags)); # Using rpath seems acceptable/encouraged in the NetBSD packaging world # since /usr/pkg/lib isn't searched by the dynamic loader by default. @@ -64,14 +86,18 @@ sub build () { "$1-L$2 -Wl,-rpath=$2$3"/egsx; my $cxx = $ENV{CXX} // 'c++'; - $cmd = "$cxx $src $fl $xflags -o $tmp/$prog"; + my $cmd = "$cxx $src $fl $xflags -o $tmp/$prog"; system($cmd) and die "$cmd failed: \$?=$?"; - my $cf = "$tmp/XFLAGS"; - open $fh, '>', $cf; + open $fh, '>', "$tmp/XFLAGS"; say $fh $xflags; close $fh; + + open $fh, '>', "$tmp/xap_modversion"; + say $fh $xap_modversion; + close $fh; + undef $xap_modversion; # do we ever build() twice? # not quite atomic, but close enough :P - rename("$tmp/$_", "$dir/$_") for ($prog, 'XFLAGS'); + rename("$tmp/$_", "$dir/$_") for ($prog, qw(XFLAGS xap_modversion)); } sub check_build () { @@ -85,7 +111,7 @@ sub check_build () { return build() if $ctime > $bin[10]; } } - xflags_chg() ? build() : 0; + needs_rebuild() ? build() : 0; } sub start (@) {