Comments (5)
The Discord GameSDK uses Rust too internally and exports rust_eh_personality
for whatever reason. This rust_eh_personality
conflicts with the one from the libstd copy used by your own program. Discord will have to fix their SDK to stop exporting rust_eh_personality
. A normal cdylib build doesn't export rust_eh_personality
. Without help from someone working at Discord it would be very hard to figure out why rust_eh_personality
gets exported by their SDK.
from rust.
I may head to use discord-sdk crate instead, although the official SDK should still be usable. By the way, this is my simplified version of discord_game_sdk_sys/build.rs
:
use std::{env, fs, path::*};
use std::fs::{create_dir_all, File};
use std::io::Write;
use zip::ZipArchive;
const SDK_VERSION: &str = "2.5.6";
fn main() {
// DO NOT RELY ON THIS
if cfg!(feature = "private-docs-rs") {
return generate_ffi_bindings(bindgen::builder().header("discord_game_sdk.h"));
}
let sdk_path = fetch_discord_game_sdk();
// println!("cargo:rustc-env=LD_LIBRARY_PATH={}", fs::canonicalize(sdk_path.join("lib/x86_64")).unwrap().display());
// println!("cargo:rustc-env=DYLD_LIBRARY_PATH={}", fs::canonicalize(sdk_path.join("lib/x86_64")).unwrap().display());
println!("cargo:rustc-link-search={}", fs::canonicalize(sdk_path.join("lib/x86_64")).unwrap().to_str().unwrap());
println!("cargo:rerun-if-changed={}", sdk_path.display());
generate_ffi_bindings(
bindgen::builder().header(sdk_path.join("c/discord_game_sdk.h").to_str().unwrap()),
);
if cfg!(feature = "link") {
let target = env::var("TARGET").unwrap();
verify_installation(&target, &sdk_path);
configure_linkage(&target, &sdk_path);
}
}
fn fetch_discord_game_sdk() -> PathBuf {
let mut sdk_version = SDK_VERSION.to_string();
println!("Target Discord GameSDK: {sdk_version}");
let main_dir = PathBuf::from("libraries");
let extract_dir = main_dir.join("discord_game_sdk");
create_dir_all(&extract_dir).unwrap();
println!("Checking local cache...");
// Check cached version
let version_file_path = extract_dir.join("VERSION");
if version_file_path.exists() {
match fs::read_to_string(&version_file_path) {
Ok(ver) => {
if ver == sdk_version {
println!("Version matched, no upgrade required.");
return extract_dir;
} else {
println!("Version not matched, an upgrade is required.");
}
}
Err(err) => eprintln!("Error opening VERSION: {err}"),
}
}
println!("Clearing cache directory...");
if extract_dir.exists() {
fs::remove_dir_all(&extract_dir).expect("remove directory");
fs::create_dir(&extract_dir).expect("create directory");
}
println!("Fetching {sdk_version} SDK...");
let download_path = main_dir.join("fetch.zip");
reqwest::blocking::get(format!(
"https://dl-game-sdk.discordapp.net/{sdk_version}/discord_game_sdk.zip"))
.expect("request Discord Game SDK")
.copy_to(&mut File::create(&download_path).expect("Discord Game SDK local cache"))
.expect("download Discord Game SDK");
ZipArchive::new(File::open(&download_path).expect("read download cache"))
.expect("valid zip")
.extract(&extract_dir)
.expect("extract cached zip");
fs::remove_file(download_path).expect("remove cached zip");
File::create(version_file_path).expect("create VERSION")
.write_all(unsafe { sdk_version.as_bytes_mut() }).expect("write VERSION");
println!("SDK fetched.");
// Prepare for library
fs::rename(extract_dir.join("lib/x86_64/discord_game_sdk.so"),
extract_dir.join("lib/x86_64/libdiscord_game_sdk.so")).unwrap();
fs::rename(extract_dir.join("lib/x86_64/discord_game_sdk.dylib"),
extract_dir.join("lib/x86_64/libdiscord_game_sdk.dylib")).unwrap();
fs::rename(extract_dir.join("lib/x86_64/discord_game_sdk.dll.lib"),
extract_dir.join("lib/x86_64/discord_game_sdk.lib")).unwrap();
fs::rename(extract_dir.join("lib/x86/discord_game_sdk.dll.lib"),
extract_dir.join("lib/x86/discord_game_sdk.lib")).unwrap();
extract_dir
}
fn verify_installation(target: &str, sdk_path: &Path) {
match target {
"x86_64-unknown-linux-gnu" => {
assert!(
sdk_path.join("lib/x86_64/libdiscord_game_sdk.so").exists(),
"{}",
MISSING_SETUP
);
}
"x86_64-apple-darwin" => {
assert!(
sdk_path
.join("lib/x86_64/libdiscord_game_sdk.dylib")
.exists(),
"{}",
MISSING_SETUP
);
}
"x86_64-pc-windows-gnu" | "x86_64-pc-windows-msvc" => {
assert!(
sdk_path.join("lib/x86_64/discord_game_sdk.lib").exists(),
"{}",
MISSING_SETUP
);
}
"i686-pc-windows-gnu" | "i686-pc-windows-msvc" => {
assert!(
sdk_path.join("lib/x86/discord_game_sdk.lib").exists(),
"{}",
MISSING_SETUP
);
}
_ => panic!("{}", INCOMPATIBLE_PLATFORM),
}
}
fn configure_linkage(target: &str, sdk_path: &Path) {
match target {
"x86_64-unknown-linux-gnu"
| "x86_64-apple-darwin"
| "x86_64-pc-windows-gnu"
| "x86_64-pc-windows-msvc" => {
println!("cargo:rustc-link-lib=discord_game_sdk");
println!(
"cargo:rustc-link-search={}",
sdk_path.join("lib/x86_64").display()
);
}
"i686-pc-windows-gnu" | "i686-pc-windows-msvc" => {
println!("cargo:rustc-link-lib=discord_game_sdk");
println!(
"cargo:rustc-link-search={}",
sdk_path.join("lib/x86").display()
);
}
_ => {}
}
}
fn generate_ffi_bindings(builder: bindgen::Builder) {
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
builder
.ctypes_prefix("ctypes")
.derive_copy(true)
.derive_debug(true)
.derive_default(true)
.derive_eq(true)
.derive_hash(true)
.derive_partialeq(true)
.generate_comments(false)
.impl_debug(true)
.impl_partialeq(true)
.parse_callbacks(Box::new(Callbacks))
.prepend_enum_name(false)
.allowlist_function("Discord.+")
.allowlist_type("[EI]?Discord.+")
.allowlist_var("DISCORD_.+")
.generate()
.expect("discord_game_sdk_sys: bindgen could not generate bindings")
.write_to_file(out_path.join("bindings.rs"))
.expect("discord_game_sdk_sys: could not write bindings to file");
}
#[derive(Debug)]
struct Callbacks;
impl bindgen::callbacks::ParseCallbacks for Callbacks {
fn int_macro(&self, name: &str, _value: i64) -> Option<bindgen::callbacks::IntKind> {
// Must match sys::DiscordVersion
if name.ends_with("_VERSION") {
Some(bindgen::callbacks::IntKind::I32)
} else {
None
}
}
}
const MISSING_SETUP: &str = r#"
discord_game_sdk_sys: Hello,
You are trying to link to the Discord Game SDK.
Some additional set-up is required, namely some files need to be copied for the linker:
# Linux: prepend with `lib` and add to library search path
$ cp $DISCORD_GAME_SDK_PATH/lib/x86_64/{,lib}discord_game_sdk.so
$ export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}$DISCORD_GAME_SDK_PATH/lib/x86_64
# Mac OS: prepend with `lib` and add to library search path
$ cp $DISCORD_GAME_SDK_PATH/lib/x86_64/{,lib}discord_game_sdk.dylib
$ export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH:+${DYLD_LIBRARY_PATH}:}$DISCORD_GAME_SDK_PATH/lib/x86_64
# Windows: copy `*.dll.lib` to `*.lib` (won't affect library search)
$ cp $DISCORD_GAME_SDK_PATH/lib/x86_64/discord_game_sdk.{dll.lib,lib}
$ cp $DISCORD_GAME_SDK_PATH/lib/x86/discord_game_sdk.{dll.lib,lib}
After all this, `cargo build` and `cargo run` should function as expected.
Please report any issues you have at:
https://github.com/ldesgoui/discord_game_sdk
Thanks, and apologies for the inconvenience
"#;
const INCOMPATIBLE_PLATFORM: &str = r#"
discord_game_sdk_sys: Hello,
You are trying to link to the Discord Game SDK.
Unfortunately, the platform you are trying to target is not supported.
Please report any issues you have at:
https://github.com/ldesgoui/discord_game_sdk
Thanks, and apologies for the inconvenience
"#;
And discord_game_sdk_sys/Cargo.toml
:
[build-dependencies]
bindgen = { version = "0.69.4", default-features = false, features = ["runtime"] }
reqwest = { version = "0.12.5", features = ["blocking"] }
zip = "2.1.3"
from rust.
Oh I see, so their SDK cannot be used in Rust as library at the moment. Perhaps this issue can be filed to Discord then?
from rust.
Yeah, that would be your best bet. Until they have fixed it, maybe you could try somehow patching the import library to remove the rust_eh_personality
export?
from rust.
It can compile when I used
lib /MACHINE:X86 /def:discord_game_sdk.def /out:discord_game_sdk.lib
with
LIBRARY DISCORD_GAME_SDK
EXPORTS
DiscordCreate @1
DiscordVersion @2
Reference: https://stackoverflow.com/a/280567
from rust.
Related Issues (20)
- Jump threading MIR opt unsoundly uses bitpattern equality for floats HOT 15
- ICE: `trait takes 1 generic argument but 0 generic arguments were supplied` HOT 2
- Bug when using `cargo check` (my program works with `cargo run`) HOT 1
- zero-sized slices are sometimes placed at 0x1 (1.79+) HOT 16
- Documentation of default value for config.toml's `rust.channel` is inaccurate
- Rustdoc: struct fields are spaced too closely HOT 3
- [Enhancement]: `must_use_xor` to Force Using One of the Functions but not all in a Struct HOT 1
- false positive `dead_code` "never constructed" warning on 1.80.0 for a `struct` where the constructor takes `&'static self` HOT 11
- rustc_contracts: differentiate between exhaustive and non-exhaustive contracts
- ICE: The Rust Compiler Panicked After I Removed A Windows SDK HOT 4
- rustc book does not document RUST_TARGET_PATH HOT 1
- Tracking Issue for `nonzero_bitwise`
- Linking with `rust-lld` causes SIGSEGV in FFI code HOT 7
- Effective breakage to `jiff` due to `ambiguous_negative_literals` HOT 3
- Tracking Issue for `float_semantics` RFC 3514 HOT 1
- Spurious CI failures on x86_64-msvc-ext: "failed to remove file `C:\a\rust\rust\build\x86_64-pc-windows-msvc\stage2-tools\x86_64-pc-windows-msvc\release\cargo.exe`" HOT 1
- compiletest: add a `needs-subprocess` directive HOT 2
- Add back io::copy file to pipe optimization HOT 13
- The suggestion to remove generic parameters proposed by help did not remove comma HOT 5
- Unhelpful error message "Attempt to negate with overflow" when calling `i64::abs(i64::MIN)`.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rust.