Skip to content

Commit 6106bd7

Browse files
committed
tools: reduce bundle size of benchmarkTools.nix
Signed-off-by: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent b2b2b41 commit 6106bd7

4 files changed

Lines changed: 182 additions & 3 deletions

File tree

‎.github/workflows/benchmark.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ jobs:
220220
nix-shell \
221221
-I nixpkgs=./tools/nix/pkgs.nix \
222222
--pure \
223-
-E '(import <nixpkgs> {}).mkShell { buildInputs = import ./tools/nix/benchmarkTools.nix { withHttpBenchmarkDeps = false; }; }' \
223+
-E '(import <nixpkgs> {}).mkShellNoCC { buildInputs = import ./tools/nix/benchmarkTools.nix { withHttpBenchmarkDeps = false; }; }' \
224224
--run '
225225
export LC_ALL=C.UTF-8
226226
echo "> [!WARNING] "

‎tools/nix/R-overlay.nix‎

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# To be used as an overlay
2+
(final: prev: {
3+
R =
4+
let
5+
inherit (final)
6+
lib
7+
stdenv
8+
stdenvNoCC
9+
fetchurl
10+
blas
11+
bzip2
12+
curlMinimal
13+
gfortran
14+
lapack
15+
ncurses
16+
pcre2
17+
readline
18+
removeReferencesTo
19+
runCommand
20+
tzdata
21+
which
22+
xz
23+
zlib
24+
;
25+
in
26+
prev.R.overrideAttrs {
27+
buildInputs = [
28+
blas
29+
bzip2
30+
gfortran
31+
lapack
32+
ncurses
33+
pcre2
34+
readline
35+
which
36+
xz
37+
zlib
38+
];
39+
40+
nativeBuildInputs = prev.R.nativeBuildInputs ++ [ removeReferencesTo ];
41+
42+
preConfigure = ''
43+
configureFlagsArray=(
44+
--disable-lto
45+
--without-recommended-packages
46+
--with-blas="-L${blas}/lib -lblas"
47+
--with-lapack="-L${lapack}/lib -llapack"
48+
--with-readline
49+
--without-aqua
50+
--without-tcltk
51+
--without-cairo
52+
--without-libpng
53+
--without-jpeglib
54+
--without-libtiff
55+
--without-ICU
56+
--without-x
57+
--disable-R-framework
58+
--disable-java
59+
AR=$(type -p ar)
60+
AWK=$(type -p gawk)
61+
CC=$(type -p cc)
62+
CXX=$(type -p c++)
63+
FC="${gfortran}/bin/gfortran" F77="${gfortran}/bin/gfortran"
64+
RANLIB=$(type -p ranlib)
65+
CURL_CONFIG="${lib.getExe' (lib.getDev curlMinimal) "curl-config"}"
66+
r_cv_have_curl728=yes
67+
R_SHELL="${stdenvNoCC.shell}"
68+
''
69+
+ lib.optionalString stdenv.hostPlatform.isDarwin ''
70+
OBJC="clang"
71+
CPPFLAGS="-isystem ${lib.getInclude stdenv.cc.libcxx}/include/c++/v1"
72+
LDFLAGS="-L${lib.getLib stdenv.cc.libcxx}/lib"
73+
''
74+
+ ''
75+
)
76+
echo >>etc/Renviron.in "TZDIR=${tzdata}/share/zoneinfo"
77+
'';
78+
79+
# Upstream postInstall link to the `tex` output, which we don't need
80+
postInstall = "mv -T \"$out/lib/R/share/texmf\" \"$tex\"";
81+
postFixup =
82+
prev.R.postFixup
83+
# Keep the C/C++ compiler out of R's runtime closure (enforced by
84+
# outputChecks.disallowedReferences below). R records the absolute path of the
85+
# compiler it was built with in Makeconf (and a couple of launchers); rewrite
86+
# those to bare command names so packages are compiled with the toolchain
87+
# provided by their own build environment. Only the compiler's runtime
88+
# libraries (…-lib) are needed at run time, so repoint the recorded library
89+
# search paths, and strip any residual paths recorded in compiled objects
90+
# (e.g. debug/.comment sections).
91+
+ ''
92+
compilers='cc|gcc|g\+\+|c\+\+|cpp|clang|clang\+\+|gccgo|gfortran|g77|ld|ld\.gold|ld\.bfd|ld\.lld|ar|ranlib|nm|as|strip|dsymutil|install_name_tool|libtool|lipo|otool'
93+
for f in \
94+
$out/lib/R/etc/Makeconf $out/lib/R/etc/Renviron \
95+
$out/lib/R/bin/R $out/bin/R \
96+
$out/lib/R/bin/libtool $out/lib/R/bin/javareconf \
97+
; do
98+
[ -f "$f" ] && sed -i -E "s#/nix/store/[a-z0-9]{32}-[^/ \"')]*/bin/($compilers)#\1#g" "$f"
99+
done
100+
101+
substituteInPlace \
102+
$out/lib/R/etc/Makeconf \
103+
${
104+
if stdenv.hostPlatform.isDarwin then
105+
# On Darwin the toolchain is clang. After bare-naming, CC/CXX are plain
106+
# `cc`/`c++`, which resolve via PATH to the gfortran cc-wrapper's GCC
107+
# drivers in an R-package build env; GCC's libstdc++ headers are
108+
# incompatible with the SDK libcxx (e.g. "'abort' has not been declared in
109+
# 'std'"). Pin them to clang/clang++, which the gfortran wrapper does not
110+
# provide (so PATH resolves to the real clang) and which are not store
111+
# paths (so the disallowedReferences check still passes).
112+
''
113+
--replace-fail 'CC = cc' 'CC = clang' \
114+
--replace-fail 'CXX = c++' 'CXX = clang++' \
115+
--replace-fail 'CXX17 = c++' 'CXX17 = clang++' \
116+
--replace-fail 'CXX20 = c++' 'CXX20 = clang++' \
117+
--replace-fail 'CXX23 = c++' 'CXX23 = clang++'
118+
''
119+
else
120+
# On Linux gfortran.cc is the same derivation as stdenv.cc.cc (the full
121+
# gcc), which the disallowedReferences check forbids, so repoint its
122+
# recorded library search paths to the -lib output. This must NOT run on
123+
# Darwin: there gfortran is a separate derivation from clang (so the check
124+
# already passes) and its -lib output lacks lib/gcc/<triple>/<ver> and the
125+
# libemutls_w/libheapt_w archives that Fortran packages link against.
126+
''
127+
$out/lib/R/etc/ldpaths \
128+
--replace-fail "${gfortran.cc}" "${lib.getLib gfortran.cc}"
129+
''
130+
}
131+
132+
${lib.optionalString (!stdenv.hostPlatform.isDarwin) ''
133+
substituteInPlace $out/lib/R/bin/libtool \
134+
--replace-fail "${stdenv.cc.cc}" "${lib.getLib stdenv.cc.cc}"''}
135+
136+
# Neutralise any residual references that are not a plain /bin/<tool> path,
137+
# e.g. the compiler resource dir baked into libtool's library search path.
138+
for f in $out/lib/R/etc/Makeconf $out/lib/R/bin/libtool; do
139+
[ -f "$f" ] && remove-references-to -t ${stdenv.cc} "$f"
140+
done
141+
142+
rm $out/lib/R/bin/javareconf
143+
144+
find $out -type f -name '*.${stdenv.hostPlatform.extensions.sharedLibrary}' -exec \
145+
remove-references-to -t ${stdenv.cc} -t ${stdenv.cc.cc} {} +
146+
147+
find $out -type f -exec remove-references-to -t "$man" {} +
148+
149+
# 1) Drop recorded `# configure …` / comment lines that pin build-time
150+
# store paths (R-man via --mandir, the *-dev pkgconfig set, …).
151+
# Pure metadata — never used at run time.
152+
sed -i -E '\|^#.*/nix/store/[a-z0-9]{32}|d' $out/lib/R/etc/Makeconf
153+
154+
# 2) Bare-name the external tool commands R records for
155+
# install.packages()/vignettes (gzip, bzip2, sed, tar, …). R uses
156+
# libz/libbz2 internally to *read* compressed data, so dropping the
157+
# store path (keeping the bare name, resolved from PATH if present)
158+
# doesn't affect running scripts or loading packages.
159+
tools='gzip|bzip2|bunzip2|sed|tar|gtar|make|gmake|unzip|zip|xz|gawk|awk'
160+
for f in $out/lib/R/etc/Renviron $out/lib/R/etc/Makeconf; do
161+
[ -f "$f" ] && sed -i -E "s#/nix/store/[a-z0-9]{32}-[^/ \"')]*/bin/($tools)#\1#g" "$f"
162+
done
163+
164+
# 3) full gfortran (its lib/gcc/<triple>/<ver> crt dir) baked into libtool.
165+
[ -f $out/lib/R/bin/libtool ] && \
166+
remove-references-to -t ${gfortran.cc} -t ${final.coreutils} -t ${final.gnugrep} -t ${final.gnused} $out/lib/R/bin/libtool
167+
'';
168+
169+
# Enforce that the compiler wrapper and the unwrapped compiler do not end up in
170+
# R's runtime closure. On Linux the postFixup above scrubs the references that
171+
# would otherwise pull them in.
172+
__structuredAttrs = true;
173+
outputChecks.out.disallowedReferences = [
174+
"man"
175+
"tex"
176+
stdenv.cc
177+
stdenv.cc.cc
178+
];
179+
};
180+
})

‎tools/nix/benchmarkTools.nix‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,3 @@
88
pkgs.rPackages.plyr
99
]
1010
++ pkgs.lib.optional withHttpBenchmarkDeps pkgs.wrk
11-
++ pkgs.lib.optional pkgs.stdenv.buildPlatform.isLinux pkgs.glibcLocales

‎tools/nix/pkgs.nix‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ let
55
nixpkgs = import (builtins.fetchTarball {
66
url = "${repo}/archive/${rev}.tar.gz";
77
sha256 = "0vi99516bn335vdzcjmvrkff8ikj0brpmjfcfdrjnb8bfd0wlr5j";
8-
}) arg;
8+
}) (arg // { overlays = (arg.overlays or [ ]) ++ [ (import ./R-overlay.nix) ]; });
99
in
1010
# Unstable channel no longer supports Intel architecture for macOS. We can use the 26.05 channel
1111
# to keep testing on that platform for a little longer.

0 commit comments

Comments
 (0)