Merge pull request #330634 from r-ryantm/auto-update/circumflex
[NixPkgs.git] / pkgs / servers / irc / inspircd / default.nix
blobdd821ce11959175e6dec705805f7456e2b6cf2ee
1 let
2   # inspircd ships a few extra modules that users can load
3   # via configuration. Upstream thus recommends to ship as
4   # many of them as possible. There is however a problem:
5   # inspircd is licensed under the GPL version 2 only and
6   # some modules link libraries that are incompatible with
7   # the GPL 2. Therefore we can't provide them as binaries
8   # via our binary-caches, but users should still be able
9   # to override this package and build the incompatible
10   # modules themselves.
11   #
12   # This means for us we need to a) prevent hydra from
13   # building a module set with a GPL incompatibility
14   # and b) dynamically figure out the largest possible
15   # set of modules to use depending on stdenv, because
16   # the used libc needs to be compatible as well.
17   #
18   # For an overview of all modules and their licensing
19   # situation, see https://docs.inspircd.org/packaging/
21   # Predicate for checking license compatibility with
22   # GPLv2. Since this is _only_ used for libc compatibility
23   # checking, only whitelist licenses used by notable
24   # libcs in nixpkgs (musl and glibc).
25   compatible = lib: drv:
26     lib.any (lic: lic == (drv.meta.license or {})) [
27       lib.licenses.mit        # musl
28       lib.licenses.lgpl2Plus  # glibc
29     ];
31   # compatible if libc is compatible
32   libcModules = [
33     "regex_posix"
34     "sslrehashsignal"
35   ];
37   # compatible if libc++ is compatible
38   # TODO(sternenseemann):
39   # we could enable "regex_stdlib" automatically, but only if
40   # we are using libcxxStdenv which is compatible with GPLv2,
41   # since the gcc libstdc++ license is GPLv2-incompatible
42   libcxxModules = [
43     "regex_stdlib"
44   ];
46   compatibleModules = lib: stdenv: [
47     # GPLv2 compatible dependencies
48     "argon2"
49     "ldap"
50     "mysql"
51     "pgsql"
52     "regex_pcre"
53     "regex_pcre2"
54     "regex_re2"
55     "regex_tre"
56     "sqlite3"
57     "ssl_gnutls"
58   ] ++ lib.optionals (compatible lib stdenv.cc.libc) libcModules;
62 { lib
63 , stdenv
64 , fetchFromGitHub
65 , nixosTests
66 , perl
67 , pkg-config
68 , libargon2
69 , openldap
70 , postgresql
71 , libmysqlclient
72 , pcre
73 , pcre2
74 , tre
75 , re2
76 , sqlite
77 , gnutls
78 , libmaxminddb
79 , openssl
80 , mbedtls
81 # For a full list of module names, see https://docs.inspircd.org/packaging/
82 , extraModules ? compatibleModules lib stdenv
85 let
86   extras = {
87     # GPLv2 compatible
88     argon2 = [
89       (libargon2 // {
90         meta = libargon2.meta // {
91           # use libargon2 as CC0 since ASL20 is GPLv2-incompatible
92           # updating this here is important that meta.license is accurate
93           # libargon2 is licensed under either ASL20 or CC0.
94           license = lib.licenses.cc0;
95         };
96       })
97     ];
98     ldap            = [ openldap ];
99     mysql           = [ libmysqlclient ];
100     pgsql           = [ postgresql ];
101     regex_pcre      = [ pcre ];
102     regex_pcre2     = [ pcre2 ];
103     regex_re2       = [ re2 ];
104     regex_tre       = [ tre ];
105     sqlite3         = [ sqlite ];
106     ssl_gnutls      = [ gnutls ];
107     # depends on stdenv.cc.libc
108     regex_posix     = [];
109     sslrehashsignal = [];
110     # depends on used libc++
111     regex_stdlib    = [];
112     # GPLv2 incompatible
113     geo_maxmind     = [ libmaxminddb ];
114     ssl_mbedtls     = [ mbedtls ];
115     ssl_openssl     = [ openssl ];
116   };
118   # buildInputs necessary for the enabled extraModules
119   extraInputs = lib.concatMap
120     (m: extras."${m}" or (builtins.throw "Unknown extra module ${m}"))
121     extraModules;
123   # if true, we can't provide a binary version of this
124   # package without violating the GPL 2
125   gpl2Conflict =
126     let
127       allowed = compatibleModules lib stdenv;
128     in
129       !lib.all (lib.flip lib.elem allowed) extraModules;
131   # return list of the license(s) of the given derivation
132   getLicenses = drv:
133     let
134       lics = drv.meta.license or [];
135     in
136       if lib.isAttrs lics || lib.isString lics
137       then [ lics ]
138       else lics;
140   # Whether any member of list1 is also member of list2, i. e. set intersection.
141   anyMembers = list1: list2:
142     lib.any (m1: lib.elem m1 list2) list1;
146 stdenv.mkDerivation rec {
147   pname = "inspircd";
148   version = "3.17.1";
150   src = fetchFromGitHub {
151     owner = pname;
152     repo = pname;
153     rev = "v${version}";
154     sha256 = "sha256-4jtIh6wpZ/rexnwhqicU1gUk6DerGLXM9OY+GkmiEnI=";
155   };
157   outputs = [ "bin" "lib" "man" "doc" "out" ];
159   nativeBuildInputs = [
160     perl
161     pkg-config
162   ];
163   buildInputs = extraInputs;
165   configurePhase = ''
166     runHook preConfigure
168     patchShebangs configure make/*.pl
170     # configure is executed twice, once to set the extras
171     # to use and once to do the Makefile setup
172     ./configure \
173       --enable-extras \
174       ${lib.escapeShellArg (lib.concatStringsSep " " extraModules)}
176     # this manually sets the flags instead of using configureFlags, because otherwise stdenv passes flags like --bindir, which make configure fail
177     ./configure \
178       --disable-auto-extras \
179       --distribution-label nixpkgs${version} \
180       --uid 0 \
181       --gid 0 \
182       --binary-dir  ${placeholder "bin"}/bin \
183       --config-dir  /etc/inspircd \
184       --data-dir    ${placeholder "lib"}/lib/inspircd \
185       --example-dir ${placeholder "doc"}/share/doc/inspircd \
186       --log-dir     /var/log/inspircd \
187       --manual-dir  ${placeholder "man"}/share/man/man1 \
188       --module-dir  ${placeholder "lib"}/lib/inspircd \
189       --runtime-dir /var/run \
190       --script-dir  ${placeholder "bin"}/share/inspircd \
192     runHook postConfigure
193   '';
195   postInstall = ''
196     # for some reasons the executables are not executable
197     chmod +x $bin/bin/*
198   '';
200   enableParallelBuilding = true;
202   passthru.tests = {
203     nixos-test = nixosTests.inspircd;
204   };
206   meta = {
207     description = "Modular C++ IRC server";
208     license = [ lib.licenses.gpl2Only ]
209       ++ lib.concatMap getLicenses extraInputs
210       ++ lib.optionals (anyMembers extraModules libcModules) (getLicenses stdenv.cc.libc)
211       # FIXME(sternenseemann): get license of used lib(std)c++ somehow
212       ++ lib.optional (anyMembers extraModules libcxxModules) "Unknown"
213       # Hack: Definitely prevent a hydra from building this package on
214       # a GPL 2 incompatibility even if it is not in a top-level attribute,
215       # but pulled in indirectly somehow.
216       ++ lib.optional gpl2Conflict lib.licenses.unfree;
217     maintainers = [ lib.maintainers.sternenseemann ];
218     # windows is theoretically possible, but requires extra work
219     # which I am not willing to do and can't test.
220     # https://github.com/inspircd/inspircd/blob/master/win/README.txt
221     platforms = lib.platforms.unix;
222     homepage = "https://www.inspircd.org/";
223   } // lib.optionalAttrs gpl2Conflict {
224     # make sure we never distribute a GPLv2-violating module
225     # in binary form. They can be built locally of course.
226     hydraPlatforms = [];
227   };