diff --git a/.envrc b/.envrc new file mode 100644 index 000000000..3550a30f2 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore index 9ae0b23df..d243ce5c6 100644 --- a/.gitignore +++ b/.gitignore @@ -95,4 +95,7 @@ completions/ core/pathsetup.lua # Nix symlink to builds -result/ +result +result-man +result-doc +result-dev diff --git a/Makefile.am b/Makefile.am index 5cbd02b16..52988e6af 100644 --- a/Makefile.am +++ b/Makefile.am @@ -68,7 +68,7 @@ EXTRA_DIST = spec tests documentation sile-dev-1.rockspec fontconfig.conf EXTRA_DIST += Makefile-distfiles EXTRA_DIST += build-aux/action-updater.js build-aux/cargo-updater.js build-aux/decore-automake.sh build-aux/git-version-gen build-aux/list-dist-files.sh EXTRA_DIST += Dockerfile build-aux/docker-bootstrap.sh build-aux/docker-fontconfig.conf hooks/build -EXTRA_DIST += default.nix flake.nix flake.lock shell.nix +EXTRA_DIST += default.nix flake.nix flake.lock shell.nix build-aux/pkg.nix EXTRA_DIST += package.json # imported by both Nix and Docker EXTRA_DIST += $(MANUAL) $(FIGURES) diff --git a/build-aux/pkg.nix b/build-aux/pkg.nix new file mode 100644 index 000000000..0951c40e8 --- /dev/null +++ b/build-aux/pkg.nix @@ -0,0 +1,192 @@ +# NOTE: This file is supposed to be similar to what is in Nixpkgs, except for +# the `version`, `src` and `libtexpdf-src` attributes that are given by the +# `flake.nix`. In Nixpkgs, we don't need `libtexpdf-src` because we use +# `fetchFromGitHub` with fetchSubmodules = true;`. +{ lib +, stdenv +, version, src, libtexpdf-src +, autoreconfHook +, gitMinimal +, pkg-config +, jq +, cargo +, rustc +, rustPlatform +, makeWrapper +, poppler_utils +, harfbuzz +, icu +, fontconfig +, lua +, libiconv +, darwin +, makeFontsConf +, gentium +, runCommand +}: + +let + luaEnv = lua.withPackages(ps: with ps; [ + cassowary + cldr + fluent + linenoise + loadkit + lpeg + lua-zlib + lua_cliargs + luaepnf + luaexpat + luafilesystem + luarepl + luasec + luasocket + luautf8 + penlight + vstruct + # lua packages needed for testing + busted + luacheck + # NOTE: Add lua packages here, to change the luaEnv also read by `flake.nix` + ] ++ lib.optionals (lib.versionOlder lua.luaversion "5.2") [ + bit32 + ] ++ lib.optionals (lib.versionOlder lua.luaversion "5.3") [ + compat53 + ]); +in stdenv.mkDerivation (finalAttrs: { + pname = "sile"; + inherit version src; + + preAutoreconf = '' + # Add the libtexpdf src instead of the git submodule. (From some reason + # without --no-preserve=mode flag, libtexpdf/ is unwriteable). As explained + # before, in Nixpkgs, we won't need to run these commands. + rm -rf ./libtexpdf + cp --no-preserve=mode -r ${libtexpdf-src} ./libtexpdf/ + # pretend to be a tarball release so sile --version will not say `vUNKNOWN`. + echo ${finalAttrs.version} > .tarball-version + ''; + + nativeBuildInputs = [ + autoreconfHook + gitMinimal + pkg-config + jq + cargo + rustc + rustPlatform.cargoSetupHook + poppler_utils + makeWrapper + ]; + # In Nixpkgs, we don't copy the Cargo.lock file from the repo to Nixpkgs' + # repo, but we inherit src, and specify a hash (it is a fixed output + # derivation). `nix-update` and `nixpkgs-update` should be able to catch that + # hash and update it as well when performing updates. + cargoDeps = rustPlatform.importCargoLock { + lockFile = ../Cargo.lock; + }; + + buildInputs = [ + luaEnv + harfbuzz + icu + fontconfig + libiconv + ] ++ lib.optionals stdenv.isDarwin [ + darwin.apple_sdk.frameworks.AppKit + ]; + + configureFlags = [ + # Nix will supply all the Lua dependencies, so stop the build system from + # bundling vendored copies of them. + "--with-system-luarocks" + # The automake check target uses pdfinfo to confirm the output of a test + # run, and uses autotools to discover it. This flake build eschews that + # test because it is run from the source directory but the binary is + # already built with system paths, so it can't be checked under Nix until + # after install. After install the Makefile isn't available of course, so + # we have our own copy of it with a hard coded path to `pdfinfo`. By + # specifying some binary here we skip the configure time test for + # `pdfinfo`, by using `false` we make sure that if it is expected during + # build time we would fail to build since we only provide it at test time. + "PDFINFO=false" + #"--with-manual" In Nixpkgs we add this flag, here its not important enough + ] ++ lib.optionals (!lua.pkgs.isLuaJIT) [ + "--without-luajit" + ]; + + postPatch = '' + patchShebangs build-aux/*.sh build-aux/git-version-gen + '' + lib.optionalString stdenv.isDarwin '' + sed -i -e 's|@import AppKit;|#import |' src/macfonts.m + ''; + + NIX_LDFLAGS = lib.optionalString stdenv.isDarwin "-framework AppKit"; + + FONTCONFIG_FILE = makeFontsConf { + fontDirectories = [ + gentium + ]; + }; + + enableParallelBuilding = true; + + # Autoconf wants to check that Makefile imports are valid files even before + # it potentially generates said files from substitution templates. The + # upstream project uses a bootstrap.sh to create this. Since we skip that, we + # have to fix this race condition ourselves. + postUnpack = '' + touch source/build-aux/rust_boilerplate.mk + ''; + + preBuild = lib.optionalString stdenv.cc.isClang '' + substituteInPlace libtexpdf/dpxutil.c \ + --replace "ASSERT(ht && ht->table && iter);" "ASSERT(ht && iter);" + ''; + + # remove forbidden references to $TMPDIR + preFixup = lib.optionalString stdenv.isLinux '' + for f in "$out"/bin/*; do + if isELF "$f"; then + patchelf --shrink-rpath --allowed-rpath-prefixes "$NIX_STORE" "$f" + fi + done + ''; + + passthru = { + # So it will be easier to inspect this environment, in comparison to others + inherit luaEnv; + # Copied from Makefile.am + tests.test = lib.optionalAttrs (!(stdenv.isDarwin && stdenv.isAarch64)) ( + runCommand "${finalAttrs.pname}-test" { + nativeBuildInputs = [ poppler_utils finalAttrs.finalPackage ]; + inherit (finalAttrs) FONTCONFIG_FILE; + } '' + output=$(mktemp -t selfcheck-XXXXXX.pdf) + echo "foo" | sile -o $output - + pdfinfo $output | grep "SILE v${finalAttrs.version}" > $out + ''); + }; + + outputs = [ "out" "doc" "man" "dev" ]; + + meta = { + description = "A typesetting system"; + longDescription = '' + SILE is a typesetting system; its job is to produce beautiful + printed documents. Conceptually, SILE is similar to TeX—from + which it borrows some concepts and even syntax and + algorithms—but the similarities end there. Rather than being a + derivative of the TeX family SILE is a new typesetting and + layout engine written from the ground up using modern + technologies and borrowing some ideas from graphical systems + such as InDesign. + ''; + homepage = "https://sile-typesetter.org"; + # In nixpkgs we use a version specific URL for CHANGELOG.md + changelog = "https://github.com/sile-typesetter/sile/raw/master/CHANGELOG.md"; + platforms = lib.platforms.unix; + maintainers = with lib.maintainers; [ doronbehar alerque ]; + license = lib.licenses.mit; + }; +}) diff --git a/flake.lock b/flake.lock index 17ea5fc9f..0dca04683 100644 --- a/flake.lock +++ b/flake.lock @@ -3,11 +3,11 @@ "flake-compat": { "flake": false, "locked": { - "lastModified": 1673956053, - "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", "owner": "edolstra", "repo": "flake-compat", - "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", "type": "github" }, "original": { @@ -21,11 +21,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1681202837, - "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", "owner": "numtide", "repo": "flake-utils", - "rev": "cfacdce06f30d2b68473a46042957675eebb3401", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", "type": "github" }, "original": { @@ -41,11 +41,11 @@ ] }, "locked": { - "lastModified": 1660459072, - "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", + "lastModified": 1694102001, + "narHash": "sha256-vky6VPK1n1od6vXbqzOXnekrQpTL4hbPAwUhT5J9c9E=", "owner": "hercules-ci", "repo": "gitignore.nix", - "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", + "rev": "9e21c80adf67ebcb077d75bd5e7d724d21eeafd6", "type": "github" }, "original": { @@ -72,11 +72,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1682109806, - "narHash": "sha256-d9g7RKNShMLboTWwukM+RObDWWpHKaqTYXB48clBWXI=", + "lastModified": 1696577711, + "narHash": "sha256-94VRjvClIKDym1QRqPkX5LTQoAwZ1E6QE/3dWtOXSIQ=", "owner": "nixos", "repo": "nixpkgs", - "rev": "2362848adf8def2866fabbffc50462e929d7fffb", + "rev": "a2eb207f45e4a14a1e3019d9e3863d1e208e2295", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 3a9634790..52addc5bb 100644 --- a/flake.nix +++ b/flake.nix @@ -37,36 +37,7 @@ inherit (gitignore.lib) gitignoreSource; # https://discourse.nixos.org/t/passing-git-commit-hash-and-tag-to-build-with-flakes/11355/2 version_rev = if (self ? rev) then (builtins.substring 0 7 self.rev) else "dirty"; - # Prepare a different luaEnv to be used in the overridden expression, - # this is also the place to choose a different lua interpreter, such as - # lua5_4 or luajit - luaEnv = pkgs.lua5_3.withPackages(ps: with ps; [ - cassowary - cldr - fluent - linenoise - loadkit - lpeg - lua-zlib - lua_cliargs - luaepnf - luaexpat - luafilesystem - luarepl - luasec - luasocket - luautf8 - penlight - vstruct - # lua packages needed for testing - busted - luacheck - # If we want to test things with lua5.2 or an even older lua, we uncomment these - #bit32 - #compat53 - ]); - # Use the expression from Nixpkgs instead of rewriting it here. - sile = pkgs.sile.overrideAttrs(oldAttr: rec { + sile = pkgs.callPackage ./build-aux/pkg.nix { version = "${(pkgs.lib.importJSON ./package.json).version}-${version_rev}-flake"; src = pkgs.lib.cleanSourceWith { # Ignore many files that gitignoreSource doesn't ignore, see: @@ -95,66 +66,38 @@ ]); src = gitignoreSource ./.; }; - # Add the libtexpdf src instead of the git submodule. - # Also pretend to be a tarball release so sile --version will not say `vUNKNOWN`. - preAutoreconf = '' - rm -rf ./libtexpdf - # From some reason without this flag, libtexpdf/ is unwriteable - cp --no-preserve=mode -r ${libtexpdf-src} ./libtexpdf/ - echo ${version} > .tarball-version - ''; - # Don't build the manual as it's time consuming, and it requires fonts - # that are not available in the sandbox due to internet connection - # missing. - configureFlags = [ - "PDFINFO=false" - ] ++ ( - pkgs.lib.lists.remove "--with-manual" oldAttr.configureFlags - ); - nativeBuildInputs = oldAttr.nativeBuildInputs ++ [ - pkgs.autoreconfHook - ]; - buildInputs = [ - # Build inputs added since release in nixpkgs - pkgs.cargo - pkgs.jq - pkgs.rustc - ] ++ [ - # Add here inputs needed for development, and not for Nixpkgs' build. - pkgs.libarchive - pkgs.perl - # This line, along with the `pkgs.list.drop 1` line afterwards, - # replaces the luaEnv originated in `oldAttr.buildInputs`. - luaEnv - ] ++ ( - # Add all buildInputs from Nixpkgs' derivation, besides the 1st - # one, which is Nixpkgs' luaEnv. NOTE it's not mandatory to `drop` - # the first buildInput of `oldAttr` as so, because the first `lua` - # interpreter that would have been found otherwise would have been - # the one belonging to the first `luaEnv` of the final - # `buildInputs`. However, we'd like to keep the `buildInputs` clean - # never the less. - pkgs.lib.lists.drop 1 oldAttr.buildInputs - ); - meta = oldAttr.meta // { - changelog = "https://github.com/sile-typesetter/sile/raw/master/CHANGELOG.md"; - }; - }); + inherit libtexpdf-src; + }; + inherit (sile.passthru) luaEnv; in rec { devShells = { default = pkgs.mkShell { - inherit (sile) checkInputs buildInputs FONTCONFIG_FILE; + inherit (sile) + buildInputs + nativeCheckInputs + FONTCONFIG_FILE + ; configureFlags = sile.configureFlags ++ [ "--enable-developer" ]; - nativeBuildInputs = sile.nativeBuildInputs ++ [ pkgs.luarocks-nix ]; - # This is written in Nixpkgs' expression as well, but we need to write - # this here so that the overridden luaEnv will be used instead. - passthru = { - inherit luaEnv; - }; + nativeBuildInputs = sile.nativeBuildInputs ++ [ + pkgs.luarocks + # For commitlint git hook + pkgs.yarn + ]; + }; + }; + packages = { + sile-lua5_2 = sile; + sile-lua5_3 = sile.override { + lua = pkgs.lua5_3; + }; + sile-lua5_4 = sile.override { + lua = pkgs.lua5_4; + }; + sile-luajit = sile.override { + lua = pkgs.luajit; }; }; - packages.sile = sile; - defaultPackage = sile; + defaultPackage = packages.sile-luajit; apps = rec { default = sile; sile = { diff --git a/package.json b/package.json index 2cd7b2b73..5e286ebbf 100644 --- a/package.json +++ b/package.json @@ -19,11 +19,11 @@ }, "homepage": "https://sile-typesetter.org", "devDependencies": { - "@commitlint/cli": "^17.6", - "@commitlint/config-conventional": "^17.6", - "@commitlint/prompt": "^17.6", + "@commitlint/cli": "^17.7", + "@commitlint/config-conventional": "^17.7", + "@commitlint/prompt": "^17.7", "commitizen": "^4.3", - "conventional-changelog-cli": "^4.0", + "conventional-changelog-cli": "^4.1", "husky": "^8.0", "standard-version": "^9.5", "yaml": "^2.3"