I am trying to find a macro like cfg (let's call it my_cfg) that would conditionally compile based on a custom configuration file (like Toml or Yaml) instead of definitions from Cargo.toml of a package. My use case is that I have a bunch of packages with workspace, and I would like to have one place, e.g. config package, that can be referenced by other packages. And my_cfg would use values in this fashion:
#[my_cfg(config1)]
const CONST1: usize = 10;
#[my_cfg(config2)]
const CONST1: usize = 100;
The values config1 and config2 are defined in a package called config.
Related
I have a Terraform Module for Docker Swarm which I reference in another module which I then use in my environment specific Terraform. I recently published a small fix for it, is it possible to specify the version I want for the module?
I saw it can be done on the providers, but I can't seem to find the equivalent for modules.
Is this what you are looking for, I m using tags in my repos to do version control, you can also use branch if you need to:
https://github.com/tomarv2/terraform-databricks-aws-workspace/blob/e44ae0fbb4eb7105c89b2bd03e2f5f8b43a9723b/s3.tf#L2
module "s3" {
source = "git::git#github.com:tomarv2/terraform-aws-s3.git?ref=v0.0.7"
custom_tags = var.custom_tags
# -----------------------------------------
# Do not change the teamid, prjid once set.
teamid = var.teamid
prjid = "${var.prjid}-${local.suffix}"
}
data "databricks_aws_bucket_policy" "this" {
bucket = module.s3.bucket_name
}
If you are loading the module from a Git repository, you specify the version as part of the source attribute in the module block.
If you are loading the module from the Terraform module repository, you specify the version by adding a version attribute in the module block.
This is all documented here.
I have a header file lets say greetings.h:
include <hello.h>;
include <bye.h>;
include <hola.h>;
...
Im using bindgen in rust to generate those file from c header to rust.
But I want to ignore generating the include <hola.h> header and generate the greeting.h only with helllo.h and bye.h.
I have searched it in docs.rs bindgen documentation but not found any hint on that.
or is there any option to do that with clang
I was able to solve this by guessing that my library that Im trying to bind from c to rust are "namespaced", in C language there is no actually namespaces but people that write open source code tend to prefix their code with "some_prefix*".
So if the h file that I want to bind looks like:
mylib.h:
include <hello.h>;
include <bye.h>;
include <hola.h>;
...
mylib_add_value(...);
mylib_remove_value(...);
mylib_display_value(...);
...
and I don't want the hola.h to be generated,
i can filter the output with allow and block functionality of bingden like:
build.rs:
fn main() {
// Tell cargo to tell rustc to link the system nvpair of zfs
// shared library.
println!("cargo:rustc-link-lib=mylib");
// 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")
.allowlist_var(r#"(\w*mylib\w*)"#)
.allowlist_type(r#"(\w*mylib\w*)"#)
.allowlist_function(r#"(\w*mylib\w*)"#)
.blocklist_item(r#"(\w*hola\w*)"#)
.blocklist_type(r#"(\w*hola\w*)"#)
.blocklist_function(r#"(\w*hola\w*)"#)
.clang_args(vec!["-I/usr/include/mylib"])
.default_enum_style(bindgen::EnumVariation::Rust {
non_exhaustive: (true),
})
// 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)
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}
Bindgen will bring all dependencies of allowlist firstly and if some of the dependencies include *hola* it won't generate it.
The autotools are providing a suite of utilities allowing the developer to configure the source code during compilation specifically to ease packaging.
One of the capabilities is the definition of several installation directory variables set during compilation and which avoids making assumptions on where the application is to be installed.
For example:
Variable
Default
prefix
/usr/local
datarootdir
${prefix}/share
sysconfdir
${prefix}/etc
localstatedir
${prefix}/var
...
How to mimic this behavior in Rust at compile time? Is there any existing standard or best practices for such need?
I'd like to make use of system paths but without having them fully hard-coded and allowing the packager to customize part of it.
You can use the std::env or std::option_env! macros to get an environment variable at compile time. This can be used to set install variables as environment variables when building your program.
If you want to additionally set defaults conveniently, here's a macro:
/// Get an environment variable during compile time, else return a default
macro_rules! env_or {
($name:expr, $default:expr) => {
// This is needed because `Option.unwrap_or` is not a const fn:
// https://github.com/rust-lang/rust/issues/91930
if let Some(value) = option_env!($name) {
value
} else {
$default
}
};
}
You can use this as follows:
const PREFIX: &str = env_or!("PREFIX", "/usr/local");
To concatenate PREFIX and /share, you can use the concatcp macro from the const_format crate as follows:
const DATAROOTDIR: &str = const_format::concatcp!(PREFIX, "/share");
I need to add uuid in one of my struct. I found one crate for uuid support. I added the dependency to my Cargo.toml
uuid = "0.8.1"
It downloaded fine but I can't use the function Uuid::new_v3(). I get the error: no function or associated item named new_v3 found for struct uuid::Uuid in the current scope.
The weird part for me is that I can use some of them like from_slice works fine.
You have to explicitly specify uuid's features you're planing to use.
You can add new_v3 support by adding v3 feature like this:
uuid = { version = "0.8", features = ["v3"] }
More info can be found there
I am trying to compile bindings for the SEAL C++ library. Here is my repo.
// Generate the bindings
let bindings = bindgen::Builder::default()
.generate_inline_functions(true)
.derive_default(true)
.header("./seal/src/seal/seal.h")
.clang_arg("-I./seal/src/")
.clang_arg("-std=c++17")
.clang_arg("-x")
.clang_arg("c++")
.opaque_type("std::.*")
.whitelist_type("seal::.*")
.generate()
.expect("Unable to generate bindings");
let out_path = PathBuf::from("./src/");
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
bindings.rs does not have anything from defaultparams.h
What do I have to add to the Builder object to include defaultparams.h's functions in the generated bindings? I need coeff_modulus_128() for example.
I tried whitelisting the std::vector but it did not have any impact on the generated bindings.
Solved by adding .whitelist_function("seal::.*") to the build.rs file. Since the inline functions weren't enclosed in a type, they were not whitelisted by the current config.