rust-lang / rust-bindgen

Automatically generates Rust FFI bindings to C (and some C++) libraries.
https://rust-lang.github.io/rust-bindgen/
BSD 3-Clause "New" or "Revised" License
4.45k stars 694 forks source link

cannot build a rust file using std::complex #1738

Open afeldman opened 4 years ago

afeldman commented 4 years ago

I want to build an interface between c++ and rust, but different errors occurred.

Input C/C++ Header

#ifndef __TEST_HPP__
#define __TEST_HPP__

#include <cstdint>
#include <array>
#include <complex>

template<uint32_t s_>
class Config{
    uint16_t    doppler_idx;
    uint16_t    range_idx;
    std::array< std::complex<float> , s_> vector;
};

#endif

If I rename the types to

class Complex : std::complex<float>{}; 

seems to help, but then I do not have the functions, containing the std::complex parent class.

Bindgen Invocation

extern crate bindgen;

use std::env;
use std::path::PathBuf;

fn main() {
    let bindings = bindgen::Builder::default()
        .header("test.hpp")
        .clang_arg("-std=c++17")
        .clang_arg("-x")
        .clang_arg("c++")
        .opaque_type("std::.*")
        .generate()    
        .unwrap();

    // Write the bindings to the $OUT_DIR/bindings.rs file.
    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("test.rs"))
        .expect("Couldn't write bindings!");
}

Actual Results

       Fresh version_check v0.1.5
       Fresh cc v1.0.50
       Fresh glob v0.3.0
       Fresh lazy_static v1.4.0
       Fresh unicode-xid v0.2.0
       Fresh regex-syntax v0.6.14
       Fresh quick-error v1.2.3
       Fresh unicode-width v0.1.7
       Fresh cfg-if v0.1.10
       Fresh ansi_term v0.11.0
       Fresh termcolor v1.1.0
       Fresh vec_map v0.8.1
       Fresh strsim v0.8.0
       Fresh shlex v0.1.1
       Fresh peeking_take_while v0.1.2
       Fresh lazycell v1.2.1
       Fresh rustc-hash v1.1.0
       Fresh thread_local v1.0.1
       Fresh humantime v1.3.0
       Fresh textwrap v0.11.0
       Fresh libc v0.2.67
       Fresh memchr v2.3.3
       Fresh log v0.4.8
       Fresh proc-macro2 v1.0.9
       Fresh bitflags v1.2.1
       Fresh atty v0.2.14
       Fresh aho-corasick v0.7.8
       Fresh nom v4.2.3
       Fresh libloading v0.5.2
       Fresh quote v1.0.2
       Fresh which v3.1.0
       Fresh regex v1.3.4
       Fresh cexpr v0.3.6
       Fresh clap v2.33.0
       Fresh clang-sys v0.28.1
       Fresh env_logger v0.7.1
       Fresh bindgen v0.53.1
   Compiling test v0.1.0 (/mnt/c/Users/Anton/rust_ffi)
     Running `rustc --crate-name test src/lib.rs --error-format=json --json=diagnostic-rendered-ansi --emit=dep-info,link -C debuginfo=2 --test -C metadata=8090ca622680a031 -C extra-filename=-8090ca622680a031 --out-dir /mnt/c/Users/Anton/rust_ffi/target/debug/deps -C incremental=/mnt/c/Users/Anton/rust_ffi/target/debug/incremental -L dependency=/mnt/c/Users/Anton/rust_ffi/target/debug/deps`
     Running `rustc --crate-name test src/lib.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type lib --emit=dep-info,metadata,link -C debuginfo=2 -C metadata=ea306d16b166d5b8 -C extra-filename=-ea306d16b166d5b8 --out-dir /mnt/c/Users/Anton/rust_ffi/target/debug/deps -C incremental=/mnt/c/Users/Anton/rust_ffi/target/debug/incremental -L dependency=/mnt/c/Users/Anton/rust_ffi/target/debug/deps`
error[E0428]: the name `FP_INT_UPWARD` is defined multiple times
     --> /mnt/c/Users/Anton/rust_ffi/target/debug/build/test-4a7a62747503f49c/out/test.rs:13105:1
      |
1000  | pub const FP_INT_UPWARD: u32 = 0;
      | --------------------------------- previous definition of the value `FP_INT_UPWARD` here

...

error[E0412]: cannot find type `_Tp` in this scope
    --> /mnt/c/Users/Anton/rust_ffi/target/debug/build/test-4a7a62747503f49c/out/test.rs:1250:27
     |
