Skip to content

Commit

Permalink
Add no-caml-startup feature flag that avoids the caml_startup sym…
Browse files Browse the repository at this point in the history
…bol.

Will also be enabled if the `OCAML_INTEROP_NO_CAML_STARTUP` environment variable is set.

This will make `OCamlRuntime::init_persistent()` a noop.

The main motivation for this feature flag is to make code that uses
ocaml-rs and ocaml-interop loadable from `dune utop`:

zshipko/ocaml-rs#70
  • Loading branch information
tizoc committed Aug 16, 2021
1 parent fefebda commit 79a3f8c
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 13 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- `no-caml-startup` feature flag that disables calls to `caml_startup` when initializing the runtime. This makes `OCamlRuntime::init_persistent()` a noop. It is useful for being able to load code that uses ocaml-interop in an utop toplevel (for example, when running `dune utop`). Will be enabled if the environment variable `OCAML_INTEROP_NO_CAML_STARTUP` is set.

## [0.8.4] - 2021-05-18

### Added
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ static_assertions = "1.1.0"
[features]
without-ocamlopt = ["ocaml-sys/without-ocamlopt", "ocaml-boxroot-sys/without-ocamlopt"]
caml-state = ["ocaml-sys/caml-state"]
no-caml-startup = []
14 changes: 14 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) Viable Systems and TezEdge Contributors
// SPDX-License-Identifier: MIT

const OCAML_INTEROP_NO_CAML_STARTUP: &'static str = "OCAML_INTEROP_NO_CAML_STARTUP";

fn main() {
println!(
"cargo:rerun-if-env-changed={}",
OCAML_INTEROP_NO_CAML_STARTUP
);
if std::env::var(OCAML_INTEROP_NO_CAML_STARTUP).is_ok() {
println!("cargo:rustc-cfg=feature=\"no-caml-startup\"");
}
}
28 changes: 16 additions & 12 deletions src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
// SPDX-License-Identifier: MIT

use ocaml_boxroot_sys::{boxroot_setup, boxroot_teardown};
use ocaml_sys::{caml_shutdown, caml_startup};
use std::{marker::PhantomData, sync::Once};
use std::marker::PhantomData;

use crate::{memory::OCamlRef, value::OCaml};

Expand All @@ -30,15 +29,20 @@ impl OCamlRuntime {
///
/// After the first invocation, this method does nothing.
pub fn init_persistent() {
static INIT: Once = Once::new();

INIT.call_once(|| {
let arg0 = "ocaml\0".as_ptr() as *const ocaml_sys::Char;
let c_args = vec![arg0, core::ptr::null()];
unsafe {
caml_startup(c_args.as_ptr());
}
})
#[cfg(not(feature = "no-caml-startup"))]
{
static INIT: std::sync::Once = std::sync::Once::new();

INIT.call_once(|| {
let arg0 = "ocaml\0".as_ptr() as *const ocaml_sys::Char;
let c_args = vec![arg0, core::ptr::null()];
unsafe {
ocaml_sys::caml_startup(c_args.as_ptr());
}
})
}
#[cfg(feature = "no-caml-startup")]
panic!("Rust code that is called from an OCaml program should not try to initialize the runtime.");
}

/// Recover the runtime handle.
Expand Down Expand Up @@ -77,7 +81,7 @@ impl Drop for OCamlRuntime {
fn drop(&mut self) {
unsafe {
boxroot_teardown();
caml_shutdown();
ocaml_sys::caml_shutdown();
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion testing/ocaml-caller/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ crate-type = ["staticlib", "cdylib"]

[dependencies]
ocaml-interop = { path = "../../../../.." }
# Above is for building with dune, bellow is for biulding from this directory
# Above is for building with dune, bellow is for building from this directory
# ocaml-interop = { path = "../../.." }

0 comments on commit 79a3f8c

Please sign in to comment.