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

Unsupported calling convention on i686-pc-windows-msvc #541

Closed
tmccrmck opened this issue Feb 25, 2017 · 6 comments
Closed

Unsupported calling convention on i686-pc-windows-msvc #541

tmccrmck opened this issue Feb 25, 2017 · 6 comments

Comments

@tmccrmck
Copy link

I was investigating how easy it would be to create bindings for Windows 32-bit with different calling conventions and so I ran the example in the ./bindgen-integration directory.

System

> rustup show
Default host: x86_64-pc-windows-msvc

installed toolchains
--------------------

stable-i686-pc-windows-msvc
stable-x86_64-pc-windows-msvc (default)
nightly-i686-pc-windows-msvc
nightly-x86_64-pc-windows-msvc

active toolchain
----------------

stable-i686-pc-windows-msvc (directory override for 'C:\Repos\rust-bindgen\bindgen-integration')
rustc 1.15.1 (021bd294c 2017-02-08)


> clang -v
clang version 3.9.1 (branches/release_39)
Target: i686-pc-windows-msvc

Input C/C++ Header

#pragma once

class Test {
  int m_int;
  double m_double;
public:
  static const char* name();
  Test(int foo);
  Test(double foo);

  static const int COUNTDOWN[];
  static const int* COUNTDOWN_PTR;
  static const int* countdown();
};

namespace testing {

typedef Test TypeAlias;

} // namespace testing

typedef testing::TypeAlias TypeAlias;

Bindgen Invokation

let bindings = Builder::default()
        .no_unstable_rust()
        .enable_cxx_namespaces()
        .raw_line("pub use self::root::*;")
        .header("cpp/Test.h")
        .clang_arg("-x")
        .clang_arg("c++")
        .clang_arg("-std=c++11")
        .generate()
        .expect("Unable to generate bindings");

Actual Results

error: failed to run custom build command for `bindgen-integration v0.1.0 (file:///C:/Repos/rust-bindgen/bindgen-integration)`
process didn't exit successfully: `C:\Repos\rust-bindgen\bindgen-integration\target\debug\build\bindgen-integration-a1a8c12a2facefae\build-script-build` (exit code: 101)
--- stdout
TARGET = Some("i686-pc-windows-msvc")
OPT_LEVEL = Some("0")
TARGET = Some("i686-pc-windows-msvc")
HOST = Some("i686-pc-windows-msvc")
TARGET = Some("i686-pc-windows-msvc")
TARGET = Some("i686-pc-windows-msvc")
HOST = Some("i686-pc-windows-msvc")
CXX_i686-pc-windows-msvc = None
CXX_i686_pc_windows_msvc = None
HOST_CXX = None
CXX = None
TARGET = Some("i686-pc-windows-msvc")
HOST = Some("i686-pc-windows-msvc")
CXXFLAGS_i686-pc-windows-msvc = None
CXXFLAGS_i686_pc_windows_msvc = None
HOST_CXXFLAGS = None
CXXFLAGS = None
PROFILE = Some("debug")
running: "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64_x86\\cl.exe" "/nologo" "/MD" "/Z7" "/FoC:\\Repos\\rust-bindgen\\bindgen-integration\\target\\debug\\build\
\bindgen-integration-89b7af89d851f38d\\out\\cpp\\Test.o" "/c" "cpp/Test.cc"
ExitStatus(ExitStatus(0))
TARGET = Some("i686-pc-windows-msvc")
running: "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64_x86\\lib.exe" "/OUT:C:\\Repos\\rust-bindgen\\bindgen-integration\\target\\debug\\build\\bindgen-integratio
n-89b7af89d851f38d\\out\\libtest.a" "/nologo" "C:\\Repos\\rust-bindgen\\bindgen-integration\\target\\debug\\build\\bindgen-integration-89b7af89d851f38d\\out\\cpp\\Test.o"
ExitStatus(ExitStatus(0))
TARGET = Some("i686-pc-windows-msvc")
HOST = Some("i686-pc-windows-msvc")
TARGET = Some("i686-pc-windows-msvc")
TARGET = Some("i686-pc-windows-msvc")
HOST = Some("i686-pc-windows-msvc")
CXX_i686-pc-windows-msvc = None
CXX_i686_pc_windows_msvc = None
HOST_CXX = None
CXX = None
cargo:rustc-link-search=native=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\atlmfc\lib\
cargo:rustc-link-lib=static=test
cargo:rustc-link-search=native=C:\Repos\rust-bindgen\bindgen-integration\target\debug\build\bindgen-integration-89b7af89d851f38d\out
TARGET = Some("i686-pc-windows-msvc")
cpp/Test.h:1:9: warning: #pragma once in main file [-Wpragma-once-outside-header], err: false

