From 46d611fe339524cf3374c0752276e3c754760422 Mon Sep 17 00:00:00 2001 From: Niklas Dewally Date: Fri, 1 Nov 2024 18:25:42 +0000 Subject: [PATCH] remove chuffed_rs Remove chuffed bindings. The chuffed bindings did not build on Redhat machines, interfering with developing Conjure Oxide on lab machines. They also are no longer being actively developed. Closes: #360 --- Cargo.lock | 19 ---- Cargo.toml | 2 - README.md | 1 - doc/index.md | 3 +- readme.md | 1 - solvers/chuffed/.gitignore | 15 --- solvers/chuffed/Cargo.toml | 13 --- solvers/chuffed/README.md | 7 -- solvers/chuffed/build.rs | 101 -------------------- solvers/chuffed/build.sh | 26 ------ solvers/chuffed/compile_flags.txt | 3 - solvers/chuffed/src/lib.rs | 71 -------------- solvers/chuffed/src/main.rs | 18 ---- solvers/chuffed/tests/chuffed_basic_run.rs | 67 -------------- solvers/chuffed/tests/chuffed_cpp_run.rs | 14 --- solvers/chuffed/tests/dummy_test.rs | 4 - solvers/chuffed/vendor | 1 - solvers/chuffed/wrapper.cpp | 102 --------------------- solvers/chuffed/wrapper.h | 32 ------- solvers/chuffed/xyz.fzn | 7 -- tools/gen_docs.sh | 2 +- 21 files changed, 2 insertions(+), 507 deletions(-) delete mode 100644 solvers/chuffed/.gitignore delete mode 100644 solvers/chuffed/Cargo.toml delete mode 100644 solvers/chuffed/README.md delete mode 100644 solvers/chuffed/build.rs delete mode 100644 solvers/chuffed/build.sh delete mode 100644 solvers/chuffed/compile_flags.txt delete mode 100644 solvers/chuffed/src/lib.rs delete mode 100644 solvers/chuffed/src/main.rs delete mode 100644 solvers/chuffed/tests/chuffed_basic_run.rs delete mode 100644 solvers/chuffed/tests/chuffed_cpp_run.rs delete mode 100644 solvers/chuffed/tests/dummy_test.rs delete mode 160000 solvers/chuffed/vendor delete mode 100644 solvers/chuffed/wrapper.cpp delete mode 100644 solvers/chuffed/wrapper.h delete mode 100644 solvers/chuffed/xyz.fzn diff --git a/Cargo.lock b/Cargo.lock index 896c23546c..6aa4a0ddea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -197,8 +197,6 @@ version = "1.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" dependencies = [ - "jobserver", - "libc", "shlex", ] @@ -230,14 +228,6 @@ dependencies = [ "windows-targets", ] -[[package]] -name = "chuffed_rs" -version = "0.1.0" -dependencies = [ - "bindgen", - "cc", -] - [[package]] name = "clang-sys" version = "1.8.1" @@ -641,15 +631,6 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" -[[package]] -name = "jobserver" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" -dependencies = [ - "libc", -] - [[package]] name = "js-sys" version = "0.3.70" diff --git a/Cargo.toml b/Cargo.toml index d6878553b5..84c799cf36 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,8 +15,6 @@ members = [ "crates/conjure_macros", "solvers/kissat", "solvers/minion", - "solvers/chuffed", - ] [workspace.lints.clippy] diff --git a/README.md b/README.md index ebc57f6558..b66089f919 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,6 @@ This repository hosts the following projects: * [Conjure Oxide](https://github.com/conjure-cp/conjure-oxide/tree/main/conjure_oxide) * [`minion_rs` - Rust bindings to Minion](https://github.com/conjure-cp/conjure-oxide/tree/main/solvers/minion) -* [`chuffed_rs` - Rust bindings to Chuffed](https://github.com/conjure-cp/conjure-oxide/tree/main/solvers/chuffed) This project is being produced by staff and students of University of St Andrews, and is licenced under the [MPL 2.0](./LICENCE). diff --git a/doc/index.md b/doc/index.md index 372679c230..bab8dd2cfe 100644 --- a/doc/index.md +++ b/doc/index.md @@ -12,7 +12,6 @@ Welcome to the documentation of Conjure Oxide. These crates contain Rust bindings for solvers: * [minion_rs](minion_rs/index.html) -* [chuffed_rs](chuffed_rs/index.html) ## Developer Documentation @@ -34,4 +33,4 @@ reference: 2. Run all tests in the workspace ```bash cargo test --workspace - ``` \ No newline at end of file + ``` diff --git a/readme.md b/readme.md index ebc57f6558..b66089f919 100644 --- a/readme.md +++ b/readme.md @@ -7,7 +7,6 @@ This repository hosts the following projects: * [Conjure Oxide](https://github.com/conjure-cp/conjure-oxide/tree/main/conjure_oxide) * [`minion_rs` - Rust bindings to Minion](https://github.com/conjure-cp/conjure-oxide/tree/main/solvers/minion) -* [`chuffed_rs` - Rust bindings to Chuffed](https://github.com/conjure-cp/conjure-oxide/tree/main/solvers/chuffed) This project is being produced by staff and students of University of St Andrews, and is licenced under the [MPL 2.0](./LICENCE). diff --git a/solvers/chuffed/.gitignore b/solvers/chuffed/.gitignore deleted file mode 100644 index e6e4e81268..0000000000 --- a/solvers/chuffed/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -# Generated by Cargo -# will have compiled files and executables -debug/ -target/ -vendor/build - -# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries -# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html -Cargo.lock - -# These are backup files generated by rustfmt -**/*.rs.bk - -# MSVC Windows builds of rustc generate these, which store debugging information -*.pdb diff --git a/solvers/chuffed/Cargo.toml b/solvers/chuffed/Cargo.toml deleted file mode 100644 index ecdd6c1d84..0000000000 --- a/solvers/chuffed/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "chuffed_rs" -version = "0.1.0" -authors = ["Kieran Fowlds "] -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] - -[build-dependencies] -cc = { version = "1.1.31", features = ["parallel"] } -bindgen = "0.70.1" diff --git a/solvers/chuffed/README.md b/solvers/chuffed/README.md deleted file mode 100644 index 6e2dc0b5f7..0000000000 --- a/solvers/chuffed/README.md +++ /dev/null @@ -1,7 +0,0 @@ -This directory contains in progress bindings for the [Chuffed solver](https://github.com/chuffed/chuffed). - -Currently, this builds, but provides no functionality. - -# Installation / Usage - -TODO diff --git a/solvers/chuffed/build.rs b/solvers/chuffed/build.rs deleted file mode 100644 index 6439f775a2..0000000000 --- a/solvers/chuffed/build.rs +++ /dev/null @@ -1,101 +0,0 @@ -// adapted from -// https://github.com/gokberkkocak/rust_glucose/blob/master/build.rs -// and -// https://rust-lang.github.io/rust-bindgen/non-system-libraries.html - -use std::env; -use std::path::PathBuf; -use std::process::Command; - -fn main() { - let out_dir = env::var("OUT_DIR").unwrap(); - - println!("cargo:rerun-if-changed=vendor"); - println!("cargo:rerun-if-changed=wrapper.h"); - println!("cargo:rerun-if-changed=wrapper.cpp"); - - println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-changed=build.sh"); - - println!("cargo:rustc-link-search=all={}/", out_dir); - println!("cargo:rustc-link-search=all={}/build", out_dir); - - println!("cargo:rustc-link-lib=static=chuffed"); - println!("cargo:rustc-link-lib=static=chuffed_fzn"); - println!("cargo:rustc-link-lib=static=wrapper"); - - // also need to (dynamically) link to c++ stdlib - // https://flames-of-code.netlify.app/blog/rust-and-cmake-cplusplus/ - let target = env::var("TARGET").unwrap(); - if target.contains("apple") { - println!("cargo:rustc-link-lib=dylib=c++"); - } else if target.contains("linux") { - println!("cargo:rustc-link-lib=dylib=stdc++"); - } else { - unimplemented!(); - } - build(); - bind(); -} -fn build() { - let output = Command::new("bash") - .args(["build.sh"]) - .output() - .expect("Failed to run build.sh"); - - /* - do cargo build -vv to see - */ - println!("stdout"); - println!("{}", String::from_utf8_lossy(&output.stdout)); - println!("stderr"); - println!("{}", String::from_utf8_lossy(&output.stderr)); - - if !output.status.success() { - panic!("build.sh has non zero exit status") - } -} - -fn bind() { - let out_dir = env::var("OUT_DIR").unwrap(); - // The bindgen::Builder is the main entry point - // to bindgen, and lets you build up options for - // the resulting bindings. - let bindings = bindgen::Builder::default() - // The input header we would like to generate - // bindings for. - .header("wrapper.h") - // Must manually give allow list to stop bindgen accidentally binding something complicated - // in C++ stdlib that will make it crash. - .allowlist_function("createVars") - .allowlist_function("createVar") - .allowlist_function("all_different") - .allowlist_function("branch") - .allowlist_function("output_vars") - .allowlist_function("var_sym_break") - .allowlist_function("new_dummy_problem") - .allowlist_function("get_idx") - .allowlist_function("make_vec_intvar") - .allowlist_function("destroy_vec_intvar") - .allowlist_function("p_addVars") - .allowlist_function("p_setcallback") - .allowlist_function("p_print") - .allowlist_function("branch_IntVar") - .allowlist_function("new_xyz_problem") - .allowlist_function("solve_xyz") - .allowlist_function("int_plus") - .clang_arg(format!("-I{}/build", out_dir)) - .clang_arg("-Ivendor") - .clang_arg(r"--std=gnu++11") - .clang_arg(r"-xc++") - // Finish the builder and generate the bindings. - .generate() - // Unwrap the Result and panic on failure. - .expect("Unable to generate bindings"); - - // Write the bindings to the $OUT_DIR/bindings.rs file. - let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); - bindings - .write_to_file(out_path.join("chuffed_bindings.rs")) - .expect("Couldn't write bindings to file!"); -} diff --git a/solvers/chuffed/build.sh b/solvers/chuffed/build.sh deleted file mode 100644 index 8f3faddacb..0000000000 --- a/solvers/chuffed/build.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -SCRIPT_DIR="$(readlink -f "$(dirname "$0")")" -cd "$SCRIPT_DIR" - -git submodule init -- vendor -git submodule sync -- vendor -git submodule update --init --recursive -- vendor - - -if [[ -z "$OUT_DIR" ]]; then - echo "OUT_DIR env variable does not exist - did you run this script through cargo build?" - exit 1 -fi - -echo "------ BUILDING ------" - -mkdir -p "$OUT_DIR/build" -cd "$OUT_DIR/build" -cmake -B . -S "$SCRIPT_DIR/vendor" -cmake --build . - -# Build wrapper.cpp as static library -cd "$OUT_DIR" || exit 1 -c++ -c "$SCRIPT_DIR/wrapper.cpp" -I"$SCRIPT_DIR/vendor" --std=c++11 -ar rvs libwrapper.a wrapper.o diff --git a/solvers/chuffed/compile_flags.txt b/solvers/chuffed/compile_flags.txt deleted file mode 100644 index fd91cc6aea..0000000000 --- a/solvers/chuffed/compile_flags.txt +++ /dev/null @@ -1,3 +0,0 @@ --I./vendor --xc++ ---std=c++11 diff --git a/solvers/chuffed/src/lib.rs b/solvers/chuffed/src/lib.rs deleted file mode 100644 index 88f06dab13..0000000000 --- a/solvers/chuffed/src/lib.rs +++ /dev/null @@ -1,71 +0,0 @@ -pub mod bindings { - #![allow(warnings)] - include!(concat!(env!("OUT_DIR"), "/chuffed_bindings.rs")); -} - -pub mod wrappers { - use core::ptr; - - use crate::bindings::{ - all_different, branch_IntVar, createVar, createVars, int_plus, make_vec_intvar, - output_vars1, var_sym_break, vec, ConLevel, IntVar, ValBranch, VarBranch, - }; - - // The signature of createVar is below for reference. - // createVar(x: *mut *mut IntVar, min: ::std::os::raw::c_int, max: ::std::os::raw::c_int, el: bool) - pub fn create_var(min: i32, max: i32, el: bool) -> *mut IntVar { - let mut ptr: *mut IntVar = ptr::null_mut(); - - unsafe { - createVar(&mut ptr, min, max, el); - ptr - } - } - - // createVars void createVars(vec& x, int n, int min, int max, bool el) - pub fn create_vars(n: i32, min: i32, max: i32, el: bool) -> *mut vec<*mut IntVar> { - let ptr: *mut vec<*mut IntVar> = unsafe { make_vec_intvar() }; - - unsafe { - createVars(ptr, n, min, max, el); - ptr - } - } - - // void all_different(vec& x, ConLevel cl) - pub unsafe fn all_different_wrapper(x: *mut vec<*mut IntVar>, cl: ConLevel) { - unsafe { - all_different(x, cl); - } - } - - // void branch(vec x, VarBranch var_branch, ValBranch val_branch); - pub unsafe fn branch_wrapper( - x: *mut vec<*mut IntVar>, - var_branch: VarBranch, - val_branch: ValBranch, - ) { - unsafe { - branch_IntVar(x, var_branch, val_branch); - } - } - - pub unsafe fn output_vars_wrapper(x: *mut vec<*mut IntVar>) { - unsafe { - // output_vars1 takes in an vec instead of branching - output_vars1(x); - } - } - - pub unsafe fn var_sym_break_wrapper(x: *mut vec<*mut IntVar>) { - unsafe { - var_sym_break(x); - } - } - - pub unsafe fn int_plus_wrapper(x: *mut IntVar, y: *mut IntVar, z: *mut IntVar) { - unsafe { - int_plus(x, y, z); - } - } -} diff --git a/solvers/chuffed/src/main.rs b/solvers/chuffed/src/main.rs deleted file mode 100644 index d00676f22f..0000000000 --- a/solvers/chuffed/src/main.rs +++ /dev/null @@ -1,18 +0,0 @@ -use chuffed_rs::bindings::{new_xyz_problem, solve_xyz}; - -// Entry point for running this problem -fn main() { - let args: Vec = std::env::args().collect(); - - if args.len() != 2 { - println!("Invalid number of arguments"); - return; - } - - let n: i32 = args[1].parse().expect("Invalid input"); - - unsafe { - let p = new_xyz_problem(n); - solve_xyz(p); - } -} diff --git a/solvers/chuffed/tests/chuffed_basic_run.rs b/solvers/chuffed/tests/chuffed_basic_run.rs deleted file mode 100644 index b66c28a913..0000000000 --- a/solvers/chuffed/tests/chuffed_basic_run.rs +++ /dev/null @@ -1,67 +0,0 @@ -use chuffed_rs::bindings::{ - get_idx, new_dummy_problem, p_addVars, p_setcallback, vec, ConLevel_CL_DEF, IntVar, - VarBranch_VAR_INORDER, VarBranch_VAR_MIN_MIN, -}; -use chuffed_rs::wrappers::{ - all_different_wrapper, branch_wrapper, create_vars, output_vars_wrapper, var_sym_break_wrapper, -}; - -/// Creates the variable for the test problem and posts some constraints and -/// branchings on it. -unsafe fn post_constraints(_n: i32) -> *mut vec<*mut IntVar> { - // Create constant - let n: i32 = _n; - // Create some variables - let x: *mut vec<*mut IntVar> = create_vars(n, 0, n, false); - - // Post some constraints - all_different_wrapper(x, ConLevel_CL_DEF); - - // Post some branchings - branch_wrapper(x as _, VarBranch_VAR_INORDER, VarBranch_VAR_MIN_MIN); - - // Declare output variables (optional) - output_vars_wrapper(x); - - // Declare symmetries (optional) - var_sym_break_wrapper(x); - - // Return the variable - x -} - -/// Custom printing function for this test problem -#[no_mangle] -pub unsafe extern "C" fn callback(x: *mut vec<*mut IntVar>) { - print!("First output is: {}", get_idx(x, 0)); -} - -/// Basic test to make sure that running the ffi bindings and wrappers does not -/// crash -#[test] -fn run_basic_problem() { - let args: Vec = std::env::args().collect(); - - if args.len() != 2 { - println!("Invalid number of arguments"); - return; - } - - let n: i32 = args[1].parse().expect("Invalid input"); - - unsafe { - let x = post_constraints(n); - // make new dummy problem - let p = new_dummy_problem(); - // Call problem.addvars() - p_addVars(p, x); - // Call problem.setcallback() - p_setcallback(p, Some(callback)); - // Commented out currently as trying to print causes the assertion of - // isFixed() in IntVar::getVal() to fail. - // p_print(p); - - // Pass test if no crash occurs - assert!(true); - } -} diff --git a/solvers/chuffed/tests/chuffed_cpp_run.rs b/solvers/chuffed/tests/chuffed_cpp_run.rs deleted file mode 100644 index 3798a4a5fe..0000000000 --- a/solvers/chuffed/tests/chuffed_cpp_run.rs +++ /dev/null @@ -1,14 +0,0 @@ -use chuffed_rs::bindings::{new_xyz_problem, solve_xyz}; - -#[test] -fn run_cpp_problem() { - let n: i32 = 1; - - unsafe { - let p = new_xyz_problem(n); - solve_xyz(p); - - // Pass test if no crash occurs - assert!(true); - } -} diff --git a/solvers/chuffed/tests/dummy_test.rs b/solvers/chuffed/tests/dummy_test.rs deleted file mode 100644 index 55939eb8e7..0000000000 --- a/solvers/chuffed/tests/dummy_test.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[test] -fn dummy() { - assert_eq!(1, 1); -} diff --git a/solvers/chuffed/vendor b/solvers/chuffed/vendor deleted file mode 160000 index 82faf9cdfa..0000000000 --- a/solvers/chuffed/vendor +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 82faf9cdfad9a8bf182c1ca9a39ae02b4e949968 diff --git a/solvers/chuffed/wrapper.cpp b/solvers/chuffed/wrapper.cpp deleted file mode 100644 index 3e6529209b..0000000000 --- a/solvers/chuffed/wrapper.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include "./wrapper.h" -#include "chuffed/flatzinc/flatzinc.h" - -DummyProblem *new_dummy_problem() { return new DummyProblem(); } -void p_addVars(DummyProblem *p, vec *_searchVars) { - p->addVars(_searchVars); -} -void p_setcallback(DummyProblem *p, void (*_callback)(vec *)) { - p->setcallback(_callback); -} -void p_print(DummyProblem *p) { p->print(); } - -int get_idx(vec *x, int i) { - IntVar *var = *x[i]; - int t = var->getVal(); - return t; -} - -vec *make_vec_intvar() { return new vec(); } - -void destroy_vec_intvar(vec *v) { delete v; } - -void branch_IntVar(vec *x, VarBranch var_branch, - ValBranch val_branch) { - branch(*x, var_branch, val_branch); -} - -// Construct problem with given number of variables -FlatZinc::FlatZincSpace *new_flat_zinc_space(int intVars, int boolVars, - int setVars) { - return new FlatZinc::FlatZincSpace(intVars, boolVars, setVars); -} - -// add new int var -void addIntVar(FlatZinc::FlatZincSpace flat_zinc_space, - FlatZinc::IntVarSpec *vs, const std::string &name) { - flat_zinc_space.newIntVar(vs, name); -} - -class XYZProblem : public Problem { - -public: - // Constants - int n; // number of variables - - // Variables - vec x; - vec y; - vec z; - - XYZProblem(int _n) : n(_n) { - // Create vars - createVars(x, n, 1, 3); - createVars(y, n, 1, 3); - createVars(z, n, 1, 3); - - // Post constraints - // find x, y, z : int(1..3) - // such that x + y = z - - all_different(x); - - for (int i = 0; i < n; i++) { - int_plus(x[i], y[i], z[i]); - } - - // Branching - branch(x, VAR_INORDER, VAL_MIN); - branch(y, VAR_INORDER, VAL_MIN); - branch(z, VAR_INORDER, VAL_MIN); - - // Declare output variables - output_vars(x); - output_vars(y); - output_vars(z); - } - - // Function to print out solution - void print(std::ostream &out) override { - out << "x = "; - for (int i = 0; i < n; i++) { - out << x[i]->getVal() << " "; - } - out << std::endl; - out << "y = "; - for (int i = 0; i < n; i++) { - out << y[i]->getVal() << " "; - } - out << std::endl; - out << "z = "; - for (int i = 0; i < n; i++) { - out << z[i]->getVal() << " "; - } - out << std::endl; - } -}; - -// Create new xyz problem -void *new_xyz_problem(int n) { return new XYZProblem(n); } - -// Solve xyz problem -void solve_xyz(void *p) { engine.solve((XYZProblem *)p); } diff --git a/solvers/chuffed/wrapper.h b/solvers/chuffed/wrapper.h deleted file mode 100644 index 30c7108f33..0000000000 --- a/solvers/chuffed/wrapper.h +++ /dev/null @@ -1,32 +0,0 @@ -#include "chuffed/branching/branching.h" -#include "chuffed/core/engine.h" -#include "chuffed/core/propagator.h" -#include "chuffed/flatzinc/flatzinc.h" -#include "chuffed/primitives/primitives.h" -#include "chuffed/vars/modelling.h" - -class DummyProblem { -public: - vec *searchVars; - // callback - void (*callback)(vec *); - - void print() { callback(searchVars); } - void setcallback(void (*_callback)(vec *)) { callback = _callback; } - void addVars(vec *_searchVars) { searchVars = _searchVars; } -}; - -DummyProblem *new_dummy_problem(); -void p_addVars(DummyProblem *p, vec *_searchVars); -void p_setcallback(DummyProblem *p, void (*_callback)(vec *)); -void p_print(DummyProblem *p); -int get_idx(vec *x, int i); - -vec *make_vec_intvar(); -void destroy_vec_intvar(vec *v); - -void branch_IntVar(vec *x, VarBranch var_branch, - ValBranch val_branch); - -void *new_xyz_problem(int n); -void solve_xyz(void *p); diff --git a/solvers/chuffed/xyz.fzn b/solvers/chuffed/xyz.fzn deleted file mode 100644 index 934105800b..0000000000 --- a/solvers/chuffed/xyz.fzn +++ /dev/null @@ -1,7 +0,0 @@ -predicate all_different_int(array [int] of var int: xs); -var 1..3: x:: output_var ; -var 1..3: y:: output_var ; -var 1..3: z:: output_var ; -constraint int_lin_eq([1,1,-1],[x,y,z],0); -solve :: int_search([x, y, z], input_order, indomain_min, complete) - satisfy; diff --git a/tools/gen_docs.sh b/tools/gen_docs.sh index 8a8a22c5e1..c0a8fbac98 100755 --- a/tools/gen_docs.sh +++ b/tools/gen_docs.sh @@ -26,5 +26,5 @@ TARGET_DIR=$(cargo metadata 2> /dev/null | jq -r .target_directory 2>/dev/null) cd "$PROJECT_ROOT" rm -rf "$TARGET_DIR/doc" -RUSTDOCFLAGS="-Zunstable-options --markdown-no-toc --index-page ${PROJECT_ROOT}/doc/index.md" cargo +nightly doc --no-deps --all-features -p conjure_oxide -p conjure_macros -p conjure_core -p minion_rs -p chuffed_rs -p enum_compatability_macro $@ +RUSTDOCFLAGS="-Zunstable-options --markdown-no-toc --index-page ${PROJECT_ROOT}/doc/index.md" cargo +nightly doc --no-deps --all-features -p conjure_oxide -p conjure_macros -p conjure_core -p minion_rs -p enum_compatability_macro $@