Skip to content

Commit

Permalink
extract and test target file name creation
Browse files Browse the repository at this point in the history
  • Loading branch information
Folkert de Vries authored and folkertdev committed Sep 10, 2024
1 parent f894a06 commit c1e4940
Showing 1 changed file with 173 additions and 65 deletions.
238 changes: 173 additions & 65 deletions src/build_targets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,82 +69,31 @@ impl BuildTargets {
) -> anyhow::Result<BuildTargets> {
let pc = targetdir.join(format!("{}.pc", &capi_config.pkg_config.filename));
let include = if capi_config.header.enabled && capi_config.header.generation {
let mut header_name = PathBuf::from(&capi_config.header.name);
header_name.set_extension("h");
Some(targetdir.join(&header_name))
Some(targetdir.join(&capi_config.header.name).with_extension("h"))
} else {
None
};

let lib_name = name;

let os = &target.os;
let env = &target.env;

let (shared_lib, static_lib, impl_lib, debug_info, def) = match (os.as_str(), env.as_str())
{
("none", _)
| ("linux", _)
| ("freebsd", _)
| ("dragonfly", _)
| ("netbsd", _)
| ("android", _)
| ("haiku", _)
| ("illumos", _)
| ("emscripten", _) => {
let static_lib = targetdir.join(format!("lib{lib_name}.a"));
let shared_lib = targetdir.join(format!("lib{lib_name}.so"));
(shared_lib, static_lib, None, None, None)
}
("macos", _) | ("ios", _) | ("tvos", _) | ("visionos", _) => {
let static_lib = targetdir.join(format!("lib{lib_name}.a"));
let shared_lib = targetdir.join(format!("lib{lib_name}.dylib"));
(shared_lib, static_lib, None, None, None)
}
("windows", env) => {
let static_lib = if env == "msvc" {
targetdir.join(format!("{lib_name}.lib"))
} else {
targetdir.join(format!("lib{lib_name}.a"))
};
let shared_lib = targetdir.join(format!("{lib_name}.dll"));
let impl_lib = if env == "msvc" {
targetdir.join(format!("{lib_name}.dll.lib"))
} else {
targetdir.join(format!("{lib_name}.dll.a"))
};
let def = targetdir.join(format!("{lib_name}.def"));
let pdb = if env == "msvc" {
Some(targetdir.join(format!("{lib_name}.pdb")))
} else {
None
};
(shared_lib, static_lib, Some(impl_lib), pdb, Some(def))
}
_ => unimplemented!("The target {}-{} is not supported yet", os, env),
};

let static_lib = if libkinds.contains(&"staticlib") {
Some(static_lib)
} else {
None
let Some(file_names) = FileNames::from_target(target, name, targetdir) else {
return Err(anyhow::anyhow!(
"The target {}-{} is not supported yet",
target.os,
target.env
));
};

// Bare metal does not support shared objects
let shared_lib = if libkinds.contains(&"cdylib") && os.as_str() != "none" {
Some(shared_lib)
} else {
None
};
let build_shared_lib = libkinds.contains(&"cdylib") && target.os.as_str() != "none";
let build_static_lib = libkinds.contains(&"staticlib");

Ok(BuildTargets {
pc,
include,
static_lib,
shared_lib,
impl_lib,
debug_info,
def,
static_lib: build_static_lib.then_some(file_names.static_lib),
shared_lib: build_shared_lib.then_some(file_names.shared_lib),
impl_lib: file_names.impl_lib,
debug_info: file_names.debug_info,
def: file_names.def,
use_meson_naming_convention,
name: name.into(),
target: target.clone(),
Expand Down Expand Up @@ -189,3 +138,162 @@ impl BuildTargets {
}
}
}

#[derive(Debug, PartialEq, Eq)]
struct FileNames {
static_lib: PathBuf,
shared_lib: PathBuf,
impl_lib: Option<PathBuf>,
debug_info: Option<PathBuf>,
def: Option<PathBuf>,
}

impl FileNames {
fn from_target(target: &Target, lib_name: &str, targetdir: &Path) -> Option<Self> {
let (shared_lib, static_lib, impl_lib, debug_info, def) = match target.os.as_str() {
"none" | "linux" | "freebsd" | "dragonfly" | "netbsd" | "android" | "haiku"
| "illumos" | "emscripten" => {
let static_lib = targetdir.join(format!("lib{lib_name}.a"));
let shared_lib = targetdir.join(format!("lib{lib_name}.so"));
(shared_lib, static_lib, None, None, None)
}
"macos" | "ios" | "tvos" | "visionos" => {
let static_lib = targetdir.join(format!("lib{lib_name}.a"));
let shared_lib = targetdir.join(format!("lib{lib_name}.dylib"));
(shared_lib, static_lib, None, None, None)
}
"windows" => {
let shared_lib = targetdir.join(format!("{lib_name}.dll"));
let def = targetdir.join(format!("{lib_name}.def"));

if target.env == "msvc" {
let static_lib = targetdir.join(format!("{lib_name}.lib"));
let impl_lib = targetdir.join(format!("{lib_name}.dll.lib"));
let pdb = Some(targetdir.join(format!("{lib_name}.pdb")));

(shared_lib, static_lib, Some(impl_lib), pdb, Some(def))
} else {
let static_lib = targetdir.join(format!("lib{lib_name}.a"));
let impl_lib = targetdir.join(format!("{lib_name}.dll.a"));
let pdb = None;

(shared_lib, static_lib, Some(impl_lib), pdb, Some(def))
}
}
_ => return None,
};

Some(Self {
static_lib,
shared_lib,
impl_lib,
debug_info,
def,
})
}
}

#[cfg(test)]
mod test {
use std::path::{Path, PathBuf};

use super::{FileNames, Target};

#[test]
fn unix() {
for os in [
"none",
"linux",
"freebsd",
"dragonfly",
"netbsd",
"android",
"haiku",
"illumos",
"emscripten",
] {
let target = Target {
is_target_overridden: false,
arch: String::from(""),
os: os.to_string(),
env: String::from(""),
};
let file_names = FileNames::from_target(&target, "ferris", Path::new("/foo/bar"));

let expected = FileNames {
static_lib: PathBuf::from("/foo/bar/libferris.a"),
shared_lib: PathBuf::from("/foo/bar/libferris.so"),
impl_lib: None,
debug_info: None,
def: None,
};

assert_eq!(file_names.unwrap(), expected);
}
}

#[test]
fn apple() {
for os in ["macos", "ios", "tvos", "visionos"] {
let target = Target {
is_target_overridden: false,
arch: String::from(""),
os: os.to_string(),
env: String::from(""),
};
let file_names = FileNames::from_target(&target, "ferris", Path::new("/foo/bar"));

let expected = FileNames {
static_lib: PathBuf::from("/foo/bar/libferris.a"),
shared_lib: PathBuf::from("/foo/bar/libferris.dylib"),
impl_lib: None,
debug_info: None,
def: None,
};

assert_eq!(file_names.unwrap(), expected);
}
}

#[test]
fn windows_msvc() {
let target = Target {
is_target_overridden: false,
arch: String::from(""),
os: String::from("windows"),
env: String::from("msvc"),
};
let file_names = FileNames::from_target(&target, "ferris", Path::new("/foo/bar"));

let expected = FileNames {
static_lib: PathBuf::from("/foo/bar/ferris.lib"),
shared_lib: PathBuf::from("/foo/bar/ferris.dll"),
impl_lib: Some(PathBuf::from("/foo/bar/ferris.dll.lib")),
debug_info: Some(PathBuf::from("/foo/bar/ferris.pdb")),
def: Some(PathBuf::from("/foo/bar/ferris.def")),
};

assert_eq!(file_names.unwrap(), expected);
}

#[test]
fn windows_gnu() {
let target = Target {
is_target_overridden: false,
arch: String::from(""),
os: String::from("windows"),
env: String::from("gnu"),
};
let file_names = FileNames::from_target(&target, "ferris", Path::new("/foo/bar"));

let expected = FileNames {
static_lib: PathBuf::from("/foo/bar/libferris.a"),
shared_lib: PathBuf::from("/foo/bar/ferris.dll"),
impl_lib: Some(PathBuf::from("/foo/bar/ferris.dll.a")),
debug_info: None,
def: Some(PathBuf::from("/foo/bar/ferris.def")),
};

assert_eq!(file_names.unwrap(), expected);
}
}

0 comments on commit c1e4940

Please sign in to comment.