mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-27 09:23:01 +00:00
tcl: Add tclPackageHook and mkTclDerivation
Implement tclPackageHook, a setup hook that adjusts TCLLIBPATH to include the paths of any installed Tcl packages, propagates that TCLLIBPATH to anti-dependencies, and wraps any installed binaries to set their TCLLIBPATH. Additionally, implement a makePythonPackage-style mkDerivation wrapper to use reasonable defaults for Tcl packages and use tclPackageHook.
This commit is contained in:
parent
d0fd8a029d
commit
c6ca1ba9c7
@ -1,55 +1,69 @@
|
||||
{ lib, stdenv
|
||||
{ lib, stdenv, callPackage, makeSetupHook, makeWrapper
|
||||
|
||||
# Version specific stuff
|
||||
, release, version, src
|
||||
, ...
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
pname = "tcl";
|
||||
inherit version;
|
||||
let
|
||||
baseInterp =
|
||||
stdenv.mkDerivation {
|
||||
pname = "tcl";
|
||||
inherit version;
|
||||
|
||||
inherit src;
|
||||
inherit src;
|
||||
|
||||
outputs = [ "out" "man" ];
|
||||
outputs = [ "out" "man" ];
|
||||
|
||||
setOutputFlags = false;
|
||||
setOutputFlags = false;
|
||||
|
||||
preConfigure = ''
|
||||
cd unix
|
||||
'';
|
||||
preConfigure = ''
|
||||
cd unix
|
||||
'';
|
||||
|
||||
configureFlags = [
|
||||
"--enable-threads"
|
||||
# Note: using $out instead of $man to prevent a runtime dependency on $man.
|
||||
"--mandir=${placeholder "out"}/share/man"
|
||||
"--enable-man-symlinks"
|
||||
# Don't install tzdata because NixOS already has a more up-to-date copy.
|
||||
"--with-tzdata=no"
|
||||
"tcl_cv_strtod_unbroken=ok"
|
||||
] ++ lib.optional stdenv.is64bit "--enable-64bit";
|
||||
configureFlags = [
|
||||
"--enable-threads"
|
||||
# Note: using $out instead of $man to prevent a runtime dependency on $man.
|
||||
"--mandir=${placeholder "out"}/share/man"
|
||||
"--enable-man-symlinks"
|
||||
# Don't install tzdata because NixOS already has a more up-to-date copy.
|
||||
"--with-tzdata=no"
|
||||
"tcl_cv_strtod_unbroken=ok"
|
||||
] ++ lib.optional stdenv.is64bit "--enable-64bit";
|
||||
|
||||
enableParallelBuilding = true;
|
||||
enableParallelBuilding = true;
|
||||
|
||||
postInstall = let
|
||||
dllExtension = stdenv.hostPlatform.extensions.sharedLibrary;
|
||||
in ''
|
||||
make install-private-headers
|
||||
ln -s $out/bin/tclsh${release} $out/bin/tclsh
|
||||
ln -s $out/lib/libtcl${release}${dllExtension} $out/lib/libtcl${dllExtension}
|
||||
'';
|
||||
postInstall = let
|
||||
dllExtension = stdenv.hostPlatform.extensions.sharedLibrary;
|
||||
in ''
|
||||
make install-private-headers
|
||||
ln -s $out/bin/tclsh${release} $out/bin/tclsh
|
||||
ln -s $out/lib/libtcl${release}${dllExtension} $out/lib/libtcl${dllExtension}
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "The Tcl scripting language";
|
||||
homepage = "https://www.tcl.tk/";
|
||||
license = licenses.tcltk;
|
||||
platforms = platforms.all;
|
||||
maintainers = with maintainers; [ vrthra ];
|
||||
};
|
||||
meta = with lib; {
|
||||
description = "The Tcl scripting language";
|
||||
homepage = "https://www.tcl.tk/";
|
||||
license = licenses.tcltk;
|
||||
platforms = platforms.all;
|
||||
maintainers = with maintainers; [ vrthra ];
|
||||
};
|
||||
|
||||
passthru = rec {
|
||||
inherit release version;
|
||||
libPrefix = "tcl${release}";
|
||||
libdir = "lib/${libPrefix}";
|
||||
};
|
||||
}
|
||||
passthru = rec {
|
||||
inherit release version;
|
||||
libPrefix = "tcl${release}";
|
||||
libdir = "lib/${libPrefix}";
|
||||
tclPackageHook = callPackage ({}: makeSetupHook {
|
||||
name = "tcl-package-hook";
|
||||
deps = [ makeWrapper ];
|
||||
} ./tcl-package-hook.sh) {};
|
||||
};
|
||||
};
|
||||
|
||||
mkTclDerivation = callPackage ./mk-tcl-derivation.nix { tcl = baseInterp; };
|
||||
|
||||
in baseInterp.overrideAttrs (self: {
|
||||
passthru = self.passthru // {
|
||||
inherit mkTclDerivation;
|
||||
};
|
||||
})
|
||||
|
69
pkgs/development/interpreters/tcl/mk-tcl-derivation.nix
Normal file
69
pkgs/development/interpreters/tcl/mk-tcl-derivation.nix
Normal file
@ -0,0 +1,69 @@
|
||||
# Generic builder for tcl packages/applications, generally based on mk-python-derivation.nix
|
||||
{ tcl
|
||||
, lib
|
||||
, makeWrapper
|
||||
, runCommand
|
||||
, writeScript
|
||||
}:
|
||||
|
||||
{ buildInputs ? []
|
||||
, nativeBuildInputs ? []
|
||||
, propagatedBuildInputs ? []
|
||||
, checkInputs ? []
|
||||
|
||||
# true if we should skip the configuration phase altogether
|
||||
, dontConfigure ? false
|
||||
|
||||
# Extra flags passed to configure step
|
||||
, configureFlags ? []
|
||||
|
||||
# Whether or not we should add common Tcl-related configure flags
|
||||
, addTclConfigureFlags ? true
|
||||
|
||||
, meta ? {}
|
||||
, passthru ? {}
|
||||
, doCheck ? true
|
||||
, ... } @ attrs:
|
||||
|
||||
let
|
||||
inherit (tcl) stdenv;
|
||||
inherit (lib) getBin optionalAttrs optionals;
|
||||
|
||||
defaultTclPkgConfigureFlags = [
|
||||
"--with-tcl=${tcl}/lib"
|
||||
"--with-tclinclude=${tcl}/include"
|
||||
"--exec-prefix=\${out}"
|
||||
];
|
||||
|
||||
self = (stdenv.mkDerivation ((builtins.removeAttrs attrs [
|
||||
"addTclConfigureFlags" "checkPhase" "checkInputs" "doCheck"
|
||||
]) // {
|
||||
|
||||
buildInputs = buildInputs ++ [ makeWrapper tcl.tclPackageHook ];
|
||||
nativeBuildInputs = nativeBuildInputs ++ [ tcl ];
|
||||
propagatedBuildInputs = propagatedBuildInputs ++ [ tcl ];
|
||||
|
||||
TCLSH = "${getBin tcl}/bin/tclsh";
|
||||
|
||||
# Run tests after install, at which point we've done all TCLLIBPATH setup
|
||||
doCheck = false;
|
||||
doInstallCheck = attrs.doCheck or ((attrs ? doInstallCheck) && attrs.doInstallCheck);
|
||||
installCheckInputs = checkInputs ++ (optionals (attrs ? installCheckInputs) attrs.installCheckInputs);
|
||||
|
||||
# Add typical values expected by TEA for configureFlags
|
||||
configureFlags =
|
||||
if (!dontConfigure && addTclConfigureFlags)
|
||||
then (configureFlags ++ defaultTclPkgConfigureFlags)
|
||||
else configureFlags;
|
||||
|
||||
meta = {
|
||||
platforms = tcl.meta.platforms;
|
||||
} // meta;
|
||||
|
||||
|
||||
} // optionalAttrs (attrs?checkPhase) {
|
||||
installCheckPhase = attrs.checkPhase;
|
||||
}
|
||||
));
|
||||
|
||||
in lib.extendDerivation true passthru self
|
74
pkgs/development/interpreters/tcl/tcl-package-hook.sh
Normal file
74
pkgs/development/interpreters/tcl/tcl-package-hook.sh
Normal file
@ -0,0 +1,74 @@
|
||||
# This hook ensures that we do the following in post-fixup:
|
||||
# * wrap any installed executables with a wrapper that configures TCLLIBPATH
|
||||
# * write a setup hook that extends the TCLLIBPATH of any anti-dependencies
|
||||
|
||||
# Add a directory to TCLLIBPATH, provided that it exists
|
||||
_addToTclLibPath() {
|
||||
local -r tclPkg="$1"
|
||||
if [ -z "$tclPkg" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [ ! -d "$tclPkg" ]; then
|
||||
>&2 echo "can't add $tclPkg to TCLLIBPATH; that directory doesn't exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$tclPkg" == *" "* ]]; then
|
||||
tclPkg="{$tclPkg}"
|
||||
fi
|
||||
|
||||
if [ -z "${TCLLIBPATH-}" ]; then
|
||||
export TCLLIBPATH="$tclPkg"
|
||||
else
|
||||
if [[ "$TCLLIBPATH" != *"$tclPkg"* ]]; then
|
||||
export TCLLIBPATH="${TCLLIBPATH} $tclPkg"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Locate any directory containing an installed pkgIndex file
|
||||
findInstalledTclPkgs() {
|
||||
local -r newLibDir="${!outputLib}/lib"
|
||||
if [ ! -d "$newLibDir" ]; then
|
||||
>&2 echo "Assuming no loadable tcl packages installed ($newLibDir does not exist)"
|
||||
return
|
||||
fi
|
||||
echo "$(find "$newLibDir" -name pkgIndex.tcl -exec dirname {} \;)"
|
||||
}
|
||||
|
||||
# Wrap any freshly-installed binaries and set up their TCLLIBPATH
|
||||
wrapTclBins() {
|
||||
if [ -z "${TCLLIBPATH-}" ]; then
|
||||
echo "skipping automatic Tcl binary wrapping (nothing to do)"
|
||||
return
|
||||
fi
|
||||
|
||||
local -r tclBinsDir="${!outputBin}/bin"
|
||||
if [ ! -d "$tclBinsDir" ]; then
|
||||
echo "No outputBin found, not using any TCLLIBPATH wrapper"
|
||||
return
|
||||
fi
|
||||
|
||||
find "$tclBinsDir" -type f -executable -print |
|
||||
while read -r someBin; do
|
||||
echo "Adding TCLLIBPATH wrapper for $someBin"
|
||||
wrapProgram "$someBin" --set TCLLIBPATH "$TCLLIBPATH"
|
||||
done
|
||||
}
|
||||
|
||||
# Generate hook to adjust TCLLIBPATH in anti-dependencies
|
||||
writeTclLibPathHook() {
|
||||
local -r hookPath="${!outputLib}/nix-support/setup-hook"
|
||||
mkdir -p "$(dirname "$hookPath")"
|
||||
|
||||
typeset -f _addToTclLibPath >> "$hookPath"
|
||||
local -r tclPkgs=$(findInstalledTclPkgs)
|
||||
while IFS= read -r tclPkg; do
|
||||
echo "_addToTclLibPath \"$tclPkg\"" >> "$hookPath"
|
||||
_addToTclLibPath "$tclPkg" true
|
||||
done <<< "$tclPkgs"
|
||||
}
|
||||
|
||||
postFixupHooks+=(writeTclLibPathHook)
|
||||
postFixupHooks+=(wrapTclBins)
|
Loading…
Reference in New Issue
Block a user