1250 |     pub static std_value: _Tp;
     |                           ^^^ not found in this scope

error[E0412]: cannot find type `_Value` in this scope
    --> /mnt/c/Users/Anton/rust_ffi/target/debug/build/test-4a7a62747503f49c/out/test.rs:6555:33
     |
6555 |     pub static __gnu_cxx___min: _Value;
     |                                 ^^^^^^ not found in this scope

error[E0412]: cannot find type `_Value` in this scope
    --> /mnt/c/Users/Anton/rust_ffi/target/debug/build/test-4a7a62747503f49c/out/test.rs:6559:33
     |
6559 |     pub static __gnu_cxx___max: _Value;
     |                                 ^^^^^^ not found in this scope

error[E0391]: cycle detected when processing `int_type`
     --> /mnt/c/Users/Anton/rust_ffi/target/debug/build/test-4a7a62747503f49c/out/test.rs:17321:21
      |
17321 | pub type int_type = int_type;
      |                     ^^^^^^^^
      |
      = note: ...which again requires processing `int_type`, completing the cycle
note: cycle used when collecting item types in top-level module
     --> src/lib.rs:1:1
      |
1     | / #![allow(non_upper_case_globals)]
2     | | #![allow(non_camel_case_types)]
3     | | #![allow(non_snake_case)]
4     | |
5     | | include!(concat!(env!("OUT_DIR"), "/test.rs"));
      | |_______________________________________________^

error: aborting due to 18 previous errors

Some errors have detailed explanations: E0391, E0412, E0428.
For more information about an error, try `rustc --explain E0391`.
error: could not compile `test`.

Caused by:
  process didn't exit successfully: `rustc --crate-name test src/lib.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type lib --emit=dep-info,metadata,link -C debuginfo=2 -C metadata=ea306d16b166d5b8 -C extra-filename=-ea306d16b166d5b8 --out-dir /mnt/c/Users/Anton/rust_ffi/target/debug/deps -C incremental=/mnt/c/Users/Anton/rust_ffi/target/debug/incremental -L dependency=/mnt/c/Users/Anton/rust_ffi/target/debug/deps` (exit code: 1)
warning: build failed, waiting for other jobs to finish...
error[E0412]: cannot find type `_Tp` in this scope
    --> /mnt/c/Users/Anton/rust_ffi/target/debug/build/test-4a7a62747503f49c/out/test.rs:1250:27
     |
1250 |     pub static std_value: _Tp;
     |                           ^^^ not found in this scope

error[E0412]: cannot find type `_Value` in this scope
    --> /mnt/c/Users/Anton/rust_ffi/target/debug/build/test-4a7a62747503f49c/out/test.rs:6555:33
     |
6555 |     pub static __gnu_cxx___min: _Value;
     |                                 ^^^^^^ not found in this scope

error[E0412]: cannot find type `_Value` in this scope
    --> /mnt/c/Users/Anton/rust_ffi/target/debug/build/test-4a7a62747503f49c/out/test.rs:6559:33
     |
6559 |     pub static __gnu_cxx___max: _Value;
     |                                 ^^^^^^ not found in this scope

error[E0391]: cycle detected when processing `int_type`
     --> /mnt/c/Users/Anton/rust_ffi/target/debug/build/test-4a7a62747503f49c/out/test.rs:17321:21
      |
17321 | pub type int_type = int_type;
      |                     ^^^^^^^^
      |
      = note: ...which again requires processing `int_type`, completing the cycle
note: cycle used when collecting item types in top-level module
     --> src/lib.rs:1:1
      |
1     | / #![allow(non_upper_case_globals)]
2     | | #![allow(non_camel_case_types)]
3     | | #![allow(non_snake_case)]
4     | |
5     | | include!(concat!(env!("OUT_DIR"), "/test.rs"));
      | |_______________________________________________^

error: aborting due to 18 previous errors

Some errors have detailed explanations: E0391, E0412, E0428.
For more information about an error, try `rustc --explain E0391`.
error: could not compile `test`.

Caused by:
  process didn't exit successfully: `rustc --crate-name test src/lib.rs --error-format=json --json=diagnostic-rendered-ansi --emit=dep-info,link -C debuginfo=2 --test -C metadata=8090ca622680a031 -C extra-filename=-8090ca622680a031 --out-dir /mnt/c/Users/Anton/rust_ffi/target/debug/deps -C incremental=/mnt/c/Users/Anton/rust_ffi/target/debug/incremental -L dependency=/mnt/c/Users/Anton/rust_ffi/target/debug/deps` (exit code: 1)
