helix
helix copied to clipboard
Can't use `cargo test`
When using Helix, I do most of my testing from Ruby. Sometimes, however, I want to test behaviour that I don't want to expose to Ruby, but still involves Helix objects. To do this, I expected to be able to use cargo test
, something like this:
#[macro_use]
extern crate helix;
ruby! {
class HelixTest {
struct {
message: String,
}
def initialize(helix, message: String) {
HelixTest { helix, message }
}
}
}
#[test]
fn hello() {
HelixTest::new("hello world".to_string());
}
cargo test
manages to compile this, but it won't run:
cargo test --verbose Fresh cstr-macro v0.1.0 Fresh libc v0.2.22 Fresh cslice v0.3.0 Fresh libcruby-sys v0.6.0 Fresh helix v0.6.0 Compiling helix_test v0.1.0 (file:///Users/alyssa/desktop/helix_test) Running `rustc --crate-name helix_test src/lib.rs --emit=dep-info,link -C debuginfo=2 --test -C metadata=0feaea9da66f2f4d -C extra-filename=-0feaea9da66f2f4d --out-dir /Users/alyssa/desktop/helix_test/target/debug/deps -L dependency=/Users/alyssa/desktop/helix_test/target/debug/deps --extern helix=/Users/alyssa/desktop/helix_test/target/debug/deps/libhelix-a44d38b1cc8a9eb4.rlib` error: linking with `cc` failed: exit code: 1 | = note: "cc" "-m64" "-L" "/Users/alyssa/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib" "/Users/alyssa/desktop/helix_test/target/debug/deps/helix_test-0feaea9da66f2f4d.0.o" "-o" "/Users/alyssa/desktop/helix_test/target/debug/deps/helix_test-0feaea9da66f2f4d" "-Wl,-dead_strip" "-nodefaultlibs" "-L" "/Users/alyssa/desktop/helix_test/target/debug/deps" "-L" "/Users/alyssa/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib" "/Users/alyssa/desktop/helix_test/target/debug/deps/libhelix-a44d38b1cc8a9eb4.rlib" "/Users/alyssa/desktop/helix_test/target/debug/deps/liblibcruby_sys-51b4faec2edea8c0.rlib" "/Users/alyssa/desktop/helix_test/target/debug/deps/libcslice-e35cab80719fd98e.rlib" "/Users/alyssa/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/libtest-85fd397c1b504b69.rlib" "/Users/alyssa/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/libterm-95ba05952512bff3.rlib" "/Users/alyssa/desktop/helix_test/target/debug/deps/liblibc-026076ef8cc90032.rlib" "/Users/alyssa/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/libgetopts-ffed193a1399c490.rlib" "/Users/alyssa/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/libstd-d19edcdb8b3582f0.rlib" "/Users/alyssa/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/libpanic_unwind-35809200ab841b7b.rlib" "/Users/alyssa/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/libunwind-dd5cb334048ac204.rlib" "/Users/alyssa/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/librand-eb0e42c8ae609eea.rlib" "/Users/alyssa/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/libcollections-6fcbe3ecfbfa6629.rlib" "/Users/alyssa/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/liballoc-7f2c52501770c1c7.rlib" "/Users/alyssa/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/liballoc_jemalloc-ea49ffd3fee5264c.rlib" "/Users/alyssa/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/liblibc-4ac31620c28c3400.rlib" "/Users/alyssa/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/libstd_unicode-7e35037032e227eb.rlib" "/Users/alyssa/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/libcore-10c94a1f2bd23f41.rlib" "/Users/alyssa/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/libcompiler_builtins-1afcf087346e8edb.rlib" "-l" "System" "-l" "pthread" "-l" "c" "-l" "m" = note: Undefined symbols for architecture x86_64: "_HELIX_Qnil", referenced from: helix_test::Init_native::_$LT$impl$u20$helix_test..HelixTest$GT$::new::h199cb45eb4b33d59 in helix_test-0feaea9da66f2f4d.0.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)error: aborting due to previous error
error: Could not compile
helix_test
.Caused by: process didn't exit successfully:
rustc --crate-name helix_test src/lib.rs --emit=dep-info,link -C debuginfo=2 --test -C metadata=0feaea9da66f2f4d -C extra-filename=-0feaea9da66f2f4d --out-dir /Users/alyssa/desktop/helix_test/target/debug/deps -L dependency=/Users/alyssa/desktop/helix_test/target/debug/deps --extern helix=/Users/alyssa/desktop/helix_test/target/debug/deps/libhelix-a44d38b1cc8a9eb4.rlib
(exit code: 101)
This is going to be because we're excepting that the helix_runtime C library will be loaded already. The solution here would be to have cargo somehow load it from the gem directory. This isn't my area of expertise so I'm not sure how easy or hard that would be be.
After much experimentation and learning, I was able to link to Helix from a C program using clang on macOS:
#include <dlfcn.h>
#include <stdio.h>
int main() {
void *handle = dlopen("./native.bundle", RTLD_NOW);
if (!handle) goto end;
dlsym(handle, "HELIX_Qnil");
end:;
char *error = dlerror();
if (error) printf("%s\n", error);
dlclose(handle);
return !!error;
}
clang -Wl,-force_load,/Users/alyssa/.rubies/ruby-2.4.1/lib/libruby-static.a \
-framework CoreFoundation -lgmp test.c
I'll look more into this and see if I can reproduce it in Rust, and then try to make it more portable.
Nice! I think with Rust you might just be able to set a linker argument (probably with build.rs) to point to the helix_runtime native bundle.
I think we might want to expose a Cargo "feature" called no_init
, and then guard the Init_native
function with a #[cfg]
. @wagenet do you know how to do that?
Further investigation on my part reveals that even if I do manage to get cargo test
to link properly, I can't run the tests because Init_native
runs before I get a chance to dynamically load the library.
@wycats's solution sounds like it would solve the problem, but I wonder if it might be a good idea to try to load helix_runtime from Rust in Init_native if it isn't present? (Is that even possible?)
For future reference (maybe if someone's Googling obscure combinations of Rust commands and linker flags like I have been for the past few hours), here is the Cargo configuration I used to get it to link:
[build]
rustflags = [
"-C", "link-arg=-undefined", "-C", "link-arg=dynamic_lookup",
"-C", "link-arg=-rdynamic",
"-C", "link-arg=-force_load",
"-C", "link-arg=/Users/alyssa/.rubies/ruby-2.4.1/lib/libruby-static.a",
"-C", "link-arg=-framework",
"-C", "link-arg=CoreFoundation",
"-C", "link-arg=-lgmp",
]