diff --git a/.gitignore b/.gitignore index fc8a4fb..0db7192 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,6 @@ .direnv /result .sass-cache +zig-out +.zig-cache +freebsd.txt diff --git a/flake.nix b/flake.nix index 6da23bd..a05d5c9 100644 --- a/flake.nix +++ b/flake.nix @@ -35,8 +35,6 @@ url = "https://download.freebsd.org/releases/amd64/14.1-RELEASE/base.txz"; flake = false; }; - # command for later: - # echo '000007: 09' | xxd -r - target/x86_64-unknown-freebsd/debug/sparse-beacon }; outputs = { self, nixpkgs, flake-utils, crane, rust-overlay, advisory-db @@ -54,7 +52,7 @@ freebsd-libs-packed; }; inherit (system-libs) - bsd-toolchain winpcap-drivers freebsd-libs libnl libpcap-linux-gnu + freebsd-toolchain winpcap-drivers freebsd-libs libnl libpcap-linux-gnu libpcap-linux-musl libpcap-freebsd; buildTools = with pkgs; [ @@ -77,10 +75,13 @@ ]; devShellTools = with pkgs; [ + # Language servers rust-analyzer + zls + + # Cargo lint tools taplo cargo-deny - cargo-generate ]; craneLib = (crane.mkLib pkgs).overrideToolchain (p: @@ -111,6 +112,10 @@ inherit pkgs buildTools buildEnvironment craneLib advisory-db winpcap-libs; } // system-libs); + + setup-zig-freebsd = pkgs.writeScriptBin "setup-zig-freebsd" '' + cp ${outputs.packages.freebsd-zig-libc} $(${pkgs.git}/bin/git rev-parse --show-toplevel)/unix-loader/freebsd.txt + ''; in { packages = outputs.packages; checks = outputs.checks; @@ -119,7 +124,7 @@ default = craneLib.devShell (buildEnvironment // { name = "sparse-default"; - packages = buildTools ++ devShellTools; + packages = buildTools ++ devShellTools ++ [ setup-zig-freebsd ]; }); }; }); diff --git a/packages.nix b/packages.nix index 53a23f6..0b824dd 100644 --- a/packages.nix +++ b/packages.nix @@ -19,6 +19,15 @@ let }; patch-freebsd-elf = patch-elf 9; + freebsd-zig-libc = pkgs.writeText "freebsd-libc.txt" '' + include_dir=${freebsd-libs}/usr/include + sys_include_dir=${freebsd-libs}/usr/include + sys_include_dir=${freebsd-libs}/usr/lib + msvc_lib_dir= + kernel32_lib_dir= + gcc_dir= + ''; + src = craneLib.cleanCargoSource ./.; commonArgs = buildEnvironment // { @@ -45,6 +54,22 @@ let ]; }; + fileSetForInstallerCrate = pkgs.lib.fileset.toSource { + root = ./.; + fileset = pkgs.lib.fileset.unions [ + ./.cargo/config.toml + ./Cargo.toml + ./Cargo.lock + ./build_common.rs + (craneLib.fileset.commonCargoSources ./sparse-actions) + (craneLib.fileset.commonCargoSources ./pcap-sys) + (craneLib.fileset.commonCargoSources ./nl-sys) + ./nl-sys/src/bridge.c + (craneLib.fileset.commonCargoSources ./packets) + (craneLib.fileset.commonCargoSources ./sparse-installer) + ]; + }; + fileSetForWebCrate = pkgs.lib.fileset.toSource { root = ./.; fileset = pkgs.lib.fileset.unions [ @@ -97,7 +122,7 @@ let sparse-beacon-linux = craneLib.buildPackage (commonArgs // { cargoArtifacts = linuxCargoArtifacts; name = "sparse-beacon-linux"; - cargoExtraArgs = "-p sparse-beacon"; + cargoExtraArgs = "-p sparse-unix-beacon"; src = fileSetForBeaconCrate; CARGO_BUILD_TARGET = "x86_64-unknown-linux-musl"; @@ -107,7 +132,7 @@ let sparse-beacon-freebsd-sysv = craneLib.buildPackage (freebsdArgs // { cargoArtifacts = freebsdCargoArtifacts; name = "sparse-beacon-freebsd"; - cargoExtraArgs = "-p sparse-beacon"; + cargoExtraArgs = "-p sparse-unix-beacon"; nativeBuildInputs = buildTools; @@ -121,12 +146,81 @@ let sparse-beacon-windows = craneLib.buildPackage (windowsArgs // { cargoArtifacts = windowsCargoArtifacts; name = "sparse-beacon-windows"; - cargoExtraArgs = "-p sparse-beacon"; + cargoExtraArgs = "-p sparse-windows-beacon"; CARGO_BUILD_TARGET = "x86_64-pc-windows-gnu"; CARGO_BUILD_RUSTFLAGS = "-Ctarget-feature=+crt-static"; }); + linux-loader = pkgs.stdenv.mkDerivation { + name = "sparse-linux-loader"; + + buildInputs = with pkgs; [ zig ]; + + src = ./unix-loader; + + buildPhase = '' + zig build \ + -Dtarget=x86_64-linux-musl + ''; + + installPhase = '' + mkdir -p $out/lib + cp zig-out/lib/libunix-loader.so $out/lib/unix-loader.so + ''; + + SPARSE_BEACON = "${sparse-beacon-linux}/bin/sparse-beacon"; + }; + + freebsd-loader = pkgs.stdenv.mkDerivation { + name = "sparse-freebsd-loader"; + + buildInputs = with pkgs; [ zig ]; + + src = ./unix-loader; + + buildPhase = '' + zig build \ + -Dtarget=x86_64-freebsd \ + --sysroot ${freebsd-libs} \ + --libc ${freebsd-zig-libc} + ''; + + installPhase = '' + mkdir -p $out/lib + cp zig-out/lib/libunix-loader.so $out/lib/unix-loader.so + ''; + + SPARSE_BEACON = "${sparse-beacon-freebsd}/bin/sparse-beacon"; + }; + + sparse-installer-linux = craneLib.buildPackage (commonArgs // { + cargoArtifacts = linuxCargoArtifacts; + name = "sparse-installer-linux"; + cargoExtraArgs = "-p sparse-installer"; + src = fileSetForInstallerCrate; + + CARGO_BUILD_TARGET = "x86_64-unknown-linux-musl"; + CARGO_BUILD_RUSTFLAGS = "-Ctarget-feature=+crt-static"; + + SPARSE_INSTALLER_LINUX = "${linux-loader}/lib/unix-loader.so"; + }); + + sparse-installer-freebsd-sysv = craneLib.buildPackage (commonArgs // { + cargoArtifacts = linuxCargoArtifacts; + name = "sparse-installer-linux"; + cargoExtraArgs = "-p sparse-installer"; + src = fileSetForInstallerCrate; + + CARGO_BUILD_TARGET = "x86_64-unknown-linux-musl"; + CARGO_BUILD_RUSTFLAGS = "-Ctarget-feature=+crt-static"; + + SPARSE_INSTALLER_FREEBSD = "${freebsd-loader}/lib/unix-loader.so"; + }); + + sparse-installer-freebsd = + patch-freebsd-elf sparse-installer-freebsd-sysv "bin/sparse-installer"; + sparse-server = craneLib.buildPackage (commonArgs // { src = fileSetForWebCrate; @@ -145,15 +239,20 @@ let cp target/x86_64-unknown-linux-musl/release/sparse-server $out/bin ''; - SPARSE_BEACON_LINUX = "${sparse-beacon-linux}/bin/sparse-beacon"; + SPARSE_INSTALLER_LINUX = "${sparse-installer-linux}/bin/sparse-installer"; + SPARSE_INSTALLER_FREEBSD = + "${sparse-installer-freebsd}/bin/sparse-installer"; SPARSE_BEACON_WINDOWS = "${sparse-beacon-windows}/bin/sparse-beacon.exe"; - SPARSE_BEACON_FREEBSD = "${sparse-beacon-freebsd}/bin/sparse-beacon"; }); outputs = rec { packages = { - inherit sparse-beacon-linux sparse-beacon-windows sparse-beacon-freebsd - sparse-server; + inherit sparse-server sparse-beacon-linux sparse-beacon-windows + linux-loader freebsd-loader sparse-beacon-freebsd; + + inherit freebsd-zig-libc; + + default = sparse-server; }; checks = outputs.packages // { rs-fmt = craneLib.cargoFmt { inherit src; }; @@ -166,6 +265,16 @@ let cargoArtifacts = linuxCargoArtifacts; cargoClippyExtraArgs = "--all-targets -- --deny warnings"; }); + + zig-fmt = pkgs.stdenv.mkDerivation { + name = "zig-fmt-check"; + + src = ./.; + + checkPhase = '' + zig fmt --check + ''; + }; }; }; in outputs diff --git a/sparse-beacon/src/lib.rs b/sparse-beacon/src/lib.rs new file mode 100644 index 0000000..df5dac5 --- /dev/null +++ b/sparse-beacon/src/lib.rs @@ -0,0 +1 @@ +pub fn run_beacon_step() {} diff --git a/sparse-beacon/src/main.rs b/sparse-beacon/src/main.rs deleted file mode 100644 index 61f0af4..0000000 --- a/sparse-beacon/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - let interfaces = pcap_sys::PcapDevIterator::new().unwrap(); - for interface in interfaces { - println!("Found interface: {interface}"); - } -} diff --git a/sparse-unix-beacon/Cargo.toml b/sparse-unix-beacon/Cargo.toml new file mode 100644 index 0000000..dd306ea --- /dev/null +++ b/sparse-unix-beacon/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "sparse-unix-beacon" +edition = "2024" +version.workspace = true + +[dependencies] diff --git a/sparse-unix-beacon/src/main.rs b/sparse-unix-beacon/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/sparse-unix-beacon/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/sparse-windows-beacon/Cargo.toml b/sparse-windows-beacon/Cargo.toml new file mode 100644 index 0000000..06e48d7 --- /dev/null +++ b/sparse-windows-beacon/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "sparse-windows-beacon" +edition = "2024" +version.workspace = true + +[dependencies] diff --git a/sparse-windows-beacon/src/main.rs b/sparse-windows-beacon/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/sparse-windows-beacon/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/system-libs.nix b/system-libs.nix index f2b573a..2dcb86c 100644 --- a/system-libs.nix +++ b/system-libs.nix @@ -13,8 +13,8 @@ let ''; }; - bsd-toolchain = with pkgs.pkgsCross.x86_64-freebsd.buildPackages; - pkgs.writeText "bsd-toolchain.cmake" '' + freebsd-toolchain = with pkgs.pkgsCross.x86_64-freebsd.buildPackages; + pkgs.writeText "freebsd-toolchain.cmake" '' set(CMAKE_SYSTEM_NAME FreeBSD) set(CMAKE_C_COMPILER ${clang}/bin/x86_64-unknown-freebsd-clang) @@ -168,7 +168,7 @@ in { export CC=x86_64-unknown-freebsd-clang export CXX=x86_64-unknown-freebsd-clang++ cmake \ - -DCMAKE_TOOLCHAIN_FILE=${bsd-toolchain} \ + -DCMAKE_TOOLCHAIN_FILE=${freebsd-toolchain} \ -DCMAKE_BUILD_TYPE=MinSizeRel \ -DBUILD_SHARED_LIBS=OFF \ -DDISABLE_BLUETOOTH=ON \ diff --git a/unix-loader/build.zig b/unix-loader/build.zig new file mode 100644 index 0000000..615c072 --- /dev/null +++ b/unix-loader/build.zig @@ -0,0 +1,26 @@ +const std = @import("std"); + +pub fn build(b: *std.Build) !void { + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + const lib = b.addSharedLibrary(.{ + .name = "unix-loader", + .root_source_file = b.path("src/loader.zig"), + .target = target, + .optimize = optimize, + }); + + const exe = b.addExecutable(.{ + .name = "unix-loader", + .root_source_file = b.path("src/test_run.zig"), + .target = target, + .optimize = optimize, + }); + + lib.linkLibC(); + b.installArtifact(lib); + + exe.linkLibC(); + b.installArtifact(exe); +} diff --git a/unix-loader/build.zig.zon b/unix-loader/build.zig.zon new file mode 100644 index 0000000..aee5d38 --- /dev/null +++ b/unix-loader/build.zig.zon @@ -0,0 +1,13 @@ +.{ + .name = "linux-loader", + + .version = "2.0.0", + + .dependencies = .{}, + + .paths = .{ + "build.zig", + "build.zig.zon", + "src", + }, +} diff --git a/unix-loader/src/libloader.zig b/unix-loader/src/libloader.zig new file mode 100644 index 0000000..e69de29 diff --git a/unix-loader/src/loader.zig b/unix-loader/src/loader.zig new file mode 100644 index 0000000..ecfeade --- /dev/null +++ b/unix-loader/src/loader.zig @@ -0,0 +1,10 @@ +const std = @import("std"); +const testing = std.testing; + +export fn add(a: i32, b: i32) i32 { + return a + b; +} + +test "basic add functionality" { + try testing.expect(add(3, 7) == 10); +} diff --git a/unix-loader/src/test_run.zig b/unix-loader/src/test_run.zig new file mode 100644 index 0000000..42837a5 --- /dev/null +++ b/unix-loader/src/test_run.zig @@ -0,0 +1,25 @@ +const std = @import("std"); + +pub fn main() !void { + // Prints to stderr (it's a shortcut based on `std.io.getStdErr()`) + std.debug.print("All your {s} are belong to us.\n", .{"codebase"}); + + // stdout is for the actual output of your application, for example if you + // are implementing gzip, then only the compressed bytes should be sent to + // stdout, not any debugging messages. + const stdout_file = std.io.getStdOut().writer(); + var bw = std.io.bufferedWriter(stdout_file); + const stdout = bw.writer(); + + try stdout.print("Run `zig build test` to run the tests.\n", .{}); + + try bw.flush(); // don't forget to flush! +} + +test "simple test" { + var list = std.ArrayList(i32).init(std.testing.allocator); + defer list.deinit(); // try commenting this out and see if zig detects the memory leak! + + try list.append(42); + try std.testing.expectEqual(@as(i32, 42), list.pop()); +}