To be able to talk to openQA, there needs to exist sort of a Rust stub which can execute the existing Perl code for as long as this Perl code still exists. There are two possiblities to do this:
implement a separate binary which uses the libperl-rs crate to execute the existing Perl code while pulling in the rust libraries.
use swig and bindgen-rs to create perl to rust bindings as a shared dynamic library. In practice this would possibly mean to create perl-C bindings and Rust-C bindings and putting them together
Information
If you want to go with the 2nd approach (which would probably be smarter as it would allow a granular rewrite of openQA's functionality into Perl while being able to keep the Perl code):
You can specify that a library should be compiled as a C-compatible dynamic library like this:
Edit your Cargo.toml file to specify that you're building a library. This involves setting the crate-type field to cdylib, which tells Cargo to compile your library as a C-compatible dynamic library. Additionally, you'll need to define the functions you want to expose to users of your library. These functions should be marked with #[no_mangle] to prevent them from being renamed during compilation, and pub extern "C" to indicate that they have C linkage.
[lib]
name = "my_shared_lib"
crate-type = ["cdylib"]
Functions you want to expose would look like this:
Then, compile your library by running cargo build --release. This command compiles your library in release mode, producing a shared library file named <library_name>.so on Linux, <library_name>.dll on Windows, and <library_name>.dylib on macOS.
Using:
After compiling your library, you can use it in other projects by adding it as a dependency in those projects' Cargo.toml files. You can also manually load the shared library at runtime using the libloading crate.
Considerations for this approach:
Memory Management: When writing a shared library in Rust, especially one intended to be used by C code, you need to carefully manage memory to avoid issues like dangling pointers or double frees. Rust's ownership model helps mitigate these risks, but you still need to be mindful of how data is passed across the boundary between Rust and C code.
ABI Compatibility: Compiling a Rust library as a shared library means it uses Rust's Application Binary Interface (ABI), not the C ABI. This can affect compatibility with C code expecting a C ABI. However, Rust's cdylib crate type aims to bridge this gap by providing a C-compatible interface.
Distribution: Distributing a Rust shared library requires careful consideration of how the library will be loaded at runtime. On Linux, you might need to set the rpath or use LD_LIBRARY_PATH to ensure the library can be found. On Windows, you'll need to ensure the DLL is in a directory listed in the PATH environment variable or explicitly load it at runtime.
openQA Version
n/A
Impacted library
isototest
Proposal
To be able to talk to openQA, there needs to exist sort of a Rust stub which can execute the existing Perl code for as long as this Perl code still exists. There are two possiblities to do this:
libperl-rs
crate to execute the existing Perl code while pulling in the rust libraries.swig
andbindgen-rs
to create perl to rust bindings as a shared dynamic library. In practice this would possibly mean to create perl-C bindings and Rust-C bindings and putting them togetherInformation
If you want to go with the 2nd approach (which would probably be smarter as it would allow a granular rewrite of openQA's functionality into Perl while being able to keep the Perl code):
You can specify that a library should be compiled as a C-compatible dynamic library like this:
Edit your
Cargo.toml
file to specify that you're building a library. This involves setting the crate-type field tocdylib
, which tells Cargo to compile your library as a C-compatible dynamic library. Additionally, you'll need to define the functions you want to expose to users of your library. These functions should be marked with#[no_mangle]
to prevent them from being renamed during compilation, andpub extern "C"
to indicate that they have C linkage.Functions you want to expose would look like this:
Then, compile your library by running
cargo build --release
. This command compiles your library in release mode, producing a shared library file named<library_name>.so
on Linux,<library_name>.dll
on Windows, and<library_name>.dylib
on macOS.Using: After compiling your library, you can use it in other projects by adding it as a dependency in those projects'
Cargo.toml
files. You can also manually load the shared library at runtime using thelibloading
crate.Considerations for this approach:
Distribution: Distributing a Rust shared library requires careful consideration of how the library will be loaded at runtime. On Linux, you might need to set the rpath or use LD_LIBRARY_PATH to ensure the library can be found. On Windows, you'll need to ensure the DLL is in a directory listed in the PATH environment variable or explicitly load it at runtime.
Ressources
libperl-rs
crate: https://crates.io/crates/libperl-rslibperl-rs
blogpost: https://hkoba.hatenablog.com/entry/2020/03/30/124746swig
Rust support issue: https://github.com/swig/swig/issues/2734swig
Rust support discussion: https://github.com/swig/swig/issues/1468rust-bindgen
: https://github.com/rust-lang/rust-bindgenDynaLoader
Dynamic .so loader: https://perldoc.perl.org/DynaLoader