From 4cbacf717298adac81f5c1096819bd6b6ddf8e11 Mon Sep 17 00:00:00 2001 From: Syed Daanish Date: Sat, 25 Jul 2026 22:00:25 +0100 Subject: [PATCH] Initial commit Setup a nix flake for an ocaml setup with mruby dependency --- .gitignore | 4 ++ .gitmodules | 16 +++++++ dune-project | 2 + flake.lock | 26 ++++++++++ flake.nix | 97 ++++++++++++++++++++++++++++++++++++++ libs/changes.patch | 33 +++++++++++++ libs/mgems/mruby-env | 1 + libs/mgems/mruby-marshal-c | 1 + libs/mgems/mruby-process | 1 + libs/mruby | 1 + src/dune | 9 ++++ src/main.ml | 20 ++++++++ 12 files changed, 211 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 dune-project create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 libs/changes.patch create mode 160000 libs/mgems/mruby-env create mode 160000 libs/mgems/mruby-marshal-c create mode 160000 libs/mgems/mruby-process create mode 160000 libs/mruby create mode 100644 src/dune create mode 100644 src/main.ml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5b542db --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +_build +result + +p.vim diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..b39bd34 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,16 @@ +[submodule "libs/mruby"] + path = libs/mruby + url = https://github.com/mruby/mruby.git + ignore = dirty +[submodule "libs/mgems/mruby-marshal-c"] + path = libs/mgems/mruby-marshal-c + url = https://github.com/LanzaSchneider/mruby-marshal-c.git + ignore = dirty +[submodule "libs/mgems/mruby-process"] + path = libs/mgems/mruby-process + url = https://github.com/iij/mruby-process.git + ignore = dirty +[submodule "libs/mgems/mruby-env"] + path = libs/mgems/mruby-env + url = https://github.com/iij/mruby-env.git + ignore = dirty diff --git a/dune-project b/dune-project new file mode 100644 index 0000000..d27b034 --- /dev/null +++ b/dune-project @@ -0,0 +1,2 @@ +(lang dune 3.23) +(using ctypes 0.3) diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..7fd8b60 --- /dev/null +++ b/flake.lock @@ -0,0 +1,26 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1784887798, + "narHash": "sha256-F/NHXIk7pOzyY505xKeMrRZ8A/jS29ERharPoQjFR00=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "10061cf0f71d935e6b26195985cc9eeb04c68b63", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..c36da54 --- /dev/null +++ b/flake.nix @@ -0,0 +1,97 @@ +{ + inputs.nixpkgs.url = "github:NixOS/nixpkgs"; + inputs.self.submodules = true; + + outputs = + { self, nixpkgs, ... }: + let + system = "x86_64-linux"; + pkgs = nixpkgs.legacyPackages.${system}; + + mruby = pkgs.stdenv.mkDerivation { + pname = "mruby"; + version = "0.0.1"; + + src = pkgs.lib.cleanSourceWith { + src = "${self}/libs"; + name = "mruby-src"; + }; + + patches = [ ./libs/changes.patch ]; + + nativeBuildInputs = with pkgs; [ + ruby + gnumake + gcc + ]; + + buildPhase = '' + (cd mruby && rake) + ''; + + installPhase = '' + mkdir -p $out + cp -r mruby/build/host/lib $out/ + ''; + }; + + kutu = pkgs.stdenv.mkDerivation { + pname = "kutu"; + version = "0.1.0"; + + src = self; + + nativeBuildInputs = with pkgs; [ + dune_3 + ocaml + ocamlPackages.findlib + ]; + + buildInputs = with pkgs; [ + libxcb + xcbutilwm + xrandr + xprop + ocamlPackages.ctypes + ocamlPackages.ctypes-foreign + mruby + ]; + + buildPhase = '' + export MRUBY_LIB=${mruby}/lib + + dune build src/main.exe --release + ''; + + installPhase = '' + mkdir -p $out/bin + cp _build/default/src/main.exe $out/bin/kutu + ''; + }; + + in + { + packages.${system} = { + default = kutu; + kutu = kutu; + mruby = mruby; + }; + + devShells.${system}.default = pkgs.mkShell { + inputsFrom = [ kutu ]; + + packages = with pkgs; [ + ocamlPackages.utop + ocamlPackages.ocaml-lsp + ocamlPackages.ocamlformat + ]; + + shellHook = '' + export CC=clang + export CXX=clang++ + export LD=clang + export MRUBY_LIB=${mruby}/lib + ''; + }; + }; +} diff --git a/libs/changes.patch b/libs/changes.patch new file mode 100644 index 0000000..cd524dd --- /dev/null +++ b/libs/changes.patch @@ -0,0 +1,33 @@ +--- ./mruby/build_config/default.rb ++++ ./mruby/build_config/default.rb +@@ -1,6 +1,18 @@ + MRuby::Build.new do |conf| + # load specific toolchain settings +- conf.toolchain ++ conf.toolchain :gcc ++ ++ conf.cc do |cc| ++ cc.command = ENV['CC'] ++ end ++ ++ conf.cxx do |cxx| ++ cxx.command = ENV['CXX'] ++ end ++ ++ conf.linker do |linker| ++ linker.command = ENV['CXX'] ++ end + + # Use mrbgems + # conf.gem 'examples/mrbgems/ruby_extension_example' +@@ -16,6 +28,10 @@ + # include the GEM box + conf.gembox 'default' + ++ conf.gem '../mgems/mruby-env' ++ conf.gem '../mgems/mruby-process' ++ conf.gem '../mgems/mruby-marshal-c' ++ + # C compiler settings + # conf.cc do |cc| + # cc.command = ENV['CC'] || 'gcc' diff --git a/libs/mgems/mruby-env b/libs/mgems/mruby-env new file mode 160000 index 0000000..056ae32 --- /dev/null +++ b/libs/mgems/mruby-env @@ -0,0 +1 @@ +Subproject commit 056ae324451ef16a50c7887e117f0ea30921b71b diff --git a/libs/mgems/mruby-marshal-c b/libs/mgems/mruby-marshal-c new file mode 160000 index 0000000..fc40e2e --- /dev/null +++ b/libs/mgems/mruby-marshal-c @@ -0,0 +1 @@ +Subproject commit fc40e2ec0f3647db3a5ebf38c46754fe697cceb4 diff --git a/libs/mgems/mruby-process b/libs/mgems/mruby-process new file mode 160000 index 0000000..95da206 --- /dev/null +++ b/libs/mgems/mruby-process @@ -0,0 +1 @@ +Subproject commit 95da206a5764f4e80146979b8e35bd7a9afd6850 diff --git a/libs/mruby b/libs/mruby new file mode 160000 index 0000000..c8f6c6c --- /dev/null +++ b/libs/mruby @@ -0,0 +1 @@ +Subproject commit c8f6c6c10cd2998a7f2e2133be693b0cdd053a32 diff --git a/src/dune b/src/dune new file mode 100644 index 0000000..4049180 --- /dev/null +++ b/src/dune @@ -0,0 +1,9 @@ +(executable + (name main) + (libraries ctypes-foreign) + (flags :standard + -cclib -Wl,--export-dynamic + -cclib -L%{env:MRUBY_LIB=../libs/mruby/build/host/lib} + -cclib -Wl,--whole-archive + -cclib -lmruby + -cclib -Wl,--no-whole-archive)) diff --git a/src/main.ml b/src/main.ml new file mode 100644 index 0000000..c7fd089 --- /dev/null +++ b/src/main.ml @@ -0,0 +1,20 @@ +open Ctypes +open Foreign + +type mrb = unit ptr + +let mrb : mrb typ = ptr void +let mrb_open = foreign "mrb_open" (void @-> returning mrb) +let mrb_close = foreign "mrb_close" (mrb @-> returning void) + +let mrb_load_string = + foreign "mrb_load_string" (mrb @-> string @-> returning void) + +let () = + let mrb_instance = mrb_open () in + + print_endline "Executing Ruby code from OCaml:"; + let _ = mrb_load_string mrb_instance "puts 'hello1234'.match?(/hello\\d+/)" in + + mrb_close mrb_instance; + print_endline "mruby instance closed successfully."