diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..4918154 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,71 @@ +# Copyright 2026 The zb Authors +# SPDX-License-Identifier: MIT + +name: Build +on: + push: + pull_request: +jobs: + build: + name: Build + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + env: + my_zb_version: '0.2.0-beta6' + my_zb_config: >- + { + "debug": true, + "trustedPublicKeys": [ + {"format":"ed25519","publicKey":"M0Wc4njJwCmAHZSp06CE1iNYVXvw023OZqgf0iPMBVA="}, + ], + "server": { + "download": { + "type": "http", + "url": "https://zb-cache.256lights.llc/store.json", + }, + }, + } + steps: + - uses: actions/checkout@v7 + - uses: google-github-actions/auth@v3 + if: github.event_name == 'push' + with: + project_id: ${{ vars.ZB_WORKLOAD_IDENTITY_PROVIDER }} + workload_identity_provider: ${{ vars.ZB_WORKLOAD_IDENTITY_PROVIDER }} + - run: mkdir -p "${XDG_CACHE_HOME:-$HOME/.cache}/zb" + - uses: 256lights/setup-zb@v1 + if: github.event_name != 'push' + with: + zb-version: ${{ env.my_zb_version }} + configuration: ${{ env.my_zb_config }} + - name: Set up zb with upload settings + if: github.event_name == 'push' + uses: 256lights/setup-zb@v1 + with: + zb-version: ${{ env.my_zb_version }} + configuration: ${{ env.my_zb_config }} + signing-key: ${{ secrets.ZB_SIGNING_KEY }} + server-upload-discovery: >- + { + "_links": { + "https://zb-build.dev/api/rel/narinfo": [ + { + "href": "gs://zb-stdlib-cache/{digest}.narinfo", + "templated": true + } + ], + "https://zb-build.dev/api/rel/nar": { + "href": "gs://zb-stdlib-cache/nar/{digest}.nar", + "templated": true + }, + "https://zb-build.dev/api/rel/realization": [ + { + "href": "gs://zb-stdlib-cache/realizations/{hashDigest}.json", + "templated": true + } + ] + } + } + - run: zb build --debug=0 ci.lua diff --git a/bootstrap/binary/linux.lua b/bootstrap/binary/linux.lua index b525a4b..4ed5799 100644 --- a/bootstrap/binary/linux.lua +++ b/bootstrap/binary/linux.lua @@ -240,19 +240,18 @@ find \ return makeDerivation(args) end - local linuxHeaders = linuxHeaders.new { + local linuxHeaders = defaultOutput(linuxHeaders.new { makeDerivation = makeDerivationWithGCC2; - buildSystem = system; + targetSystem = system; version = "4.14.336"; - } + }, system) - local busybox = busybox.new { + local busybox = defaultOutput(busybox.new { makeDerivation = makeDerivationWithGCC2; - buildSystem = system; version = "1.36.1"; configFile = path "busybox-config"; linuxHeaders = linuxHeaders; - } + }, system) return { gcc = gcc2; diff --git a/ci.lua b/ci.lua new file mode 100644 index 0000000..efb942f --- /dev/null +++ b/ci.lua @@ -0,0 +1,11 @@ +-- Copyright 2026 The zb Authors +-- SPDX-License-Identifier: MIT + +return { + stdenv = import("stdenv/stdenv.lua").makeDerivation { + name = "stdenv-test"; + dontUnpack = true; + installPhase = "touch $out"; + }; + go = import("packages/go/go.lua")["1.26"]; +} diff --git a/packages/bash/bash.lua b/packages/bash/bash.lua index 701aab6..6e49194 100644 --- a/packages/bash/bash.lua +++ b/packages/bash/bash.lua @@ -8,7 +8,8 @@ local strings = import "../../strings.lua" local systems = import "../../systems.lua" local tables = import "../../tables.lua" -local module = {} +local getters = {} +local module = setmetatable({}, { __index = tables.lazyModule(getters) }) local tarballArgs = { ["5.2.15"] = { @@ -24,104 +25,101 @@ local patches = { path "patches/5.2.15/02-omit-rdynamic.diff", } +---@generic T ---@param args { ----makeDerivation: function, ----buildSystem: string, +---makeDerivation: (fun(args: table): T), ---version: string, ---} ----@return derivation +---@return T function module.new(args) local src = module.tarballs[args.version] if not src then error("bash.new: unsupported version "..args.version) end - local buildSystem = systems.parse(args.buildSystem) - local configureFlags = { - "--without-bash-malloc", - "--disable-nls", - } - if buildSystem.isLinux then - configureFlags[#configureFlags+1] = "--enable-static-link" - end - return args.makeDerivation { - pname = "bash"; - version = args.version; - buildSystem = args.buildSystem; - src = src; - patches = patches; - postInstall = [[ln -s bash "$out/bin/sh"]]; - - configureFlags = configureFlags; - } + return tables.withOutputs(args, function(args, system) + local buildSystem = systems.parse(system) + local configureFlags = { + "--without-bash-malloc", + "--disable-nls", + } + if buildSystem.isLinux then + configureFlags[#configureFlags + 1] = "--enable-static-link" + end + return outputs(args.makeDerivation { + pname = "bash"; + version = args.version; + src = src; + patches = patches; + postInstall = [[ln -s bash "$out/bin/sh"]]; + + configureFlags = configureFlags; + }, system) + end) end -for _, system in ipairs(systems.stdlibSystems) do - local system = system - module[system] = tables.lazyModule { - bootstrap = function() - local version = "5.2.15" - - local sys = systems.parse(system) - if sys and sys.isLinux then - local seeds = import "../../bootstrap/seeds.lua" - return derivation { - name = "bash-"..version; - pname = "bash"; - version = version; - - system = system; - builder = seeds[system].busybox.."/bin/sh"; - args = { path "build.sh" }; - - src = module.tarballs[version]; - patches = patches; - - PATH = strings.makeBinPath { - gnumake[system].bootstrap, - seeds[system].busybox, - gcc[system].bootstrap, - }; - LDFLAGS = { "-static" }; - SOURCE_DATE_EPOCH = 0; - KBUILD_BUILD_TIMESTAMP = "@0"; - } - elseif sys and sys.isMacOS then - return derivation { - name = "bash-"..version; - pname = "bash"; - version = version; - - system = system; - builder = "/bin/sh"; - args = { path "build.sh" }; - - src = module.tarballs[version]; - patches = patches; - - PATH = strings.makeBinPath { - "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr", - "/Library/Developer/CommandLineTools/usr", - "/usr", - "/", - }; - __buildSystemDeps = { "/usr", "/bin", "/Library/Developer/CommandLineTools" }; - SOURCE_DATE_EPOCH = 0; - KBUILD_BUILD_TIMESTAMP = "@0"; - } - else - return nil - end - end; - - stdenv = function() - local stdenv = import "../../stdenv/stdenv.lua" - return module.new { - makeDerivation = stdenv.makeBootstrapDerivation; - buildSystem = system; - version = "5.2.15"; - } - end; +function getters.stdenv() + local stdenv = import "../../stdenv/stdenv.lua" + return module.new { + makeDerivation = stdenv.makeBootstrapDerivation; + version = "5.2.15"; } end +function getters.bootstrap() + local version = "5.2.15" + + return tables.withOutputs({ version = version }, function(_self, system) + local sys = systems.parse(system) + if sys and sys.isLinux then + local seeds = import "../../bootstrap/seeds.lua" + return outputs(derivation { + name = "bash-"..version; + pname = "bash"; + version = version; + + system = system; + builder = defaultOutput(seeds[system].busybox, system).."/bin/sh"; + args = { path "build.sh" }; + + src = module.tarballs[version]; + patches = patches; + + PATH = strings.makeBinPath(system, { + gnumake.bootstrap, + seeds[system].busybox, + gcc.bootstrap, + }); + LDFLAGS = { "-static" }; + SOURCE_DATE_EPOCH = 0; + KBUILD_BUILD_TIMESTAMP = "@0"; + }, system) + elseif sys and sys.isMacOS then + return outputs(derivation { + name = "bash-"..version; + pname = "bash"; + version = version; + + system = system; + builder = "/bin/sh"; + args = { path "build.sh" }; + + src = module.tarballs[version]; + patches = patches; + + PATH = strings.makeBinPath(system, { + "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr", + "/Library/Developer/CommandLineTools/usr", + "/usr", + "/", + }); + __buildSystemDeps = { "/usr", "/bin", "/Library/Developer/CommandLineTools" }; + SOURCE_DATE_EPOCH = 0; + KBUILD_BUILD_TIMESTAMP = "@0"; + }, system) + else + error("bash.bootstrap: unsupported system "..system) + end + end) +end + return module diff --git a/packages/busybox/busybox.lua b/packages/busybox/busybox.lua index 4ad70fe..cd74f77 100644 --- a/packages/busybox/busybox.lua +++ b/packages/busybox/busybox.lua @@ -23,10 +23,9 @@ local patches = { ---@param args { ---makeDerivation: (fun(args: table): derivation), ----buildSystem: string, ---version: string, ----configFile: derivation|string, ----linuxHeaders: derivation|string, +---configFile: any, +---linuxHeaders: any, ---} ---@return derivation function module.new(args) @@ -34,23 +33,29 @@ function module.new(args) if not src then error("busybox.new: unsupported version "..args.version) end - return args.makeDerivation { + return tables.withOutputs({ pname = "busybox"; version = args.version; - buildSystem = args.buildSystem; src = src; patches = patches[args.version]; - - CONFIG_INSTALL_NO_USR = "y"; - configFile = args.configFile; - configurePhase = "cp $configFile .config"; - - C_INCLUDE_PATH = strings.makeIncludePath { - args.linuxHeaders - }; - - installPhase = [[make CONFIG_PREFIX="$out" ${makeFlags:-} ${installFlags:-} install]]; - } + }, function(self, system) + return args.makeDerivation { + pname = self.pname; + version = self.version; + src = self.src; + patches = self.patches; + + CONFIG_INSTALL_NO_USR = "y"; + configFile = defaultOutput(args.configFile, system); + configurePhase = "cp $configFile .config"; + + C_INCLUDE_PATH = strings.makeIncludePath(system, { + defaultOutput(args.linuxHeaders, system), + }); + + installPhase = [[make CONFIG_PREFIX="$out" ${makeFlags:-} ${installFlags:-} install]]; + } + end) end return module diff --git a/packages/bzip2/bzip2.lua b/packages/bzip2/bzip2.lua index 466134d..d072239 100644 --- a/packages/bzip2/bzip2.lua +++ b/packages/bzip2/bzip2.lua @@ -1,10 +1,10 @@ -- Copyright 2025 The zb Authors -- SPDX-License-Identifier: MIT -local systems = import "../../systems.lua" local tables = import "../../tables.lua" -local module = {} +local getters = {} +local module = setmetatable({}, { __index = tables.lazyModule(getters) }) local tarballArgs = { ["1.0.8"] = { @@ -16,12 +16,12 @@ local tarballArgs = { module.tarballs = tables.lazyMap(fetchurl, tarballArgs) +---@generic T ---@param args { ----makeDerivation: (fun(args: table): derivation), ----buildSystem: string, +---makeDerivation: (fun(args: table): T), ---version: string, ---} ----@return derivation +---@return T function module.new(args) local src = module.tarballs[args.version] if not src then @@ -30,7 +30,6 @@ function module.new(args) return args.makeDerivation { pname = "bzip2"; version = args.version; - buildSystem = args.buildSystem; src = src; dontConfigure = true; @@ -39,17 +38,11 @@ function module.new(args) } end -for _, system in ipairs(systems.stdlibSystems) do - local system = system - module[system] = tables.lazyModule { - stdenv = function() - local stdenv = import "../../stdenv/stdenv.lua" - return module.new { - makeDerivation = stdenv.makeBootstrapDerivation; - buildSystem = system; - version = "1.0.8"; - } - end; +function getters.stdenv() + local stdenv = import "../../stdenv/stdenv.lua" + return module.new { + makeDerivation = stdenv.makeBootstrapDerivation; + version = "1.0.8"; } end diff --git a/packages/coreutils/coreutils.lua b/packages/coreutils/coreutils.lua index 1698fb6..8b2093e 100644 --- a/packages/coreutils/coreutils.lua +++ b/packages/coreutils/coreutils.lua @@ -2,10 +2,10 @@ -- SPDX-License-Identifier: MIT local fetchGNU = import "../../fetchgnu.lua" -local systems = import "../../systems.lua" local tables = import "../../tables.lua" -local module = {} +local getters = {} +local module = setmetatable({}, { __index = tables.lazyModule(getters) }) local tarballArgs = { ["9.7"] = { @@ -16,12 +16,12 @@ local tarballArgs = { module.tarballs = tables.lazyMap(fetchGNU, tarballArgs) +---@generic T ---@param args { ----makeDerivation: (fun(args: table): derivation), ----buildSystem: string, +---makeDerivation: (fun(args: table): T), ---version: string, ---} ----@return derivation +---@return T function module.new(args) local src = module.tarballs[args.version] if not src then @@ -30,24 +30,17 @@ function module.new(args) return args.makeDerivation { pname = "coreutils"; version = args.version; - buildSystem = args.buildSystem; src = src; -- stdbuf insists on creating a .so file, which fails. Disable it. configureFlags = { "utils_cv_stdbuf_supported=no" }; } end -for _, system in ipairs(systems.stdlibSystems) do - local system = system - module[system] = tables.lazyModule { - stdenv = function() - local stdenv = import "../../stdenv/stdenv.lua" - return module.new { - makeDerivation = stdenv.makeBootstrapDerivation; - buildSystem = system; - version = "9.7"; - } - end; +function getters.stdenv() + local stdenv = import "../../stdenv/stdenv.lua" + return module.new { + makeDerivation = stdenv.makeBootstrapDerivation; + version = "9.7"; } end diff --git a/packages/diffutils/diffutils.lua b/packages/diffutils/diffutils.lua index 349b7e4..62f813e 100644 --- a/packages/diffutils/diffutils.lua +++ b/packages/diffutils/diffutils.lua @@ -2,10 +2,10 @@ -- SPDX-License-Identifier: MIT local fetchGNU = import "../../fetchgnu.lua" -local systems = import "../../systems.lua" local tables = import "../../tables.lua" -local module = {} +local getters = {} +local module = setmetatable({}, { __index = tables.lazyModule(getters) }) local tarballArgs = { ["3.12"] = { @@ -35,17 +35,11 @@ function module.new(args) } end -for _, system in ipairs(systems.stdlibSystems) do - local system = system - module[system] = tables.lazyModule { - stdenv = function() - local stdenv = import "../../stdenv/stdenv.lua" - return module.new { - makeDerivation = stdenv.makeBootstrapDerivation; - buildSystem = system; - version = "3.12"; - } - end; +function getters.stdenv() + local stdenv = import "../../stdenv/stdenv.lua" + return module.new { + makeDerivation = stdenv.makeBootstrapDerivation; + version = "3.12"; } end diff --git a/packages/findutils/findutils.lua b/packages/findutils/findutils.lua index 6dfed98..dea4ea2 100644 --- a/packages/findutils/findutils.lua +++ b/packages/findutils/findutils.lua @@ -2,10 +2,10 @@ -- SPDX-License-Identifier: MIT local fetchGNU = import "../../fetchgnu.lua" -local systems = import "../../systems.lua" local tables = import "../../tables.lua" -local module = {} +local getters = {} +local module = setmetatable({}, { __index = tables.lazyModule(getters) }) local tarballArgs = { ["4.10.0"] = { @@ -18,7 +18,6 @@ module.tarballs = tables.lazyMap(fetchGNU, tarballArgs) ---@param args { ---makeDerivation: (fun(args: table): derivation), ----buildSystem: string, ---version: string, ---} ---@return derivation @@ -30,22 +29,15 @@ function module.new(args) return args.makeDerivation { pname = "findutils"; version = args.version; - buildSystem = args.buildSystem; src = src; } end -for _, system in ipairs(systems.stdlibSystems) do - local system = system - module[system] = tables.lazyModule { - stdenv = function() - local stdenv = import "../../stdenv/stdenv.lua" - return module.new { - makeDerivation = stdenv.makeBootstrapDerivation; - buildSystem = system; - version = "4.10.0"; - } - end; +function getters.stdenv() + local stdenv = import "../../stdenv/stdenv.lua" + return module.new { + makeDerivation = stdenv.makeBootstrapDerivation; + version = "4.10.0"; } end diff --git a/packages/gawk/gawk.lua b/packages/gawk/gawk.lua index 922d41c..58c98df 100644 --- a/packages/gawk/gawk.lua +++ b/packages/gawk/gawk.lua @@ -2,10 +2,10 @@ -- SPDX-License-Identifier: MIT local fetchGNU = import "../../fetchgnu.lua" -local systems = import "../../systems.lua" local tables = import "../../tables.lua" -local module = {} +local getters = {} +local module = setmetatable({}, { __index = tables.lazyModule(getters) }) local tarballArgs = { ["5.3.2"] = { @@ -18,7 +18,6 @@ module.tarballs = tables.lazyMap(fetchGNU, tarballArgs) ---@param args { ---makeDerivation: (fun(args: table): derivation), ----buildSystem: string, ---version: string, ---} ---@return derivation @@ -30,23 +29,16 @@ function module.new(args) return args.makeDerivation { pname = "gawk"; version = args.version; - buildSystem = args.buildSystem; src = src; configureFlags = { "--disable-shared" }; } end -for _, system in ipairs(systems.stdlibSystems) do - local system = system - module[system] = tables.lazyModule { - stdenv = function() - local stdenv = import "../../stdenv/stdenv.lua" - return module.new { - makeDerivation = stdenv.makeBootstrapDerivation; - buildSystem = system; - version = "5.3.2"; - } - end; +function getters.stdenv() + local stdenv = import "../../stdenv/stdenv.lua" + return module.new { + makeDerivation = stdenv.makeBootstrapDerivation; + version = "5.3.2"; } end diff --git a/packages/gcc/gcc.lua b/packages/gcc/gcc.lua index 22e385b..c1e2628 100644 --- a/packages/gcc/gcc.lua +++ b/packages/gcc/gcc.lua @@ -28,7 +28,6 @@ module.tarballs = tables.lazyMap(fetchGNU, tarballArgs) --- Creates a wrapper script that always includes GCC's includes and libraries. ---@param args { ----buildSystem: string, ---targetSystem: string, ---gcc: derivation|string, ---coreutils: derivation|string, @@ -59,44 +58,42 @@ function module.makeWrapper(args) end end end - local sh = args.sh.."/bin/sh" - return derivation { - name = "gcc-"..version; - pname = "gcc"; - version = version; - system = args.buildSystem; - builder = sh; - args = { path "make-wrapper.sh" }; + return tables.withOutputs(args, function(args, system) + local sh = defaultOutput(args.sh, system).."/bin/sh" + return derivation { + name = "gcc-"..version; + pname = "gcc"; + version = version; - template = path "wrapper.sh"; - PATH = strings.makeBinPath { - args.gcc, - args.sh, - args.coreutils, - }; - gcc = args.gcc; - targetSystem = args.targetSystem; - runtimeShell = sh; - } -end + system = system; + builder = sh; + args = { path "make-wrapper.sh" }; -for system, seeds in pairs(bootstrap) do - local system = system - local seeds = seeds - module[system] = tables.lazyModule { - bootstrap = function() - local targetSystem = systems.parse(system) - targetSystem.env = "musl" - return module.makeWrapper { - buildSystem = system; - targetSystem = tostring(targetSystem); - gcc = seeds.gcc; - coreutils = seeds.busybox; - sh = seeds.busybox; - } - end; - } + template = path "wrapper.sh"; + PATH = strings.makeBinPath(system, { + args.gcc, + args.sh, + args.coreutils, + }); + gcc = args.gcc; + targetSystem = args.targetSystem; + runtimeShell = sh; + } + end) end +module.bootstrap = tables.withOutputs({}, function(_, system) + local seeds = bootstrap[system] + local targetSystem = systems.parse(system) + targetSystem.env = "musl" + return outputs(module.makeWrapper { + buildSystem = system; + targetSystem = tostring(targetSystem); + gcc = seeds.gcc; + coreutils = seeds.busybox; + sh = seeds.busybox; + }, system) +end) + return module diff --git a/packages/gmp/gmp.lua b/packages/gmp/gmp.lua index 8edc735..2ffee03 100644 --- a/packages/gmp/gmp.lua +++ b/packages/gmp/gmp.lua @@ -1,12 +1,12 @@ -- Copyright 2025 The zb Authors -- SPDX-License-Identifier: MIT -local bootstrap = import "../../bootstrap/seeds.lua" local fetchGNU = import "../../fetchgnu.lua" local strings = import "../../strings.lua" local tables = import "../../tables.lua" -local module = {} +local getters = {} +local module = setmetatable({}, { __index = tables.lazyModule(getters) }) local tarballArgs = { ["6.2.1"] = { @@ -17,43 +17,38 @@ local tarballArgs = { module.tarballs = tables.lazyMap(fetchGNU, tarballArgs) +---@generic T ---@param args { ----makeDerivation: function, ----buildSystem: string, +---makeDerivation: (fun(args: table): T), ---version: string, ----gnum4: derivation|string, +---gnum4: any, ---} ----@return derivation +---@return T function module.new(args) local src = module.tarballs[args.version] if not src then error("gmp.new: unsupported version "..args.version) end - return args.makeDerivation { - pname = "gmp"; - version = args.version; - buildSystem = args.buildSystem; - src = src; - configureFlags = { "--disable-shared" }; - PATH = strings.makeBinPath { - args.gnum4, - }; - } + return tables.withOutputs(args, function(args, system) + return args.makeDerivation { + pname = "gmp"; + version = args.version; + src = src; + configureFlags = { "--disable-shared" }; + PATH = strings.makeBinPath(system, { + args.gnum4, + }); + } + end) end -for system in pairs(bootstrap) do - local system = system - module[system] = tables.lazyModule { - stdenv = function() - local stdenv = import "../../stdenv/stdenv.lua" - local gnum4 = import("../gnum4/gnum4.lua")[system].stdenv - return module.new { - makeDerivation = stdenv.makeBootstrapDerivation; - buildSystem = system; - version = "6.2.1"; - gnum4 = gnum4; - } - end; +function getters.stdenv() + local stdenv = import "../../stdenv/stdenv.lua" + local gnum4 = import("../gnum4/gnum4.lua").stdenv + return module.new { + makeDerivation = stdenv.makeBootstrapDerivation; + version = "6.2.1"; + gnum4 = gnum4; } end diff --git a/packages/gnugrep/gnugrep.lua b/packages/gnugrep/gnugrep.lua index 34812b2..ce96f5b 100644 --- a/packages/gnugrep/gnugrep.lua +++ b/packages/gnugrep/gnugrep.lua @@ -2,10 +2,10 @@ -- SPDX-License-Identifier: MIT local fetchGNU = import "../../fetchgnu.lua" -local systems = import "../../systems.lua" local tables = import "../../tables.lua" -local module = {} +local getters = {} +local module = setmetatable({}, { __index = tables.lazyModule(getters) }) local tarballArgs = { ["3.12"] = { @@ -16,12 +16,12 @@ local tarballArgs = { module.tarballs = tables.lazyMap(fetchGNU, tarballArgs) +---@generic T ---@param args { ----makeDerivation: (fun(args: table): derivation), ----buildSystem: string, +---makeDerivation: (fun(args: table): T), ---version: string, ---} ----@return derivation +---@return T function module.new(args) local src = module.tarballs[args.version] if not src then @@ -30,22 +30,15 @@ function module.new(args) return args.makeDerivation { pname = "gnugrep"; version = args.version; - buildSystem = args.buildSystem; src = src; } end -for _, system in ipairs(systems.stdlibSystems) do - local system = system - module[system] = tables.lazyModule { - stdenv = function() - local stdenv = import "../../stdenv/stdenv.lua" - return module.new { - makeDerivation = stdenv.makeBootstrapDerivation; - buildSystem = system; - version = "3.12"; - } - end; +function getters.stdenv() + local stdenv = import "../../stdenv/stdenv.lua" + return module.new { + makeDerivation = stdenv.makeBootstrapDerivation; + version = "3.12"; } end diff --git a/packages/gnum4/gnum4.lua b/packages/gnum4/gnum4.lua index e307f18..ee2be87 100644 --- a/packages/gnum4/gnum4.lua +++ b/packages/gnum4/gnum4.lua @@ -2,10 +2,10 @@ -- SPDX-License-Identifier: MIT local fetchGNU = import "../../fetchgnu.lua" -local systems = import "../../systems.lua" local tables = import "../../tables.lua" -local module = {} +local getters = {} +local module = setmetatable({}, { __index = tables.lazyModule(getters) }) local tarballArgs = { ["1.4.7"] = { @@ -20,12 +20,12 @@ local tarballArgs = { module.tarballs = tables.lazyMap(fetchGNU, tarballArgs) +---@generic T ---@param args { ----makeDerivation: (fun(args: table): derivation), ----buildSystem: string, +---makeDerivation: (fun(args: table): T), ---version: string, ---} ----@return derivation +---@return T function module.new(args) local src = module.tarballs[args.version] if not src then @@ -34,22 +34,15 @@ function module.new(args) return args.makeDerivation { pname = "gnum4"; version = args.version; - buildSystem = args.buildSystem; src = src; } end -for _, system in ipairs(systems.stdlibSystems) do - local system = system - module[system] = tables.lazyModule { - stdenv = function() - local stdenv = import "../../stdenv/stdenv.lua" - return module.new { - makeDerivation = stdenv.makeBootstrapDerivation; - buildSystem = system; - version = "1.4.19"; - } - end; +function getters.stdenv() + local stdenv = import "../../stdenv/stdenv.lua" + return module.new { + makeDerivation = stdenv.makeBootstrapDerivation; + version = "1.4.19"; } end diff --git a/packages/gnumake/gnumake.lua b/packages/gnumake/gnumake.lua index 2d38a4d..fc01cac 100644 --- a/packages/gnumake/gnumake.lua +++ b/packages/gnumake/gnumake.lua @@ -8,7 +8,8 @@ local strings = import "../../strings.lua" local systems = import "../../systems.lua" local tables = import "../../tables.lua" -local module = {} +local getters = {} +local module = setmetatable({}, { __index = tables.lazyModule(getters) }) local tarballArgs = { ["3.82"] = { @@ -29,12 +30,12 @@ local patches = { }; } +---@generic T ---@param args { ----makeDerivation: function, ----buildSystem: string, +---makeDerivation: (fun(args: table): T), ---version: string, ---} ----@return derivation +---@return T function module.new(args) local src = module.tarballs[args.version] if not src then @@ -47,79 +48,70 @@ function module.new(args) return args.makeDerivation { pname = "gnumake"; version = args.version; - buildSystem = args.buildSystem; src = src; patches = patches[args.version]; - configureFlags = configureFlags; } end -for _, system in ipairs(systems.stdlibSystems) do - local system = system - module[system] = tables.lazyModule { - bootstrap = function() - local version = "3.82" - local sys = systems.parse(system) - - if sys and sys.isLinux then - return derivation { - name = "gnumake-"..version; - pname = "gnumake"; - version = version; - - system = system; - builder = seeds[system].busybox.."/bin/sh"; - args = { path "build.sh" }; - - src = module.tarballs[version]; - sourceRoot = "make-"..version; - patches = patches[version]; - - PATH = strings.makeBinPath { - gcc[system].bootstrap, - seeds[system].busybox, - }; - SOURCE_DATE_EPOCH = 0; - KBUILD_BUILD_TIMESTAMP = "@0"; - } - elseif sys and sys.isMacOS then - return derivation { - name = "gnumake-"..version; - pname = "gnumake"; - version = version; - - system = system; - builder = "/bin/sh"; - args = { path "build.sh" }; - - src = module.tarballs[version]; - sourceRoot = "make-"..version; - patches = patches[version]; - - PATH = strings.makeBinPath { - "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr", - "/Library/Developer/CommandLineTools/usr", - "/usr", - "/", - }; - __buildSystemDeps = { "/usr", "/bin", "/Library/Developer/CommandLineTools" }; - SOURCE_DATE_EPOCH = 0; - KBUILD_BUILD_TIMESTAMP = "@0"; - } - else - return nil - end - end; - - stdenv = function() - local stdenv = import "../../stdenv/stdenv.lua" - return module.new { - makeDerivation = stdenv.makeBootstrapDerivation; - buildSystem = system; - version = "4.4.1"; - } - end; +module.bootstrap = tables.withOutputs({ version = "3.82" }, function(self, system) + local sys = systems.parse(system) + + if sys and sys.isLinux then + return outputs(derivation { + name = "gnumake-"..self.version; + pname = "gnumake"; + version = self.version; + + system = system; + builder = defaultOutput(seeds[system].busybox, system).."/bin/sh"; + args = { path "build.sh" }; + + src = module.tarballs[self.version]; + sourceRoot = "make-"..self.version; + patches = patches[self.version]; + + PATH = strings.makeBinPath(system, { + gcc.bootstrap, + seeds[system].busybox, + }); + SOURCE_DATE_EPOCH = 0; + KBUILD_BUILD_TIMESTAMP = "@0"; + }, system) + elseif sys and sys.isMacOS then + return outputs(derivation { + name = "gnumake-"..self.version; + pname = "gnumake"; + version = self.version; + + system = system; + builder = "/bin/sh"; + args = { path "build.sh" }; + + src = module.tarballs[self.version]; + sourceRoot = "make-"..self.version; + patches = patches[self.version]; + + PATH = strings.makeBinPath(system, { + "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr", + "/Library/Developer/CommandLineTools/usr", + "/usr", + "/", + }); + __buildSystemDeps = { "/usr", "/bin", "/Library/Developer/CommandLineTools" }; + SOURCE_DATE_EPOCH = 0; + KBUILD_BUILD_TIMESTAMP = "@0"; + }, system) + else + error("gnumake.bootstrap: unsupported system "..system) + end +end) + +function getters.stdenv() + local stdenv = import "../../stdenv/stdenv.lua" + return module.new { + makeDerivation = stdenv.makeBootstrapDerivation; + version = "4.4.1"; } end diff --git a/packages/gnupatch/gnupatch.lua b/packages/gnupatch/gnupatch.lua index 9b2c923..99be1c4 100644 --- a/packages/gnupatch/gnupatch.lua +++ b/packages/gnupatch/gnupatch.lua @@ -2,10 +2,10 @@ -- SPDX-License-Identifier: MIT local fetchGNU = import "../../fetchgnu.lua" -local systems = import "../../systems.lua" local tables = import "../../tables.lua" -local module = {} +local getters = {} +local module = setmetatable({}, { __index = tables.lazyModule(getters) }) local tarballArgs = { ["2.8"] = { @@ -16,12 +16,12 @@ local tarballArgs = { module.tarballs = tables.lazyMap(fetchGNU, tarballArgs) +---@generic T ---@param args { ----makeDerivation: function, ----buildSystem: string, +---makeDerivation: (fun(args: table): T), ---version: string, ---} ----@return derivation +---@return T function module.new(args) local src = module.tarballs[args.version] if not src then @@ -30,22 +30,15 @@ function module.new(args) return args.makeDerivation { pname = "gnupatch"; version = args.version; - buildSystem = args.buildSystem; src = src; } end -for _, system in ipairs(systems.stdlibSystems) do - local system = system - module[system] = tables.lazyModule { - stdenv = function() - local stdenv = import "../../stdenv/stdenv.lua" - return module.new { - makeDerivation = stdenv.makeBootstrapDerivation; - buildSystem = system; - version = "2.8"; - } - end; +function getters.stdenv() + local stdenv = import "../../stdenv/stdenv.lua" + return module.new { + makeDerivation = stdenv.makeBootstrapDerivation; + version = "2.8"; } end diff --git a/packages/gnused/gnused.lua b/packages/gnused/gnused.lua index 40f4aad..4d7f067 100644 --- a/packages/gnused/gnused.lua +++ b/packages/gnused/gnused.lua @@ -2,19 +2,19 @@ -- SPDX-License-Identifier: MIT local fetchGNU = import "../../fetchgnu.lua" -local systems = import "../../systems.lua" local tables = import "../../tables.lua" -local module = {} +local getters = {} +local module = setmetatable({}, { __index = tables.lazyModule(getters) }) local patchDir48 = path { path = "patches/4.8"; name = "gnused-patches-4.8"; - filter = function (name) return name:find(".diff$") ~= nil end + filter = function(name) return name:find(".diff$") ~= nil end; } local patches = { ["4.8"] = { - patchDir48.."/01-noreturn.diff" + patchDir48.."/01-noreturn.diff", }; } @@ -31,13 +31,13 @@ local tarballArgs = { module.tarballs = tables.lazyMap(fetchGNU, tarballArgs) +---@generic T ---@param args { ----makeDerivation: function, ----buildSystem: string, +---makeDerivation: (fun(args: table): T), ---version: string, ---i18n?: boolean, ---} ----@return derivation +---@return T function module.new(args) local src = module.tarballs[args.version] if not src then @@ -45,30 +45,23 @@ function module.new(args) end local configureFlags = {} if not args.i18n then - configureFlags[#configureFlags+1] = "--disable-nls" - configureFlags[#configureFlags+1] = "--disable-i18n" + configureFlags[#configureFlags + 1] = "--disable-nls" + configureFlags[#configureFlags + 1] = "--disable-i18n" end return args.makeDerivation { pname = "gnused"; version = args.version; - buildSystem = args.buildSystem; src = src; patches = patches[args.version]; configureFlags = configureFlags; } end -for _, system in ipairs(systems.stdlibSystems) do - local system = system - module[system] = tables.lazyModule { - stdenv = function() - local stdenv = import "../../stdenv/stdenv.lua" - return module.new { - makeDerivation = stdenv.makeBootstrapDerivation; - buildSystem = system; - version = "4.8"; - } - end; +function getters.stdenv() + local stdenv = import "../../stdenv/stdenv.lua" + return module.new { + makeDerivation = stdenv.makeBootstrapDerivation; + version = "4.8"; } end diff --git a/packages/gnutar/gnutar.lua b/packages/gnutar/gnutar.lua index 25756ba..7e99c75 100644 --- a/packages/gnutar/gnutar.lua +++ b/packages/gnutar/gnutar.lua @@ -5,7 +5,8 @@ local fetchGNU = import "../../fetchgnu.lua" local systems = import "../../systems.lua" local tables = import "../../tables.lua" -local module = {} +local getters = {} +local module = setmetatable({}, { __index = tables.lazyModule(getters) }) local tarballArgs = { ["1.35"] = { @@ -17,41 +18,35 @@ local tarballArgs = { module.tarballs = tables.lazyMap(fetchGNU, tarballArgs) ---@param args { ----makeDerivation: function, ----buildSystem: string, +---makeDerivation: (fun(args: table): any), ---version: string, ---} ----@return derivation +---@return any function module.new(args) local src = module.tarballs[args.version] if not src then error("gnutar.new: unsupported version "..args.version) end - local buildSystem = systems.parse(args.buildSystem) - local LDFLAGS = {} - if buildSystem.isMacOS then - LDFLAGS[#LDFLAGS+1] = "-liconv" - end - return args.makeDerivation { - pname = "gnutar"; - version = args.version; - buildSystem = args.buildSystem; - src = src; - LDFLAGS = LDFLAGS; - } + return tables.withOutputs(args, function(args, system) + local sys = systems.parse(system) + local LDFLAGS = {} + if sys.isMacOS then + LDFLAGS[#LDFLAGS + 1] = "-liconv" + end + return outputs(args.makeDerivation { + pname = "gnutar"; + version = args.version; + src = src; + LDFLAGS = LDFLAGS; + }, system) + end) end -for _, system in ipairs(systems.stdlibSystems) do - local system = system - module[system] = tables.lazyModule { - stdenv = function() - local stdenv = import "../../stdenv/stdenv.lua" - return module.new { - makeDerivation = stdenv.makeBootstrapDerivation; - buildSystem = system; - version = "1.35"; - } - end; +function getters.stdenv() + local stdenv = import "../../stdenv/stdenv.lua" + return module.new { + makeDerivation = stdenv.makeBootstrapDerivation; + version = "1.35"; } end diff --git a/packages/go/go.lua b/packages/go/go.lua index 6e8aedb..8392398 100644 --- a/packages/go/go.lua +++ b/packages/go/go.lua @@ -5,7 +5,8 @@ local strings = import "../../strings.lua" local systems = import "../../systems.lua" local tables = import "../../tables.lua" -local module = {} +local getters = {} +local module = setmetatable({}, { __index = tables.lazyModule(getters) }) local tarballArgs = { ["1.4"] = { @@ -74,7 +75,7 @@ local function useMacOSARMSeed(targetSystem, version) targetSystem = systems.parse(targetSystem) end return targetSystem and targetSystem.isMacOS and targetSystem.isARM and targetSystem.is64Bit and - version == trimPatch(macOSARMSeedVersion) + version == trimPatch(macOSARMSeedVersion) end local bootstrapVersion = "1.4" @@ -99,66 +100,64 @@ local bootstrapSequence = { ["1.21"] = "1.19"; -- >=1.17 ["1.22"] = "1.21"; -- >=1.20 ["1.23"] = "1.21"; -- >=1.20 - ["1.24"] = "1.23"; -- >=1.22 - ["1.25"] = "1.23"; -- >=1.22 - ["1.26"] = "1.25"; -- >=1.24 + ["1.24"] = "1.23"; -- >=1.22 + ["1.25"] = "1.23"; -- >=1.22 + ["1.26"] = "1.25"; -- >=1.24 } module.tarballs = tables.lazyMap(fetchurl, tarballArgs) ---@param args { ----makeDerivation: function, ----buildSystem: string, +---makeDerivation: (fun(args: table): any), ---version: string, ----go: derivation|string?, +---go: any, ---} ----@return derivation +---@return table function module.new(args) - if not args.go then - if useMacOSARMSeed(args.buildSystem, args.version) then - return args.makeDerivation { - pname = "go"; - version = macOSARMSeedVersion; - buildSystem = args.buildSystem; - src = fetchurl(macOSARMSeedArgs); - - dontConfigure = true; - dontBuild = true; - - installPhase = "cp -a --reflink=auto . $out"; - } - end - assert(args.version == bootstrapVersion, "go.new: missing go") - end - local src = module.tarballs[args.version] - if not src then - error("go.new: unsupported version "..args.version) - end - local PATH - if args.go then - PATH = strings.makeBinPath { args.go } - end - return args.makeDerivation { + local src = assert(module.tarballs[args.version], "go.new: unsupported version "..args.version) + return tables.withOutputs({ pname = "go"; version = versionForURL(tarballArgs[args.version].url); - buildSystem = args.buildSystem; - src = src; + }, function(self, system) + if not args.go then + if useMacOSARMSeed(system, args.version) then + return outputs(args.makeDerivation { + pname = "go"; + version = macOSARMSeedVersion; + src = fetchurl(macOSARMSeedArgs); + + dontConfigure = true; + dontBuild = true; + + installPhase = "cp -a --reflink=auto . $out"; + }, system) + end + assert(args.version == bootstrapVersion, "go.new: missing go") + end + local PATH + if args.go then + PATH = strings.makeBinPath(system, { args.go }) + end + return outputs(args.makeDerivation { + pname = "go"; + version = self.version, + src = src; - postPatch = [[ + postPatch = [[ patchShebangs src/make.bash ]]; - -- TODO(#14): CGO_ENABLED=0 because cgo requires gcc 4.6 or newer. - -- https://go.dev/wiki/MinimumRequirements - configurePhase = [[ + -- TODO(#14): CGO_ENABLED=0 because cgo requires gcc 4.6 or newer. + -- https://go.dev/wiki/MinimumRequirements + configurePhase = [[ export GOROOT_FINAL="$out/share/go" export GOPATH="$ZB_BUILD_TOP/gopath" export GOCACHE="$ZB_BUILD_TOP/cache" export CGO_ENABLED=0 mkdir "$GOPATH" "$GOCACHE" ]]; - buildPhase = [[( cd src && ./make.bash )]]; - installPhase = [=[ + buildPhase = [[( cd src && ./make.bash )]]; + installPhase = [=[ mkdir -p "$out/share/go" cp --reflink=auto --archive bin pkg src lib misc api doc "$out/share/go/" if [[ -e go.env ]]; then @@ -167,8 +166,9 @@ fi mkdir -p "$out/bin" ln -s "$out/share/go/bin"/* "$out/bin/" ]=]; - PATH = PATH; - } + PATH = PATH; + }, system) + end) end ---Compute the environment variables to use to instruct Go to cross-compile for the given system. @@ -207,21 +207,21 @@ function module.envForSystem(system) return result end -for _, system in ipairs(systems.stdlibSystems) do - local system = system - module[system] = tables.lazyMap(function(_, version) - local stdenv = import "../../stdenv/stdenv.lua" - local go - if version ~= bootstrapVersion and not useMacOSARMSeed(system, version) then - go = module[system][bootstrapSequence[version]] - end - return module.new { - makeDerivation = stdenv.makeDerivation; - buildSystem = system; - version = version; - go = go; - } - end, tarballArgs) +local function getVersion(_, version) + local stdenv = import "../../stdenv/stdenv.lua" + local go + if version ~= bootstrapVersion and not useMacOSARMSeed(system, version) then + go = module[bootstrapSequence[version]] + end + return module.new { + makeDerivation = stdenv.makeDerivation; + version = version; + go = go; + } +end + +for version in pairs(tarballArgs) do + getters[version] = getVersion end return module diff --git a/packages/gzip/gzip.lua b/packages/gzip/gzip.lua index 4bba2c4..0ec71d0 100644 --- a/packages/gzip/gzip.lua +++ b/packages/gzip/gzip.lua @@ -2,10 +2,10 @@ -- SPDX-License-Identifier: MIT local fetchGNU = import "../../fetchgnu.lua" -local systems = import "../../systems.lua" local tables = import "../../tables.lua" -local module = {} +local getters = {} +local module = setmetatable({}, { __index = tables.lazyModule(getters) }) local tarballArgs = { ["1.14"] = { @@ -16,12 +16,12 @@ local tarballArgs = { module.tarballs = tables.lazyMap(fetchGNU, tarballArgs) +---@generic T ---@param args { ----makeDerivation: function, ----buildSystem: string, +---makeDerivation: (fun(args: table): T), ---version: string, ---} ----@return derivation +---@return T function module.new(args) local src = module.tarballs[args.version] if not src then @@ -30,22 +30,15 @@ function module.new(args) return args.makeDerivation { pname = "gzip"; version = args.version; - buildSystem = args.buildSystem; src = src; } end -for _, system in ipairs(systems.stdlibSystems) do - local system = system - module[system] = tables.lazyModule { - stdenv = function() - local stdenv = import "../../stdenv/stdenv.lua" - return module.new { - makeDerivation = stdenv.makeBootstrapDerivation; - buildSystem = system; - version = "1.14"; - } - end; +function getters.stdenv() + local stdenv = import "../../stdenv/stdenv.lua" + return module.new { + makeDerivation = stdenv.makeBootstrapDerivation; + version = "1.14"; } end diff --git a/packages/libmpc/libmpc.lua b/packages/libmpc/libmpc.lua index 3040f3e..48010a5 100644 --- a/packages/libmpc/libmpc.lua +++ b/packages/libmpc/libmpc.lua @@ -1,11 +1,11 @@ -- Copyright 2025 The zb Authors -- SPDX-License-Identifier: MIT -local bootstrap = import "../../bootstrap/seeds.lua" local fetchGNU = import "../../fetchgnu.lua" local tables = import "../../tables.lua" -local module = {} +local getters = {} +local module = setmetatable({}, { __index = tables.lazyModule(getters) }) local tarballArgs = { ["1.2.1"] = { @@ -17,51 +17,49 @@ local tarballArgs = { module.tarballs = tables.lazyMap(fetchGNU, tarballArgs) ---@param args { ----makeDerivation: function, ----buildSystem: string, +---makeDerivation: (fun(args: table): any), ---version: string, ---gmp: derivation|string, ---mpfr: derivation|string, ---shared: boolean?, ---} ----@return derivation +---@return any function module.new(args) local src = module.tarballs[args.version] if not src then error("libmpc.new: unsupported version "..args.version) end - local configureFlags = { - "--with-gmp="..args.gmp, - "--with-mpfr="..args.mpfr, - } - if args.shared == false then - configureFlags[#configureFlags + 1] = "--disable-shared" - end - return args.makeDerivation { + return tables.withOutputs({ pname = "libmpc"; version = args.version; - buildSystem = args.buildSystem; src = src; - configureFlags = configureFlags; - } + }, function(_, system) + local configureFlags = { + "--with-gmp="..defaultOutput(args.gmp, system), + "--with-mpfr="..defaultOutput(args.mpfr, system), + } + if args.shared == false then + configureFlags[#configureFlags + 1] = "--disable-shared" + end + return outputs(args.makeDerivation { + pname = "libmpc"; + version = args.version; + src = src; + configureFlags = configureFlags; + }, system) + end) end -for system in pairs(bootstrap) do - local system = system - module[system] = tables.lazyModule { - stdenv = function() - local stdenv = import "../../stdenv/stdenv.lua" - local gmp = import("../gmp/gmp.lua")[system].stdenv - local mpfr = import("../mpfr/mpfr.lua")[system].stdenv - return module.new { - makeDerivation = stdenv.makeBootstrapDerivation; - buildSystem = system; - version = "1.2.1"; - gmp = gmp; - mpfr = mpfr; - shared = false; - } - end; +function getters.stdenv() + local stdenv = import "../../stdenv/stdenv.lua" + local gmp = import("../gmp/gmp.lua").stdenv + local mpfr = import("../mpfr/mpfr.lua").stdenv + return module.new { + makeDerivation = stdenv.makeBootstrapDerivation; + version = "1.2.1"; + gmp = gmp; + mpfr = mpfr; + shared = false; } end diff --git a/packages/linux-headers/linux-headers.lua b/packages/linux-headers/linux-headers.lua index e1b52c2..90304f4 100644 --- a/packages/linux-headers/linux-headers.lua +++ b/packages/linux-headers/linux-headers.lua @@ -17,23 +17,23 @@ module.tarballs = tables.lazyMap(fetchurl, tarballArgs) local builderScript = path "build.sh" +---@generic T ---@param args { ----makeDerivation: (fun(args: table): derivation), ----buildSystem: string, +---makeDerivation: (fun(args: table): T), +---targetSystem: string, ---version: string, ---} ----@return derivation +---@return T function module.new(args) local src = module.tarballs[args.version] if not src then error("linux-headers.new: unsupported version "..args.version) end - local sys = assert(systems.parse(args.buildSystem), "invalid buildSystem "..args.buildSystem) - assert(sys.isX86 or sys.isARM, "unsupported system "..args.buildSystem) + local sys = systems.parse(args.targetSystem) + assert(sys and sys.isLinux and (sys.isX86 or sys.isARM), "unsupported system "..args.targetSystem) return args.makeDerivation { pname = "linux-headers"; version = args.version; - buildSystem = args.buildSystem; src = src; builder = builderScript; diff --git a/packages/mpfr/mpfr.lua b/packages/mpfr/mpfr.lua index 22ce247..913f914 100644 --- a/packages/mpfr/mpfr.lua +++ b/packages/mpfr/mpfr.lua @@ -1,11 +1,12 @@ -- Copyright 2025 The zb Authors -- SPDX-License-Identifier: MIT -local bootstrap = import "../../bootstrap/seeds.lua" local fetchGNU = import "../../fetchgnu.lua" +local strings = import "../../strings.lua" local tables = import "../../tables.lua" -local module = {} +local getters = {} +local module = setmetatable({}, { __index = tables.lazyModule(getters) }) local tarballArgs = { ["4.1.0"] = { @@ -17,47 +18,45 @@ local tarballArgs = { module.tarballs = tables.lazyMap(fetchGNU, tarballArgs) ---@param args { ----makeDerivation: function, ----buildSystem: string, +---makeDerivation: (fun(args: table): any), ---version: string, ----gmp: derivation|string, +---gmp: any, ---shared: boolean?, ---} ----@return derivation +---@return any function module.new(args) local src = module.tarballs[args.version] if not src then error("mpfr.new: unsupported version "..args.version) end - local configureFlags = { - "--with-gmp="..args.gmp, - } - if args.shared == false then - configureFlags[#configureFlags + 1] = "--disable-shared" - end - return args.makeDerivation { + return tables.withOutputs({ pname = "mpfr"; version = args.version; - buildSystem = args.buildSystem; src = src; - configureFlags = configureFlags; - } + }, function(_, system) + local configureFlags = { + "--with-gmp="..defaultOutput(args.gmp, system), + } + if args.shared == false then + configureFlags[#configureFlags + 1] = "--disable-shared" + end + return args.makeDerivation { + pname = "mpfr"; + version = args.version; + src = src; + configureFlags = configureFlags; + } + end) end -for system in pairs(bootstrap) do - local system = system - module[system] = tables.lazyModule { - stdenv = function() - local stdenv = import "../../stdenv/stdenv.lua" - local gmp = import("../gmp/gmp.lua")[system].stdenv - return module.new { - makeDerivation = stdenv.makeBootstrapDerivation; - buildSystem = system; - version = "4.1.0"; - gmp = gmp; - shared = false; - } - end; +function getters.stdenv() + local stdenv = import "../../stdenv/stdenv.lua" + local gmp = import("../gmp/gmp.lua").stdenv + return module.new { + makeDerivation = stdenv.makeBootstrapDerivation; + version = "4.1.0"; + gmp = gmp; + shared = false; } end diff --git a/packages/musl/musl.lua b/packages/musl/musl.lua index de7d490..f10439f 100644 --- a/packages/musl/musl.lua +++ b/packages/musl/musl.lua @@ -18,13 +18,13 @@ local tarballArgs = { module.tarballs = tables.lazyMap(fetchurl, tarballArgs) +---@generic T ---@param args { ----makeDerivation: function, ----buildSystem: string, +---makeDerivation: (fun(args: table): T), ---version: string, ---shared: boolean?, ---} ----@return derivation +---@return T function module.new(args) local src = module.tarballs[args.version] if not src then @@ -37,7 +37,6 @@ function module.new(args) return args.makeDerivation { pname = "musl"; version = args.version; - buildSystem = args.buildSystem; src = src; configureFlags = configureFlags; } diff --git a/packages/unzip/unzip.lua b/packages/unzip/unzip.lua index f6aabc6..786e44f 100644 --- a/packages/unzip/unzip.lua +++ b/packages/unzip/unzip.lua @@ -2,8 +2,9 @@ -- SPDX-License-Identifier: MIT local tables = import "../../tables.lua" -local systems = import "../../systems.lua" -local module = {} + +local getters = {} +local module = setmetatable({}, { __index = tables.lazyModule(getters) }) local tarballArgs = { ["6.0"] = { @@ -14,13 +15,13 @@ local tarballArgs = { module.tarballs = tables.lazyMap(fetchurl, tarballArgs) +---@generic T ---@param args { ----makeDerivation: function, ----buildSystem: string, +---makeDerivation: (fun(args: table): T), ---version: string, ---shared: boolean?, ---} ----@return derivation +---@return T function module.new(args) local src = module.tarballs[args.version] if not src then @@ -29,25 +30,18 @@ function module.new(args) return args.makeDerivation { pname = "unzip"; version = args.version; - buildSystem = args.buildSystem; src = src; - makeFlags = {"-f", "unix/Makefile", "CC=gcc", "prefix="}; - buildFlags = {"generic"}; + makeFlags = { "-f", "unix/Makefile", "CC=gcc", "prefix=" }; + buildFlags = { "generic" }; installPhase = "make install ${makeFlags:-} ${installFlags:-} prefix=${out?}"; } end -for _, system in ipairs(systems.stdlibSystems) do - local system = system - module[system] = tables.lazyModule { - stdenv = function() - local stdenv = import "../../stdenv/stdenv.lua" - return module.new { - makeDerivation = stdenv.makeBootstrapDerivation; - buildSystem = system; - version = "6.0"; - } - end; +function getters.stdenv() + local stdenv = import "../../stdenv/stdenv.lua" + return module.new { + makeDerivation = stdenv.makeBootstrapDerivation; + version = "6.0"; } end diff --git a/packages/xz/xz.lua b/packages/xz/xz.lua index a39031f..e760297 100644 --- a/packages/xz/xz.lua +++ b/packages/xz/xz.lua @@ -1,10 +1,10 @@ -- Copyright 2025 The zb Authors -- SPDX-License-Identifier: MIT -local systems = import "../../systems.lua" local tables = import "../../tables.lua" -local module = {} +local getters = {} +local module = setmetatable({}, { __index = tables.lazyModule(getters) }) local tarballArgs = { ["5.6.3"] = { @@ -15,13 +15,13 @@ local tarballArgs = { module.tarballs = tables.lazyMap(fetchurl, tarballArgs) +---@generic T ---@param args { ----makeDerivation: function, ----buildSystem: string, +---makeDerivation: (fun(args: table): T), ---version: string, ---shared?: boolean, ---} ----@return derivation +---@return T function module.new(args) local src = module.tarballs[args.version] if not src then @@ -34,25 +34,17 @@ function module.new(args) return args.makeDerivation { pname = "xz"; version = args.version; - buildSystem = args.buildSystem; src = src; - configureFlags = configureFlags; } end -for _, system in ipairs(systems.stdlibSystems) do - local system = system - module[system] = tables.lazyModule { - stdenv = function() - local stdenv = import "../../stdenv/stdenv.lua" - return module.new { - makeDerivation = stdenv.makeBootstrapDerivation; - buildSystem = system; - version = "5.6.3"; - shared = false; - } - end; +function getters.stdenv() + local stdenv = import "../../stdenv/stdenv.lua" + return module.new { + makeDerivation = stdenv.makeBootstrapDerivation; + version = "5.6.3"; + shared = false; } end diff --git a/stdenv/stdenv.lua b/stdenv/stdenv.lua index 8e1f610..2cab92e 100644 --- a/stdenv/stdenv.lua +++ b/stdenv/stdenv.lua @@ -24,7 +24,7 @@ local function concatStringLists(sep, ...) elseif argType ~= "nil" then for _, part in strings.split(tostring(arg), sep) do if part ~= "" then - parts[#parts+1] = part + parts[#parts + 1] = part end end end @@ -32,22 +32,22 @@ local function concatStringLists(sep, ...) return table.concat(parts, sep) end +---@param system string ---@param bash string|derivation ---@param deps string|derivation[] ---@param args { ---pname: string?, ---version: string?, ----buildSystem: string, ---builder: string|derivation?, ---realBuilder: string|derivation?, ---args: (string|derivation|number|boolean)[]?, ---[string]: string|derivation|number|boolean|(string|derivation|number|boolean)[], ---} ----@return derivation -local function makeDerivation(bash, deps, args) +---@return table +local function makeDerivation(system, bash, deps, args) args = tables.clone(args) - args.system = args.buildSystem - args.PATH = concatStringLists(":", args.PATH, strings.makeBinPath(deps)) + args.system = system + args.PATH = concatStringLists(":", args.PATH, strings.makeBinPath(system, deps)) if not args.name then local name = args.pname if not name then @@ -61,73 +61,74 @@ local function makeDerivation(bash, deps, args) end args.helpersNix = args.helpersNix or module.helpersNix args.args = args.args or { args.builder or module.builderScript } - args.builder = args.realBuilder or bash.."/bin/bash" + args.builder = args.realBuilder or defaultOutput(bash, system).."/bin/bash" if not args.SOURCE_DATE_EPOCH then args.SOURCE_DATE_EPOCH = 0 end if not args.KBUILD_BUILD_TIMESTAMP then args.KBUILD_BUILD_TIMESTAMP = "@0" end - return derivation(args) + return outputs(derivation(args), system) end ---Build a derivation using the bootstrap toolchain. ---@param args { ---pname: string?, ---version: string?, ----buildSystem: string, ---builder: string|derivation?, ---realBuilder: string|derivation?, ---args: (string|derivation|number|boolean)[]?, ---[string]: string|derivation|number|boolean|(string|derivation|number|boolean)[], ---} ----@return derivation +---@return table function module.makeBootstrapDerivation(args) - local buildSystem = systems.parse(args.buildSystem) - local gnumake = import("../packages/gnumake/gnumake.lua")[args.buildSystem].bootstrap - local bash = import("../packages/bash/bash.lua")[args.buildSystem].bootstrap - if buildSystem.isLinux then - local gcc = import("../packages/gcc/gcc.lua")[args.buildSystem].bootstrap - local busybox = import("../bootstrap/seeds.lua")[args.buildSystem].busybox - return makeDerivation(bash, { gcc, gnumake, bash, busybox }, args) - elseif buildSystem.isMacOS then - local deps = { - gnumake, - bash, - "/Library/Developer/CommandLineTools/usr", - "/usr", - "/", - } - args = tables.clone(args) - args.SDKROOT = args.SDKROOT or "/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk" - args.__buildSystemDeps = concatStringLists(" ", args.__buildSystemDeps, { - "/Library/Developer/CommandLineTools", - "/usr", - "/bin", - }) - return makeDerivation(bash, deps, args) - else - error(string.format("unsupported buildSystem = %s", args.buildSystem)) - end + return tables.withOutputs(args, function(args, buildSystemString) + local buildSystem = systems.parse(buildSystemString) + local gnumake = import("../packages/gnumake/gnumake.lua").bootstrap + local bash = import("../packages/bash/bash.lua").bootstrap + if buildSystem.isLinux then + local gcc = import("../packages/gcc/gcc.lua").bootstrap + local busybox = import("../bootstrap/seeds.lua")[buildSystemString].busybox + return makeDerivation(buildSystemString, bash, { gcc, gnumake, bash, busybox }, args) + elseif buildSystem.isMacOS then + local deps = { + gnumake, + bash, + "/Library/Developer/CommandLineTools/usr", + "/usr", + "/", + } + args = tables.clone(args) + args.SDKROOT = args.SDKROOT or "/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk" + args.__buildSystemDeps = concatStringLists(" ", args.__buildSystemDeps, { + "/Library/Developer/CommandLineTools", + "/usr", + "/bin", + }) + return makeDerivation(buildSystemString, bash, deps, args) + else + error(string.format("unsupported system = %s", buildSystemString)) + end + end) end -local function baseDeps(buildSystem) - local bash = import("../packages/bash/bash.lua")[buildSystem].stdenv +local function baseDeps() + local bash = import("../packages/bash/bash.lua").stdenv return bash, { assert(bash), - assert(import("../packages/bzip2/bzip2.lua")[buildSystem].stdenv), - assert(import("../packages/coreutils/coreutils.lua")[buildSystem].stdenv), - assert(import("../packages/diffutils/diffutils.lua")[buildSystem].stdenv), - assert(import("../packages/findutils/findutils.lua")[buildSystem].stdenv), - assert(import("../packages/gawk/gawk.lua")[buildSystem].stdenv), - assert(import("../packages/gnugrep/gnugrep.lua")[buildSystem].stdenv), - assert(import("../packages/gnumake/gnumake.lua")[buildSystem].stdenv), - assert(import("../packages/gnupatch/gnupatch.lua")[buildSystem].stdenv), - assert(import("../packages/gnused/gnused.lua")[buildSystem].stdenv), - assert(import("../packages/gnutar/gnutar.lua")[buildSystem].stdenv), - assert(import("../packages/gzip/gzip.lua")[buildSystem].stdenv), - assert(import("../packages/unzip/unzip.lua")[buildSystem].stdenv), - assert(import("../packages/xz/xz.lua")[buildSystem].stdenv), + assert(import("../packages/bzip2/bzip2.lua").stdenv), + assert(import("../packages/coreutils/coreutils.lua").stdenv), + assert(import("../packages/diffutils/diffutils.lua").stdenv), + assert(import("../packages/findutils/findutils.lua").stdenv), + assert(import("../packages/gawk/gawk.lua").stdenv), + assert(import("../packages/gnugrep/gnugrep.lua").stdenv), + assert(import("../packages/gnumake/gnumake.lua").stdenv), + assert(import("../packages/gnupatch/gnupatch.lua").stdenv), + assert(import("../packages/gnused/gnused.lua").stdenv), + assert(import("../packages/gnutar/gnutar.lua").stdenv), + assert(import("../packages/gzip/gzip.lua").stdenv), + assert(import("../packages/unzip/unzip.lua").stdenv), + assert(import("../packages/xz/xz.lua").stdenv), } end @@ -135,41 +136,43 @@ end ---@param args { ---pname: string?, ---version: string?, ----buildSystem: string, ---builder: string|derivation?, ---realBuilder: string|derivation?, ---args: (string|derivation|number|boolean)[]?, ---[string]: string|derivation|number|boolean|(string|derivation|number|boolean)[], ---} ----@return derivation +---@return table function module.makeDerivationNoCC(args) - local bash, deps = baseDeps(args.buildSystem) - return makeDerivation(bash, deps, args) + return tables.withOutputs(args, function(args, system) + local bash, deps = baseDeps() + return makeDerivation(system, bash, deps, args) + end) end ---Build a derivation using the standard environment. ---@param args { ---pname: string?, ---version: string?, ----buildSystem: string, ---builder: string|derivation?, ---realBuilder: string|derivation?, ---args: (string|derivation|number|boolean)[]?, ---[string]: string|derivation|number|boolean|(string|derivation|number|boolean)[], ---} ----@return derivation +---@return table function module.makeDerivation(args) - local bash, deps = baseDeps(args.buildSystem) - local buildSystem = systems.parse(args.buildSystem) - if buildSystem.isMacOS then - deps[#deps+1] = "/Library/Developer/CommandLineTools/usr" - args = tables.clone(args) - args.SDKROOT = args.SDKROOT or "/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk" - args.__buildSystemDeps = concatStringLists(" ", args.__buildSystemDeps, "/Library/Developer/CommandLineTools") - else - deps[#deps+1] = import("../packages/gcc/gcc.lua")[args.buildSystem].bootstrap - end - return makeDerivation(bash, deps, args) + return tables.withOutputs(args, function(args, buildSystemString) + local bash, deps = baseDeps() + local buildSystem = systems.parse(buildSystemString) + if buildSystem.isMacOS then + deps[#deps + 1] = "/Library/Developer/CommandLineTools/usr" + args = tables.clone(args) + args.SDKROOT = args.SDKROOT or "/Library/Developer/CommandLineTools/SDKs/MacOSX15.sdk" + args.__buildSystemDeps = concatStringLists(" ", args.__buildSystemDeps, "/Library/Developer/CommandLineTools") + else + deps[#deps + 1] = import("../packages/gcc/gcc.lua").bootstrap + end + return makeDerivation(buildSystemString, bash, deps, args) + end) end return module diff --git a/strings.lua b/strings.lua index afbc82b..8baf880 100644 --- a/strings.lua +++ b/strings.lua @@ -44,22 +44,19 @@ end ---to the specified `output` of each of the packages. ---@param output string ---@param subDir string +---@param system string ---@param paths (derivation|string)[] ---@return string -function makeSearchPathOutput(output, subDir, paths) +function makeSearchPathOutput(output, subDir, system, paths) local parts = {} for i, x in ipairs(paths) do - local xout - if type(x) == "string" then - xout = x - else - xout = x[output] or x.out - end + local xouts = outputs(x, system) + local xout = xouts[output] or xouts[""] if xout then if #parts > 0 then parts[#parts + 1] = ":" end - parts[#parts + 1] = tostring(xout) + parts[#parts + 1] = xout parts[#parts + 1] = "/" parts[#parts + 1] = subDir end @@ -71,20 +68,20 @@ end ---containing the binaries for a set of packages. ---@param pkgs derivation[] ---@return string # colon-separated paths -function makeBinPath(pkgs) - return makeSearchPathOutput("out", "bin", pkgs) +function makeBinPath(system, pkgs) + return makeSearchPathOutput("out", "bin", system, pkgs) end ---@param pkgs derivation[] ---@return string -function makeIncludePath(pkgs) - return makeSearchPathOutput("dev", "include", pkgs) +function makeIncludePath(system, pkgs) + return makeSearchPathOutput("dev", "include", system, pkgs) end ---@param pkgs derivation[] ---@return string -function makeLibraryPath(pkgs) - return makeSearchPathOutput("out", "lib", pkgs) +function makeLibraryPath(system, pkgs) + return makeSearchPathOutput("out", "lib", system, pkgs) end ---@param name string diff --git a/tables.lua b/tables.lua index 6080187..dbf2b76 100644 --- a/tables.lua +++ b/tables.lua @@ -31,7 +31,7 @@ end ---@param t table ---@return table function clone(t) - return map(function (x) return x end, t) + return map(function(x) return x end, t) end ---Copy the pairs from each argument into the first argument. @@ -179,3 +179,35 @@ function lazyMap(f, t) end; }) end + +---Returns an immutable copy of a table whose __outputs function is given. +---@param t table +---@param f fun(self: table, system: string): any +---@return table +function withOutputs(t, f) + t = clone(t) + local mt = { + __index = t; + __outputs = f; + } + local object = setmetatable({}, mt) + + function mt:__len() + return #t + end + + function mt:__newindex() + error("cannot modify table with outputs", 2) + end + + local function tnext(self, index) + assert(self == object) + return next(t, index) + end + + function mt:__pairs() + return tnext, self, nil + end + + return object +end