diff --git a/Cargo.toml b/Cargo.toml index ba42923..ef0347e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,9 @@ license = "GPL-3.0" description = 'A strongly typed "filesystem" for the age of connectivity.' repository = "https://github.com/c2vi/mize" +[package.metadata.wasm-pack.profile.dev] +wasm-opt = false + [lib] name = "mize" path = "src/lib.rs" @@ -17,6 +20,7 @@ path = "src/platform/os/main.rs" required-features = [ "os-target" ] [features] +default = [ "os-target" ] os-target = [ "clap", "home", "nix", "sysinfo", "ciborium/default", "tracing-subscriber", "async", "tracing-subscriber/env-filter", "libloading", "ciborium-io", "tracing-core" ] wasm-target = [ "wasm-bindgen", "console_error_panic_hook", "wasm-bindgen-cli" ] async = ["tokio/net", "tokio", "tokio/rt-multi-thread", "tokio/io-util"] diff --git a/deploy b/deploy index a0d0e22..98c988d 100755 --- a/deploy +++ b/deploy @@ -2,14 +2,14 @@ if [[ "$1" == "a" ]] then ssh acern mkdir -p /tmp/victorinix - rsync -rv --exclude="target" ./* acern:/tmp/victorinix/ + rsync -rv --exclude="target" --exclude="gitignore" ./* acern:/tmp/victorinix/ path=$(ssh acern nix build /tmp/victorinix#webfiles -L --print-out-paths) echo doneeeeeeeeeeeeeee echo path: $path #scp -r acern:$path/* ocih:host/webserver/webfiles - rsync -rv $path/* ocih:host/webserver/webfiles --rsync-path="sudo rsync" + rsync -rv $path/* ocih:host/webserver/webfiles --rsync-path="sudo rsync" else path=$(nix build .#webfiles -L -v --print-out-paths $@) diff --git a/flake.lock b/flake.lock index a83a79a..57992ea 100644 --- a/flake.lock +++ b/flake.lock @@ -1,17 +1,12 @@ { "nodes": { "crane": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, "locked": { - "lastModified": 1715274763, - "narHash": "sha256-3Iv1PGHJn9sV3HO4FlOVaaztOxa9uGLfOmUWrH7v7+A=", + "lastModified": 1725125250, + "narHash": "sha256-CB20rDD5eHikF6mMTTJdwPP1qvyoiyyw1RDUzwIaIF8=", "owner": "ipetkov", "repo": "crane", - "rev": "27025ab71bdca30e7ed0a16c88fd74c5970fc7f5", + "rev": "96fd12c7100e9e05fa1a0a5bd108525600ce282f", "type": "github" }, "original": { @@ -62,14 +57,18 @@ "mize_modules": { "flake": false, "locked": { - "lastModified": 1725174598, - "narHash": "sha256-jB5YUArfAiwYwZ7qLwWMHCAY4DMWmLp7F3hzEG5mezk=", - "path": "/home/me/work/modules", - "type": "path" + "dirtyRev": "fa3b462cbe3e63fc9ecada6c4445d366e58a6f86-dirty", + "dirtyShortRev": "fa3b462-dirty", + "lastModified": 1725362504, + "narHash": "sha256-uL7SRKxrCpS/9sXVOdClijqdxXNLIuiHZ54YYZck42E=", + "submodules": true, + "type": "git", + "url": "file:///home/me/work/modules" }, "original": { - "path": "/home/me/work/modules", - "type": "path" + "submodules": true, + "type": "git", + "url": "file:///home/me/work/modules" } }, "nixpkgs": { diff --git a/flake.nix b/flake.nix index 85025f0..a9097d8 100644 --- a/flake.nix +++ b/flake.nix @@ -10,7 +10,6 @@ crane = { url = "github:ipetkov/crane"; - inputs.nixpkgs.follows = "nixpkgs"; }; rust-overlay = { @@ -19,7 +18,8 @@ }; mize_modules = { - url = "github:c2vi/mize-modules"; + #url = "github:c2vi/mize-modules"; + url = "git+file:///home/me/work/modules?submodules=1"; flake = false; }; @@ -34,9 +34,22 @@ let fenix.packages.${system}.targets.wasm32-unknown-unknown.latest.toolchain fenix.packages.${system}.latest.toolchain ]; + wasmCrane = (crane.mkLib pkgs).overrideToolchain wasmToolchain; + osToolchain = fenix.packages.${system}.latest.toolchain; - wasmCrane = crane.lib.${system}.overrideToolchain wasmToolchain; - osCrane = crane.lib.${system}.overrideToolchain osToolchain; + osCrane = (crane.mkLib pkgs).overrideToolchain osToolchain; + + #winToolchain = fenix.packages.${system}.combine [ + #fenix.packages.${system}.targets.x86_64-pc-windows-gnu.latest.toolchain + #fenix.packages.${system}.latest.toolchain + #]; + winToolchain = with fenix.packages.${system}; + combine [ + minimal.rustc + minimal.cargo + targets.x86_64-pc-windows-gnu.latest.rust-std + ]; + winCrane = (crane.mkLib pkgs).overrideToolchain winToolchain; wasmArtifacts = wasmCrane.buildDepsOnly ({ src = self; @@ -51,21 +64,55 @@ let }; }; + #systems = [ "aarch64-linux" "x86_64-linux" "x86_64-pc-windows-gnu" "wasm32-unknown-none-unknown" "x86_64-apple-darwin" "aarch64-apple-darwin" ]; + systems = [ "aarch64-unknown-linux-gnu" "x86_64-unknown-linux-gnu" "x86_64-pc-windows-gnu" "wasm32-unknown-none-unknown" ]; + mizeLib = import ./lib.nix { - inherit inputs nixpkgs self osCrane defaultMizeConfig mize_modules; - inherit rust-overlay crane; + inherit inputs nixpkgs pkgs self osCrane defaultMizeConfig mize_modules; + inherit rust-overlay crane fenix; localSystem = system; }; in { ############################## PACKAGES ############################## - packages = { + packages = rec { - osCrane = osCrane; + inherit osCrane; + #test = mizeLib.buildMizeForSystem "wasm32-unknown-none-unknown"; + test = mizeLib.buildMizeForSystem "aarch64-linux"; + #test = mizeLib.buildMizeForSystem "x86_64-pc-windows-gnu"; + + mizeFor = let + mizes = map mizeLib.buildMizeForSystem systems; + in builtins.listToAttrs ( map ( mize: { name = mize.system.name; value = mize; } ) mizes ); + + #pkgsCross = import nixpkgs { localSystem = system; crossSystem = { config = "x86_64-pc-windows-gnu"; }; overlays = [ rust-overlay.overlays.default ]; }; + + pkgsTest = pkgs; + + #pkgsCross = import nixpkgs { localSystem = system; crossSystem = { config = "x86_64-w64-windows-mingw"; }; overlays = [ rust-overlay.overlays.default ]; }; + pkgsCross = import nixpkgs { localSystem = system; crossSystem = { config = "x86_64-unknown-linux-gnu"; }; overlays = [ rust-overlay.overlays.default ]; }; + craneLib = (crane.mkLib pkgsCross).overrideToolchain (p: p.rust-bin.stable.latest.default); + + + one = craneLib.buildPackage { + src = "${self}"; + #cargoExtraArgs = "--bin mize --features os-target"; + cargoExtraArgs = "--bin mize"; + doCheck = false; # tests does not work in wasm + CARGO_BUILD_TARGET = "x86_64-pc-windows-gnu"; + MIZE_BUILD_CONFIG = pkgs.writeTextFile { + name = "mize-build-config"; + text = builtins.toJSON (defaultMizeConfig // { + mize_version = one.version; + }); + }; + }; webfiles = pkgs.callPackage ./webfiles.nix { inherit (mizeLib) buildMizeForSystem mkInstallPhase; + inherit systems; }; default = osCrane.buildPackage { @@ -76,6 +123,7 @@ in { wasm = wasmCrane.buildPackage { src = "${self}"; CARGO_BUILD_TARGET = "wasm32-unknown-unknown"; + cargoExtraArgs = "--bin mize --features wasm-target"; doCheck = false; }; @@ -105,37 +153,94 @@ in { }; ############################## DEV SHELLS ############################## - devShells.default = pkgs.mkShell { - buildInputs = with pkgs; [ - wasm-pack #pkg-config openssl #cargo rustc - cargo-generate - /* - (fenix.packages.${system}.complete.withComponents [ - "cargo" - "clippy" - "rust-src" - "rustc" - "rustfmt" - ]) - */ - (fenix.packages.${system}.combine [ wasmToolchain osToolchain ]) - lldb gdb - ]; + devShells = { - MIZE_BUILD_CONFIG = pkgs.writeTextFile { - name = "vic-build-config"; - text = builtins.toJSON defaultMizeConfig; + one = pkgs.stdenv.mkDerivation { + name = "hiiiiiiii"; + nativeBuildInputs = [ + (fenix.packages.${system}.combine [ wasmToolchain osToolchain winToolchain ]) + ]; + buildInputs = [ + pkgs.pkgsCross.mingwW64.stdenv.cc.cc + pkgs.pkgsCross.mingwW64.windows.pthreads + (fenix.packages.${system}.combine [ wasmToolchain osToolchain winToolchain ]) + ]; + LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath [ + pkgs.pkgsCross.mingwW64.windows.pthreads + ]; + + RUSTFLAGS="-L ${pkgs.pkgsCross.mingwW64.windows.pthreads}/lib"; + CARGO_BUILD_TARGET = "x86_64-pc-windows-gnu"; + + + #fixes issues related to openssl + OPENSSL_DIR = "${pkgs.openssl.dev}"; + OPENSSL_LIB_DIR = "${pkgs.openssl.out}/lib"; + OPENSSL_INCLUDE_DIR = "${pkgs.openssl.dev}/include/"; + + depsBuildBuild = with pkgs; [ + pkgsCross.mingwW64.stdenv.cc + pkgsCross.mingwW64.windows.pthreads + ]; }; - shellHook = '' - export MIZE_CONFIG_FILE=${self}/test-config.toml - ''; + win = winCrane.buildPackage { + #src = winCrane.cleanCargoSource ./testing; + #pname = "testing"; + src = ./testing; + + strictDeps = true; + doCheck = false; + + CARGO_BUILD_TARGET = "x86_64-pc-windows-gnu"; + + # fixes issues related to libring + TARGET_CC = "${pkgs.pkgsCross.mingwW64.stdenv.cc}/bin/${pkgs.pkgsCross.mingwW64.stdenv.cc.targetPrefix}cc"; + + #fixes issues related to openssl + OPENSSL_DIR = "${pkgs.openssl.dev}"; + OPENSSL_LIB_DIR = "${pkgs.openssl.out}/lib"; + OPENSSL_INCLUDE_DIR = "${pkgs.openssl.dev}/include/"; + + depsBuildBuild = with pkgs; [ + pkgsCross.mingwW64.stdenv.cc + pkgsCross.mingwW64.windows.pthreads + ]; + shellHook = '' + export MIZE_CONFIG_FILE=${self}/test-config.toml + ''; + MIZE_BUILD_CONFIG = pkgs.writeTextFile { + name = "vic-build-config"; + text = builtins.toJSON defaultMizeConfig; + }; + }; + + + default = pkgs.mkShell { + buildInputs = with pkgs; [ + + wasm-pack #pkg-config openssl #cargo rustc + cargo-generate + (fenix.packages.${system}.combine [ wasmToolchain osToolchain ]) + lldb gdb + ]; + + MIZE_BUILD_CONFIG = pkgs.writeTextFile { + name = "vic-build-config"; + text = builtins.toJSON defaultMizeConfig; + }; + + shellHook = '' + export MIZE_CONFIG_FILE=${self}/test-config.toml + ''; + }; }; }) // { ############################## SOME GLOBAL OUTPUTS ############################## inherit inputs self; + rustPkgs = import nixpkgs { overlays = [rust-overlay.overlays.default]; system = "x86_64-linux"; }; }; } diff --git a/lib.nix b/lib.nix index bf6251c..9f9d536 100644 --- a/lib.nix +++ b/lib.nix @@ -1,5 +1,4 @@ -{ stdenv -, pkgs +{ pkgs , osCrane , self , defaultMizeConfig @@ -8,11 +7,14 @@ , nixpkgs , rust-overlay , crane +, fenix , ... }: rec { - # get a list of all modules, that have a mize_module.nix in their folder - module_list_drv = pkgs.stdenv.mkDerivation { + + # get a list of all modules + # aka folders with a mize_module.nix in them + module_list_drv = path: pkgs.stdenv.mkDerivation { name = "mize_module_list"; dontUnpack = true; configurePhase = ""; @@ -20,112 +22,263 @@ rec { mkdir -p $out touch $out/modules_to_build - for d in ${mize_modules}/modules/*; do - [[ -f $d/mize_module.nix ]] && echo "$d/mize_module.nix" >> $out/modules_to_build + for d in ${path}/modules/*; do + [[ -f $d/mize_module.nix ]] && (echo "$d/mize_module.nix" >> $out/modules_to_build; echo found module $d/mize_module.nix) done exit 0 ''; }; - module_list_string = builtins.readFile "${module_list_drv}/modules_to_build"; - module_list = pkgs.lib.lists.remove "" (pkgs.lib.strings.splitString "\n" module_list_string); + findModules = path: let + module_list_string = builtins.readFile "${module_list_drv path}/modules_to_build"; + module_list = pkgs.lib.lists.remove "" (pkgs.lib.strings.splitString "\n" module_list_string); + in module_list; - - toolchain_version_drv = pkgs.stdenv.mkDerivation { - name = "toolchain_version_drv"; - dontUnpack = true; - configurePhase = ""; - buildPhase = '' - mkdir -p $out - touch $out/rustc-version - - ${osCrane.rustc}/bin/rustc --version > $out/rustc-version - - exit 0 - ''; - }; - toolchain_version_string = pkgs.lib.strings.removeSuffix "\n" (builtins.readFile "${toolchain_version_drv}/rustc-version"); + findModulesNix = path: let + dirs = builtins.readDir path; + filtered_dirs = map (dir: builtins.trace "dir: ${dir}" (dir)); + module_list = filtered_dirs; + in module_list; - - buildMizeForSystem = system: let - crossSystem = (if builtins.isString system then pkgs.lib.systems.mkSystemFrommString system else system) - // { - name = if crossSystem.vendor == "unknown" + getCrossSystem = system: let + crossSystem = (if builtins.isString system then (pkgs.lib.systems.parse.mkSystemFromString system) else system) + // rec { + name = if crossSystem.vendor != "unknown" then "${crossSystem.cpu.name}-${crossSystem.kernel.name}-${crossSystem.abi.name}" else "${crossSystem.cpu.name}-${crossSystem.vendor.name}-${crossSystem.kernel.name}-${crossSystem.abi.name}"; nameFull = "${crossSystem.cpu.name}-${crossSystem.vendor.name}-${crossSystem.kernel.name}-${crossSystem.abi.name}"; + config = nameFull; }; - pkgsCross = import nixpkgs { inherit crossSystem localSystem; overlays = [ rust-overlay ]; }; + in crossSystem; - craneLib = (crane.mkLib pkgsCross).overrideToolchain (p: p.rust-bin.stable.latest.default); + + buildMizeForSystem = system: let + crossSystem = getCrossSystem system; + + pkgsCross = import nixpkgs { inherit localSystem crossSystem; overlays = [ rust-overlay.overlays.default ]; }; + + pkgsNative = import nixpkgs { inherit localSystem; overlays = [ rust-overlay.overlays.default ]; }; + + craneLib = + if crossSystem.kernel.name == "windows" + then + (crane.mkLib pkgs).overrideToolchain (fenix.packages.${localSystem}.combine [ + fenix.packages.${localSystem}.minimal.rustc + fenix.packages.${localSystem}.minimal.cargo + fenix.packages.${localSystem}.targets."${crossSystem.cpu.name}-pc-windows-gnu".latest.rust-std + ]) + + else if crossSystem.cpu.name == "wasm32" + then + (crane.mkLib pkgs).overrideToolchain (fenix.packages.${localSystem}.combine [ + fenix.packages.${localSystem}.targets.wasm32-unknown-unknown.latest.toolchain + fenix.packages.${localSystem}.latest.toolchain + ]) + else if crossSystem.name == "x86_64-linux-gnu" + then + builtins.trace "x86_64-linux-gnu hackfix...." + (crane.mkLib pkgs).overrideToolchain (fenix.packages.${localSystem}.combine [ + fenix.packages.${localSystem}.latest.toolchain + ]) + + else + (crane.mkLib pkgsCross).overrideToolchain (p: p.rust-bin.stable.latest.default) + ; mkSelString = attrs: builtins.toJSON (attrs // { - toolchain_version = toolchain_version_string; - mize_version = main.version; + inherit toolchain_version; + system = crossSystem.nameFull; + mize_version = main-default.version; }); - mkMizeModule = attrs: { - a = builtins.error "todo!()"; - }; + toolchain_version_drv = pkgs.stdenv.mkDerivation { + name = "toolchain_version_drv"; + dontUnpack = true; + configurePhase = ""; + buildPhase = '' + mkdir -p $out + touch $out/rustc-version - mkMizeRustModule = attrs: craneLib.buildPackage attrs // { - cargoExtraArgs = "--target ${crossSystem.nameFull} " + attrs.cargoExtraArgs or ""; - "CARGO_TARGET_${pkgsCross.lib.strings.toUpper crossSystem.nameFull}_LINKER" = "${pkgsCross.stdenv.cc.targetPrefix}cc"; - HOST_CC = "${pkgsCross.stdenv.cc.nativePrefix}cc"; - TARGET_CC = "${pkgsCross.stdenv.cc.targetPrefix}cc"; - }; + echo hiiiiiiiiiiiiiiiiiiiiiiii + echo 'rustc 1.80.1 (3f5fd8dd4 2024-08-06)' > $out/rustc-version + ${craneLib.cargo}/bin/rustc --version > $out/rustc-version - buildModule = path: (pkgsCross.callPackage path { - inherit mkSelString craneLib; - inherit mkMizeModule mkMizeRustModule; - toolchain_version = toolchain_version_string; - mize_version = main.version; - }); - - main = craneLib.buildPackage { - src = "${self}"; - cargoExtraArgs = "--bin mize --features os-target"; - - MIZE_BUILD_CONFIG = pkgs.writeTextFile { - name = "mize-build-config"; - text = builtins.toJSON (defaultMizeConfig // { - toolchain_version = toolchain_version_string; - mize_version = main.version; - }); - }; - # patch the interpreter to run on most linux-gnu distros - postBuild = '' - patchelf --set-interpreter /lib64/ld-linux-x86-64.so.2 /build/source/target/release/mize + exit 0 ''; }; + toolchain_version = pkgs.lib.strings.removeSuffix "\n" (builtins.readFile "${toolchain_version_drv}/rustc-version"); + + mkMizeModule = attrs: pkgsCross.stdenv.mkDerivation (attrs // { + selector_string = mkSelString attrs.select; + }); + + mkMizeRustModule = attrs: craneLib.buildPackage (attrs // { + MIZE_BUILD_CONFIG = mizeBildConfig; + selector_string = mkSelString (attrs.select or {} // { + }); + } + + # linux specific stuff + // (if crossSystem.kernel.name == "linux" then { + "CARGO_TARGET_${builtins.replaceStrings ["-"] ["_"] (pkgsCross.lib.strings.toUpper crossSystem.nameFull)}_LINKER" = "${pkgsCross.stdenv.cc.targetPrefix}cc"; + HOST_CC = "${pkgsCross.stdenv.cc.nativePrefix}cc"; + TARGET_CC = "${pkgsCross.stdenv.cc.targetPrefix}cc"; + CARGO_BUILD_TARGET = crossSystem.nameFull; + nativeBuildInputs = attrs.nativeBuildInputs or [] ++ [ + pkgsCross.stdenv.cc + ]; + } else {}) + + # add wasm stuff + // (if crossSystem.cpu.name == "wasm32" then { + CARGO_BUILD_TARGET = "wasm32-unknown-unknown"; + + # checks fail on wasm + doCheck = false; + } else {}) + + # add windows stuff + // (if crossSystem.kernel.name == "windows" then { + strictDeps = true; + doCheck = false; + + CARGO_BUILD_TARGET = "${crossSystem.cpu.name}-pc-windows-gnu"; + + # fixes issues related to libring + TARGET_CC = "${pkgs.pkgsCross.mingwW64.stdenv.cc}/bin/${pkgs.pkgsCross.mingwW64.stdenv.cc.targetPrefix}cc"; + + #fixes issues related to openssl + OPENSSL_DIR = "${pkgs.openssl.dev}"; + OPENSSL_LIB_DIR = "${pkgs.openssl.out}/lib"; + OPENSSL_INCLUDE_DIR = "${pkgs.openssl.dev}/include/"; + + depsBuildBuild = [ + pkgs.pkgsCross.mingwW64.stdenv.cc + pkgs.pkgsCross.mingwW64.windows.pthreads + ]; + } else {}) + ); + + buildModule = path: extraArgs: (pkgs.callPackage path { + inherit mkSelString craneLib toolchain_version; + inherit mkMizeModule mkMizeRustModule buildModule findModules crossSystem pkgsCross pkgsNative; + mize_version = main-default.version; + } // extraArgs ); + + mizeBildConfig = pkgs.writeTextFile { + name = "mize-build-config"; + text = builtins.toJSON (defaultMizeConfig // { + inherit toolchain_version; + mize_version = main-default.version; + }); + }; + + main-default = craneLib.buildPackage ({ + src = "${self}"; + cargoExtraArgs = "--bin mize --features os-target"; + strictDeps = true; + + MIZE_BUILD_CONFIG = mizeBildConfig; + + # patch the interpreter to run on most linux-gnu distros + postBuild = + if crossSystem.cpu.name == "x86_64" + then "patchelf --set-interpreter /lib64/ld-linux-x86-64.so.2 /build/source/target/release/mize" + else if crossSystem.cpu.name == "aarch64" + then "patchelf --set-interpreter /lib64/ld-linux-aarch64.so.2 /build/source/target/${crossSystem.nameFull}/release/mize" + else "" + ; + + } + // (if crossSystem.name == "x86_64-linux-gnu" then builtins.trace "another x86_64-linux hackfix..." {} else { + CARGO_BUILD_TARGET = crossSystem.nameFull; + "CARGO_TARGET_${builtins.replaceStrings ["-"] ["_"] (pkgsCross.lib.strings.toUpper crossSystem.nameFull)}_LINKER" = "${pkgsCross.stdenv.cc.targetPrefix}cc"; + HOST_CC = "${pkgsCross.stdenv.cc.nativePrefix}cc"; + TARGET_CC = "${pkgsCross.stdenv.cc.targetPrefix}cc"; + }) + ); + + main-win = craneLib.buildPackage { + src = craneLib.cleanCargoSource ./.; + + strictDeps = true; + doCheck = false; + + cargoExtraArgs = "--bin mize --features os-target"; + + CARGO_BUILD_TARGET = "${crossSystem.cpu.name}-pc-windows-gnu"; + + MIZE_BUILD_CONFIG = mizeBildConfig; + + # fixes issues related to libring + TARGET_CC = "${pkgs.pkgsCross.mingwW64.stdenv.cc}/bin/${pkgs.pkgsCross.mingwW64.stdenv.cc.targetPrefix}cc"; + + #fixes issues related to openssl + OPENSSL_DIR = "${pkgs.openssl.dev}"; + OPENSSL_LIB_DIR = "${pkgs.openssl.out}/lib"; + OPENSSL_INCLUDE_DIR = "${pkgs.openssl.dev}/include/"; + + depsBuildBuild = [ + pkgs.pkgsCross.mingwW64.stdenv.cc + pkgs.pkgsCross.mingwW64.windows.pthreads + ]; + }; + + main-wasm = craneLib.buildPackage { + src = "${self}"; + CARGO_BUILD_TARGET = "wasm32-unknown-unknown"; + doCheck = false; + cargoExtraArgs = "--features wasm-target"; + MIZE_BUILD_CONFIG = mizeBildConfig; + }; + in rec { - inherit main; + inherit toolchain_version_drv pkgsCross craneLib; + main = + if crossSystem.kernel.name == "windows" + then main-win + else if crossSystem.cpu.name == "wasm32" + then main-wasm + else main-default + ; system = crossSystem; - modules = pkgs.lib.lists.flatten (map buildModule module_list); - }; + modulesListDrv = module_list_drv mize_modules; + modulesFileList = pkgs.lib.lists.flatten (findModules mize_modules); + modulesList = map (mod: (buildModule mod {})) modulesFileList; + modules = builtins.listToAttrs ( map ( mod: { name = mod.modName; value = mod; } ) modulesList ); + }; mkInstallPhase = mize: '' # install mize mkdir -p $out/mize/${mize.system.name} - cp ${mize.main}/bin/mize $out/mize/${mize.system.name}/ + + ${ + if mize.system.kernel.name == "windows" + then "cp ${mize.main}/bin/mize.exe $out/mize/${mize.system.name}/" + else if mize.system.cpu.name == "wasm32" + then "cp ${mize.main}/lib/mize.wasm $out/mize/${mize.system.name}/" + else "cp ${mize.main}/bin/mize $out/mize/${mize.system.name}/" + } # intall the modules - ${mkModulesInstallPhase mize.modules} + ${mkModulesInstallPhase mize.modulesList} ''; - mkModulesInstallPhase = modules: pkgs.lib.concatStringsSep "\n" (map (module: '' + mkModulesInstallPhase = modules: pkgs.lib.concatStringsSep "\n" (map mkModuleInstallPhase modules); + + mkModuleInstallPhase = module: '' echo got module: ${module.name} hash=$(echo ${module.selector_string} | sha256sum | cut -c -32) mkdir -p $out/mize/dist/$hash cp -r ${module}/* $out/mize/dist/$hash - echo '${module.selector_string}' > $out/mize/dist/$hash/selector_string - '')) modules; + echo '${module.selector_string}' > $out/mize/dist/$hash/selector + ''; } diff --git a/src/core/instance/mod.rs b/src/core/instance/mod.rs index 55ed609..7cd637b 100644 --- a/src/core/instance/mod.rs +++ b/src/core/instance/mod.rs @@ -64,8 +64,8 @@ pub struct Instance { // TODO: set to a random uuid pub self_namespace: Arc>, pub op_tx: channel::Sender, - context: Vec, - threads: Vec, + threads: Arc>>, + next_thread_id: Arc>, give_msg_wait: Arc>>>>, create_msg_wait: Arc>>>, update_thread_busy: Arc>, @@ -100,8 +100,8 @@ impl Instance { namespace, self_namespace, op_tx, namespace_pool: Arc::new(Mutex::new(namespace_pool_raw)), modules: Arc::new(Mutex::new(HashMap::new())), - context: vec![], - threads: vec![], + threads: Arc::new(Mutex::new(Vec::new())), + next_thread_id: Arc::new(Mutex::new(0)), next_con_id: Arc::new(Mutex::new(1)), give_msg_wait, create_msg_wait, update_thread_busy: Arc::new(Mutex::new(false)), @@ -151,16 +151,15 @@ impl Instance { crate::platform::any::instance_init(self); // end of platform specific init code - self.load_module("Blob")?; - let mut modules_inner = self.modules.lock()?; - let module = modules_inner.get_mut("Blob").unwrap(); + self.load_module("String")?; - println!("right before segfault"); - module.init(&self); + //let mut modules_inner = self.modules.lock()?; + //let module = modules_inner.get_mut("String").unwrap(); + //println!("right before segfault"); + //module.init(&self); - //self.load_module("String")?; debug!("INSTANCE INIT DONE"); Ok(()) @@ -398,8 +397,33 @@ impl Instance { } pub fn spawn(&mut self, name: &str, func: impl FnOnce() -> MizeResult<()> + Send + 'static) -> MizeResult<()> { - self.threads.push(name.to_owned()); - thread::spawn(move || func()); + let threads_inner = self.threads.lock()?; + let mut next_thread_id = self.next_thread_id.lock()?; + + threads_inner.push((next_thread_id, name.to_owned())); + + let to_spawn = move || { + debug!("spawning thread: {}", name); + let my_thread_id = next_thread_id; + + func()?; + + let mut threads_inner = self.threads.lock()?; + threads_inner = threads_inner.into_iter().filter(|el| match el { + (my_thread_id, _) => false, + (_, _) => true, + }); + debug!("thread '{}' stopped", name); + }; + + *next_thread_id += 1; + + #[cfg(feature = "os-target")] + thread::spawn(move || to_spawn()); + + #[cfg(feature = "wasm-target")] + crate::platform::wasm::wasm_spawn(move || to_spawn())?; + Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index e35b16f..8d6fc3d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,11 @@ #![ allow( warnings ) ] +#[no_mangle] +pub fn main() { + println!("hello from main fn"); +} + static PROTO_VERSION: u8 = 1; // the core part has the code that can run on any platform @@ -43,6 +48,9 @@ pub mod platform { #[cfg(feature = "os-target")] pub use super::os::load_module; + #[cfg(feature = "wasm-target")] + pub use super::super::load_module; + #[cfg(not(any(feature = "os-target", feature = "wasm-target")))] pub use super::super::load_module; diff --git a/src/platform/wasm/mod.rs b/src/platform/wasm/mod.rs index 6310cfe..e7707d2 100644 --- a/src/platform/wasm/mod.rs +++ b/src/platform/wasm/mod.rs @@ -1,9 +1,25 @@ -mod utils; - use wasm_bindgen::prelude::*; +use std::ptr::NonNull; +use std::panic; -use crate::instance::Instance; +use crate::instance::{self, Instance}; use crate::error::MizeResult; +use crate::Module; + + +// console_log macro +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(js_namespace = console)] + fn log(s: &str); +} +macro_rules! console_log { + // Note that this is using the `log` function imported above during + // `bare_bones` + ($($t:tt)*) => (log(&format_args!($($t)*).to_string())) +} +//end of console_log macro + // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global // allocator. @@ -11,19 +27,71 @@ use crate::error::MizeResult; #[global_allocator] static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; -#[wasm_bindgen] -extern { - fn alert(s: &str); + +// A function imitating `std::thread::spawn`. +// thanks to: https://www.tweag.io/blog/2022-11-24-wasm-threads-and-messages/ +pub fn wasm_spawn(f: impl FnOnce() + Send + 'static) -> MizeResult<()> { + let worker = web_sys::Worker::new("./worker.js")?; + // Double-boxing because `dyn FnOnce` is unsized and so `Box` is a fat pointer. + // But `Box>` is just a plain pointer, and since wasm has 32-bit pointers, + // we can cast it to a `u32` and back. + let ptr = Box::into_raw(Box::new(Box::new(f) as Box)); + let msg = js_sys::Array::new(); + // Send the worker a reference to our memory chunk, so it can initialize a wasm module + // using the same memory. + msg.push(&wasm_bindgen::memory()); + // Also send the worker the address of the closure we want to execute. + msg.push(&JsValue::from(ptr as u32)); + worker.post_message(&msg); + + Ok(()) } #[wasm_bindgen] -pub fn greet() { - alert("Hello, wasm-game-of-life!"); +// This function is here for `worker.js` to call. +pub fn worker_entry_point(addr: u32) { + // Interpret the address we were given as a pointer to a closure to call. + let closure = unsafe { Box::from_raw(ptr as *mut Box) }; + (*closure)(); } + pub fn wasm_instance_init(instance: &mut Instance) -> MizeResult<()> { - println!("Hello world from wasm_instance_init!!!!!!!!!!"); - alert("Hello world from wasm_instance_init!!!!!!!!!!"); + console_log!("Hello world from wasm_instance_init!!!!!!!!!!"); Ok(()) } + +#[wasm_bindgen] +pub struct JsInstance { + inner: NonNull, +} + +/* +#[wasm_bindgen] +pub struct JsModule { + inner: NonNull>, + //inner: *mut Mme, +} +*/ + +#[wasm_bindgen] +impl JsInstance { + #[wasm_bindgen(constructor)] + pub fn new() -> JsInstance { + panic::set_hook(Box::new(console_error_panic_hook::hook)); + + let instance = match Instance::new() { + Ok(val) => val, + Err(e) => { + console_log!("Instance::new() failed with: {:?}", e); + panic!() + }, + }; + let mut js_instance = JsInstance { inner: NonNull::from(Box::leak(Box::new(instance))) }; + return js_instance; + } + + //#[wasm_bindgen] + +} diff --git a/webfiles.nix b/webfiles.nix index b5050a1..967295e 100644 --- a/webfiles.nix +++ b/webfiles.nix @@ -2,11 +2,13 @@ , pkgs , mkInstallPhase , buildMizeForSystem +, systems , ... }: let # list of systems, we build mize for for webfiles - systems = [ "x86_64-linux" "aarch64-linux" "wasm32" ]; + #systems = [ "x86_64-linux" "aarch64-linux" "wasm32" ]; + #systems = [ "x86_64-linux" "aarch64-linux" ]; list_of_mizes = map buildMizeForSystem systems; @@ -18,9 +20,10 @@ stdenv.mkDerivation { # so that /bin/sh does not get patched to a nix store path in victorinix-s dontPatchShebangs = true; - buildPhase = ""; + buildPhase = '' + ''; - InstallPhase = '' + installPhase = '' mkdir -p $out mkdir -p $out/mize mkdir -p $out/mize/dist