|
1 | 1 | { |
| 2 | + # Builtin |
| 3 | + pkgs, |
2 | 4 | lib, |
| 5 | + |
| 6 | + # Rust version. (Override this with an overlay if you like) |
| 7 | + rustToolchain, |
| 8 | + |
| 9 | + # Native build dependencies: |
| 10 | + python, |
| 11 | + maturin, |
3 | 12 | buildPythonPackage, |
4 | | - rustPlatform, |
5 | 13 | perl, |
6 | 14 | git, |
7 | | - # Python packages: |
| 15 | + |
| 16 | + # Python package dependencies: |
8 | 17 | cbor2, |
9 | 18 | opentelemetry-api, |
10 | 19 | opentelemetry-exporter-otlp, |
11 | 20 | opentelemetry-sdk, |
12 | 21 | }: |
13 | 22 | let |
14 | | - root = ../../.; |
15 | | - util = import (root + /nix/util.nix) { inherit lib; }; |
16 | | -in |
17 | | -buildPythonPackage rec { |
18 | | - pname = "opsqueue"; |
19 | | - version = "0.1.0"; |
20 | | - pyproject = true; |
| 23 | + sources = import ../../nix/sources.nix; |
| 24 | + crane = import sources.crane { pkgs = pkgs; }; |
| 25 | + craneLib = crane.overrideToolchain (pkgs: rustToolchain); |
| 26 | + extraFileFilter = path: _type: builtins.match ".*(db|sql|py|md)$" path != null; |
| 27 | + fileFilter = path: type: (extraFileFilter path type) || (craneLib.filterCargoSources path type); |
21 | 28 |
|
22 | | - src = util.fileFilter { |
23 | | - name = "opsqueue_python"; |
24 | | - src = root; |
| 29 | + src = lib.cleanSourceWith { |
| 30 | + src = ../../.; |
| 31 | + name = "opsqueue"; |
| 32 | + filter = fileFilter; |
| 33 | + }; |
25 | 34 |
|
26 | | - # We're copying slightly too much to the Nix store here, |
27 | | - # but using the more granular file filter was very error-prone. |
28 | | - # This is one thing that could be improved a little in the future. |
29 | | - srcGlobalWhitelist = [ |
30 | | - ".py" |
31 | | - ".pyi" |
32 | | - "py.typed" |
33 | | - ".rs" |
34 | | - ".toml" |
35 | | - ".lock" |
36 | | - ".db" |
37 | | - ".md" |
38 | | - ]; |
| 35 | + crateName = craneLib.crateNameFromCargoToml { cargoToml = ./Cargo.toml; }; |
| 36 | + pname = crateName.pname; |
| 37 | + version = crateName.version; |
| 38 | + commonArgs = { |
| 39 | + inherit src version pname; |
| 40 | + strictDeps = true; |
| 41 | + nativeBuildInputs = [ python ]; |
| 42 | + cargoExtraArgs = "--package opsqueue_python"; |
39 | 43 | }; |
| 44 | + cargoArtifacts = craneLib.buildDepsOnly (commonArgs // { pname = pname; }); |
40 | 45 |
|
41 | | - cargoDeps = rustPlatform.importCargoLock { lockFile = ../../Cargo.lock; }; |
| 46 | + wheelTail = "py3-abi3-linux_x86_64"; |
| 47 | + wheelName = "opsqueue-${version}-${wheelTail}.whl"; |
42 | 48 |
|
43 | | - env = { |
44 | | - DATABASE_URL = "sqlite://./opsqueue/opsqueue_example_database_schema.db"; |
45 | | - }; |
| 49 | + crateWheel = |
| 50 | + (craneLib.buildPackage (commonArgs // { inherit cargoArtifacts; })).overrideAttrs |
| 51 | + (old: { |
| 52 | + nativeBuildInputs = old.nativeBuildInputs ++ [ maturin ]; |
46 | 53 |
|
47 | | - pythonImportsCheck = [ pname ]; |
| 54 | + # We intentionally _override_ rather than extend the buildPhase |
| 55 | + # as Maturin itself calls `cargo build`, no need to call it twice. |
| 56 | + buildPhase = '' |
| 57 | + cargo --version |
| 58 | + maturin build --release --offline --target-dir ./target --manifest-path "./libs/opsqueue_python/Cargo.toml" |
| 59 | + ''; |
48 | 60 |
|
49 | | - maturinBuildFlags = [ |
50 | | - "--manifest-path" |
51 | | - "./libs/opsqueue_python/Cargo.toml" |
52 | | - ]; |
| 61 | + # We build a single wheel |
| 62 | + # but by convention its name is based on the precise combination of |
| 63 | + # Python version + OS version + architecture + ... |
| 64 | + # |
| 65 | + # The Nix hash already covers us for uniqueness and compatibility. |
| 66 | + # So this 'trick' copies it to a predictably named file. |
| 67 | + # |
| 68 | + # Just like `buildPhase`, we override rather than extend |
| 69 | + # because we are only interested in the wheel output of Maturin as a whole. |
| 70 | + # (which is an archive inside of it containing the `.so` cargo built) |
| 71 | + installPhase = '' |
| 72 | + mkdir -p $out |
| 73 | + for wheel in ./target/wheels/*.whl ; do |
| 74 | + cp "$wheel" $out/${wheelName} |
| 75 | + done |
| 76 | + ''; |
53 | 77 |
|
54 | | - nativeBuildInputs = with rustPlatform; [ |
55 | | - perl |
56 | | - git |
57 | | - cargoSetupHook |
58 | | - maturinBuildHook |
59 | | - ]; |
| 78 | + # There are no Rust unit tests in the Python FFI library currently, |
| 79 | + # so we can skip rebuilding opsqueue_python for tests. |
| 80 | + doCheck = false; |
| 81 | + }); |
| 82 | +in |
| 83 | +buildPythonPackage { |
| 84 | + pname = pname; |
| 85 | + format = "wheel"; |
| 86 | + version = crateName.version; |
| 87 | + src = "${crateWheel}/${wheelName}"; |
| 88 | + doCheck = false; |
| 89 | + pythonImportsCheck = [ "opsqueue" ]; |
60 | 90 |
|
61 | 91 | propagatedBuildInputs = [ |
62 | 92 | cbor2 |
|
0 commit comments