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

autocxx bindings couldn't be generated #673

Closed
schphil opened this issue Nov 14, 2021 · 1 comment
Closed

autocxx bindings couldn't be generated #673

schphil opened this issue Nov 14, 2021 · 1 comment

Comments

@schphil
Copy link

schphil commented Nov 14, 2021

hi, I'm trying to generate bindings for this class: actor_t, but they are not being created. the outcome of the auto-generated file looks like this:

autocxx-ffi-default-gen.rs
#[allow(non_snake_case)]
#[allow(dead_code)]
#[allow(non_upper_case_globals)]
#[allow(non_camel_case_types)]
mod ffi {
    pub trait ToCppString {
        fn into_cpp(self) -> cxx::UniquePtr<cxx::CxxString>;
    }
    impl ToCppString for &str {
        fn into_cpp(self) -> cxx::UniquePtr<cxx::CxxString> {
            make_string(self)
        }
    }
    impl ToCppString for String {
        fn into_cpp(self) -> cxx::UniquePtr<cxx::CxxString> {
            make_string(&self)
        }
    }
    impl ToCppString for &String {
        fn into_cpp(self) -> cxx::UniquePtr<cxx::CxxString> {
            make_string(self)
        }
    }
    impl ToCppString for cxx::UniquePtr<cxx::CxxString> {
        fn into_cpp(self) -> cxx::UniquePtr<cxx::CxxString> {
            self
        }
    }
    mod bindgen {
        pub(super) mod root {
            pub mod valhalla {
                pub mod tyr {
                    pub use cxxbridge::actor_t;
                    impl actor_t {
                        #[doc = "autocxx bindings couldn't be generated: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization."]
                        fn route(_uhoh: autocxx::BindingGenerationFailure) {}
                        #[doc = "autocxx bindings couldn't be generated: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization."]
                        fn locate(_uhoh: autocxx::BindingGenerationFailure) {}
                        #[doc = "autocxx bindings couldn't be generated: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization."]
                        fn matrix(_uhoh: autocxx::BindingGenerationFailure) {}
                        #[doc = "autocxx bindings couldn't be generated: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization."]
                        fn optimized_route(_uhoh: autocxx::BindingGenerationFailure) {}
                        #[doc = "autocxx bindings couldn't be generated: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization."]
                        fn isochrone(_uhoh: autocxx::BindingGenerationFailure) {}
                        #[doc = "autocxx bindings couldn't be generated: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization."]
                        fn trace_route(_uhoh: autocxx::BindingGenerationFailure) {}
                        #[doc = "autocxx bindings couldn't be generated: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization."]
                        fn trace_attributes(_uhoh: autocxx::BindingGenerationFailure) {}
                        #[doc = "autocxx bindings couldn't be generated: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization."]
                        fn height(_uhoh: autocxx::BindingGenerationFailure) {}
                        #[doc = "autocxx bindings couldn't be generated: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization."]
                        fn transit_available(_uhoh: autocxx::BindingGenerationFailure) {}
                        #[doc = "autocxx bindings couldn't be generated: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization."]
                        fn expansion(_uhoh: autocxx::BindingGenerationFailure) {}
                        #[doc = "autocxx bindings couldn't be generated: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization."]
                        fn centroid(_uhoh: autocxx::BindingGenerationFailure) {}
                        #[doc = "autocxx bindings couldn't be generated: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization."]
                        fn status(_uhoh: autocxx::BindingGenerationFailure) {}
                    }
                    #[allow(unused_imports)]
                    use self::super::super::super::super::cxxbridge;
                    #[allow(unused_imports)]
                    use self::super::super::super::super::ToCppString;
                    #[allow(unused_imports)]
                    use self::super::super::super::root;
                }
                #[allow(unused_imports)]
                use self::super::super::super::cxxbridge;
                #[allow(unused_imports)]
                use self::super::super::super::ToCppString;
                #[allow(unused_imports)]
                use self::super::super::root;
            }
            #[allow(unused_imports)]
            use self::super::super::cxxbridge;
            #[allow(unused_imports)]
            use self::super::super::ToCppString;
            #[allow(unused_imports)]
            use self::super::root;
        }
    }
    #[cxx::bridge]
    mod cxxbridge {
        unsafe extern "C++" {
            fn autocxx_make_string_default(str_: &str) -> UniquePtr<CxxString>;
            #[namespace = "valhalla::tyr"]
            type actor_t;
            #[namespace = "valhalla::tyr"]
            pub fn cleanup(self: Pin<&mut actor_t>);
            include!("/usr/local/include/valhalla/tyr/actor.h");
            include!("autocxxgen_ffi.h");
        }
        extern "Rust" {}
    }
    #[allow(unused_imports)]
    use bindgen::root;
    pub use cxxbridge::autocxx_make_string_default as make_string;
    pub mod valhalla {
        pub mod tyr {
            pub use super::super::cxxbridge::actor_t;
        }
    }
}
build.rs
use walkdir::WalkDir;

fn compile() -> String {
    let dst = cmake::Config::new("src")
        .cxxflag("-DGEOS_INLINE")
        .build();

    dst.display().to_string()
}

fn generate_bindings(out_dir: String) {
    let d = std::path::PathBuf::from("/work/code/valhalla/valhalla")
        .display()
        .to_string();

    let mut paths = vec![
        "src".to_string(),
        "valhalla/third_party/date/include".to_string(),
        "valhalla/third_party/rapidjson/include".to_string(),
        "/usr/local/include/boost/".to_string(),
    ];

    for entry in WalkDir::new(d).into_iter().filter_map(|e| e.ok()) {
        if entry.path().ends_with("include") {
            paths.push(entry.path().display().to_string());
        }
    }

    let mut b = autocxx_build::Builder::new("src/lib.rs", paths)
        .extra_clang_args(&["-std=c++14"])
        .expect_build();

    b.opt_level(2)
        .cpp(true)
        .flag_if_supported("-std=c++14")
        .flag_if_supported("/std:c++14")
        .compile("project"); //.file("src/actor_wrapper.cc");

    println!("cargo:rerun-if-changed=src/lib.rs");

    println!("cargo:rustc-link-lib=static=project");
}

fn compile_protos() {
    tonic_build::configure()
        .build_client(false)
        .build_server(false)
        .type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]")
        .format(false)
        .compile(&["valhalla/proto/api.proto"], &["valhalla/proto/"])
        .expect("compiling protos");
}

