summary refs log tree commit diff
path: root/pkgs/development/libraries/nss/generic.nix
blob: 7384413d7719ba5fc8d96c01535b6334eda0f722 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
{ version, hash }:
{ lib
, stdenv
, fetchurl
, nspr
, perl
, zlib
, sqlite
, ninja
, darwin
, fixDarwinDylibNames
, buildPackages
, useP11kit ? true
, p11-kit
, # allow FIPS mode. Note that this makes the output non-reproducible.
  # https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/NSS_Tech_Notes/nss_tech_note6
  enableFIPS ? false
, nixosTests
}:

let
  underscoreVersion = lib.replaceStrings [ "." ] [ "_" ] version;
in
stdenv.mkDerivation rec {
  pname = "nss";
  inherit version;

  src = fetchurl {
    url = "mirror://mozilla/security/nss/releases/NSS_${underscoreVersion}_RTM/src/${pname}-${version}.tar.gz";
    inherit hash;
  };

  depsBuildBuild = [ buildPackages.stdenv.cc ];

  nativeBuildInputs = [ perl ninja (buildPackages.python3.withPackages (ps: with ps; [ gyp ])) ]
    ++ lib.optionals stdenv.hostPlatform.isDarwin [ darwin.cctools fixDarwinDylibNames ];

  buildInputs = [ zlib sqlite ];

  propagatedBuildInputs = [ nspr ];

  patches = [
    # Based on http://patch-tracker.debian.org/patch/series/dl/nss/2:3.15.4-1/85_security_load.patch
    (if (lib.versionOlder version "3.84") then
      ./85_security_load_3.77+.patch
    else
      ./85_security_load_3.85+.patch
    )
    ./fix-cross-compilation.patch
  ];

  patchFlags = [ "-p0" ];

  postPatch = ''
    patchShebangs nss

    for f in nss/coreconf/config.gypi nss/build.sh nss/coreconf/config.gypi; do
      substituteInPlace "$f" --replace "/usr/bin/env" "${buildPackages.coreutils}/bin/env"
    done

    substituteInPlace nss/coreconf/config.gypi --replace "/usr/bin/grep" "${buildPackages.coreutils}/bin/env grep"
  '' + lib.optionalString stdenv.hostPlatform.isDarwin ''
    substituteInPlace nss/coreconf/Darwin.mk --replace '@executable_path/$(notdir $@)' "$out/lib/\$(notdir \$@)"
    substituteInPlace nss/coreconf/config.gypi --replace "'DYLIB_INSTALL_NAME_BASE': '@executable_path'" "'DYLIB_INSTALL_NAME_BASE': '$out/lib'"
  '';

  outputs = [ "out" "dev" "tools" ];

  preConfigure = "cd nss";

  buildPhase =
    let
      getArch = platform:
        if platform.isx86_64 then "x64"
        else if platform.isx86_32 then "ia32"
        else if platform.isAarch32 then "arm"
        else if platform.isAarch64 then "arm64"
        else if platform.isPower && platform.is64bit then
          (
            if platform.isLittleEndian then "ppc64le" else "ppc64"
          )
        else platform.parsed.cpu.name;
      # 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
      target = getArch stdenv.hostPlatform;
      host = getArch stdenv.buildPlatform;
    in
    ''
      runHook preBuild

      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
      ./build.sh -v --opt \
        --with-nspr=${nspr.dev}/include:${nspr.out}/lib \
        --system-sqlite \
        --enable-legacy-db \
        --target ${target} \
        -Dhost_arch=${host} \
        -Duse_system_zlib=1 \
        --enable-libpkix \
        ${lib.optionalString enableFIPS "--enable-fips"} \
        ${lib.optionalString stdenv.isDarwin "--clang"} \
        ${lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) "--disable-tests"}

      runHook postBuild
    '';

  NIX_CFLAGS_COMPILE = toString [
    "-Wno-error"
    "-DNIX_NSS_LIBDIR=\"${placeholder "out"}/lib/\""
  ] ++ lib.optionals stdenv.hostPlatform.is64bit [
    "-DNSS_USE_64=1"
  ] ++ lib.optionals stdenv.hostPlatform.isILP32 [
    "-DNS_PTR_LE_32=1" # See RNG_RandomUpdate() in drdbg.c
  ];

  installPhase = ''
    runHook preInstall

    rm -rf $out/private
    find $out -name "*.TOC" -delete
    mv $out/public $out/include

    ln -s lib $out/lib64

    # Upstream issue: https://bugzilla.mozilla.org/show_bug.cgi?id=530672
    # https://gitweb.gentoo.org/repo/gentoo.git/plain/dev-libs/nss/files/nss-3.32-gentoo-fixups.patch?id=af1acce6c6d2c3adb17689261dfe2c2b6771ab8a
    NSS_MAJOR_VERSION=`grep "NSS_VMAJOR" lib/nss/nss.h | awk '{print $3}'`
    NSS_MINOR_VERSION=`grep "NSS_VMINOR" lib/nss/nss.h | awk '{print $3}'`
    NSS_PATCH_VERSION=`grep "NSS_VPATCH" lib/nss/nss.h | awk '{print $3}'`
    PREFIX="$out"

    mkdir -p $out/lib/pkgconfig
    sed -e "s,%prefix%,$PREFIX," \
        -e "s,%exec_prefix%,$PREFIX," \
        -e "s,%libdir%,$PREFIX/lib64," \
        -e "s,%includedir%,$dev/include/nss," \
        -e "s,%NSS_VERSION%,$NSS_MAJOR_VERSION.$NSS_MINOR_VERSION.$NSS_PATCH_VERSION,g" \
        -e "s,%NSPR_VERSION%,4.16,g" \
        pkg/pkg-config/nss.pc.in > $out/lib/pkgconfig/nss.pc
    chmod 0644 $out/lib/pkgconfig/nss.pc

    sed -e "s,@prefix@,$PREFIX," \
        -e "s,@MOD_MAJOR_VERSION@,$NSS_MAJOR_VERSION," \
        -e "s,@MOD_MINOR_VERSION@,$NSS_MINOR_VERSION," \
        -e "s,@MOD_PATCH_VERSION@,$NSS_PATCH_VERSION," \
        pkg/pkg-config/nss-config.in > $out/bin/nss-config
    chmod 0755 $out/bin/nss-config
  '';

  postInstall = lib.optionalString useP11kit ''
    # Replace built-in trust with p11-kit connection
    ln -sf ${p11-kit}/lib/pkcs11/p11-kit-trust.so $out/lib/libnssckbi.so
  '';

  postFixup =
    let
      isCross = stdenv.hostPlatform != stdenv.buildPlatform;
      nss = if isCross then buildPackages.nss.tools else "$out";
    in
    (lib.optionalString enableFIPS (''
      for libname in freebl3 nssdbm3 softokn3
      do libfile="$out/lib/lib$libname${stdenv.hostPlatform.extensions.sharedLibrary}"'' +
    (if stdenv.isDarwin
    then ''
      DYLD_LIBRARY_PATH=$out/lib:${nspr.out}/lib \
    '' else ''
      LD_LIBRARY_PATH=$out/lib:${nspr.out}/lib \
    '') + ''
          ${nss}/bin/shlibsign -v -i "$libfile"
      done
    '')) +
    ''
      moveToOutput bin "$tools"
      moveToOutput bin/nss-config "$dev"
      moveToOutput lib/libcrmf.a "$dev" # needed by firefox, for example
      rm -f "$out"/lib/*.a

      runHook postInstall
    '';

  passthru.updateScript = ./update.sh;

  passthru.tests = lib.optionalAttrs (lib.versionOlder version "3.69") {
    inherit (nixosTests) firefox-esr-91;
  } // lib.optionalAttrs (lib.versionAtLeast version "3.69") {
    inherit (nixosTests) firefox firefox-esr-102;
  };

  meta = with lib; {
    homepage = "https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS";
    description = "A set of libraries for development of security-enabled client and server applications";
    changelog = "https://github.com/nss-dev/nss/blob/master/doc/rst/releases/nss_${underscoreVersion}.rst";
    maintainers = with maintainers; [ hexa ajs124 ];
    license = licenses.mpl20;
    platforms = platforms.all;
  };
}