- replace demangling with never mangling
This commit is contained in:
@@ -1,56 +0,0 @@
|
||||
name: Publish
|
||||
|
||||
on: [push, pull_request, workflow_call]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
crates_io_publish:
|
||||
name: Publish (crates.io)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 25
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
submodules: 'true'
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: cargo-release Cache
|
||||
id: cargo_release_cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cargo/bin/cargo-release
|
||||
key: ${{ runner.os }}-cargo-release
|
||||
|
||||
- run: cargo install cargo-release
|
||||
if: steps.cargo_release_cache.outputs.cache-hit != 'true'
|
||||
|
||||
- name: cargo login
|
||||
run: cargo login ${{ secrets.CRATES_IO_API_TOKEN }}
|
||||
|
||||
# allow-branch HEAD is because GitHub actions switches
|
||||
# to the tag while building, which is a detached head
|
||||
|
||||
# Publishing is currently messy, because:
|
||||
#
|
||||
# * `peace_rt_model_core` exports `NativeError` or `WebError` depending on the target.
|
||||
# * `peace_rt_model_web` fails to build when publishing the workspace for a native target.
|
||||
# * `peace_rt_model_web` still needs its dependencies to be published before it can be
|
||||
# published.
|
||||
# * `peace_rt_model_hack` needs `peace_rt_model_web` to be published before it can be
|
||||
# published.
|
||||
#
|
||||
# We *could* pass through `--no-verify` so `cargo` doesn't build the crate before publishing,
|
||||
# which is reasonable, since this job only runs after the Linux, Windows, and WASM builds
|
||||
# have passed.
|
||||
- name: "cargo release publish"
|
||||
run: |-
|
||||
cargo release \
|
||||
publish \
|
||||
--workspace \
|
||||
--all-features \
|
||||
--allow-branch "main" \
|
||||
--no-confirm \
|
||||
--no-verify \
|
||||
--execute
|
||||
@@ -22,8 +22,6 @@ thiserror = "2"
|
||||
[build-dependencies]
|
||||
bindgen = "0.72"
|
||||
cmake = "0.1"
|
||||
cpp_demangle = "0.5"
|
||||
msvc-demangler = "0.11"
|
||||
|
||||
[features]
|
||||
dynamic = []
|
||||
@@ -5,11 +5,6 @@ use std::path::{Path, PathBuf};
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[cfg(not(feature = "dynamic"))]
|
||||
use bindgen::callbacks::ItemInfo;
|
||||
|
||||
#[cfg(not(feature = "dynamic"))]
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
fn find_static_lib(dir: &Path, base_name: &str, target_is_windows: bool) -> Option<PathBuf> {
|
||||
@@ -76,6 +71,46 @@ impl Error {
|
||||
}
|
||||
}
|
||||
|
||||
fn restore_importexport(libcziapi_inc: &Path) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let header = libcziapi_inc.join("importexport.h");
|
||||
let relative = header.strip_prefix("libczi").unwrap_or(&header);
|
||||
let status = std::process::Command::new("git")
|
||||
.args(["checkout", "HEAD", "--", relative.to_str().unwrap()])
|
||||
.current_dir("libczi")
|
||||
.status()?;
|
||||
if !status.success() {
|
||||
return Err(Error::msg("failed to restore importexport.h"));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
struct ImportExportGuard<'a> {
|
||||
libcziapi_inc: &'a Path,
|
||||
}
|
||||
|
||||
impl<'a> Drop for ImportExportGuard<'a> {
|
||||
fn drop(&mut self) {
|
||||
if let Err(e) = restore_importexport(self.libcziapi_inc) {
|
||||
eprintln!("warning: failed to restore importexport.h: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn patch_importexport(
|
||||
libcziapi_inc: &Path,
|
||||
) -> Result<ImportExportGuard<'_>, Box<dyn std::error::Error>> {
|
||||
let path = libcziapi_inc.join("importexport.h");
|
||||
let original = std::fs::read_to_string(&path)?;
|
||||
let patched = original.replace(
|
||||
"#define EXTERNALLIBCZIAPI_API(_returntype_) _returntype_",
|
||||
"#define EXTERNALLIBCZIAPI_API(_returntype_) extern \"C\" _returntype_",
|
||||
);
|
||||
if patched != original {
|
||||
std::fs::write(&path, &patched)?;
|
||||
}
|
||||
Ok(ImportExportGuard { libcziapi_inc })
|
||||
}
|
||||
|
||||
fn fix_xwin_lib_case() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let toolchain_key = format!(
|
||||
"CMAKE_TOOLCHAIN_FILE_{}",
|
||||
@@ -120,7 +155,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
if env::var("DOCS_RS").is_err() {
|
||||
let host = env::var("HOST")?;
|
||||
let target = env::var("TARGET")?;
|
||||
let is_cross = host != target;
|
||||
let is_cross = host != target
|
||||
|| env::var(format!(
|
||||
"CMAKE_TOOLCHAIN_FILE_{}",
|
||||
target.replace('-', "_")
|
||||
))
|
||||
.is_ok()
|
||||
|| env::var("TARGET_CMAKE_TOOLCHAIN_FILE").is_ok()
|
||||
|| env::var("CMAKE_TOOLCHAIN_FILE").is_ok();
|
||||
let is_windows = target.contains("windows");
|
||||
let _is_macos = target.contains("apple");
|
||||
|
||||
@@ -177,6 +219,13 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
if target.contains("aarch64") {
|
||||
cmake_config.define("NEON_INTRINSICS_CAN_BE_USED", "ON");
|
||||
}
|
||||
} else {
|
||||
cmake_config
|
||||
.define("CRASH_ON_UNALIGNED_ACCESS", "OFF")
|
||||
.define("_UNALIGNED_ACCESS_RESULT_EXITCODE", "0");
|
||||
if target.contains("aarch64") {
|
||||
cmake_config.define("_NEON_INTRINSICS_RESULT_EXITCODE", "0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,25 +233,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
cmake_config.build_target("libCZIAPIStatic");
|
||||
}
|
||||
|
||||
let _importexport_guard = patch_importexport(&libcziapi_inc)?;
|
||||
let dst = cmake_config.build();
|
||||
|
||||
#[cfg(not(feature = "dynamic"))]
|
||||
let bindings = {
|
||||
let libcziapi_search_dirs = [
|
||||
dst.join("build/Src/libCZIAPI"),
|
||||
dst.join("Src/libCZIAPI"),
|
||||
dst.join("lib"),
|
||||
dst.join("lib64"),
|
||||
];
|
||||
let libcziapi_static = libcziapi_search_dirs
|
||||
.iter()
|
||||
.find_map(|dir| find_static_lib(dir, "libCZIAPIStatic", is_windows))
|
||||
.ok_or(Error::msg("cannot find libCZIAPIStatic library"))?;
|
||||
bindgen::Builder::default().parse_callbacks(Box::new(DeMangler::new(
|
||||
libcziapi_static,
|
||||
is_cross && is_windows,
|
||||
)?))
|
||||
};
|
||||
let bindings = bindgen::Builder::default();
|
||||
|
||||
#[cfg(feature = "dynamic")]
|
||||
let bindings = bindgen::Builder::default();
|
||||
@@ -346,106 +381,3 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("cargo::rerun-if-changed=build.rs");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "dynamic"))]
|
||||
#[derive(Debug)]
|
||||
struct DeMangler {
|
||||
map: HashMap<String, String>,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "dynamic"))]
|
||||
impl DeMangler {
|
||||
fn new(a_file: PathBuf, use_llvm_nm: bool) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
let nm_cmd = if use_llvm_nm { "llvm-nm" } else { "nm" };
|
||||
let cmd = std::process::Command::new(nm_cmd)
|
||||
.arg("--defined-only")
|
||||
.arg(&a_file)
|
||||
.output()?;
|
||||
let mut map = HashMap::new();
|
||||
for line in std::str::from_utf8(&cmd.stdout)?.lines() {
|
||||
let line = line.trim();
|
||||
let mangled = if let Some(sym) = line.split_whitespace().last() {
|
||||
sym
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
let plain_name = Self::demangle(mangled);
|
||||
if let Some(name) = plain_name {
|
||||
if name.starts_with("libCZI_") {
|
||||
Self::insert_mapping(&mut map, &name, mangled, &a_file)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Self { map })
|
||||
}
|
||||
|
||||
fn demangle(symbol: &str) -> Option<String> {
|
||||
// Only demangle actual function symbols, not catch/dtor/cppxdata metadata
|
||||
if let Some(rest) = symbol.strip_prefix('?') {
|
||||
// MSVC: real functions start with "libCZI_", not "catch$", "dtor$", etc.
|
||||
if !rest.starts_with("libCZI_") {
|
||||
return None;
|
||||
}
|
||||
let flags = msvc_demangler::DemangleFlags::llvm();
|
||||
let demangled = msvc_demangler::demangle(symbol, flags).ok()?;
|
||||
Self::extract_msvc_name(&demangled)
|
||||
} else if symbol.starts_with("_Z") {
|
||||
// Itanium: demangle and extract the function name
|
||||
let sym = cpp_demangle::Symbol::new(symbol.as_bytes()).ok()?;
|
||||
let demangled = sym.demangle().ok()?;
|
||||
// e.g. "libCZI_Foo(int, bool)" -> "libCZI_Foo"
|
||||
// e.g. "ns::libCZI_Foo(int)" -> "libCZI_Foo"
|
||||
demangled.split('(').next().and_then(|s| {
|
||||
let s = s.trim();
|
||||
if let Some(name) = s.rsplit("::").next() {
|
||||
Some(name.to_string())
|
||||
} else {
|
||||
Some(s.to_string())
|
||||
}
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_msvc_name(demangled: &str) -> Option<String> {
|
||||
// Find the identifier that looks like a function name.
|
||||
// MSVC demangled output: "return_type calling_conv name(params)"
|
||||
for word in demangled.split_whitespace() {
|
||||
if let Some(rest) = word.strip_prefix("libCZI_") {
|
||||
let name = format!("libCZI_{}", rest.split('(').next().unwrap_or(rest));
|
||||
return Some(name);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn insert_mapping(
|
||||
map: &mut HashMap<String, String>,
|
||||
demangled: &str,
|
||||
mangled: &str,
|
||||
a_file: &Path,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
if let Some(existing_mangled) = map.get(demangled) {
|
||||
if existing_mangled != mangled {
|
||||
return Err(Error::msg(format!(
|
||||
"conflicting mangled symbols for {} in {}: {}, {}",
|
||||
demangled,
|
||||
a_file.to_string_lossy(),
|
||||
existing_mangled,
|
||||
mangled
|
||||
)));
|
||||
}
|
||||
} else {
|
||||
map.insert(demangled.to_string(), mangled.to_string());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "dynamic"))]
|
||||
impl bindgen::callbacks::ParseCallbacks for DeMangler {
|
||||
fn generated_link_name_override(&self, item_info: ItemInfo<'_>) -> Option<String> {
|
||||
self.map.get(item_info.name).cloned()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1127,6 +1127,7 @@ impl CompositionChannelInfo {
|
||||
pub fn get_look_up_table_element_count(&self) -> i32 {
|
||||
self.0.look_up_table_element_count
|
||||
}
|
||||
#[allow(clippy::unnecessary_cast)]
|
||||
pub fn get_look_up_table(&self) -> Vec<u8> {
|
||||
unsafe {
|
||||
Vec::from_raw_parts(
|
||||
|
||||
Reference in New Issue
Block a user