at master 4.7 kB view raw
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 enableParallelBuilding = true; 94 95 postInstall = 96 let 97 dllExtension = stdenv.hostPlatform.extensions.sharedLibrary; 98 staticExtension = stdenv.hostPlatform.extensions.staticLibrary; 99 in 100 '' 101 make install-private-headers 102 ln -s $out/bin/tclsh${release} $out/bin/tclsh 103 if [[ -e $out/lib/libtcl${release}${staticExtension} ]]; then 104 ln -s $out/lib/libtcl${release}${staticExtension} $out/lib/libtcl${staticExtension} 105 fi 106 ${lib.optionalString (!stdenv.hostPlatform.isStatic) '' 107 ln -s $out/lib/libtcl${release}${dllExtension} $out/lib/libtcl${dllExtension} 108 ''} 109 ''; 110 111 meta = with lib; { 112 description = "Tcl scripting language"; 113 homepage = "https://www.tcl.tk/"; 114 license = licenses.tcltk; 115 platforms = platforms.all; 116 maintainers = with maintainers; [ agbrooks ]; 117 }; 118 119 passthru = rec { 120 inherit release version; 121 libPrefix = "tcl${release}"; 122 libdir = "lib/${libPrefix}"; 123 tclPackageHook = callPackage ( 124 { buildPackages }: 125 makeSetupHook { 126 name = "tcl-package-hook"; 127 propagatedBuildInputs = [ buildPackages.makeBinaryWrapper ]; 128 meta = { 129 inherit (meta) maintainers platforms; 130 }; 131 } ./tcl-package-hook.sh 132 ) { }; 133 # verify that Tcl's clock library can access tzdata 134 tests.tzdata = runCommand "${pname}-test-tzdata" { } '' 135 ${baseInterp}/bin/tclsh <(echo "set t [clock scan {2004-10-30 05:00:00} \ 136 -format {%Y-%m-%d %H:%M:%S} \ 137 -timezone :America/New_York]") > $out 138 ''; 139 }; 140 }; 141 142 mkTclDerivation = callPackage ./mk-tcl-derivation.nix { tcl = baseInterp; }; 143 144in 145baseInterp.overrideAttrs (self: { 146 passthru = self.passthru // { 147 inherit mkTclDerivation; 148 }; 149})