JVM / PHP and other languages¶
Overview¶
Beyond the Python / Node / Rust / Go survey, Nixpkgs’ Languages and frameworks chapter covers many other ecosystems—JVM (Java/Gradle), PHP (Composer), Ruby, Perl, OCaml, and more. Each has specialised builders or hooks on top of stdenv.mkDerivation, usually scoped into a matching package set.
This page is a survey hub: entry points and FOD patterns, not a mirror of each manual section. Same rules as Python / Node / Rust / Go: prefer language builders; stay in the matching package set; pin lock/vendor inputs with fixed-output hashes (fetchers and pinning).
Details¶
Shared packaging rules¶
| Rule | Why |
|---|---|
| Prefer the documented language builder / hooks | They wire phases, setup hooks, and dependency FODs you would otherwise reimplement |
| Depend inside the matching package set | Same interpreter/compiler scope (e.g. php.extensions, ruby.gems, perlPackages) |
| Pin lock / vendor trees with FODs | vendorHash, Gradle deps.json / mitmCache, Composer repository hashes — same FOD workflow as cargoHash / npmDepsHash |
Explore nested sets in nix repl (the Languages chapter shows tab-completing javaPackages and similar). For shell-oriented toolchain maps, see language toolchains.
JVM / Java¶
javaPackages groups compiler and related variants (OpenJFX releases, javaPackages.compiler, helpers such as mavenfod). The manual’s Languages intro walks navigating that set with nix repl (Languages and frameworks).
Classic Ant-based packages usually take ant, a jdk, and often stripJavaArchivesHook in nativeBuildInputs, then run ant in buildPhase. Install shared JARs under $out/share/java so JDK setup hooks can put them on CLASSPATH; wrap programs with makeWrapper and a JRE. Details: Java.
Gradle (Java/Kotlin) does not make dependency resolution reproducible by itself. Nixpkgs records Gradle network fetches via a MITM cache:
- Put
gradleinnativeBuildInputsso the Gradle setup hook runs configure/build/check. - Set
mitmCache = gradle.fetchDeps { …; data = ./deps.json; }(and usuallypnameorpkg) so the build restores pinned deps. - Refresh the lock with the cache’s
updateScriptwhen dependencies change.
Optional knobs include gradleFlags, gradleBuildTask (default assemble), and gradleCheckTask (default test). Full API: Gradle / Building a Gradle package.
PHP¶
PHP interpreters live under versioned attributes (php81, …); php is the release’s preferred default. Extensions and tools hang off that interpreter (php.extensions, php.packages.composer); compose runtimes with php.withExtensions / php.buildEnv (PHP).
For Composer applications, the documented high-level builder is php.buildComposerProject2: a mkDerivation wrapper that builds a fixed-output Composer repository from composer.json / composer.lock, installs vendor, and links bin scripts. Pin deps with vendorHash; if upstream omits the lockfile, pass composerLock. Lower-level composition uses php.mkComposerRepository and php.composerHooks inside a normal derivation. See Building PHP projects.
Ruby¶
Default interpreter is ruby (versioned MRI as ruby_3_y, plus jruby / mruby). Gems live under ruby.gems (and per-interpreter sets); prefer ruby.withPackages (ps: [ … ]) so the interpreter can require them. Application packaging may use a locked Gemfile workflow or the shared gem set—follow Ruby rather than inventing Bundler helpers.
Perl¶
CPAN-style libraries use buildPerlPackage and live in perlPackages. The builder runs perl Makefile.PL, adjusts shebangs/PERL5LIB, and propagates Perl deps for nix-env-style installs. Prefer mirror://cpan/ sources and depend on siblings from the same set. See Perl / Packaging Perl programs.
Rest of the Languages chapter¶
OCaml (ocamlPackages / ocaml-ng.ocamlPackages_*), and many other ecosystems, are documented in the same Languages and frameworks chapter. Treat those sections as the source of truth for builders and package-set names; this hub does not duplicate them. Haskell has its own leaf: Haskell packaging.
Examples¶
Minimal shapes only—replace placeholder hashes after the first failed build.
Gradle (mitmCache + gradle.fetchDeps):
stdenv.mkDerivation (finalAttrs: {
pname = "example";
version = "1.0.0";
src = fetchFromGitHub {
owner = "example";
repo = "example";
tag = "v${finalAttrs.version}";
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
};
nativeBuildInputs = [ gradle makeWrapper ];
mitmCache = gradle.fetchDeps {
inherit (finalAttrs) pname;
data = ./deps.json;
};
# gradleFlags / gradleBuildTask as needed — see Gradle manual section
# Refresh deps: $(nix-build -A mitmCache.updateScript) then commit deps.json
})
PHP Composer app (php.buildComposerProject2):
{ php, fetchFromGitHub }:
php.buildComposerProject2 (finalAttrs: {
pname = "php-app";
version = "1.0.0";
src = fetchFromGitHub {
owner = "example";
repo = "php-app";
tag = finalAttrs.version;
hash = "sha256-BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=";
};
vendorHash = "sha256-CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC=";
# composerLock = ./composer.lock; # if missing from src
})
Ruby environment (withPackages):
Perl library (buildPerlPackage in perlPackages):
buildPerlPackage rec {
pname = "Class-C3";
version = "0.21";
src = fetchurl {
url = "mirror://cpan/authors/id/F/FL/FLORA/Class-C3-${version}.tar.gz";
hash = "sha256-DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD=";
};
}
References¶
- Languages and frameworks — chapter hub;
javaPackages/ package-set navigation - Java — Ant, JARs, wrappers, JDKs
- Gradle —
gradle.fetchDeps,mitmCache - Building a Gradle package
- PHP — interpreters, extensions,
withExtensions - Building PHP projects —
php.buildComposerProject2,vendorHash - Ruby —
ruby.withPackages, gems - Perl —
buildPerlPackage,perlPackages - OCaml —
ocamlPackages/ocaml-ng
See also¶
- Python / Node / Rust / Go — parallel survey for those four ecosystems
- Haskell packaging —
haskellPackagesand Cabal builders - Package sets — nested scopes (
perlPackages, language sets) - Fetchers and pinning — FODs and lock-style hashes
- Language toolchains — shells vs packaging entry points
- Simple package — Autotools/C-style baseline