Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting the wasm-opt version programatically #106

Open
HCastano opened this issue Oct 19, 2022 · 2 comments
Open

Getting the wasm-opt version programatically #106

HCastano opened this issue Oct 19, 2022 · 2 comments

Comments

@HCastano
Copy link

Hey! Thanks for these bindings 😄

I want to be able to get programmatically the version of the underlying version of
wasm-opt which was built by the library. So something like wasm_opt::VERSION
or wasm_opt::version(). From what I can tell the only way to do that right now is to
either parse the crate version number, or use a locally installed wasm-opt binary.

I'd be happy to implement this myself if you point me to the right area of the codebase.

@brson
Copy link
Owner

brson commented Oct 21, 2022

@HCastano I am happy to include this feature, though I am interested to know your use case if you can tell me what you will be doing with the version number.

The binaryen version can take two different forms, depending on whether it is being built from git or from a redistributable package. Our build script attempts to reproduce the same logic for extracting the version number as binaryen's own build system.

Here is the build script code for finding the version:

fn get_project_version_from_cmake() -> anyhow::Result<String> {
let re = Regex::new(r".*?binaryen LANGUAGES C CXX VERSION \d+.*?").unwrap();
let binaryen_dir = get_binaryen_dir()?;
let cmake_file = binaryen_dir.join("CMakeLists.txt");
let file = File::open(cmake_file)?;
let version_info: Vec<String> = BufReader::new(file)
.lines()
.map(|line| line.unwrap())
.filter(|line| re.is_match(line.as_ref()))
.collect();
let re = Regex::new(r"\d+").unwrap();
let cap = re.captures(&version_info[0]).expect("cmake version");
let version = &cap[0];
Ok(version.to_string())
}
fn get_project_version_from_git() -> anyhow::Result<String> {
let binaryen_dir = get_binaryen_dir()?;
let output = Command::new("git")
.arg("-C")
.arg(binaryen_dir.as_os_str())
.arg("describe")
.arg("--tags")
.arg("--match")
.arg("version_*")
.output();
let output = output?;
let output = String::from_utf8(output.stdout)?.trim().to_string();
Ok(output)
}

That version is written as a string to the PROJECT_VERSION define in config.h.

Exposing this to the Rust API should entail:

  • Modifying components/wasm-opt-cxx-sys/src/shims.h to add a function to return this value. It can probably live with the grab bag of misc functions at the end of the file.
  • Modifying components/wasm-opt-cxx-sys/src/lib.rs to add the cxx bindings
  • Adding a wrapping function to components/wasm-opt/src/base.rs
  • Probably that function will have a signature of fn() -> String. In that case it can be reexported from lib.rs

I'd like to call the function binaryen_version to distinguish it from the crate version.

It might be possible to arrange for the function signature to be fn() -> &'static str, but I don't know offhand how to do it. It would probably involve defining a C++ static to hold the value, and carefully defining all the FFI functions. I am fine with either String or &'static str.

@brson
Copy link
Owner

brson commented Oct 21, 2022

It would also be possible to expose this as a static value BINARYEN_VERSION, though it would require emitting some Rust code from the wasm-opt-sys build script (probably into OUT_DIR/binaryen_version.rs or something), including it in the wasm-opt-sys crate, possibly with include!, and then reexporting it from wasm-opt.

This method might actually require less code.

I am ok with either way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants