modified: CONTRIBUTING.md
new file: flake.lock new file: flake.nix
This commit is contained in:
1 parent
0398a813c8
commit
75e9472a47
3 files changed
+200
No files matched your search
@@ -28,6 +28,46 @@ HTTPS or localhost, because it uses the Origin Private File System.
|
|||||||
|
|
||||||
Windows from Linux: `cargo xwin build --release --target x86_64-pc-windows-msvc -p solvecraft`.
|
Windows from Linux: `cargo xwin build --release --target x86_64-pc-windows-msvc -p solvecraft`.
|
||||||
|
|
||||||
|
### NixOS: `nix develop`
|
||||||
|
|
||||||
|
NixOS has no `/usr/lib`, so nothing is on `LD_LIBRARY_PATH` and a plain `cargo run` finds none of
|
||||||
|
the libraries the app loads at run time: the Wayland ones winit opens the window through, the EGL
|
||||||
|
loader wgpu renders through, and libdbus-1, which rfd's file dialogs reach xdg-desktop-portal
|
||||||
|
through (a dialog then never appears and the pick returns no path):
|
||||||
|
|
||||||
|
```
|
||||||
|
ERROR solvecraft: winit EventLoopError: ... The wayland library could not be loaded
|
||||||
|
ERROR eframe::native::run: Exiting because of error: WGPU error: Failed to create surface for any enabled backend: {}
|
||||||
|
ERROR rfd::backend::xdg_desktop_portal::portal::libdbus: Can't connect to a portal: libdbus-1.so not found
|
||||||
|
```
|
||||||
|
|
||||||
|
`nix develop` (the [`flake.nix`](flake.nix) in the repository root) puts the Wayland, X11,
|
||||||
|
EGL-loader and D-Bus libraries on `LD_LIBRARY_PATH`, so `cargo run --release -p solvecraft` works
|
||||||
|
from that shell as on any other distribution, file dialogs included. `nix run` builds the app and
|
||||||
|
wraps the binary the same way. The Mesa drivers stay the system's, from `/run/opengl-driver`
|
||||||
|
(`hardware.graphics.enable`): that is the driver stack the compositor runs on, and wgpu reaches the
|
||||||
|
integrated GPU through the EGL loader. The shell deliberately brings no Rust toolchain — the one on
|
||||||
|
`PATH` keeps its build cache, where a second `rustc` would make every build recompile the workspace
|
||||||
|
from scratch; `nix develop .#rust` is there for a machine with no Rust at all.
|
||||||
|
|
||||||
|
**Anti-aliasing on the OpenGL backend.** NixOS keeps the Vulkan ICD descriptions
|
||||||
|
(`/run/opengl-driver/share/vulkan/icd.d`) off the Vulkan loader's search path, so wgpu picks its
|
||||||
|
OpenGL backend on the integrated GPU. On that backend any multisampling above 1× — the default is
|
||||||
|
4× — draws a black window: the UI still lays out and the control channel still answers, but every
|
||||||
|
frame, `ui.screenshot` included, comes out empty. Set **Preferences ▸ Graphics ▸ Anti-aliasing** to
|
||||||
|
1× and restart (the setting applies on the next start), or write it before the first run, since a
|
||||||
|
black window is no way to reach the dialog:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
mkdir -p ~/.local/share/solvecraft
|
||||||
|
echo '{"msaa": 1}' > ~/.local/share/solvecraft/graphics.json
|
||||||
|
```
|
||||||
|
|
||||||
|
`apps/solvecraft/src/main.rs` reads that file (`graphics_path()`, eframe's storage dir) before the
|
||||||
|
window opens; 2× and 4× are the same black window. The Vulkan backend is no way out of it either:
|
||||||
|
`libvulkan.so.1` is not on `LD_LIBRARY_PATH`, so `WGPU_BACKEND=vulkan` exits with a
|
||||||
|
`CreateSurfaceError` instead.
|
||||||
|
|
||||||
## How the code is laid out
|
## How the code is laid out
|
||||||
|
|
||||||
The [README](README.md#architecture) has the layer table. The short version:
|
The [README](README.md#architecture) has the layer table. The short version:
|
||||||
|
|||||||
Generated
+27
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1791594108,
|
||||||
|
"narHash": "sha256-XK4KceonkwD8LuMAt/vNrz982mXJM5jeHAxMwsUXXAQ=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "6510408d147d8c5e6d76043e899e9251756f6a75",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
{
|
||||||
|
description = "SolveCraft — native app development shell and package for Linux";
|
||||||
|
|
||||||
|
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
|
||||||
|
outputs =
|
||||||
|
{ self, nixpkgs }:
|
||||||
|
let
|
||||||
|
systems = [
|
||||||
|
"x86_64-linux"
|
||||||
|
"aarch64-linux"
|
||||||
|
];
|
||||||
|
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system});
|
||||||
|
|
||||||
|
# Why this shell exists. winit opens the window by dlopen'ing the Wayland client libraries,
|
||||||
|
# wgpu renders through the EGL loader (libEGL.so.1), and rfd's file dialogs reach
|
||||||
|
# xdg-desktop-portal through libdbus-1; a plain `cargo run` under NixOS finds none of them,
|
||||||
|
# because there is no /usr/lib and nothing puts them on LD_LIBRARY_PATH:
|
||||||
|
# winit EventLoopError: The wayland library could not be loaded
|
||||||
|
# eframe: WGPU error: Failed to create surface for any enabled backend: {}
|
||||||
|
# rfd::backend::xdg_desktop_portal::portal::libdbus: Can't connect to a portal: libdbus-1.so not found
|
||||||
|
# The Mesa drivers themselves — and the EGL vendor / Vulkan ICD descriptions that name them —
|
||||||
|
# come from the system in /run/opengl-driver (hardware.graphics.enable), not from here, since
|
||||||
|
# that is the driver stack the compositor runs on. Verified on an Intel LNL iGPU under
|
||||||
|
# Wayland: wgpu picks the GL backend through this loader and draws.
|
||||||
|
# The X11 libraries are the ones the app actually uses on a Wayland desktop: with `DISPLAY`
|
||||||
|
# set and `SOLVECRAFT_WAYLAND` unset, winit runs through XWayland (file drag and drop exists
|
||||||
|
# only there). The Wayland ones are for `SOLVECRAFT_WAYLAND=1`, and both are needed under
|
||||||
|
# `xvfb-run` on a machine with no display at all.
|
||||||
|
runtimeLibs =
|
||||||
|
pkgs:
|
||||||
|
(with pkgs; [
|
||||||
|
wayland
|
||||||
|
libxkbcommon
|
||||||
|
libglvnd
|
||||||
|
dbus
|
||||||
|
])
|
||||||
|
++ (with pkgs; [
|
||||||
|
# xorg.libX11 and friends are deprecated aliases in current nixpkgs.
|
||||||
|
libx11
|
||||||
|
libxcursor
|
||||||
|
libxi
|
||||||
|
libxrandr
|
||||||
|
libxrender
|
||||||
|
libxext
|
||||||
|
libxcb
|
||||||
|
]);
|
||||||
|
driverLibDir = "/run/opengl-driver/lib";
|
||||||
|
libraryPath = pkgs: "${pkgs.lib.makeLibraryPath (runtimeLibs pkgs)}:${driverLibDir}";
|
||||||
|
|
||||||
|
shellHook = ''
|
||||||
|
if [ ! -d ${driverLibDir} ]; then
|
||||||
|
echo "solvecraft: ${driverLibDir} is missing — set hardware.graphics.enable = true so the Mesa drivers and their EGL vendor descriptions exist." >&2
|
||||||
|
fi
|
||||||
|
command -v cc >/dev/null || echo "solvecraft: no C linker on PATH, cargo cannot link — use nix develop .#rust" >&2
|
||||||
|
echo "solvecraft: cargo run --release -p solvecraft -- --sample"
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
devShells = forAllSystems (pkgs: {
|
||||||
|
# The shell to work in. It brings no toolchain of its own, Rust or C: the ones already on
|
||||||
|
# PATH (a system package, rustup, nixpkgs) keep their build cache and their linker, where a
|
||||||
|
# second rustc — or mkShell's second gcc, with another glibc behind it — would make every
|
||||||
|
# `cargo build` produce binaries from somewhere else.
|
||||||
|
default = pkgs.mkShellNoCC {
|
||||||
|
name = "solvecraft";
|
||||||
|
LD_LIBRARY_PATH = libraryPath pkgs;
|
||||||
|
inherit shellHook;
|
||||||
|
};
|
||||||
|
|
||||||
|
# For a machine with no Rust at all: `nix develop .#rust`. Its own target directory, so
|
||||||
|
# switching between this toolchain and the system one does not thrash the cache.
|
||||||
|
rust = pkgs.mkShell {
|
||||||
|
name = "solvecraft-rust";
|
||||||
|
packages = [
|
||||||
|
pkgs.cargo
|
||||||
|
pkgs.rustc
|
||||||
|
pkgs.rustfmt
|
||||||
|
pkgs.clippy
|
||||||
|
];
|
||||||
|
LD_LIBRARY_PATH = libraryPath pkgs;
|
||||||
|
# Under target/, which .gitignore already covers.
|
||||||
|
CARGO_TARGET_DIR = "target/nix";
|
||||||
|
shellHook = ''
|
||||||
|
${shellHook}
|
||||||
|
echo "solvecraft: $(rustc --version), building into target/nix"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
packages = forAllSystems (pkgs: {
|
||||||
|
default = pkgs.rustPlatform.buildRustPackage {
|
||||||
|
pname = "solvecraft";
|
||||||
|
version = (pkgs.lib.importTOML ./Cargo.toml).workspace.package.version;
|
||||||
|
src = self;
|
||||||
|
|
||||||
|
cargoLock.lockFile = ./Cargo.lock;
|
||||||
|
# Build and install the app alone: the workspace also holds the CLI, the web app, xtask
|
||||||
|
# and the crates only the test suites need.
|
||||||
|
cargoBuildFlags = [
|
||||||
|
"-p"
|
||||||
|
"solvecraft"
|
||||||
|
];
|
||||||
|
cargoInstallFlags = [
|
||||||
|
"-p"
|
||||||
|
"solvecraft"
|
||||||
|
];
|
||||||
|
# `cargo xtask ci` is the test gate (it wants a wasm target and a GPU); the sandbox has
|
||||||
|
# neither.
|
||||||
|
doCheck = false;
|
||||||
|
|
||||||
|
nativeBuildInputs = [ pkgs.makeWrapper ];
|
||||||
|
buildInputs = runtimeLibs pkgs;
|
||||||
|
|
||||||
|
# The app reaches the window through dlopen'd libraries, so the packaged binary needs the
|
||||||
|
# same LD_LIBRARY_PATH the shell exports.
|
||||||
|
postFixup = ''
|
||||||
|
wrapProgram $out/bin/solvecraft --prefix LD_LIBRARY_PATH : "${libraryPath pkgs}"
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "Rust-native parametric 3D CAD app";
|
||||||
|
homepage = "https://github.com/bherbruck/solvecraft";
|
||||||
|
license = with pkgs.lib.licenses; [
|
||||||
|
mit
|
||||||
|
asl20
|
||||||
|
];
|
||||||
|
mainProgram = "solvecraft";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in new issue
Block a user