about summary refs log tree commit diff
path: root/nixpkgs/pkgs/servers/irc/inspircd/default.nix
blob: d554b17542e936157ec982eddd61340962d16b4b (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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
let
  # inspircd ships a few extra modules that users can load
  # via configuration. Upstream thus recommends to ship as
  # many of them as possible. There is however a problem:
  # inspircd is licensed under the GPL version 2 only and
  # some modules link libraries that are incompatible with
  # the GPL 2. Therefore we can't provide them as binaries
  # via our binary-caches, but users should still be able
  # to override this package and build the incompatible
  # modules themselves.
  #
  # This means for us we need to a) prevent hydra from
  # building a module set with a GPL incompatibility
  # and b) dynamically figure out the largest possible
  # set of modules to use depending on stdenv, because
  # the used libc needs to be compatible as well.
  #
  # For an overview of all modules and their licensing
  # situation, see https://docs.inspircd.org/packaging/

  # Predicate for checking license compatibility with
  # GPLv2. Since this is _only_ used for libc compatibility
  # checking, only whitelist licenses used by notable
  # libcs in nixpkgs (musl and glibc).
  compatible = lib: drv:
    lib.any (lic: lic == (drv.meta.license or {})) [
      lib.licenses.mit        # musl
      lib.licenses.lgpl2Plus  # glibc
    ];

  # compatible if libc is compatible
  libcModules = [
    "regex_posix"
    "sslrehashsignal"
  ];

  # compatible if libc++ is compatible
  # TODO(sternenseemann):
  # we could enable "regex_stdlib" automatically, but only if
  # we are using libcxxStdenv which is compatible with GPLv2,
  # since the gcc libstdc++ license is GPLv2-incompatible
  libcxxModules = [
    "regex_stdlib"
  ];

  compatibleModules = lib: stdenv: [
    # GPLv2 compatible dependencies
    "argon2"
    "ldap"
    "mysql"
    "pgsql"
    "regex_pcre"
    "regex_pcre2"
    "regex_re2"
    "regex_tre"
    "sqlite3"
    "ssl_gnutls"
  ] ++ lib.optionals (compatible lib stdenv.cc.libc) libcModules;

in

{ lib
, stdenv
, fetchFromGitHub
, nixosTests
, perl
, pkg-config
, libargon2
, openldap
, postgresql
, libmysqlclient
, pcre
, pcre2
, tre
, re2
, sqlite
, gnutls
, libmaxminddb
, openssl
, mbedtls
# For a full list of module names, see https://docs.inspircd.org/packaging/
, extraModules ? compatibleModules lib stdenv
}:

let
  extras = {
    # GPLv2 compatible
    argon2 = [
      (libargon2 // {
        meta = libargon2.meta // {
          # use libargon2 as CC0 since ASL20 is GPLv2-incompatible
          # updating this here is important that meta.license is accurate
          # libargon2 is licensed under either ASL20 or CC0.
          license = lib.licenses.cc0;
        };
      })
    ];
    ldap            = [ openldap ];
    mysql           = [ libmysqlclient ];
    pgsql           = [ postgresql ];
    regex_pcre      = [ pcre ];
    regex_pcre2     = [ pcre2 ];
    regex_re2       = [ re2 ];
    regex_tre       = [ tre ];
    sqlite3         = [ sqlite ];
    ssl_gnutls      = [ gnutls ];
    # depends on stdenv.cc.libc
    regex_posix     = [];
    sslrehashsignal = [];
    # depends on used libc++
    regex_stdlib    = [];
    # GPLv2 incompatible
    geo_maxmind     = [ libmaxminddb ];
    ssl_mbedtls     = [ mbedtls ];
    ssl_openssl     = [ openssl ];
  };

  # buildInputs necessary for the enabled extraModules
  extraInputs = lib.concatMap
    (m: extras."${m}" or (builtins.throw "Unknown extra module ${m}"))
    extraModules;

  # if true, we can't provide a binary version of this
  # package without violating the GPL 2
  gpl2Conflict =
    let
      allowed = compatibleModules lib stdenv;
    in
      !lib.all (lib.flip lib.elem allowed) extraModules;

  # return list of the license(s) of the given derivation
  getLicenses = drv:
    let
      lics = drv.meta.license or [];
    in
      if lib.isAttrs lics || lib.isString lics
      then [ lics ]
      else lics;

  # Whether any member of list1 is also member of list2, i. e. set intersection.
  anyMembers = list1: list2:
    lib.any (m1: lib.elem m1 list2) list1;

in

stdenv.mkDerivation rec {
  pname = "inspircd";
  version = "3.16.1";

  src = fetchFromGitHub {
    owner = pname;
    repo = pname;
    rev = "v${version}";
    sha256 = "sha256-UpDjxF4zRrtiY4Z1tRML1uWQdklfgCeLsJtxCKfHOdw=";
  };

  outputs = [ "bin" "lib" "man" "doc" "out" ];

  nativeBuildInputs = [
    perl
    pkg-config
  ];
  buildInputs = extraInputs;

  configurePhase = ''
    runHook preConfigure

    patchShebangs configure make/*.pl

    # configure is executed twice, once to set the extras
    # to use and once to do the Makefile setup
    ./configure \
      --enable-extras \
      ${lib.escapeShellArg (lib.concatStringsSep " " extraModules)}

    # this manually sets the flags instead of using configureFlags, because otherwise stdenv passes flags like --bindir, which make configure fail
    ./configure \
      --disable-auto-extras \
      --distribution-label nixpkgs${version} \
      --uid 0 \
      --gid 0 \
      --binary-dir  ${placeholder "bin"}/bin \
      --config-dir  /etc/inspircd \
      --data-dir    ${placeholder "lib"}/lib/inspircd \
      --example-dir ${placeholder "doc"}/share/doc/inspircd \
      --log-dir     /var/log/inspircd \
      --manual-dir  ${placeholder "man"}/share/man/man1 \
      --module-dir  ${placeholder "lib"}/lib/inspircd \
      --runtime-dir /var/run \
      --script-dir  ${placeholder "bin"}/share/inspircd \

    runHook postConfigure
  '';

  postInstall = ''
    # for some reasons the executables are not executable
    chmod +x $bin/bin/*
  '';

  enableParallelBuilding = true;

  passthru.tests = {
    nixos-test = nixosTests.inspircd;
  };

  meta = {
    description = "A modular C++ IRC server";
    license = [ lib.licenses.gpl2Only ]
      ++ lib.concatMap getLicenses extraInputs
      ++ lib.optionals (anyMembers extraModules libcModules) (getLicenses stdenv.cc.libc)
      # FIXME(sternenseemann): get license of used lib(std)c++ somehow
      ++ lib.optional (anyMembers extraModules libcxxModules) "Unknown"
      # Hack: Definitely prevent a hydra from building this package on
      # a GPL 2 incompatibility even if it is not in a top-level attribute,
      # but pulled in indirectly somehow.
      ++ lib.optional gpl2Conflict lib.licenses.unfree;
    maintainers = [ lib.maintainers.sternenseemann ];
    # windows is theoretically possible, but requires extra work
    # which I am not willing to do and can't test.
    # https://github.com/inspircd/inspircd/blob/master/win/README.txt
    platforms = lib.platforms.unix;
    homepage = "https://www.inspircd.org/";
  } // lib.optionalAttrs gpl2Conflict {
    # make sure we never distribute a GPLv2-violating module
    # in binary form. They can be built locally of course.
    hydraPlatforms = [];
  };
}