Rust-bindgen: Both _WIN32 and _WIN64 are defined when targeting 32-bit windows from 64-bit windows

Created on 6 Oct 2017  路  11Comments  路  Source: rust-lang/rust-bindgen

I tried to investigate https://github.com/rust-lang-nursery/rust-bindgen/issues/541 and found out that both _WIN32 and _WIN64 are defined. I could see how it makes many troubles, and perhaps related to that issue .
It won't happen if the command has the --target=i686-pc-windows-msvc flag, but it does happen if it has the --target=x86_64-pc-windows-msvc flag.
It also happens when I use bindgen through build.rs script (this way it happens on both cargo run --target=i686-pc-windows-msvc and cargo run --target=x86_64-pc-windows-msvc).

Input C/C++ Header

// example.h
#ifdef _WIN32
typedef int type1;
#endif
#ifdef _WIN64
typedef long long type2;
#endif

Bindgen Invocation

bindgen.exe example.h

Actual Results

pub type type1 = ::std::os::raw::c_int;
pub type type2 = ::std::os::raw::c_longlong;

Expected Results

// when --target=i686-pc-windows-msvc

pub type type1 = ::std::os::raw::c_int;

// when --target=x86_64-pc-windows-msvc

pub type type2 = ::std::os::raw::c_longlong;
A-macros

Most helpful comment

_WIN32 is always defined these days (on both 32 and 64 bit targets), see https://msdn.microsoft.com/en-us/library/b0084kay.aspx

_WIN32 Defined as 1 when the compilation target is 32-bit ARM, 64-bit ARM, x86, or x64. Otherwise, undefined.
_WIN64 Defined as 1 when the compilation target is 64-bit ARM or x64. Otherwise, undefined.

32 here is supposed to be the opposite to 16, not 64.

All 11 comments

Thanks for the bug report!

I'm not really familiar with windows development, but to be clear, only one of either _WIN32 or _WIN64 should ever be defined at once, right?

_WIN32 is always defined these days (on both 32 and 64 bit targets), see https://msdn.microsoft.com/en-us/library/b0084kay.aspx

_WIN32 Defined as 1 when the compilation target is 32-bit ARM, 64-bit ARM, x86, or x64. Otherwise, undefined.
_WIN64 Defined as 1 when the compilation target is 64-bit ARM or x64. Otherwise, undefined.

32 here is supposed to be the opposite to 16, not 64.

_WIN32 is always defined these days (on both 32 and 64 bit targets), see https://msdn.microsoft.com/en-us/library/b0084kay.aspx

Does that mean that this issue can be closed as exhibiting expected behavior?

Ah good to know.
Yet there is a problem, because through build.rs script _WIN64 is defined for 32bit.

To make sure I understand: the remaining issue is that when invoking bindgen as a library via build.rs on 32 bit host platforms, _WIN64 is still defined? But not when targeting 32-bit from 64 bit?

No.
It happens on my 64 bit machine when targeting to 32 bit.
I don't know what happens on 32 bit hosts.

Thanks for the clarification!

If I had to guess, I'd say it's related to https://github.com/rust-lang/rust/issues/42587
In other words, I guess that the bindgen library uses conditional compilation that misleads it because it's executed on a process that is 64 bit (like the build host).

Update:
It happens on version 0.30, but it's working as expected on master.

Ok I used git bisect to find the commit that solved it and it's https://github.com/rust-lang-nursery/rust-bindgen/commit/26da3447a73d0364849f0325f222c4a8c9337550
Makes sense that it solved it because it implements find_effective_target.

Only need to publish a new version.

We'll publish a new version after merging https://github.com/rust-lang-nursery/rust-bindgen/pull/1042

Was this page helpful?
0 / 5 - 0 ratings