1{ version, hash }:
2{
3 lib,
4 stdenv,
5 fetchFromGitHub,
6 nspr,
7 perl,
8 installShellFiles,
9 zlib,
10 sqlite,
11 ninja,
12 cctools,
13 fixDarwinDylibNames,
14 buildPackages,
15 useP11kit ? true,
16 p11-kit,
17 # allow FIPS mode. Note that this makes the output non-reproducible.
18 # https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/NSS_Tech_Notes/nss_tech_note6
19 enableFIPS ? false,
20 nixosTests,
21 nss_latest,
22}:
23
24let
25 underscoreVersion = lib.replaceStrings [ "." ] [ "_" ] version;
26in
27stdenv.mkDerivation rec {
28 pname = "nss";
29 inherit version;
30
31 src = fetchFromGitHub {
32 owner = "nss-dev";
33 repo = "nss";
34 rev = "NSS_${lib.replaceStrings [ "." ] [ "_" ] version}_RTM";
35 inherit hash;
36 };
37
38 depsBuildBuild = [ buildPackages.stdenv.cc ];
39
40 nativeBuildInputs = [
41 perl
42 ninja
43 (buildPackages.python3.withPackages (ps: with ps; [ gyp ]))
44 installShellFiles
45 ]
46 ++ lib.optionals stdenv.hostPlatform.isDarwin [
47 cctools
48 fixDarwinDylibNames
49 ];
50
51 buildInputs = [
52 zlib
53 sqlite
54 ];
55
56 propagatedBuildInputs = [ nspr ];
57
58 patches = [
59 # Based on http://patch-tracker.debian.org/patch/series/dl/nss/2:3.15.4-1/85_security_load.patch
60 ./85_security_load_3.85+.patch
61 ./fix-cross-compilation.patch
62 ];
63
64 postPatch = ''
65 patchShebangs .
66
67 for f in coreconf/config.gypi build.sh; do
68 substituteInPlace "$f" --replace "/usr/bin/env" "${buildPackages.coreutils}/bin/env"
69 done
70
71 substituteInPlace coreconf/config.gypi --replace "/usr/bin/grep" "${buildPackages.coreutils}/bin/env grep"
72 ''
73 + lib.optionalString stdenv.hostPlatform.isDarwin ''
74 substituteInPlace coreconf/Darwin.mk --replace '@executable_path/$(notdir $@)' "$out/lib/\$(notdir \$@)"
75 substituteInPlace coreconf/config.gypi --replace "'DYLIB_INSTALL_NAME_BASE': '@executable_path'" "'DYLIB_INSTALL_NAME_BASE': '$out/lib'"
76 '';
77
78 outputs = [
79 "out"
80 "dev"
81 "tools"
82 "man"
83 ];
84
85 buildPhase =
86 let
87 getArch =
88 platform:
89 if platform.isx86_64 then
90 "x64"
91 else if platform.isx86_32 then
92 "ia32"
93 else if platform.isAarch32 then
94 "arm"
95 else if platform.isAarch64 then
96 "arm64"
97 else if platform.isPower && platform.is64bit then
98 (if platform.isLittleEndian then "ppc64le" else "ppc64")
99 else
100 platform.parsed.cpu.name;
101 # yes, this is correct. nixpkgs uses "host" for the platform the binary will run on whereas nss uses "host" for the platform that the build is running on
102 target = getArch stdenv.hostPlatform;
103 target_system = stdenv.hostPlatform.uname.system;
104 host = getArch stdenv.buildPlatform;
105
106 buildFlags = [
107 "-v"
108 "--opt"
109 "--with-nspr=${nspr.dev}/include:${nspr.out}/lib"
110 "--system-sqlite"
111 "--enable-legacy-db"
112 "--target ${target}"
113 "-Dhost_arch=${host}"
114 "-Duse_system_zlib=1"
115 "--enable-libpkix"
116 "-j"
117 "$NIX_BUILD_CORES"
118 ]
119 ++ lib.optional enableFIPS "--enable-fips"
120 ++ lib.optional stdenv.hostPlatform.isDarwin "--clang"
121 ++ lib.optionals (target_system != stdenv.buildPlatform.uname.system) [
122 "-DOS=${target_system}"
123 ]
124 ++ lib.optionals (!stdenv.buildPlatform.canExecute stdenv.hostPlatform) [
125 "--disable-tests"
126 ];
127 in
128 ''
129 runHook preBuild
130
131 sed -i 's|nss_dist_dir="$dist_dir"|nss_dist_dir="'$out'"|;s|nss_dist_obj_dir="$obj_dir"|nss_dist_obj_dir="'$out'"|' build.sh
132 ./build.sh ${lib.concatStringsSep " " buildFlags}
133
134 runHook postBuild
135 '';
136
137 env.NIX_CFLAGS_COMPILE = toString (
138 [
139 "-Wno-error"
140 "-DNIX_NSS_LIBDIR=\"${placeholder "out"}/lib/\""
141 ]
142 ++ lib.optionals stdenv.hostPlatform.is64bit [
143 "-DNSS_USE_64=1"
144 ]
145 ++ lib.optionals stdenv.hostPlatform.isILP32 [
146 "-DNS_PTR_LE_32=1" # See RNG_RandomUpdate() in drdbg.c
147 ]
148 ++ lib.optionals stdenv.hostPlatform.isFreeBSD [
149 "-D_XOPEN_SOURCE=700"
150 "-D__BSD_VISIBLE"
151 # uses compiler intrinsics gated behind runtime checks for cpu feature flags
152 "-mavx2"
153 "-maes"
154 "-mpclmul"
155 ]
156 );
157
158 installPhase = ''
159 runHook preInstall
160
161 rm -rf $out/private
162 find $out -name "*.TOC" -delete
163 mv $out/public $out/include
164
165 ln -s lib $out/lib64
166
167 # Upstream issue: https://bugzilla.mozilla.org/show_bug.cgi?id=530672
168 # https://gitweb.gentoo.org/repo/gentoo.git/plain/dev-libs/nss/files/nss-3.32-gentoo-fixups.patch?id=af1acce6c6d2c3adb17689261dfe2c2b6771ab8a
169 NSS_MAJOR_VERSION=`grep "NSS_VMAJOR" lib/nss/nss.h | awk '{print $3}'`
170 NSS_MINOR_VERSION=`grep "NSS_VMINOR" lib/nss/nss.h | awk '{print $3}'`
171 NSS_PATCH_VERSION=`grep "NSS_VPATCH" lib/nss/nss.h | awk '{print $3}'`
172 PREFIX="$out"
173
174 mkdir -p $out/lib/pkgconfig
175 sed -e "s,%prefix%,$PREFIX," \
176 -e "s,%exec_prefix%,$PREFIX," \
177 -e "s,%libdir%,$PREFIX/lib64," \
178 -e "s,%includedir%,$dev/include/nss," \
179 -e "s,%NSS_VERSION%,$NSS_MAJOR_VERSION.$NSS_MINOR_VERSION.$NSS_PATCH_VERSION,g" \
180 -e "s,%NSPR_VERSION%,4.16,g" \
181 pkg/pkg-config/nss.pc.in > $out/lib/pkgconfig/nss.pc
182 chmod 0644 $out/lib/pkgconfig/nss.pc
183
184 sed -e "s,@prefix@,$PREFIX," \
185 -e "s,@MOD_MAJOR_VERSION@,$NSS_MAJOR_VERSION," \
186 -e "s,@MOD_MINOR_VERSION@,$NSS_MINOR_VERSION," \
187 -e "s,@MOD_PATCH_VERSION@,$NSS_PATCH_VERSION," \
188 pkg/pkg-config/nss-config.in > $out/bin/nss-config
189 chmod 0755 $out/bin/nss-config
190
191 installManPage doc/nroff/*
192 '';
193
194 postInstall = lib.optionalString useP11kit ''
195 # Replace built-in trust with p11-kit connection
196 ln -sf ${p11-kit}/lib/pkcs11/p11-kit-trust${stdenv.hostPlatform.extensions.sharedLibrary} $out/lib/libnssckbi${stdenv.hostPlatform.extensions.sharedLibrary}
197 '';
198
199 postFixup =
200 let
201 isCross = stdenv.hostPlatform != stdenv.buildPlatform;
202 nss = if isCross then buildPackages.nss.tools else "$out";
203 in
204 (lib.optionalString enableFIPS (
205 ''
206 for libname in freebl3 nssdbm3 softokn3
207 do libfile="$out/lib/lib$libname${stdenv.hostPlatform.extensions.sharedLibrary}"''
208 + (
209 if stdenv.hostPlatform.isDarwin then
210 ''
211 DYLD_LIBRARY_PATH=$out/lib:${nspr.out}/lib \
212 ''
213 else
214 ''
215 LD_LIBRARY_PATH=$out/lib:${nspr.out}/lib \
216 ''
217 )
218 + ''
219 ${nss}/bin/shlibsign -v -i "$libfile"
220 done
221 ''
222 ))
223 + ''
224 moveToOutput bin "$tools"
225 moveToOutput bin/nss-config "$dev"
226 moveToOutput lib/libcrmf.a "$dev" # needed by firefox, for example
227 rm -f "$out"/lib/*.a
228
229 runHook postInstall
230 '';
231
232 passthru.updateScript = ./update.sh;
233
234 passthru.tests =
235 lib.optionalAttrs (lib.versionOlder version nss_latest.version) {
236 inherit (nixosTests) firefox-esr;
237 }
238 // lib.optionalAttrs (lib.versionAtLeast version nss_latest.version) {
239 inherit (nixosTests) firefox;
240 };
241
242 meta = with lib; {
243 homepage = "https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS";
244 description = "Set of libraries for development of security-enabled client and server applications";
245 changelog = "https://github.com/nss-dev/nss/blob/master/doc/rst/releases/nss_${underscoreVersion}.rst";
246 maintainers = with maintainers; [
247 hexa
248 ajs124
249 ];
250 license = licenses.mpl20;
251 platforms = platforms.all;
252 };
253}