我在DarkEld3r's os_info repository中打开了一个拉取请求,以检索实际的Windows版本和版本名称。
应用程序需要链接到ntdll.dll才能使用RtlGetVersion()
。当使用Cygwin和普通的Windows控制台将目标设置为x86_64-pc-windows-msvc
时,DLL会正确链接。当目标为x86_64-pc-windows-gnu
时,the linker returns an error:
Running `rustc --crate-name print_version examples\print_version.rs --crate-type bin --emit=dep-info,link -C debuginfo=2 -C metadata=ec9720acb7c740b3 -C extra-filename=-ec9720acb7c740b3 --out-dir C:\projects\os-info\target\debug\examples -L dependency=C:\projects\os-info\target\debug\deps --extern kernel32=C:\projects\os-info\target\debug\deps\libkernel32-beacffc979f26c46.rlib --extern user32=C:\projects\os-info\target\debug\deps\libuser32-fbb28ae30109687c.rlib --extern winapi=C:\projects\os-info\target\debug\deps\libwinapi-bb7af3f2a31ea235.rlib --extern os_info=C:\projects\os-info\target\debug\deps\libos_info-c5887b186deb8679.rlib`
error: linking with `gcc` failed: exit code: 1
|
= note: "gcc" "-Wl,--enable-long-section-names" "-fno-use-linker-plugin" "-Wl,--nxcompat" "-nostdlib" "-m64" "C:\\Users\\appveyor\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib\\crt2.o" "C:\\Users\\appveyor\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib\\rsbegin.o" "-L" "C:\\Users\\appveyor\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib" "C:\\projects\\os-info\\target\\debug\\examples\\print_version-ec9720acb7c740b3.print_version0.rust-cgu.o" "C:\\projects\\os-info\\target\\debug\\examples\\print_version-ec9720acb7c740b3.print_version1.rust-cgu.o" "C:\\projects\\os-info\\target\\debug\\examples\\print_version-ec9720acb7c740b3.print_version10.rust-cgu.o" "C:\\projects\\os-info\\target\\debug\\examples\\print_version-ec9720acb7c740b3.print_version11.rust-cgu.o" "C:\\projects\\os-info\\target\\debug\\examples\\print_version-ec9720acb7c740b3.print_version12.rust-cgu.o" "C:\\projects\\os-info\\target\\debug\\examples\\print_version-ec9720acb7c740b3.print_version2.rust-cgu.o" "C:\\projects\\os-info\\target\\debug\\examples\\print_version-ec9720acb7c740b3.print_version3.rust-cgu.o" "C:\\projects\\os-info\\target\\debug\\examples\\print_version-ec9720acb7c740b3.print_version4.rust-cgu.o" "C:\\projects\\os-info\\target\\debug\\examples\\print_version-ec9720acb7c740b3.print_version5.rust-cgu.o" "C:\\projects\\os-info\\target\\debug\\examples\\print_version-ec9720acb7c740b3.print_version6.rust-cgu.o" "C:\\projects\\os-info\\target\\debug\\examples\\print_version-ec9720acb7c740b3.print_version7.rust-cgu.o" "C:\\projects\\os-info\\target\\debug\\examples\\print_version-ec9720acb7c740b3.print_version8.rust-cgu.o" "C:\\projects\\os-info\\target\\debug\\examples\\print_version-ec9720acb7c740b3.print_version9.rust-cgu.o" "-o" "C:\\projects\\os-info\\target\\debug\\examples\\print_version-ec9720acb7c740b3.exe" "C:\\projects\\os-info\\target\\debug\\examples\\print_version-ec9720acb7c740b3.crate.allocator.rust-cgu.o" "-Wl,--gc-sections" "-nodefaultlibs" "-L" "C:\\projects\\os-info\\target\\debug\\deps" "-L" "C:\\Users\\appveyor\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib" "-Wl,-Bstatic" "C:\\projects\\os-info\\target\\debug\\deps\\libos_info-c5887b186deb8679.rlib" "C:\\projects\\os-info\\target\\debug\\deps\\libkernel32-beacffc979f26c46.rlib" "C:\\projects\\os-info\\target\\debug\\deps\\libuser32-fbb28ae30109687c.rlib" "C:\\projects\\os-info\\target\\debug\\deps\\libwinapi-bb7af3f2a31ea235.rlib" "C:\\Users\\appveyor\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib\\libstd-60d4a252bdda9250.rlib" "C:\\Users\\appveyor\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib\\libpanic_unwind-0b63e20460046692.rlib" "C:\\Users\\appveyor\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib\\libunwind-7daa32005d584d8a.rlib" "C:\\Users\\appveyor\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib\\liblibc-49ff25caaa6e945f.rlib" "C:\\Users\\appveyor\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib\\liballoc_system-a05404e5e059417a.rlib" "C:\\Users\\appveyor\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib\\liballoc-f824a78e715239af.rlib" "C:\\Users\\appveyor\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib\\libstd_unicode-2abaea46f194a6e1.rlib" "C:\\Users\\appveyor\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib\\librand-81cbf6f1d5a19206.rlib" "C:\\Users\\appveyor\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib\\libcore-f2bd2d524c6ace24.rlib" "C:\\Users\\appveyor\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib\\libcompiler_builtins-c6139fac5e899293.rlib" "-Wl,-Bdynamic" "-l" "ntdll" "-l" "kernel32" "-l" "user32" "-l" "advapi32" "-l" "ws2_32" "-l" "userenv" "-l" "shell32" "-Wl,-Bstatic" "-l" "gcc_eh" "-l" "pthread" "-Wl,-Bdynamic" "-lmingwex" "-lmingw32" "-lgcc" "-lmsvcrt" "-luser32" "-lkernel32" "C:\\Users\\appveyor\\.rustup\\toolchains\\stable-x86_64-pc-windows-gnu\\lib\\rustlib\\x86_64-pc-windows-gnu\\lib\\rsend.o"
= note: ld: cannot find -lntdll
NTDLL.DLL已链接on line 12 of this file。
我没有发现任何关于链接到NTDLL的问题。我找到了How do I specify the linker path in Rust?,但这个解决方案对我来说也不起作用。我在Cygwin的/usr/lib/w32api
目录中找到了“libntdll.a”库,但似乎GCC没有使用它。
在针对GNU时,有没有办法让它在Windows上运行,或者在链接系统DLL时我被迫使用MSVC目标?
答案 0 :(得分:1)
我通过查看winapi crate repository来了解如何做到这一点。
因为,0.2.8的crate不支持RtlGetVersion()DLL函数,所以我必须在repo中包含libntdll.a。完成后,我必须创建一个自定义构建脚本来包含库的源路径。
```
/// build.rs
/// Run custom functionality when a build executes
fn main() {
use std::env::var;
use std::path::Path;
// When targeting x86_64-pc-windows-gnu, we need to include the DLL libraries
// found in the lib/x86_64 directory
if var("TARGET").map(|target| target == "x86_64-pc-windows-gnu").unwrap_or(false) {
let dir = var("CARGO_MANIFEST_DIR").unwrap();
println!("cargo:rustc-link-search=native={}", Path::new(&dir).join("lib/x86_64").display());
}
// When targeting i686-pc-windows-gnu, we need to include the DLL libraries
// found in the lib/i686 directory
if var("TARGET").map(|target| target == "i686-pc-windows-gnu").unwrap_or(false) {
let dir = var("CARGO_MANIFEST_DIR").unwrap();
println!("cargo:rustc-link-search=native={}", Path::new(&dir).join("lib/i686").display());
}
}
```
答案 1 :(得分:0)
默认情况下 ntdll.dll 文件不在 GNU windows 目标的路径上,因此您可以通过在 build.rs 文件中写入以下内容来添加它:
fn main() {
println!(r"cargo:rustc-link-search=C:\windows\system32");
}