diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7c696bbdc..7190f9786 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -58,3 +58,9 @@ jobs: - name: (x86) Miso sample app jsaddle (GHC 8.6.5) run: nix-build -A sample-app + + - name: (x86) Example.hs (MicroHS 0.12.4.0) + run: cd micro/ && nix-shell --run 'mhs -temscripten Example -oout.js && qjs out.js' + + - name: (JS) Example.hs (MicroHS 0.12.4.0) + run: cd micro/ && nix-shell --run 'mhs -r Example' diff --git a/default.nix b/default.nix index 29ab63ead..b43bceb19 100644 --- a/default.nix +++ b/default.nix @@ -81,4 +81,10 @@ with pkgs.haskell.lib; ''; }; + # MicroHs-Miso + inherit (pkgs) + microhs + microhs-env + microhs-wrapper; + } diff --git a/flake.nix b/flake.nix index aa46995f2..96a130f19 100644 --- a/flake.nix +++ b/flake.nix @@ -86,6 +86,37 @@ ]; }); + # MicroHS shell + microhs = + pkgs.mkShell { + name = "The micro miso ${system} shell"; + buildInputs = with pkgs; + [ pkgs.microhs nodejs quickjs emscripten + ]; + + # https://github.com/NixOS/nixpkgs/issues/139943#issuecomment-930432045 + # dmj: Fix for using emcc in Darwin shell environment + # + # dmj: to compile /only/ JS, and work w/ QuickJS: + # $ emcc -sENVIRONMENT=shell -sWASM=0 main.c -oout.js && qjs out.js + shellHook = + # with inputs.ghc-wasm-meta.packages.${system}.all_9_12; + '' + export MHSDIR=${pkgs.microhs} + export CC=${pkgs.emscripten}/bin/emcc + export PATH=$PATH:${pkgs.microhs}/bin + mkdir -p ~/.emscripten_cache + chmod u+rwX -R ~/.emscripten_cache + # cp -r ${pkgs.emscripten}/share/emscripten/cache ~/.emscripten_cache + export EM_CACHE=~/.emscripten_cache + + function build () { + mhs -temscripten Example -oout.js && qjs out.js + } + + ''; + }; + # Shell for JavaScript / TypeScript development typescript = pkgs.mkShell { diff --git a/micro/Example.hs b/micro/Example.hs new file mode 100644 index 000000000..aec85687a --- /dev/null +++ b/micro/Example.hs @@ -0,0 +1,11 @@ +module Example(fac, main) where + +fac :: Int -> Int +fac 0 = 1 +fac n = n * fac(n - 1) + +main :: IO () +main = do + let rs = map fac [1,2,3,10] + putStrLn "Some factorials" + print rs diff --git a/micro/miso.cabal b/micro/miso.cabal new file mode 100644 index 000000000..ec8779f05 --- /dev/null +++ b/micro/miso.cabal @@ -0,0 +1,81 @@ +cabal-version: 3.0 +name: miso +version: 1.9.0.0 +synopsis: A tasty Haskell front-end framework +homepage: https://haskell-miso.org +license: BSD-3-Clause +license-file: LICENSE +author: dmjio +maintainer: code@dmj.io +copyright: Copyright (c) 2016-2025 @dmjio +category: Web +build-type: Simple +extra-doc-files: CHANGELOG.md + +library + default-language: + Haskell2010 + other-modules: + Miso.Concurrent + Miso.Delegate + Miso.Diff + Miso.Effect + Miso.Event + Miso.Event.Decoder + Miso.Event.Types + Miso.Exception + Miso.FFI + Miso.FFI.History + Miso.FFI.SSE + Miso.FFI.Storage + Miso.FFI.WebSocket + Miso.FFI.Internal + Miso.Html + Miso.Html.Element + Miso.Html.Event + Miso.Html.Property + Miso.Html.Types + Miso.Internal + Miso.Mathml + Miso.Mathml.Element + Miso.Render + Miso.Router + Miso.Run + Miso.Storage + Miso.Subscription + Miso.Subscription.History + Miso.Subscription.Keyboard + Miso.Subscription.Mouse + Miso.Subscription.WebSocket + Miso.Subscription.Window + Miso.Subscription.SSE + Miso.Svg.Attribute + Miso.Svg.Element + Miso.Svg.Event + Miso.Types + Miso.Util + Miso.WebSocket + exposed-modules: + Miso + Miso.Lens + Miso.Svg + Miso.String + ghc-options: + -Wall + hs-source-dirs: + ../src, ../text-src + build-depends: + aeson < 2.3, + base < 5, + bytestring < 0.13, + containers < 0.9, + http-api-data < 0.9, + http-media < 0.9, + http-types < 0.13, + jsaddle < 0.10, + mtl < 2.4, + network-uri < 2.7, + servant < 0.21, + tagsoup < 0.15, + text < 2.2, + transformers < 0.7, diff --git a/micro/shell.nix b/micro/shell.nix new file mode 100644 index 000000000..d4c5e4d8c --- /dev/null +++ b/micro/shell.nix @@ -0,0 +1 @@ +(import ../default.nix {}).microhs-env diff --git a/nix/haskell/packages/ghc/default.nix b/nix/haskell/packages/ghc/default.nix index 741f9b7ac..9a3654c75 100644 --- a/nix/haskell/packages/ghc/default.nix +++ b/nix/haskell/packages/ghc/default.nix @@ -25,4 +25,7 @@ self: super: monad-logger = doJailbreak super.monad-logger; string-interpolate = doJailbreak super.string-interpolate; servant-server = doJailbreak super.servant-server; + + /* microhs */ + microhs = self.callCabal2nix "microhs" source.microhs {}; } diff --git a/nix/overlay.nix b/nix/overlay.nix index 924a33246..786511342 100644 --- a/nix/overlay.nix +++ b/nix/overlay.nix @@ -11,6 +11,99 @@ self: super: { then import ./haskell/packages/ghcjs self else import ./haskell/packages/ghc self; }; + ghc9101 = super.haskell.packages.ghc9101.override { + overrides = import ./haskell/packages/ghc self; + }; + }; + }; + + microhsTargetsConf = + super.writeTextFile { + name = "targets.conf"; + text = '' + [default] + cc = "cc" + ccflags = "-w -Wall -O3" + cclibs = "-lm" + conf = "unix" + + [debug] + cc = "cc" + ccflags = "-w -Wall -g" + cclibs = "-lm" + conf = "unix" + + [emscripten] + cc = "emcc" + ccflags = "-O3 -sEXPORTED_RUNTIME_METHODS=stringToNewUTF8 -sALLOW_MEMORY_GROWTH -sTOTAL_STACK=5MB -sNODERAWFS -sSINGLE_FILE -DUSE_SYSTEM_RAW -sEXIT_RUNTIME -Wno-address-of-packed-member -sERROR_ON_UNDEFINED_SYMBOLS=0 -sWASM=0" + cclibs = "-lm" + conf = "unix" + + [tcc] + cc = "tcc" + ccflags = "-D__TCC__=1" + cclibs = "-lm" + conf = "unix" + + [windows] + cc = "cl" + ccflags = "-O2" + cclibs = "" + conf = "windows" + cout = "-Fe" + + [environment] + -- Get all values from the environment + cc = "$CC" + ccflags = "$MHSCCFLAGS" + cclibs = "$MHSCCLIBS" + conf = "$MHSCONF" + ''; + }; + + microhs = + super.stdenv.mkDerivation { + name = "MicroHs"; + src = (import ../nix/source.nix super).microhs; + buildInputs = with super; [ emscripten ]; + installPhase = '' + mkdir -p $out/{bin,share,lib/bin} + + cp -v ./bin/mcabal $out/bin + cp -v ./bin/cpphs $out/bin + cp -v ./bin/mhs $out/bin + cp -rv ./lib $out + + cp -rv ./generated $out + cp -rv ./boards $out + cp -rv ./paths $out + cp -rv ./doc $out + cp -rv ./src $out + cat ${self.microhsTargetsConf} > $out/targets.conf + + cp README.md $out/share + ls -lah + ls -lah $out/ + ''; }; + + microhs-env = super.mkShell { + name = "microhs-env"; + buildInputs = with self; [ microhs emscripten nodejs quickjs ]; + # https://github.com/NixOS/nixpkgs/issues/139943#issuecomment-930432045 + # dmj: Fix for using emcc in Darwin shell environment + # + # dmj: to compile /only/ JS, and work w/ QuickJS: + # $ emcc -sENVIRONMENT=shell -sWASM=0 main.c -oout.js && qjs out.js + shellHook = with super; '' + export MHSDIR=${self.microhs} + export CC=${super.emscripten}/bin/emcc + export PATH=$PATH:${self.microhs}/bin + mkdir -p ~/.emscripten_cache + chmod u+rwX -R ~/.emscripten_cache + cp -r ${super.emscripten}/share/emscripten/cache ~/.emscripten_cache + export EM_CACHE=~/.emscripten_cache + ''; }; + } diff --git a/nix/source.nix b/nix/source.nix index 2263c700e..b2e6e47e1 100644 --- a/nix/source.nix +++ b/nix/source.nix @@ -43,4 +43,10 @@ in rev = "8c7635889ca0a5aaac36a8b21db7f5e5ec0ae4c9"; sha256 = "0s6kzqxbshsnqbqfj7rblqkrr5mzkjxknb6k8m8z4h10mcv1zh7j"; }; + microhs = fetchFromGitHub { + owner = "augustss"; + repo = "microhs"; + rev = "849d5494919a1270fa61e0dd421ca4efd8c6973b"; + hash = "sha256-BplxfCPjktA9D7Hht4juGgpX4gCDgA1UnZRHbnfT49g="; + }; } diff --git a/shell.nix b/shell.nix index 4ca93e7c0..39ce36bc7 100644 --- a/shell.nix +++ b/shell.nix @@ -1,7 +1,5 @@ { pkg ? "ghc" }: - with (import ./default.nix {}); - if pkg == "ghcjs9122" then miso-ghcjs-9122.env.overrideAttrs (drv: { shellHook = '' @@ -15,4 +13,7 @@ then miso-ghcjs-9122.env.overrideAttrs (drv: { else if pkg == "ghcjs" then miso-ghcjs.env +else +if pkg == "micro" +then pkgs.microhs-env else miso-ghc-9122.env