Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cross-compiling raw-dylib doesn't work on Windows #103939

Open
mati865 opened this issue Nov 3, 2022 · 17 comments
Open

Cross-compiling raw-dylib doesn't work on Windows #103939

mati865 opened this issue Nov 3, 2022 · 17 comments
Assignees
Labels
C-bug Category: This is a bug. F-raw_dylib `#![feature(raw_dylib)]` O-windows-gnu Toolchain: GNU, Operating system: Windows T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@mati865
Copy link
Contributor

mati865 commented Nov 3, 2022

I tried this code:

#![feature(raw_dylib)]

fn main() {
    unsafe {
        MessageBoxA(0, b"hello\0".as_ptr(), "world\0".as_ptr(), 0);
    }
}

#[link(name = "user32", kind = "raw-dylib")]
extern "system" {
    fn MessageBoxA(hwnd: usize, lptext: *const u8, lpcaption: *const u8, flags: u32) -> i32;
}

I expected to see this happen:
Successful compilation

Instead, this happened:

$ PATH=/d/msys64/mingw32/bin:$PATH /c/Users/mateusz/.cargo/bin/rustc test.rs --target i686-pc-windows-gnu
error: Error calling dlltool: program not found

error: aborting due to previous error

Worth mentioning it works fine when building natively from x86_64 to x86_64 target.

Meta

rustc --version --verbose:

rustc 1.67.0-nightly (edf018221 2022-11-02)
binary: rustc
commit-hash: edf0182213a9e30982eb34f3925ddc4cf5ed3471
commit-date: 2022-11-02
host: x86_64-pc-windows-gnu
release: 1.67.0-nightly
LLVM version: 15.0.4
@mati865 mati865 added the C-bug Category: This is a bug. label Nov 3, 2022
@bjorn3
Copy link
Member

bjorn3 commented Nov 3, 2022

// We are cross-compiling, so we need the tool with the prefix matching our target
if sess.target.arch == "x86" {
"i686-w64-mingw32-dlltool"
} else {
"x86_64-w64-mingw32-dlltool"
}

Looks like rustc expects a toolchain that cross compiles from the host (x86_64 mingw) to the target (i686 mingw) rather than a toolchain native to the target (i686 mingw) like in your case. I guess it could try both executable names.

@mati865
Copy link
Contributor Author

mati865 commented Nov 3, 2022

On Windows toolchains commonly provide only dlltool without prefix but it's possible to cross-generate import library using dlltool for any host with trick discovered by glandium: microsoft/windows-rs@cb8d6a9 (#2016)

@mati865
Copy link
Contributor Author

mati865 commented Nov 15, 2022

I have it on my radar but cannot tell when when I can find free time to do it.

@dpaoliello
Copy link
Contributor

@rustbot claim

bors added a commit to rust-lang-ci/rust that referenced this issue Mar 23, 2023
Fix cross-compiling with dlltool for raw-dylib

Fix for rust-lang#103939

Issue Details:
When attempting to cross-compile using the `raw-dylib` feature and the GNU toolchain, rustc would attempt to find a cross-compiling version of dlltool (e.g., `i686-w64-mingw32-dlltool`). The has two issues 1) on Windows dlltool is always `dlltool` (no cross-compiling named versions exist) and 2) it only supported compiling to i686 and x86_64 resulting in ARM 32 and 64 compiling as x86_64.

Fix Details:
* On Windows always use the normal `dlltool` binary.
* Add the ARM64 cross-compiling dlltool name (support for this is coming: https://sourceware.org/bugzilla/show_bug.cgi?id=29964)
* Provide the `-m` argument to dlltool to indicate the target machine type.

(This is the first of two PRs to fix the remaining issues for the `raw-dylib` feature (rust-lang#58713) that is blocking stabilization (rust-lang#104218))
@eiderdaus
Copy link

I am unsure whether the linked pull request above actually fixed this issue for cross-compilation, but I get the same exact error with the stable-x86_64-pc-windows-gnu toolchain version 1.71.0. In this version, the feature should have been stabilized. Should I open a new issue because this one only regards cross-compilation?

@dpaoliello
Copy link
Contributor

I am unsure whether the linked pull request above actually fixed this issue for cross-compilation, but I get the same exact error with the stable-x86_64-pc-windows-gnu toolchain version 1.71.0. In this version, the feature should have been stabilized. Should I open a new issue because this one only regards cross-compilation?

@eiderdaus what is your host environment (Windows? Linux?) and what dlltool(s) do you have on your PATH?

@mati865
Copy link
Contributor Author

mati865 commented Aug 2, 2023

Looking at tokio-rs/mio#1632 (comment) your issue is a bit different. How did you install mingw-w64 toolchain?
MSYS2 and mingw-w64 builds provide dlltool.exe but other toolchains might provide x86_64-w64-mingw32-dlltool.exe instead. In such case the easiest workaround is to symlink dlltool.exe pointing to your *-dlltool.exe.

@mati865
Copy link
Contributor Author

mati865 commented Aug 2, 2023

Alternatively you could try RUSTFLAGS='-Cdlltool=<your-dlltool-bin>'.

@eiderdaus
Copy link

Hi, thanks for the prompt responses! My host is Windows, there's no dlltool on my %PATH%. I used Rustup to install Rust and I found a dlltool.exe in the following folder:

%USERPROFILE%.rustup\toolchains\stable-x86_64-pc-windows-gnu\lib\rustlib\x86_64-pc-windows-gnu\bin\self-contained

I would expect that this should be enough for building working Rust applications. I tried passing this dlltool via RUSTFLAGS and got an error

error: Dlltool could not create import library:
       [redacted]\.rustup\toolchains\stable-x86_64-pc-windows-gnu\lib\rustlib\x86_64-pc-windows-gnu\bin\self-contained\dlltool.exe: CreateProcess

How did you install mingw-w64 toolchain?

I never mentioned any mingw-w64 but actually I do have MSYS2 at my disposal. It's not on my %PATH% at the moment. I just used RUSTFLAGS=-Cdlltool=C:\msys64\clang64\bin\dlltool.exe with success - however I would call this a workaround, not a solution!

@dpaoliello
Copy link
Contributor

I never mentioned any mingw-w64 but actually I do have MSYS2 at my disposal. It's not on my %PATH% at the moment. I just used RUSTFLAGS=-Cdlltool=C:\msys64\clang64\bin\dlltool.exe with success - however I would call this a workaround, not a solution!

Correct, the use of dlltool is considered to be a temporary workaround until the minimum required binutils version supports the import libraries that LLVM generates: #104218 (comment)

I the meantime, having dlltool on your PATH, or using -Cdlltool is required.

@mati865
Copy link
Contributor Author

mati865 commented Aug 2, 2023

I would expect that this should be enough for building working Rust applications.

I'd expect that as well.

I tried passing this dlltool via RUSTFLAGS and got an error

error: Dlltool could not create import library:
       [redacted]\.rustup\toolchains\stable-x86_64-pc-windows-gnu\lib\rustlib\x86_64-pc-windows-gnu\bin\self-contained\dlltool.exe: CreateProcess

This definitely doesn't seem right, might be worth to create issue for having self-contained dlltool working by the default.

@eiderdaus
Copy link

I the meantime, having dlltool on your PATH, or using -Cdlltool is required.

Alright, thanks a lot for this information. To be honest I am a little bit disenchanted after the great feature announcement on the Rust blog - I don't normally expect a stabilized feature to still require such workarounds.

This definitely doesn't seem right, might be worth to create issue for having self-contained dlltool working by the default.

Not sure if another issue makes much sense when the whole dlltool invocation should be removed either way if I understood correctly?

@mati865
Copy link
Contributor Author

mati865 commented Aug 2, 2023

Not sure if another issue makes much sense when the whole dlltool invocation should be removed either way if I understood correctly?

Removal of dlltool might take years, in the meantime bundled dlltool should be fixed and used by the default.

@eiderdaus
Copy link

Removal of dlltool might take years, in the meantime bundled dlltool should be fixed and used by the default.

I see. Just so I fully understand: If what I described is a new issue in your opinion, then why is this one still open?

@ChrisDenton ChrisDenton added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. O-windows-gnu Toolchain: GNU, Operating system: Windows F-raw_dylib `#![feature(raw_dylib)]` labels Nov 6, 2023
@ChrisDenton
Copy link
Member

It's been a year since this issue was originally reported. Can we bump the self-contained binutils at least?

@mati865
Copy link
Contributor Author

mati865 commented Nov 6, 2023

Can we bump the self-contained binutils at least?

That's my plan for the near future but it's easier said than done. Though, at current pace it should hit nightly before 2024.

@ChrisDenton
Copy link
Member

Thanks for the quick reply! And sorry that updating is still an ordeal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. F-raw_dylib `#![feature(raw_dylib)]` O-windows-gnu Toolchain: GNU, Operating system: Windows T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants