Skip to content

Conversation

@ofalvai
Copy link
Collaborator

@ofalvai ofalvai commented Dec 16, 2025

Add runtime dependency environment variables for Nix packages

Improve compatibility for tools by automatically setting up environment variables for their runtime dependencies. For example, nixpkgs#ruby have the following runtime dependencies:

❯ nix-store --query --requisites ~/.local/share/mise/installs/nixpkgs-ruby/3.3.8/result/
/nix/store/1254dv820b6xp5gw9fjz9i0rjxxx3fkh-libffi-39
/nix/store/l619460n5l5jgg2y3b3y6k11q4l462d5-libcxx-19.1.7
/nix/store/p1llvdzvsgy9bgjcxiadhzrp2kv2dd3a-zlib-1.3.1
/nix/store/pff8c9a4l487r0jaipibq21mkww5f1yw-libiconv-109
/nix/store/qz8sy946bfh14jb90wagc43q5clnzxp4-libxml2-2.14.5
/nix/store/6wb8wlgfpqw1n2f0r0x4qqxkp2g67q53-llvm-19.1.7-lib
/nix/store/fsa52rzijpyngswr7k6qq53xm122qxij-libyaml-0.2.5
/nix/store/xjmm1z747hxzlrcd916cgslp6bpnsi1v-clang-19.1.7-lib
/nix/store/h7s2kf798azdmxpj7fccdirlb1hys3r8-clang-19.1.7
/nix/store/vhpaiaa94mqzivqkzjrad6af72irp89j-openssl-3.5.1
/nix/store/z5dn71p2v8zs4ivli9ki35m6bm50fli4-ruby-3.3.8

These store paths each have the usual /lib, /include and /lib/pkgsconfig dirs for shared C headers, dynamic libraries and pkgconfig definitions. These should be made available at runtime. For example, the gem install command often builds native C extensions of gems and needs to have access to libyaml's C headers and .so/.dylib.

How it works

When a tool is installed via the Nix backend, the plugin now:

  1. Queries nix-store --requisites to get all runtime dependencies
  2. Scans each dependency for lib/ and lib/pkgconfig/ directories
  3. Sets environment variables:
    • LD_LIBRARY_PATH (Linux) or DYLD_LIBRARY_PATH (macOS) for shared libraries
    • PKG_CONFIG_PATH for pkg-config files

This ensures that Nix-installed tools can find their dependencies at runtime without requiring additional configuration.

@ofalvai
Copy link
Collaborator Author

ofalvai commented Dec 16, 2025

Summary

Add runtime dependency environment variables for Nix packages. Automatically sets up LD_LIBRARY_PATH, DYLD_LIBRARY_PATH, and PKG_CONFIG_PATH by querying nix-store for dependencies and scanning for lib/ and pkgconfig/ directories.

Walkthrough

File Summary
lib/runtime_deps.lua New module implementing runtime dependency environment variable setup for Nix packages, including functions to query dependencies and configure library paths
hooks/backend_exec_env.lua Integrated runtime dependency environment variables by calling lib.runtime_deps.get_env_vars() and inserting results into env_vars table
mise.toml Updated format task to include lib/ and spec/ directories in stylua formatting
spec/helpers/.lua, spec/hooks/_spec.lua, spec/lib/*.lua Added and updated test files including new runtime_deps_spec.lua and test helper/mock modules
mise-tasks/test-integration Updated test task file

@ofalvai ofalvai force-pushed the push-ywnvpnmmuqot branch 2 times, most recently from 0611ad0 to 04966c7 Compare December 17, 2025 11:42
Copy link
Collaborator Author

@ofalvai ofalvai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an AI-generated review. Please review it carefully.

Actionable comments posted: 1


for _, lib_path in ipairs(lib_paths) do
local is_linux_glibc = os_type == "linux" and lib_path:match("glibc")
local is_darwin_llvm = os_type == "darwin" and lib_path:gmatch("(llvm)?(clang)?")
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Bug

The gmatch method returns an iterator function, not a boolean. This will always evaluate to true (a function object is truthy), causing the condition to incorrectly filter out all Darwin library paths. Should use match instead to check if the pattern exists in the string.

🔄 Suggestion:

Suggested change
local is_darwin_llvm = os_type == "darwin" and lib_path:gmatch("(llvm)?(clang)?")
local is_darwin_llvm = os_type == "darwin" and lib_path:match("(llvm)|(clang)")

@ofalvai ofalvai force-pushed the push-ywnvpnmmuqot branch 2 times, most recently from daeb776 to d5ab89e Compare December 17, 2025 11:53
Copy link
Collaborator Author

@ofalvai ofalvai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an AI-generated review. Please review it carefully.

Actionable comments posted: 1

Comment on lines 31 to 33
-- for _, var in ipairs(lib_env_vars) do
-- table.insert(env_vars, var)
-- end
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Bug

Library environment variables are computed but commented out, so LD_LIBRARY_PATH/DYLD_LIBRARY_PATH are never set. This means shared libraries from runtime dependencies won't be found at runtime, defeating the purpose of this feature. The library paths are found and filtered correctly, but they're never exposed to the environment.

🤖 Prompt for AI Agents:
In lib/runtime_deps.lua between lines 31 and 33, Uncomment the code that inserts library environment variables into the env_vars table so that LD_LIBRARY_PATH (Linux) and DYLD_LIBRARY_PATH (macOS) are properly set with the discovered library paths.

Copy link
Collaborator Author

@ofalvai ofalvai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an AI-generated review. Please review it carefully.

Actionable comments posted: 1

Comment on lines 31 to 33
-- for _, var in ipairs(lib_env_vars) do
-- table.insert(env_vars, var)
-- end
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Bug

Library environment variables are commented out, preventing LD_LIBRARY_PATH (Linux) and DYLD_LIBRARY_PATH (macOS) from being set. This means shared libraries from Nix dependencies won't be discoverable at runtime, breaking tools that need to load dynamic libraries.

🔄 Suggestion:

Suggested change
-- for _, var in ipairs(lib_env_vars) do
-- table.insert(env_vars, var)
-- end
for _, var in ipairs(lib_env_vars) do
table.insert(env_vars, var)
end

Copy link
Collaborator Author

@ofalvai ofalvai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an AI-generated review. Please review it carefully.

Actionable comments posted: 1

{ key = "PATH", value = bin_path },
}

local runtime_deps = require("lib.runtime_deps")
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Bug

The runtime_deps module has a critical bug where library environment variables (LD_LIBRARY_PATH/DYLD_LIBRARY_PATH) are commented out in lib/runtime_deps.lua at lines 31-33. This means the get_env_vars() function will only return PKG_CONFIG_PATH variables, not the library paths needed for runtime dependencies to work properly. The library environment variables must be uncommented to expose shared libraries at runtime.

🤖 Prompt for AI Agents:
In hooks/backend_exec_env.lua at line 17, Uncomment lines 31-33 in lib/runtime_deps.lua to enable\nLD_LIBRARY_PATH/DYLD_LIBRARY_PATH environment variables\nso that runtime dependencies are properly exposed.

@ofalvai ofalvai force-pushed the push-ywnvpnmmuqot branch 2 times, most recently from 98325e5 to b31670f Compare December 17, 2025 12:19
@ofalvai ofalvai force-pushed the push-ywnvpnmmuqot branch 3 times, most recently from e89c232 to 8add043 Compare December 17, 2025 16:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants