diff --git a/.gitignore b/.gitignore index 284acf248c..d7fd92b074 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ CMakeUserPresets.json /*build*/ **/target/ /*install*/ +/Nixpile-build *.swp diff --git a/README.md b/README.md index 97789702c9..0b58c93010 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,35 @@ If you're having trouble with something, want to suggest a feature or report a b You can directly [report issues here on GitHub](/drawpile/Drawpile/issues). If you got Discord, you can [join the Drawpile server](https://drawpile.net/discord/) on there. You can also [use the chatroom on libera.chat](https://drawpile.net/irc/), it can be done directly through the browser and doesn't need any account. +## Drawpile on nix + +> Linux users hate him for descovering how to reproduce an ENTIRE ENVIROMENT with just ONE COMMAND
+> \- Qubic 2023 + +Having a reproducible work enviroment is nice. +Especialy if you can do it only with one command. + +### Dev enviroment + +To get a dev shell with nix you just do `nix shell .#(cmake profile without linux prefix)` +(I did not include linux prefix becuse I'm quite sure it will probably work with nix + macOs) + +### Dev shell functions + +In dev shells you have 2 very simple functions + +`firstBuild` for setuping cmake and building drawpile for first time
+`incrementalBuild` for building drawpile successive times + +### Package names + +We name packages same way we name shell-s + + + ## Contributing Pull requests are welcome, be it for code or anything else! If you want to contribute documentation, you can do so [over in this repository](/drawpile/drawpile.github.io). diff --git a/default.nix b/default.nix new file mode 100644 index 0000000000..90fefe10a4 --- /dev/null +++ b/default.nix @@ -0,0 +1,6 @@ +(import (let lock = builtins.fromJSON (builtins.readFile ./flake.lock); +in fetchTarball { + url = + lock.nodes.flake-compat.locked.url or "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = lock.nodes.flake-compat.locked.narHash; +}) { src = ./.; }).defaultNix diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000000..90fc50df7b --- /dev/null +++ b/flake.lock @@ -0,0 +1,92 @@ +{ + "nodes": { + "flake-compat": { + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "revCount": 57, + "type": "tarball", + "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nix-filter": { + "locked": { + "lastModified": 1705332318, + "narHash": "sha256-kcw1yFeJe9N4PjQji9ZeX47jg0p9A0DuU4djKvg1a7I=", + "owner": "numtide", + "repo": "nix-filter", + "rev": "3449dc925982ad46246cfc36469baf66e1b64f17", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "nix-filter", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1706550542, + "narHash": "sha256-UcsnCG6wx++23yeER4Hg18CXWbgNpqNXcHIo5/1Y+hc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "97b17f32362e475016f942bbdfda4a4a72a8a652", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-compat": "flake-compat", + "flake-utils": "flake-utils", + "nix-filter": "nix-filter", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000000..f0eb9e83a0 --- /dev/null +++ b/flake.nix @@ -0,0 +1,240 @@ +# TODO: Consider using mold (linker) +#TODO: Add declarative drawpile server support +#TODO: Consider my terrible life choices that led me to derive os-es from config files +{ + description = "Collaborative drawing program that lets multiple people draw."; + + inputs = { + #main packages + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + #utilities in writing flakes + flake-utils.url = "github:numtide/flake-utils"; + + #compatibility with non flaked nix + flake-compat.url = "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"; + + # source filtering + nix-filter.url = "github:numtide/nix-filter"; + }; + + outputs = { self, nixpkgs, flake-utils, nix-filter, ... }: + #Support x86_64/arm linux + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = nixpkgs.legacyPackages.${system}; + + #Compile time libs + + mkNativeInputs = { qt5 }: + let + qtStuff = if qt5 then + [ pkgs.libsForQt5.qt5.wrapQtAppsHook ] + else + [ pkgs.qt6.wrapQtAppsHook ]; + + buildSystems = with pkgs; [ cmake ninja gcc ]; + + in qtStuff ++ buildSystems; + + mkDepends = { qt5, shell }: + let + #decide what QT to use + qtDependences = if qt5 then + with pkgs.libsForQt5.qt5; + [ qtbase qtsvg qttools qtmultimedia ] + ++ [ pkgs.libsForQt5.karchive ] + else + with pkgs; [ qt6.qtbase qt6.qtsvg qt6.qttools qt6.qtmultimedia ]; + + #Other dependencies required for building + otherDeps = with pkgs; [ + + git + libxkbcommon + libzip + libsodium + libmicrohttpd + libpulseaudio + ]; + + shellDpeneds = if shell then + with pkgs; [ cargo rustc rustfmt clippy ] + else + with pkgs; [ ]; + + in qtDependences ++ shellDpeneds ++ otherDeps; + + mkDpShell = { useQt5, preset, debug ? false }: + pkgs.mkShell { + + nativeBuildInputs = mkNativeInputs { qt5 = useQt5; }; + + buildInputs = mkDepends { + qt5 = useQt5; + shell = true; + }; + + shellHook = '' + export ROOT="$PWD/Nixpile-build/${preset}" + mkdir -p "$ROOT" + export LD_LIBRARY_PATH="$CMAKE_LIBRARY_PATH" + + configure() { + cmake -S "$ROOT/../../" -B "$ROOT" \ + --preset ${preset} \ + "-DCMAKE_INSTALL_PREFIX=$out" + } + + build() { + if ! [ -e "$ROOT" ]; then + configure || return 1 + fi + if [ -e "$ROOT/bin/.drawpile-wrapped" ]; then + mv "$ROOT/bin/.drawpile-wrapped" "$ROOT/bin/drawpile" + fi + cmake --build "$ROOT" || return 1 + wrapQtApp "$ROOT/bin/drawpile" + } + + run() { + build || return 1 + "$ROOT/bin/drawpile" + } + ''; + }; + + mkDrawpile = { useQt5, preset, debug ? false }: + pkgs.rustPlatform.buildRustPackage { + name = "drawpile"; + + src = nix-filter { + root = ./.; + # Filter source + include = [ + # Include /src + "src" + # Include rust stuff + ./Cargo.toml + ./Cargo.lock + # Include CMAKE stuff + "cmake" + ./CMakePresets.json + ./CMakeLists.txt + + #Other misalanius stuff + ./LICENSE.txt + ./ChangeLog + ./README.md + "doc" + ]; + }; + + nativeBuildInputs = mkNativeInputs { qt5 = useQt5; }; + + buildInputs = mkDepends { + qt5 = useQt5; + shell = false; + }; + + cargoLock = { lockFile = ./Cargo.lock; }; + + configurePhase = '' + cmake -S ./ -B Drawpile-build \ + --preset ${preset} \ + -DCMAKE_INSTALL_PREFIX=$out + ''; + + enableParallelBuilding = true; + + buildPhase = '' + cmake --build ./Drawpile-build + ''; + + installPhase = '' + mkdir -p $out + cmake --install ./Drawpile-build + ''; + }; + + in rec { + + packages = { + debug-qt6-all-ninja = mkDrawpile { + preset = "linux-debug-qt6-all-ninja"; + useQt5 = false; + }; + + release-qt6-all-ninja = mkDrawpile { + preset = "linux-release-qt6-all-ninja"; + useQt5 = false; + }; + + release-qt6-server-ninja = mkDrawpile { + preset = "linux-release-qt6-server-ninja"; + useQt5 = false; + }; + + debug-qt5-all-ninja = mkDrawpile { + preset = "linux-debug-qt5-all-ninja"; + useQt5 = true; + }; + + release-qt5-all-ninja = mkDrawpile { + preset = "linux-release-qt5-all-ninja"; + useQt5 = true; + }; + + release-qt5-server-ninja = mkDrawpile { + preset = "linux-release-qt5-server-ninja"; + useQt5 = true; + }; + + default = self.outputs.packages.${system}.release-qt6-all-ninja; + }; + + #Dev shells + + devShells = rec { + debug-qt6-all-ninja = mkDpShell { + preset = "linux-debug-qt6-all-ninja"; + useQt5 = false; + debug = true; + }; + + release-qt6-all-ninja = mkDpShell { + preset = "linux-release-qt6-all-ninja"; + useQt5 = false; + debug = true; + }; + + release-qt6-server-ninja = mkDpShell { + preset = "linux-release-qt6-server-ninja"; + useQt5 = false; + debug = true; + }; + + debug-qt5-all-ninja = mkDpShell { + preset = "linux-debug-qt5-all-ninja"; + useQt5 = true; + debug = true; + }; + + release-qt5-all-ninja = mkDpShell { + preset = "linux-release-qt5-all-ninja"; + useQt5 = true; + debug = true; + }; + + release-qt5-server-ninja = mkDpShell { + preset = "linux-release-qt5-server-ninja"; + useQt5 = true; + debug = true; + }; + + default = self.outputs.devShells.${system}.debug-qt6-all-ninja; + }; + + formatter = pkgs.nixfmt; + }); +} diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000000..71e7def5b6 --- /dev/null +++ b/shell.nix @@ -0,0 +1,6 @@ +(import (let lock = builtins.fromJSON (builtins.readFile ./flake.lock); +in fetchTarball { + url = + lock.nodes.flake-compat.locked.url or "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = lock.nodes.flake-compat.locked.narHash; +}) { src = ./.; }).shellNix