Skip to content
1 change: 1 addition & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use flake
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,10 @@ dkms.conf

# --- End of C.gitignore ---
tools/.ucd-cache/

# --- Nix ---
result
result-*
build/
build-*/
.direnv/
48 changes: 48 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

111 changes: 111 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
{
description = "Lython: an LLVM/MLIR 23 based Python compiler toolchain";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";

# Formatting tooling stays behind `formatter`/`checks` only. Referencing
# it from `packages` or `devShells` would make `nix run`/`nix build` fetch
# the tooling input again.
treefmt-nix.url = "github:numtide/treefmt-nix";
treefmt-nix.inputs.nixpkgs.follows = "nixpkgs";
};

outputs =
{
self,
nixpkgs,
treefmt-nix,
...
}:
let
# nix-systems/default, inlined: four system names are not worth an input
# every `nix run` user would fetch.
systems = [
"aarch64-darwin"
"aarch64-linux"
"x86_64-darwin"
"x86_64-linux"
];

forAllSystems = nixpkgs.lib.genAttrs systems;

pkgsFor = system: import nixpkgs { inherit system; };

treefmtEvalFor =
system:
treefmt-nix.lib.evalModule (pkgsFor system) {
projectRootFile = "flake.nix";
programs.nixfmt.enable = true;
settings.formatter = { };
};
in
{
packages = forAllSystems (
system:
let
pkgs = pkgsFor system;
llvmPackages = pkgs.llvmPackages_23;
lython = pkgs.callPackage ./nix/build-lython.nix {
llvm = llvmPackages.llvm;
mlir = llvmPackages.mlir;
tblgen = llvmPackages.tblgen;
};
in
{
default = lython;
inherit lython;
}
);

formatter = forAllSystems (system: (treefmtEvalFor system).config.build.wrapper);

checks = forAllSystems (system: {
treefmt = (treefmtEvalFor system).config.build.check self;
});

devShells = forAllSystems (
system:
let
pkgs = pkgsFor system;
llvmPackages = pkgs.llvmPackages_23;
in
{
default = pkgs.mkShell {
packages = [
llvmPackages.llvm
llvmPackages.mlir
# mlir-tblgen and llvm-tblgen live only in `tblgen`; nixpkgs's
# mlir derivation does not install them into its `out`. Lython's
# CMake looks them up on PATH at configure time, so the
# devShell has to bring them in.
llvmPackages.tblgen
llvmPackages.clang
llvmPackages.lld
pkgs.cmake
pkgs.ninja
pkgs.gnumake
pkgs.pkg-config
pkgs.python3
pkgs.uv
pkgs.gdb
# `lyc` shells out to the clang in llvm23 for AOT and WASI
# linking; that clang locates the C++ runtime by finding gcc on
# PATH.
pkgs.gcc
pkgs.binutils
];

LLVM_DIR = "${llvmPackages.llvm.dev}/lib/cmake/llvm";
MLIR_DIR = "${llvmPackages.mlir.dev}/lib/cmake/mlir";

shellHook = ''
export LLVM_DIR="${llvmPackages.llvm.dev}/lib/cmake/llvm"
export MLIR_DIR="${llvmPackages.mlir.dev}/lib/cmake/mlir"
echo "LLVM_DIR=$LLVM_DIR"
echo "MLIR_DIR=$MLIR_DIR"
'';
};
}
);
};
}
62 changes: 62 additions & 0 deletions nix/build-lython.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
lib,
stdenv,
cmake,
ninja,
llvm,
mlir,
tblgen,
zlib,
zstd,
libxml2,
ncurses,
}:

stdenv.mkDerivation {
pname = "lython";
version = "0.1.0";

src = ../.;

nativeBuildInputs = [
cmake
ninja
llvm
mlir
tblgen
];

buildInputs = [
llvm
mlir
zlib
zstd
libxml2
ncurses
];

cmakeFlags = [
(lib.cmakeFeature "CMAKE_BUILD_TYPE" "Release")
"-DLLVM_DIR=${llvm.dev}/lib/cmake/llvm"
"-DMLIR_DIR=${mlir.dev}/lib/cmake/mlir"
# nixpkgs's mlir does not install mlir-tblgen into its `out`; the tablegen
# binary lives in `llvmPackages_23.tblgen`. Lython's CMake requires
# mlir-tblgen (and llvm-tblgen) at configure time, so we hand it the
# absolute paths here and skip the find_program search.
"-DLLVM_TABLEGEN_EXE=${tblgen}/bin/llvm-tblgen"
"-DMLIR_TABLEGEN_EXE=${tblgen}/bin/mlir-tblgen"
# tests/CMakeLists.txt pulls googletest through FetchContent, which has no
# network inside the Nix sandbox. The unit and golden suites are run from
# the devShell, where the fetch can reach the network.
"-DLYTHON_BUILD_TESTS=OFF"
];

meta = {
description = "An LLVM/MLIR 23 based Python compiler toolchain";
homepage = "https://github.com/t3tra-dev/lython";
# Without this `nix run` looks for bin/lython (the pname) and fails; the
# installed binary is lyc.
mainProgram = "lyc";
platforms = [ "x86_64-linux" ];
};
}