nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 lib,
3 stdenv,
4 callPackage,
5 makeSetupHook,
6 runCommand,
7 tzdata,
8 zip,
9 zlib,
10
11 # Version specific stuff
12 release,
13 version,
14 src,
15 extraPatch ? "",
16 ...
17}:
18
19let
20 baseInterp = stdenv.mkDerivation rec {
21 pname = "tcl";
22 inherit version src;
23
24 outputs = [
25 "out"
26 "man"
27 ];
28
29 setOutputFlags = false;
30
31 postPatch = ''
32 substituteInPlace library/clock.tcl \
33 --replace "/usr/share/zoneinfo" "${tzdata}/share/zoneinfo" \
34 --replace "/usr/share/lib/zoneinfo" "" \
35 --replace "/usr/lib/zoneinfo" "" \
36 --replace "/usr/local/etc/zoneinfo" ""
37 ''
38 + extraPatch;
39
40 nativeBuildInputs = lib.optionals (lib.versionAtLeast version "9.0") [
41 # Only used to detect the presence of zlib. Could be replaced with a stub.
42 zip
43 ];
44
45 buildInputs = lib.optionals (lib.versionAtLeast version "9.0") [
46 zlib
47 ];
48
49 preConfigure = ''
50 cd unix
51 '';
52
53 # Note: pre-9.0 flags are temporarily interspersed to avoid a mass rebuild.
54 configureFlags =
55 lib.optionals (lib.versionOlder version "9.0") [
56 "--enable-threads"
57 ]
58 ++ [
59 # Note: using $out instead of $man to prevent a runtime dependency on $man.
60 "--mandir=${placeholder "out"}/share/man"
61 ]
62 ++ lib.optionals (lib.versionOlder version "9.0") [
63 "--enable-man-symlinks"
64 # Don't install tzdata because NixOS already has a more up-to-date copy.
65 "--with-tzdata=no"
66 ]
67 ++ lib.optionals (lib.versionOlder version "8.6") [
68 # configure check broke due to GCC 14
69 "ac_cv_header_stdc=yes"
70 ]
71 ++ lib.optionals (lib.versionAtLeast version "9.0") [
72 # By default, tcl libraries get zipped and embedded into libtcl*.so,
73 # which gets `zipfs mount`ed at runtime. This is fragile (for example
74 # stripping the .so removes the zip trailer), so we install them as
75 # traditional files.
76 # This might make tcl slower to start from slower storage on cold cache,
77 # however according to my benchmarks on fast storage and warm cache
78 # tcl built with --disable-zipfs actually starts in half the time.
79 "--disable-zipfs"
80 ]
81 ++ [
82 # During cross compilation, the tcl build system assumes that libc
83 # functions are broken if it cannot test if they are broken or not and
84 # then causes a link error on static platforms due to symbol conflict.
85 # These functions are *checks notes* strtoul and strstr. These are
86 # never broken on modern platforms!
87 "tcl_cv_strtod_unbroken=ok"
88 "tcl_cv_strtoul_unbroken=ok"
89 "tcl_cv_strstr_unbroken=ok"
90 ]
91 ++ lib.optional stdenv.hostPlatform.is64bit "--enable-64bit";
92
93 buildFlags = lib.optionals stdenv.hostPlatform.isStatic [
94 # Don't use the default Make target for static,
95 # since it builds shared libraries for bundled packages.
96 "binaries"
97 "libraries"
98 "doc"
99 ];
100
101 makeFlags = lib.optionals stdenv.hostPlatform.isStatic [
102 "INSTALL_PACKAGE_TARGETS="
103 ];
104
105 enableParallelBuilding = true;
106
107 postInstall =
108 let
109 dllExtension = stdenv.hostPlatform.extensions.sharedLibrary;
110 staticExtension = stdenv.hostPlatform.extensions.staticLibrary;
111 in
112 ''
113 make install-private-headers
114 ln -s $out/bin/tclsh${release} $out/bin/tclsh
115 if [[ -e $out/lib/libtcl${release}${staticExtension} ]]; then
116 ln -s $out/lib/libtcl${release}${staticExtension} $out/lib/libtcl${staticExtension}
117 fi
118 ${lib.optionalString (!stdenv.hostPlatform.isStatic) ''
119 ln -s $out/lib/libtcl${release}${dllExtension} $out/lib/libtcl${dllExtension}
120 ''}
121 '';
122
123 meta = {
124 description = "Tcl scripting language";
125 homepage = "https://www.tcl.tk/";
126 license = lib.licenses.tcltk;
127 platforms = lib.platforms.all;
128 maintainers = with lib.maintainers; [ agbrooks ];
129 };
130
131 passthru = rec {
132 inherit release version;
133 libPrefix = "tcl${release}";
134 libdir = "lib/${libPrefix}";
135 tclPackageHook = callPackage (
136 { buildPackages }:
137 makeSetupHook {
138 name = "tcl-package-hook";
139 propagatedBuildInputs = [ buildPackages.makeBinaryWrapper ];
140 meta = {
141 inherit (meta) maintainers platforms;
142 };
143 } ./tcl-package-hook.sh
144 ) { };
145 # verify that Tcl's clock library can access tzdata
146 tests.tzdata = runCommand "${pname}-test-tzdata" { } ''
147 ${baseInterp}/bin/tclsh <(echo "set t [clock scan {2004-10-30 05:00:00} \
148 -format {%Y-%m-%d %H:%M:%S} \
149 -timezone :America/New_York]") > $out
150 '';
151 };
152 };
153
154 mkTclDerivation = callPackage ./mk-tcl-derivation.nix { tcl = baseInterp; };
155
156in
157baseInterp.overrideAttrs (self: {
158 passthru = self.passthru // {
159 inherit mkTclDerivation;
160 };
161})