--- stderr
thread 'main' panicked at 'unsupported calling convention: 4', C:\Repos\rust-bindgen\src\ir\function.rs:103
note: Run with `RUST_BACKTRACE=1` for a backtrace.

Steps to reproduce

  1. Install clang 3.9.1 for Windows 32-bit
  2. > git clone https://github.com/servo/rust-bindgen.git
  3. > cd rust-bindgen\bindgen-integration
  4. > rustup override set stable-i686-pc-windows-msvc
  5. > cargo build
@tmccrmck
Copy link
Author

OK I wanted to isolate the problem so I could try with stdcall and cdecl so I removed nearly everything from the header:

#pragma once

class Test {
  int m_int;
  double m_double;
public:
  static const char* name();
};

And it compiles with this. But as soon as you try to use cargo test you get

  = note: bindgen_integration-2ef5a86ee87393d3.0.o : error LNK2019: unresolved external symbol _?name@Test@@SAPBDXZ referenced in function __ZN19bindgen_integration8bindings4root4Test4name17h1c2ec80b5b5613d1E
C:\Repos\rust-bindgen\bindgen-integration\target\debug\deps\bindgen_integration-2ef5a86ee87393d3.exe : fatal error LNK1120: 1 unresolved externals

Which just looks like a mangling problem.

@emilio
Copy link
Contributor

emilio commented Feb 25, 2017

I don't have a windows machine to test on, could you inspect the generated library to see which mangled names are being generated?

@froydnj
Copy link
Contributor

froydnj commented May 16, 2017

The original issue here is that calling convention 4 is __thiscall, which is the default ABI for methods in MSVC. However, the packages bindgen is using (syntex_syntax) don't define anything for __thiscall.

@emilio is it feasible to just modify syntex_syntax here to define __thiscall, and then do the appropriate adjustments to bindgen?

@emilio
Copy link
Contributor

emilio commented May 17, 2017

@froydnj yeah, also, note that syntex_syntax is pretty much a clone of libsyntax in the rust compiler, so this should probably be upstreamed.

Is this blocking you in any meaningful way? If there's any workaround we can do in bindgen, happy to help. Perhaps making it a soft error may help for now.

@froydnj
Copy link
Contributor

froydnj commented May 17, 2017

Is this blocking you in any meaningful way? If there's any workaround we can do in bindgen, happy to help. Perhaps making it a soft error may help for now.

Throwing a soft error here is hard, because we have to pass in /something/ for the calling convention. I guess we already have special cases for Obj-C method declarations, we could fake things up for C++ method declarations, and then cross fingers that nobody is actually bindgen'ing calls to C++ methods? That seems like a giant hack, though, with some definite footgun possibilities.

We can work around this in Stylo by simply not building Stylo for win32 for the time being.

bors-servo pushed a commit that referenced this issue May 26, 2017
ir: Don't panic when finding an unknown calling convention until code generation

This unblocks stylo in windows until we get `__thiscall` support in syntex. see #541.
@fitzgen
Copy link
Member

fitzgen commented Jul 21, 2017

All that is required to repro is this:

// bindgen-flags: -- --target=i686-pc-windows-msvc

class Foo {
  public:
    void test();
};

or with --target=i686-pc-win32 as well.

bors-servo pushed a commit that referenced this issue Oct 10, 2017
Add support for the thiscall ABI

Fixes #541

The thiscall ABI is experimental, so in order to use it nightly is required and also the following statement:
`#![feature(abi_thiscall)]`
That's a problem because the `tests_expectations` crate (in the tests folder) tries to compile it (and stable is required).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants