about summary refs log tree commit homepage
path: root/lib/PublicInbox
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2023-11-13 13:15:38 +0000
committerEric Wong <e@80x24.org>2023-11-13 21:54:58 +0000
commitbde6b348110031b6d82aab5641dbdb7f62d5686f (patch)
tree418d42888d2951f6d2823c5781d821fa58c08fc4 /lib/PublicInbox
parent6924c00a335f6703e1b83dd3595b053ceaa2cba8 (diff)
downloadpublic-inbox-bde6b348110031b6d82aab5641dbdb7f62d5686f.tar.gz
We need to have stable filenames and separate compilation
from the linkage stage for ccache to hit.  So avoid the use
of a temporary directory and instead rely on a lock file to
guard against parallel builds.
Diffstat (limited to 'lib/PublicInbox')
-rw-r--r--lib/PublicInbox/XapHelperCxx.pm32
1 files changed, 19 insertions, 13 deletions
diff --git a/lib/PublicInbox/XapHelperCxx.pm b/lib/PublicInbox/XapHelperCxx.pm
index 0891074d..7aa52416 100644
--- a/lib/PublicInbox/XapHelperCxx.pm
+++ b/lib/PublicInbox/XapHelperCxx.pm
@@ -7,7 +7,7 @@
 # The resulting executable is not linked to Perl in any way.
 package PublicInbox::XapHelperCxx;
 use v5.12;
-use PublicInbox::Spawn qw(run_qx which);
+use PublicInbox::Spawn qw(run_die run_qx which);
 use PublicInbox::IO qw(read_all write_file);
 use PublicInbox::Search;
 use Fcntl qw(SEEK_SET);
@@ -24,8 +24,8 @@ my @pm_dep = map { $srcpfx.$_ } qw(Search.pm CodeSearch.pm);
 my $ldflags = '-Wl,-O1';
 $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;
+        ' -DTHREADID=' . PublicInbox::Search::THREADID .
+        ' ' . ($ENV{LDFLAGS} // $ldflags);
 my $xap_modversion;
 
 sub xap_cfg (@) {
@@ -58,12 +58,12 @@ sub build () {
                 die "mkdir($dir): $err" if !-d $dir;
         }
         use autodie;
-        require File::Temp;
         require PublicInbox::CodeSearch;
+        require PublicInbox::Lock;
+        require PublicInbox::OnDestroy;
         my ($prog) = ($bin =~ m!/([^/]+)\z!);
-        my $tmp = File::Temp->newdir(DIR => $dir) // die "newdir: $!";
-        my $src = "$tmp/$prog.cpp";
-        open my $fh, '>', $src;
+        my $lk = PublicInbox::Lock->new("$dir/$prog.lock")->lock_for_scope;
+        open my $fh, '>', "$dir/$prog.cpp";
         for (@srcs) {
                 say $fh qq(# line 1 "$_");
                 open my $rfh, '<', $_;
@@ -73,6 +73,10 @@ sub build () {
         print $fh PublicInbox::CodeSearch::generate_cxx();
         close $fh;
 
+        opendir my $dh, '.';
+        my $restore = PublicInbox::OnDestroy->new(\&chdir, $dh);
+        chdir $dir;
+
         # xap_modversion may be set by needs_rebuild
         $xap_modversion //= xap_cfg('--modversion');
         my $fl = xap_cfg(qw(--libs --cflags));
@@ -84,14 +88,16 @@ sub build () {
         # distributed packages.
         $^O eq 'netbsd' and $fl =~ s/(\A|[ \t])\-L([^ \t]+)([ \t]|\z)/
                                 "$1-L$2 -Wl,-rpath=$2$3"/egsx;
-
-        my $cmd = "$cxx $src $fl $xflags -o $tmp/$prog";
-        system($cmd) and die "$cmd failed: \$?=$?";
-        write_file '>', "$tmp/XFLAGS", $xflags, "\n";
-        write_file '>', "$tmp/xap_modversion", $xap_modversion, "\n";
+        my @xflags = split(/\s+/, "$fl $xflags");
+        my @cflags = grep(!/\A-(?:Wl|l|L)/, @xflags);
+        run_die([$cxx, '-c', "$prog.cpp", @cflags]);
+        run_die([$cxx, '-o', "$prog.tmp", "$prog.o", @xflags]);
+        unlink "$prog.cpp", "$prog.o";
+        write_file '>', 'XFLAGS.tmp', $xflags, "\n";
+        write_file '>', 'xap_modversion.tmp', $xap_modversion, "\n";
         undef $xap_modversion; # do we ever build() twice?
         # not quite atomic, but close enough :P
-        rename("$tmp/$_", "$dir/$_") for ($prog, qw(XFLAGS xap_modversion));
+        rename("$_.tmp", $_) for ($prog, qw(XFLAGS xap_modversion));
 }
 
 sub check_build () {