commit 0cef0722ad3486bbb8f3dd8fa88194c3ffe1ab64
parent 066b714718f9b06148f47aec1d621013533ec8bd
Author: Silas Brack <silasbrack@gmail.com>
Date: Sun, 28 Sep 2025 15:10:55 +0200
build: set up for Mac OS
Diffstat:
| M | .gitignore | | | 3 | +++ |
| M | flake.nix | | | 291 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- |
2 files changed, 149 insertions(+), 145 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -19,3 +19,6 @@ db.sqlite3*
# Nix
result
+# Mac OS
+.DS_Store
+
diff --git a/flake.nix b/flake.nix
@@ -32,6 +32,7 @@
}:
let
inherit (nixpkgs) lib;
+ forAllSystems = lib.genAttrs lib.systems.flakeExposed;
# Load a uv workspace from a workspace root.
# Uv2nix treats all uv projects as workspace projects.
@@ -39,36 +40,32 @@
# Create package overlay from workspace.
overlay = workspace.mkPyprojectOverlay {
- # Prefer prebuilt binary wheels as a package source.
- # Sdists are less likely to "just work" because of the metadata missing from uv.lock.
- # Binary wheels are more likely to, but may still require overrides for library dependencies.
- sourcePreference = "wheel"; # or sourcePreference = "sdist";
+ sourcePreference = "wheel";
# Optionally customise PEP 508 environment
# environ = {
# platform_release = "5.10.65";
# };
};
- # Extend generated overlay with build fixups
- #
- # Uv2nix can only work with what it has, and uv.lock is missing essential metadata to perform some builds.
- # This is an additional overlay implementing build fixups.
- # See:
- # - https://pyproject-nix.github.io/uv2nix/FAQ.html
- pyprojectOverrides = _final: _prev: {
- # Implement build fixups here.
- # Note that uv2nix is _not_ using Nixpkgs buildPythonPackage.
- # It's using https://pyproject-nix.github.io/pyproject.nix/build.html
- };
-
- # This example is only using x86_64-linux
- pkgs = nixpkgs.legacyPackages.x86_64-linux;
-
- # Use Python 3.12 from nixpkgs
- python = pkgs.python313;
+ # # Extend generated overlay with build fixups
+ # #
+ # # Uv2nix can only work with what it has, and uv.lock is missing essential metadata to perform some builds.
+ # # This is an additional overlay implementing build fixups.
+ # # See:
+ # # - https://pyproject-nix.github.io/uv2nix/FAQ.html
+ # pyprojectOverrides = _final: _prev: {
+ # # Implement build fixups here.
+ # # Note that uv2nix is _not_ using Nixpkgs buildPythonPackage.
+ # # It's using https://pyproject-nix.github.io/pyproject.nix/build.html
+ # };
# Construct package set
- pythonSet =
+ pythonSets = forAllSystems (
+ system:
+ let
+ pkgs = nixpkgs.legacyPackages.${system};
+ python = pkgs.python3;
+ in
# Use base package set from pyproject.nix builders
(pkgs.callPackage pyproject-nix.build.packages {
inherit python;
@@ -77,28 +74,17 @@
lib.composeManyExtensions [
pyproject-build-systems.overlays.default
overlay
- pyprojectOverrides
- # (final: prev: {
- # simple-web-app = prev.simple-web-app.overrideAttrs (old: {
- # src = lib.fileset.toSource {
- # root = old.src;
- # fileset = lib.fileset.unions [
- # (old.src + "/pyproject.toml")
- # (old.src + "/src")
- # (old.src + "/queries")
- # ];
- # };
- # });
- # })
+ # pyprojectOverrides
]
- );
- inherit (pkgs.callPackages pyproject-nix.build.util { }) mkApplication;
+ )
+ );
+ # inherit (pkgs.callPackages pyproject-nix.build.util { }) mkApplication;
in
{
# Package a virtual environment as our main application.
#
# Enable no optional dependencies for production build.
- packages.x86_64-linux.default = pythonSet.mkVirtualEnv "simple-web-app-env" workspace.deps.default;
+ packages = forAllSystems (system: { default = pythonSets.${system}.mkVirtualEnv "simple-web-app-env" workspace.deps.default; });
# default = mkApplication {
# venv = pythonSet.mkVirtualEnv "simple-web-app-env" workspace.deps.default;
@@ -106,129 +92,144 @@
# };
# Make hello runnable with `nix run`
- apps.x86_64-linux.default = {
- type = "app";
- program = "${self.packages.x86_64-linux.default}/bin/simple-web-app";
- };
+ apps = forAllSystems (
+ system:
+ let
+ appRoot = self.packages.${system}.default;
+ appProgram = "${appRoot}/bin/simple-web-app";
+ in {
+ default = {
+ type = "app";
+ program = appProgram;
+ };
+ }
+ );
# This example provides two different modes of development:
# - Impurely using uv to manage virtual environments
# - Pure development using uv2nix to manage virtual environments
- devShells.x86_64-linux = {
- # It is of course perfectly OK to keep using an impure virtualenv workflow and only use uv2nix to build packages.
- # This devShell simply adds Python and undoes the dependency leakage done by Nixpkgs Python infrastructure.
- impure = pkgs.mkShell {
- packages = [
- python
- pkgs.uv
- pkgs.ruff
- pkgs.basedpyright
- ];
- env = {
- # Prevent uv from managing Python downloads
- UV_PYTHON_DOWNLOADS = "never";
- # Force uv to use nixpkgs Python interpreter
- UV_PYTHON = python.interpreter;
- # LD_LIBRARY_PATH = "${pkgs.stdenv.cc.cc.lib}/lib/:/run/opengl-driver/lib/";
- LD_LIBRARY_PATH = lib.makeLibraryPath pkgs.pythonManylinuxPackages.manylinux1;
- };
- # // lib.optionalAttrs pkgs.stdenv.isLinux {
- # # Python libraries often load native shared objects using dlopen(3).
- # # Setting LD_LIBRARY_PATH makes the dynamic library loader aware of libraries without using RPATH for lookup.
- # LD_LIBRARY_PATH = lib.makeLibraryPath pkgs.pythonManylinuxPackages.manylinux1;
- #};
- shellHook = ''
- unset PYTHONPATH
- '';
- };
-
- # This devShell uses uv2nix to construct a virtual environment purely from Nix, using the same dependency specification as the application.
- # The notable difference is that we also apply another overlay here enabling editable mode ( https://setuptools.pypa.io/en/latest/userguide/development_mode.html ).
- #
- # This means that any changes done to your local files do not require a rebuild.
- #
- # Note: Editable package support is still unstable and subject to change.
- uv2nix =
- let
- # Create an overlay enabling editable mode for all local dependencies.
- editableOverlay = workspace.mkEditablePyprojectOverlay {
- # Use environment variable
- root = "$REPO_ROOT";
- # Optional: Only enable editable for these packages
- # members = [ "hello-world" ];
- };
-
- # Override previous set with our overrideable overlay.
- editablePythonSet = pythonSet.overrideScope (
- lib.composeManyExtensions [
- editableOverlay
-
- # Apply fixups for building an editable package of your workspace packages
- (final: prev: {
- hello-world = prev.hello-world.overrideAttrs (old: {
- # It's a good idea to filter the sources going into an editable build
- # so the editable package doesn't have to be rebuilt on every change.
- src = lib.fileset.toSource {
- root = old.src;
- fileset = lib.fileset.unions [
- (old.src + "/pyproject.toml")
- (old.src + "/README.md")
- (old.src + "/src/hello_world/__init__.py")
- ];
- };
-
- # Hatchling (our build system) has a dependency on the `editables` package when building editables.
- #
- # In normal Python flows this dependency is dynamically handled, and doesn't need to be explicitly declared.
- # This behaviour is documented in PEP-660.
- #
- # With Nix the dependency needs to be explicitly declared.
- nativeBuildInputs =
- old.nativeBuildInputs
- ++ final.resolveBuildSystem {
- editables = [ ];
- };
- });
-
- })
- ]
- );
-
- # Build virtual environment, with local packages being editable.
- #
- # Enable all optional dependencies for development.
- virtualenv = editablePythonSet.mkVirtualEnv "hello-world-dev-env" workspace.deps.all;
-
- in
- pkgs.mkShell {
+ devShells = forAllSystems (
+ system:
+ let
+ pkgs = nixpkgs.legacyPackages.${system};
+ python = pkgs.python3;
+ in {
+ # It is of course perfectly OK to keep using an impure virtualenv workflow and only use uv2nix to build packages.
+ # This devShell simply adds Python and undoes the dependency leakage done by Nixpkgs Python infrastructure.
+ impure = pkgs.mkShell {
packages = [
- virtualenv
+ python
pkgs.uv
pkgs.ruff
pkgs.basedpyright
];
-
env = {
- # Don't create venv using uv
- UV_NO_SYNC = "1";
-
+ # Prevent uv from managing Python downloads
+ UV_PYTHON_DOWNLOADS = "never";
# Force uv to use nixpkgs Python interpreter
UV_PYTHON = python.interpreter;
-
- # Prevent uv from downloading managed Python's
- UV_PYTHON_DOWNLOADS = "never";
-
- LD_LIBRARY_PATH = lib.makeLibraryPath pkgs.pythonManylinuxPackages.manylinux1;
+ LD_LIBRARY_PATH = "${pkgs.stdenv.cc.cc.lib}/lib/:/run/opengl-driver/lib/";
+ # LD_LIBRARY_PATH = lib.makeLibraryPath pkgs.pythonManylinuxPackages.manylinux1;
};
-
+ # // lib.optionalAttrs pkgs.stdenv.isLinux {
+ # # Python libraries often load native shared objects using dlopen(3).
+ # # Setting LD_LIBRARY_PATH makes the dynamic library loader aware of libraries without using RPATH for lookup.
+ # LD_LIBRARY_PATH = lib.makeLibraryPath pkgs.pythonManylinuxPackages.manylinux1;
+ #};
shellHook = ''
- # Undo dependency propagation by nixpkgs.
unset PYTHONPATH
-
- # Get repository root using git. This is expanded at runtime by the editable `.pth` machinery.
- export REPO_ROOT=$(git rev-parse --show-toplevel)
'';
};
- };
+
+ # This devShell uses uv2nix to construct a virtual environment purely from Nix, using the same dependency specification as the application.
+ # The notable difference is that we also apply another overlay here enabling editable mode ( https://setuptools.pypa.io/en/latest/userguide/development_mode.html ).
+ #
+ # This means that any changes done to your local files do not require a rebuild.
+ #
+ # Note: Editable package support is still unstable and subject to change.
+ uv2nix =
+ let
+ # Create an overlay enabling editable mode for all local dependencies.
+ editableOverlay = workspace.mkEditablePyprojectOverlay {
+ # Use environment variable
+ root = "$REPO_ROOT";
+ # Optional: Only enable editable for these packages
+ # members = [ "hello-world" ];
+ };
+
+ pythonSet = pythonSets.${system}.overrideScope editableOverlay;
+
+ # Override previous set with our overrideable overlay.
+ editablePythonSet = pythonSet.overrideScope (
+ lib.composeManyExtensions [
+ editableOverlay
+
+ # Apply fixups for building an editable package of your workspace packages
+ (final: prev: {
+ hello-world = prev.hello-world.overrideAttrs (old: {
+ # It's a good idea to filter the sources going into an editable build
+ # so the editable package doesn't have to be rebuilt on every change.
+ src = lib.fileset.toSource {
+ root = old.src;
+ fileset = lib.fileset.unions [
+ (old.src + "/pyproject.toml")
+ (old.src + "/README.md")
+ (old.src + "/src/hello_world/__init__.py")
+ ];
+ };
+
+ # Hatchling (our build system) has a dependency on the `editables` package when building editables.
+ #
+ # In normal Python flows this dependency is dynamically handled, and doesn't need to be explicitly declared.
+ # This behaviour is documented in PEP-660.
+ #
+ # With Nix the dependency needs to be explicitly declared.
+ nativeBuildInputs =
+ old.nativeBuildInputs
+ ++ final.resolveBuildSystem {
+ editables = [ ];
+ };
+ });
+
+ })
+ ]
+ );
+
+ # Build virtual environment, with local packages being editable.
+ #
+ # Enable all optional dependencies for development.
+ virtualenv = editablePythonSet.mkVirtualEnv "hello-world-dev-env" workspace.deps.all;
+
+ in
+ pkgs.mkShell {
+ packages = [
+ virtualenv
+ pkgs.uv
+ pkgs.ruff
+ pkgs.basedpyright
+ ];
+
+ env = {
+ # Don't create venv using uv
+ UV_NO_SYNC = "1";
+
+ # Force uv to use nixpkgs Python interpreter
+ UV_PYTHON = python.interpreter;
+
+ # Prevent uv from downloading managed Python's
+ UV_PYTHON_DOWNLOADS = "never";
+
+ # LD_LIBRARY_PATH = lib.makeLibraryPath pkgs.pythonManylinuxPackages.manylinux1;
+ };
+
+ shellHook = ''
+ # Undo dependency propagation by nixpkgs.
+ unset PYTHONPATH
+
+ # Get repository root using git. This is expanded at runtime by the editable `.pth` machinery.
+ export REPO_ROOT=$(git rev-parse --show-toplevel)
+ '';
+ };
+ });
};
}