fn main() {
    println!("cargo:rustc-link-search=native=/work/code/valhalla/build/src");
    println!("cargo:rustc-link-lib=static=valhalla");
    println!("cargo:rustc-link-search=native=/work/code/valhalla/build/src/baldr");`
    println!("cargo:rustc-link-lib=static=valhalla-baldr");
    println!("cargo:rustc-link-search=native=/work/code/valhalla/build/src/meili");
    println!("cargo:rustc-link-lib=static=valhalla-meili");
    println!("cargo:rustc-link-search=native=/work/code/valhalla/build/src/midgard");
    println!("cargo:rustc-link-lib=static=valhalla-midgard");
    println!("cargo:rustc-link-search=native=/work/code/valhalla/build/src/odin");
    println!("cargo:rustc-link-lib=static=valhalla-odin");
    println!("cargo:rustc-link-search=native=/work/code/valhalla/build/src/sif");
    println!("cargo:rustc-link-lib=static=valhalla-sif");
    println!("cargo:rustc-link-search=native=/work/code/valhalla/build/src/skadi");
    println!("cargo:rustc-link-lib=static=valhalla-skadi");
    println!("cargo:rustc-link-search=native=/work/code/valhalla/build/src/tyr");
    println!("cargo:rustc-link-lib=static=valhalla-tyr");
    println!("cargo:rustc-link-search=native=work/code/valhalla/build/src/thor");
    println!("cargo:rustc-link-lib=static=valhalla-thor");

    generate_bindings("hello".to_string());
    compile_protos();
}
lib.rs
use anyhow::Result;
use autocxx::include_cpp;
use autocxx::subclass::prelude::*;
use cxx::UniquePtr;

mod config;
pub mod proto;

pub use config::Config;
use proto::Api;

include_cpp! {
    #include "/usr/local/include/valhalla/tyr/actor.h"

    safety!(unsafe)

    generate!("valhalla::tyr::actor_t")
}

when building the project I get the following output, saying the functions are ignored:

build output
[valhalla 3.1.3+rs.1] Ignored valhalla::tyr::actor_t_route: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization.
[valhalla 3.1.3+rs.1] Ignored valhalla::tyr::actor_t_locate: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization.
[valhalla 3.1.3+rs.1] Ignored valhalla::tyr::actor_t_matrix: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization.
[valhalla 3.1.3+rs.1] Ignored valhalla::tyr::actor_t_optimized_route: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization.
[valhalla 3.1.3+rs.1] Ignored valhalla::tyr::actor_t_isochrone: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization.
[valhalla 3.1.3+rs.1] Ignored valhalla::tyr::actor_t_trace_route: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization.
[valhalla 3.1.3+rs.1] Ignored valhalla::tyr::actor_t_trace_attributes: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization.
[valhalla 3.1.3+rs.1] Ignored valhalla::tyr::actor_t_height: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization.
[valhalla 3.1.3+rs.1] Ignored valhalla::tyr::actor_t_transit_available: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization.
[valhalla 3.1.3+rs.1] Ignored valhalla::tyr::actor_t_expansion: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization.
[valhalla 3.1.3+rs.1] Ignored valhalla::tyr::actor_t_centroid: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization.
[valhalla 3.1.3+rs.1] Ignored valhalla::tyr::actor_t_status: This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization.
[valhalla 3.1.3+rs.1] Ignored std::locale_facet: This type is nested within another struct/class, yet is abstract (or is not on the allowlist so we can't be sure). This is not yet supported by autocxx. If you don't believe this type is abstract, add it to the allowlist.
[valhalla 3.1.3+rs.1] Ignored std::ios_base_failure: This type is nested within another struct/class, yet is abstract (or is not on the allowlist so we can't be sure). This is not yet supported by autocxx. If you don't believe this type is abstract, add it to the allowlist.
[valhalla 3.1.3+rs.1] Ignored google::protobuf::internal::InternalMetadata_Container: This type is nested within another struct/class, yet is abstract (or is not on the allowlist so we can't be sure). This is not yet supported by autocxx. If you don't believe this type is abstract, add it to the allowlist.

many thanks in advance.

@adetaylor
Copy link
Collaborator

Thanks for the report.

As it reports,

This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization.

Looking at the functions in question, I don't know if the problem is the std::function or the Api* or what.

Unfortunately the error message you're seeing means we're running into pretty deep fundamental problems in bindgen - quite possibly rust-lang/rust-bindgen#1975, which I've been failing to solve for almost a year. Or it could be any of the bindgen C++ template-related features listed here. The error message you're seeing is autocxx bailing and saying "argh, this is too hard".

autocxx is willing to generate bindings for other functions - just not those. I'm afraid you're not going to be able to use autocxx to generate bindings for these APIs as-is.

Your options are:

  • Write a header file in C++ which has simpler (inline) functions, calling through to valhalla but with simpler types, and then use autocxx to generate bindings to that.
  • Or, give up on autocxx and just manually build bindings using https://cxx.rs.

Good luck!

PS if you raise a pull request adding a Valhalla example into the examples directory, obviously I won't be able to accept the PR right now because it won't build, but it would make it easier for me to investigate and report exactly what bindgen is choking on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants