about summary refs log tree commit diff
path: root/pkgs/development/interpreters
diff options
context:
space:
mode:
authorMatthieu Coudron <coudron@iij.ad.jp>2019-02-04 20:30:58 +0900
committerMichael Raskin <7c6f434c@mail.ru>2019-02-04 11:30:58 +0000
commit2ba891788bacfb2c52f25a7a119b88c6cc298e35 (patch)
tree415e485e22f4ce10573fb404d5ec6d02268124cb /pkgs/development/interpreters
parent0955567a7d9fa9e1e472a37549e039ff4fe4f50a (diff)
downloadnixlib-2ba891788bacfb2c52f25a7a119b88c6cc298e35.tar
nixlib-2ba891788bacfb2c52f25a7a119b88c6cc298e35.tar.gz
nixlib-2ba891788bacfb2c52f25a7a119b88c6cc298e35.tar.bz2
nixlib-2ba891788bacfb2c52f25a7a119b88c6cc298e35.tar.lz
nixlib-2ba891788bacfb2c52f25a7a119b88c6cc298e35.tar.xz
nixlib-2ba891788bacfb2c52f25a7a119b88c6cc298e35.tar.zst
nixlib-2ba891788bacfb2c52f25a7a119b88c6cc298e35.zip
Lua generate nix packages from luarocks (#54978)
* lua: generate packages from luarocks

* luarocks-nix: update

* removed packages already available in nixpkgs

* adressing reviews

update script can now accept another csv file as input with -c

* Remove obsolete comment
Diffstat (limited to 'pkgs/development/interpreters')
-rw-r--r--pkgs/development/interpreters/lua-5/build-lua-package.nix182
-rw-r--r--pkgs/development/interpreters/lua-5/setup-hook.sh6
-rw-r--r--pkgs/development/interpreters/lua-5/wrap-lua.nix19
-rw-r--r--pkgs/development/interpreters/lua-5/wrap.sh99
-rw-r--r--pkgs/development/interpreters/lua-5/wrapper.nix2
5 files changed, 304 insertions, 4 deletions
diff --git a/pkgs/development/interpreters/lua-5/build-lua-package.nix b/pkgs/development/interpreters/lua-5/build-lua-package.nix
new file mode 100644
index 000000000000..0bed5efe4f79
--- /dev/null
+++ b/pkgs/development/interpreters/lua-5/build-lua-package.nix
@@ -0,0 +1,182 @@
+# Generic builder for lua packages
+{ lib
+, lua
+, stdenv
+, wrapLua
+, unzip
+, writeText
+# Whether the derivation provides a lua module or not.
+, toLuaModule
+}:
+
+{
+name ? "${attrs.pname}-${attrs.version}"
+
+, version
+
+# by default prefix `name` e.g. "lua5.2-${name}"
+, namePrefix ? "lua" + lua.luaversion + "-"
+
+# Dependencies for building the package
+, buildInputs ? []
+
+# Dependencies needed for running the checkPhase.
+# These are added to buildInputs when doCheck = true.
+, checkInputs ? []
+
+# propagate build dependencies so in case we have A -> B -> C,
+# C can import package A propagated by B
+, propagatedBuildInputs ? []
+, propagatedNativeBuildInputs ? []
+
+# used to disable derivation, useful for specific lua versions
+, disabled ? false
+
+# Additional arguments to pass to the makeWrapper function, which wraps
+# generated binaries.
+, makeWrapperArgs ? []
+, external_deps ? propagatedBuildInputs ++ buildInputs
+
+# Skip wrapping of lua programs altogether
+, dontWrapLuaPrograms ? false
+
+, meta ? {}
+
+, passthru ? {}
+, doCheck ? false
+
+# appended to the luarocks generated config
+# in peculiar variables like { EVENT_INCDIR } can be useful to work around
+# luarocks limitations, ie, luarocks consider include/lib folders to be subfolders of the same package in external_deps_dirs
+# as explained in https://github.com/luarocks/luarocks/issues/766
+, extraConfig ? ""
+
+# relative to srcRoot, path to the rockspec to use when using rocks
+, rockspecFilename ?  "../*.rockspec"
+
+# must be set for packages that don't have a rock
+, knownRockspec ? null
+
+, ... } @ attrs:
+
+
+# Keep extra attributes from `attrs`, e.g., `patchPhase', etc.
+if disabled
+then throw "${name} not supported for interpreter ${lua}"
+else
+
+let
+
+  deps_dirs= lib.concatStringsSep ", " (
+    map (x: "\"${builtins.toString x}\"") external_deps
+  );
+
+  # TODO
+  # - add rocktrees (look at torch-distro.nix/https://github.com/luarocks/luarocks/wiki/Config-file-format)
+  # - silence warnings
+  luarocks_config = "luarocksConfig";
+  luarocks_content = ''
+    local_cache = ""
+    -- array of strings
+    external_deps_dirs = {
+    ${deps_dirs}
+    }
+    rocks_trees = {
+    }
+    ${extraConfig}
+  '';
+in
+toLuaModule ( lua.stdenv.mkDerivation (
+builtins.removeAttrs attrs ["disabled" "checkInputs"] // {
+
+  name = namePrefix + name;
+
+  buildInputs = [ wrapLua lua.pkgs.luarocks ]
+    ++ buildInputs
+    ++ lib.optionals doCheck checkInputs
+    ;
+
+  # propagate lua to active setup-hook in nix-shell
+  propagatedBuildInputs = propagatedBuildInputs ++ [ lua ];
+  doCheck = false;
+
+  # enabled only for src.rock
+  setSourceRoot= let
+    name_only=(builtins.parseDrvName name).name;
+  in
+    lib.optionalString (knownRockspec == null) ''
+    # format is rockspec_basename/source_basename
+    # rockspec can set it via spec.source.dir
+    folder=$(find . -mindepth 2 -maxdepth 2 -type d -path '*${name_only}*/*'|head -n1)
+    sourceRoot="$folder"
+  '';
+
+  configurePhase = ''
+    runHook preConfigure
+
+    cat > ${luarocks_config} <<EOF
+    ${luarocks_content}
+    EOF
+    export LUAROCKS_CONFIG=$PWD/${luarocks_config};
+  ''
+  + lib.optionalString (knownRockspec != null) ''
+
+    # prevents the following type of error:
+    # Inconsistency between rockspec filename (42fm1b3d7iv6fcbhgm9674as3jh6y2sh-luv-1.22.0-1.rockspec) and its contents (luv-1.22.0-1.rockspec)
+    rockspecFilename="$TMP/$(stripHash ''${knownRockspec})"
+    cp ''${knownRockspec} $rockspecFilename
+    runHook postConfigure
+  '';
+
+  buildPhase = ''
+    runHook preBuild
+
+    nix_debug "Using LUAROCKS_CONFIG=$LUAROCKS_CONFIG"
+
+    LUAROCKS=luarocks
+    if (( ''${NIX_DEBUG:-0} >= 1 )); then
+        LUAROCKS="$LUAROCKS --verbose"
+    fi
+
+    patchShebangs .
+
+    runHook postBuild
+  '';
+
+  postFixup = lib.optionalString (!dontWrapLuaPrograms) ''
+    wrapLuaPrograms
+  '' + attrs.postFixup or '''';
+
+  installPhase = attrs.installPhase or ''
+    runHook preInstall
+
+    # luarocks make assumes sources are available in cwd
+    # After the build is complete, it also installs the rock.
+    # If no argument is given, it looks for a rockspec in the current directory
+    # but some packages have several rockspecs in their source directory so
+    # we force the use of the upper level since it is
+    # the sole rockspec in that folder
+    # maybe we could reestablish dependency checking via passing --rock-trees
+
+    nix_debug "ROCKSPEC $rockspecFilename"
+    nix_debug "cwd: $PWD"
+    $LUAROCKS make --deps-mode=none --tree $out ''${rockspecFilename}
+
+    # to prevent collisions when creating environments
+    # also added -f as it doesn't always exist
+    # don't remove the whole directory as
+    rm -rf $out/lib/luarocks/rocks/manifest
+
+    runHook postInstall
+  '';
+
+  passthru = {
+    inherit lua; # The lua interpreter
+  } // passthru;
+
+  meta = with lib.maintainers; {
+    platforms = lua.meta.platforms;
+    # add extra maintainer(s) to every package
+    maintainers = (meta.maintainers or []) ++ [ ];
+  } // meta;
+}))
diff --git a/pkgs/development/interpreters/lua-5/setup-hook.sh b/pkgs/development/interpreters/lua-5/setup-hook.sh
index 5e37bd27f617..3989bedffdb1 100644
--- a/pkgs/development/interpreters/lua-5/setup-hook.sh
+++ b/pkgs/development/interpreters/lua-5/setup-hook.sh
@@ -1,7 +1,7 @@
 # set -e
 
 nix_print() {
-    if (( "${NIX_DEBUG:-0}" >= $1 )); then
+    if [ ${NIX_DEBUG:-0} -ge $1 ]; then
         echo "$2"
     fi
 }
@@ -32,13 +32,13 @@ addToLuaPath() {
     cd "$dir"
     for pattern in @luapathsearchpaths@;
     do
-        addToLuaSearchPathWithCustomDelimiter LUA_PATH "$PWD/$pattern"
+        addToLuaSearchPathWithCustomDelimiter NIX_LUA_PATH "$PWD/$pattern"
     done
 
     # LUA_CPATH
     for pattern in @luacpathsearchpaths@;
     do
-        addToLuaSearchPathWithCustomDelimiter LUA_CPATH "$PWD/$pattern"
+        addToLuaSearchPathWithCustomDelimiter NIX_LUA_CPATH "$PWD/$pattern"
     done
     cd - >/dev/null
 }
diff --git a/pkgs/development/interpreters/lua-5/wrap-lua.nix b/pkgs/development/interpreters/lua-5/wrap-lua.nix
new file mode 100644
index 000000000000..f00e0d5ac336
--- /dev/null
+++ b/pkgs/development/interpreters/lua-5/wrap-lua.nix
@@ -0,0 +1,19 @@
+{ lib
+, lua
+, makeSetupHook
+, makeWrapper
+}:
+
+with lib;
+
+# defined in trivial-builders.nix
+# imported as wrapLua in lua-packages.nix and passed to build-lua-derivation to be used as buildInput
+makeSetupHook {
+      deps = makeWrapper;
+      substitutions.executable = lua.interpreter;
+      substitutions.lua = lua;
+      substitutions.LuaPathSearchPaths = lib.escapeShellArgs lua.LuaPathSearchPaths;
+      substitutions.LuaCPathSearchPaths = lib.escapeShellArgs lua.LuaPathSearchPaths;
+
+} ./wrap.sh
+
diff --git a/pkgs/development/interpreters/lua-5/wrap.sh b/pkgs/development/interpreters/lua-5/wrap.sh
new file mode 100644
index 000000000000..545a0ae271c4
--- /dev/null
+++ b/pkgs/development/interpreters/lua-5/wrap.sh
@@ -0,0 +1,99 @@
+# Inspired by python/wrapper.nix
+# Wrapper around wrapLuaProgramsIn, below. The $luaPath
+# variable is passed in from the buildLuarocksPackage function.
+set -e
+
+wrapLuaPrograms() {
+    wrapLuaProgramsIn "$out/bin" "$out $luaPath"
+}
+
+# Builds environment variables like LUA_PATH and PATH walking through closure
+# of dependencies.
+buildLuaPath() {
+    local luaPath="$1"
+    local path
+
+    # Create an empty table of paths (see doc on loadFromPropagatedInputs
+    # for how this is used). Build up the program_PATH and program_LUA_PATH
+    # variables.
+    declare -A luaPathsSeen=()
+    program_PATH=
+    luaPathsSeen["@lua@"]=1
+    addToSearchPath program_PATH @lua@/bin
+    for path in $luaPath; do
+        addToLuaPath "$path"
+    done
+}
+
+
+# with an executable shell script which will set some environment variables
+# and then call into the original binary (which has been given a .wrapped suffix).
+# luaPath is a list of directories
+wrapLuaProgramsIn() {
+    local dir="$1"
+    local luaPath="$2"
+    local f
+
+    buildLuaPath "$luaPath"
+
+    if [ ! -d "$dir" ]; then
+        nix_debug "$dir not a directory"
+        return
+    fi
+
+    nix_debug "wrapping programs in [$dir]"
+
+    # Find all regular files in the output directory that are executable.
+    find "$dir" -type f -perm -0100 -print0 | while read -d "" f; do
+        # Rewrite "#! .../env lua" to "#! /nix/store/.../lua".
+        # Strip suffix, like "3" or "2.7m" -- we don't have any choice on which
+        # Lua to use besides one with this hook anyway.
+        if head -n1 "$f" | grep -q '#!.*/env.*\(lua\)'; then
+            sed -i "$f" -e "1 s^.*/env[ ]*\(lua\)[^ ]*^#! @executable@^"
+        fi
+
+        # wrapProgram creates the executable shell script described
+        # above. The script will set LUA_(C)PATH and PATH variables!
+        # (see pkgs/build-support/setup-hooks/make-wrapper.sh)
+        local -a wrap_args=("$f"
+            --prefix PATH ':' "$program_PATH"
+            --prefix LUA_PATH ';' "$NIX_LUA_PATH"
+            --prefix LUA_CPATH ';' "$NIX_LUA_CPATH"
+        )
+
+        # Add any additional arguments provided by makeWrapperArgs
+        # argument to buildLuaPackage.
+        # makeWrapperArgs
+        local -a user_args="($makeWrapperArgs)"
+        local -a wrapProgramArgs=("${wrap_args[@]}" "${user_args[@]}")
+
+        # see setup-hooks/make-wrapper.sh
+        wrapProgram "${wrapProgramArgs[@]}"
+
+    done
+}
+
+# Adds the lib and bin directories to the LUA_PATH and PATH variables,
+# respectively. Recurses on any paths declared in
+# `propagated-native-build-inputs`, while avoiding duplicating paths by
+# flagging the directories it has visited in `luaPathsSeen`.
+loadFromPropagatedInputs() {
+    local dir="$1"
+    # Stop if we've already visited here.
+    if [ -n "${luaPathsSeen[$dir]}" ]; then
+        return;
+    fi
+    luaPathsSeen[$dir]=1
+
+    addToLuaPath "$dir"
+    addToSearchPath program_PATH $dir/bin
+
+    # Inspect the propagated inputs (if they exist) and recur on them.
+    local prop="$dir/nix-support/propagated-native-build-inputs"
+    if [ -e "$prop" ]; then
+        local new_path
+        for new_path in $(cat $prop); do
+            loadFromPropagatedInputs "$new_path"
+        done
+    fi
+}
diff --git a/pkgs/development/interpreters/lua-5/wrapper.nix b/pkgs/development/interpreters/lua-5/wrapper.nix
index 9abbd77d575e..7f584c0f0aff 100644
--- a/pkgs/development/interpreters/lua-5/wrapper.nix
+++ b/pkgs/development/interpreters/lua-5/wrapper.nix
@@ -44,7 +44,7 @@ let
               rm -f "$out/bin/$prg"
               if [ -x "$prg" ]; then
                 nix_debug "Making wrapper $prg"
-                makeWrapper "$path/bin/$prg" "$out/bin/$prg" --suffix LUA_PATH ';' "$LUA_PATH"   --suffix LUA_CPATH ';' "$LUA_CPATH" ${stdenv.lib.concatStringsSep " " makeWrapperArgs}
+                makeWrapper "$path/bin/$prg" "$out/bin/$prg" --suffix LUA_PATH ';' "$NIX_LUA_PATH"   --suffix LUA_CPATH ';' "$NIX_LUA_CPATH" ${stdenv.lib.concatStringsSep " " makeWrapperArgs}
               fi
             fi
           done