mirror of
https://git.proxmox.com/git/perlmod
synced 2025-10-04 22:07:05 +00:00
macro: derive library name from Cargo.toml
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
f3d18a7492
commit
b813397be8
@ -12,6 +12,7 @@ failure = "0.1"
|
|||||||
proc-macro2 = "1.0"
|
proc-macro2 = "1.0"
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
syn = { version = "1.0", features = [ "full" ] }
|
syn = { version = "1.0", features = [ "full" ] }
|
||||||
|
toml = "0.4.10"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
perlmod = { path = "../perlmod" }
|
perlmod = { path = "../perlmod" }
|
||||||
|
@ -1,17 +1,21 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
use std::env;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
|
|
||||||
use proc_macro2::Ident;
|
use proc_macro2::{Ident, Span};
|
||||||
|
|
||||||
use syn::parse::Parse;
|
use syn::parse::Parse;
|
||||||
use syn::punctuated::Punctuated;
|
use syn::punctuated::Punctuated;
|
||||||
use syn::AttributeArgs;
|
use syn::AttributeArgs;
|
||||||
use syn::Token;
|
use syn::Token;
|
||||||
|
|
||||||
use crate::attribs::ModuleAttrs;
|
use toml::Value;
|
||||||
|
|
||||||
const LIB_NAME_DEFAULT: &str = r#"($pkg =~ /(?:^|::)([^:]+)$/)"#;
|
use crate::attribs::ModuleAttrs;
|
||||||
|
|
||||||
const MODULE_HEAD: &str = r#"
|
const MODULE_HEAD: &str = r#"
|
||||||
use strict;
|
use strict;
|
||||||
@ -104,7 +108,8 @@ impl Package {
|
|||||||
if let Some(lib) = &self.attrs.lib_name {
|
if let Some(lib) = &self.attrs.lib_name {
|
||||||
source = source.replace("{{LIB_NAME}}", &format!("('{}')", lib));
|
source = source.replace("{{LIB_NAME}}", &format!("('{}')", lib));
|
||||||
} else {
|
} else {
|
||||||
source = source.replace("{{LIB_NAME}}", LIB_NAME_DEFAULT);
|
let lib_name = get_default_lib_name(Span::call_site())?;
|
||||||
|
source = source.replace("{{LIB_NAME}}", &format!("('{}')", lib_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
let file_name = self
|
let file_name = self
|
||||||
@ -204,3 +209,55 @@ impl Parse for ExportItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_cargo_toml(why: Span) -> Result<HashMap<String, Value>, syn::Error> {
|
||||||
|
let manifest_dir = env::var("CARGO_MANIFEST_DIR")
|
||||||
|
.map_err(|err| format_err!(why, "failed to get CARGO_MANIFEST_DIR variable: {}", err))?;
|
||||||
|
let cargo_toml_path = PathBuf::from(manifest_dir).join("Cargo.toml");
|
||||||
|
|
||||||
|
use std::io::Read;
|
||||||
|
let mut content = String::new();
|
||||||
|
File::open(cargo_toml_path)
|
||||||
|
.map_err(|err| format_err!(why, "failed to open Cargo.toml: {}", err))?
|
||||||
|
.read_to_string(&mut content)
|
||||||
|
.map_err(|err| format_err!(why, "failed to read Cargo.toml: {}", err))?;
|
||||||
|
|
||||||
|
toml::from_str(&content).map_err(|err| format_err!(why, "failed to parse Cargo.toml: {}", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
static mut LIB_NAME: Option<String> = None;
|
||||||
|
pub fn get_default_lib_name(why: Span) -> Result<&'static str, syn::Error> {
|
||||||
|
unsafe {
|
||||||
|
if let Some(name) = &LIB_NAME {
|
||||||
|
return Ok(&name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let cargo = read_cargo_toml(why)?;
|
||||||
|
|
||||||
|
let package = cargo
|
||||||
|
.get("package")
|
||||||
|
.ok_or_else(|| format_err!(
|
||||||
|
why,
|
||||||
|
"did not find a [package] section in Cargo.toml, try to specify the library name manually",
|
||||||
|
))?;
|
||||||
|
|
||||||
|
let name = package.get("name").ok_or_else(|| {
|
||||||
|
format_err!(
|
||||||
|
why,
|
||||||
|
"failed to find the package name in Cargo.toml, try to specify the library name manually",
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let name = name.as_str().ok_or_else(|| {
|
||||||
|
format_err!(
|
||||||
|
why,
|
||||||
|
"package name in Cargo.toml is not a string, try to specify the library name manually",
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
LIB_NAME = Some(name.replace('-', "_"));
|
||||||
|
return Ok(&LIB_NAME.as_ref().unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -17,7 +17,7 @@ fn func_b(a: u32) -> Result<u32, Error> {
|
|||||||
perlmod::make_package! {
|
perlmod::make_package! {
|
||||||
package "RSPM::Foo";
|
package "RSPM::Foo";
|
||||||
|
|
||||||
lib "perlmod_test";
|
//lib "perlmod_test";
|
||||||
|
|
||||||
subs {
|
subs {
|
||||||
foo,
|
foo,
|
||||||
|
Loading…
Reference in New Issue
Block a user