Closed stuartZhang closed 3 years ago
That means that the examples build.rs failed to run. Not much opportunity for that one to fail really.
I assume you don't have libglib-2.0-0.dll and libgio-2.0-0.dll (or without the lib-prefix) not in your PATH
?
Try running https://github.com/lucasg/Dependencies on H:\github_projects\gtk-rs\target\debug\build\gtk-rs-examples-ef7eb270685706d0\build-script-build
to see which DLLs it doesn't find.
Hello @sdroege ,
Indeed, there are the (libglib-2.0-0.dll) and (libgio-2.0-0.dll) in (msys2) directory:
Maybe, is it helpful for me to uninstall them from (msys2)?
You mean you have multiple versions in your PATH
? That seems problematic, yes.
You mean you have multiple versions in your
PATH
? That seems problematic, yes.
@sdroege I discovered that both (libglib-2.0-0.dll) and (libgio-2.0-0.dll) are just one of (mingw-w64-x86_64-gtk3)'s dependencies. It means there aren't multiple versions. In fact,
mingw-w64-x86_64-gtk3 --> mingw-w64-x86_64-glib2 --> (libglib-2.0-0.dll) and (libgio-2.0-0.dll)
@sdroege I run (DependenciesGui.exe) from (msys2) so that all ENV variables visible to (msys2) are available to (DependenciesGui.exe).
I lose the DLL files:
That seems like a problem in your setup then, best to bring that up with the msys64 project where you got the binaries from.
Hello @sdroege , I have just resolved the problem utterly. The root reason is
On the contrary, (libgio-2.0-0.dll) enables (SafeDllSearchMode). That's to say,
As a result, regardless of what the PATH env variable is, the DLL files under the (C:/Windows/System32) folder always take precedence over others. The merely workaround is to place (zlib1.dll) in the same folder as the (*.exe) file that (cargo run) outputs.
Conclusion:
@sdroege Do you know how to disable (SafeDllSearchMode) partly and temporarily?
Sorry, I don't
There are more details about safe dll search here: https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order
There is no way to make windows load DLLs from PATH
first. You should basically never put third-party DLLs in C:\Windows\System32
. Any installer that does that is broken. The DLL search order exists so that system libraries are always loaded correctly.
Hello @nirbheek @sdroege ,
I submit my awesome solution for the hassle specific to Windows OS:
Under the project-root directory, write a new file named "build.rs" and including the following codes. Here, I have to paste the source code, because the *.rs file can't be uploaded normally.
use ::std::{env, fs, os, path::Path, process};
#[cfg(windows)]
fn main() {
let msys2_home = match env::var("MSYS2_HOME") {
Ok(value) => value,
Err(_) => {
println!("cargo:warning=环境变量`MSYS2_HOME`没有提供,没有链接操作会被执行");
return;
}
};
println!("调试:MSYS2_HOME={}", msys2_home);
let out_dir = env::var("OUT_DIR")
.expect("失败:环境变量`OUT_DIR`未提供");
println!("调试:OUT_DIR={}", out_dir);
let exe_dir = Path::new(&out_dir[..]).join("../../..").canonicalize()
.expect(&format!("失败:不能从 {} 推断出 exe 目录", out_dir)[..]);
println!("调试:EXE_DIR={}", exe_dir.display());
if !exe_dir.is_dir() {
println!("cargo:warning={} 不是一个目录", exe_dir.display());
process::exit(1);
}
let zlib1_exe = exe_dir.join("zlib1.dll");
println!("调试:ZLIB1_EXE={}", zlib1_exe.display());
if zlib1_exe.exists() {
fs::remove_file(zlib1_exe.clone())
.expect(&format!("失败:不能删除原来的 {} 符号链接文件", zlib1_exe.display())[..]);
}
let bits = if cfg!(target_pointer_width = "32") {
32usize
} else {
64usize
};
let bin_dir = Path::new(&msys2_home[..]).join(&format!("mingw{}", bits)[..]).join("bin");
let bin_dir = bin_dir.canonicalize()
.expect(&format!("失败:不能从 {} 推断出 mingw**/bin 目录", bin_dir.display())[..]);
println!("调试:BIN_DIR={}", bin_dir.display());
if !bin_dir.is_dir() {
println!("cargo:warning={} 不是一个目录", bin_dir.display());
process::exit(1);
}
let zlib1_file = bin_dir.join("zlib1.dll");
println!("调试:ZLIB1_FILE={}", zlib1_file.display());
if !zlib1_file.is_file() {
println!("cargo:warning={} 不是一个文件", zlib1_file.display());
process::exit(1);
}
os::windows::fs::symlink_file(zlib1_file.clone(), zlib1_exe.clone())
.expect(&format!("失败:不能创建文件链接 {} 指向 {}", zlib1_exe.display(), zlib1_file.display())[..]);
println!("成功:能创建文件链接 {} 指向 {}", zlib1_exe.display(), zlib1_file.display());
}
Make a custom environment variable "MSYS2_HOME" which holds the absolute path of the MSYS2 installation directory.
And then, before (cargo & rustc) really compile the rust source code, a soft symbolic link pointing to one of (msys2/mingw64/bin/zlib1.dll) and (msys2/mingw32/bin/zlib1.dll) is always automatically made and named after "zlib1.dll" under the either "target/debug" or "target/release" folder in the project directory. The action is merely taken in Windows OS.
Perfect! Bypass all rules related to the DLL Searching Orders.
Hello,
According to the tutorial, I have done the following steps:
My question: which action I have taken is wrong?