emilio commented 4 years ago

Yeah, std template soup really confuses bindgen sometimes. This could get some work... Generally we're already close-to-libclang-limits when dealing with templates :(

tgross35 commented 1 year ago

Does anyone have a correct recipe to get these to be ignored?

I currently have

.blocklist_function("strtold")
// qvct, evct, qfcvt_r, ...
.blocklist_function("[a-z]{1,2}cvt(?:_r)?")
// c++ things that aren't supported
.blocklist_item("List_iterator")
.blocklist_type("std::char_traits")
.opaque_type("std_.*")
.blocklist_item("std_basic_string")
.blocklist_item("std_collate.*")
.blocklist_item("__gnu_cxx__min")

I have tried a ton of combinations of blocklist and opaque, but I can't for the life of me get it to not include the following:

pub type std_collate_string_type = std_basic_string<_CharT>;
pub type std_collate_byname_string_type = std_basic_string<_CharT>;
extern "C" {
    #[link_name = "\u{1}value"]
    pub static std_value: _Tp;
}
extern "C" {
    #[link_name = "\u{1}__min"]
    pub static __gnu_cxx___min: _Value;
}
extern "C" {
    #[link_name = "\u{1}__max"]
    pub static __gnu_cxx___max: _Value;
}
evanw commented 1 year ago

I'm hitting this after upgrading to Xcode 14.3:

error[E0412]: cannot find type `_Tp` in this scope
  --> bindings.rs:89:27
   |
89 |     pub static std_value: _Tp;
   |                           ^^^ not found in this scope

I found this issue through Google. FWIW I can get rid of the _Tp problem with this:

.blocklist_item("std::value")
bokenator commented 1 year ago

Does anyone have a correct recipe to get these to be ignored?

I currently have

.blocklist_function("strtold")
// qvct, evct, qfcvt_r, ...
.blocklist_function("[a-z]{1,2}cvt(?:_r)?")
// c++ things that aren't supported
.blocklist_item("List_iterator")
.blocklist_type("std::char_traits")
.opaque_type("std_.*")
.blocklist_item("std_basic_string")
.blocklist_item("std_collate.*")
.blocklist_item("__gnu_cxx__min")

I have tried a ton of combinations of blocklist and opaque, but I can't for the life of me get it to not include the following:

pub type std_collate_string_type = std_basic_string<_CharT>;
pub type std_collate_byname_string_type = std_basic_string<_CharT>;
extern "C" {
    #[link_name = "\u{1}value"]
    pub static std_value: _Tp;
}
extern "C" {
    #[link_name = "\u{1}__min"]
    pub static __gnu_cxx___min: _Value;
}
extern "C" {
    #[link_name = "\u{1}__max"]
    pub static __gnu_cxx___max: _Value;
}
.blocklist_file(r"/usr/share/mingw-w64/include/.*")
.blocklist_file(r"/usr/lib/gcc/x86_64-w64-mingw32/.*")

worked for me and excluded all of the items you mentioned.

empire-penguin commented 6 months ago

Does anyone have a correct recipe to get these to be ignored?

I currently have

.blocklist_function("strtold")
// qvct, evct, qfcvt_r, ...
.blocklist_function("[a-z]{1,2}cvt(?:_r)?")
// c++ things that aren't supported
.blocklist_item("List_iterator")
.blocklist_type("std::char_traits")
.opaque_type("std_.*")
.blocklist_item("std_basic_string")
.blocklist_item("std_collate.*")
.blocklist_item("__gnu_cxx__min")

I have tried a ton of combinations of blocklist and opaque, but I can't for the life of me get it to not include the following:

pub type std_collate_string_type = std_basic_string<_CharT>;
pub type std_collate_byname_string_type = std_basic_string<_CharT>;
extern "C" {
    #[link_name = "\u{1}value"]
    pub static std_value: _Tp;
}
extern "C" {
    #[link_name = "\u{1}__min"]
    pub static __gnu_cxx___min: _Value;
}
extern "C" {
    #[link_name = "\u{1}__max"]
    pub static __gnu_cxx___max: _Value;
}

On linux what worked for me was:

.blocklist_item("std::value")
.blocklist_item("__gnu_cxx::__min")
.blocklist_item("__gnu_cxx::__max")

Apparently bindgen uses underscores as a replacement for scope resolution operator