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 can give silent failures #1269

Open
vext01 opened this issue Apr 13, 2023 · 5 comments
Open

autocxx can give silent failures #1269

vext01 opened this issue Apr 13, 2023 · 5 comments
Labels
bug Something isn't working

Comments

@vext01
Copy link

vext01 commented Apr 13, 2023

Hi,

I'm very new to autocxx. Apologies if my expectations are naive.

We are investigating whether it would be possible to use autocxx on an existing codebase that already uses the cc crate to build some C++ code that interfaces with LLVM. Currently we use the regular Rust C FFI and linkage magic.

I spent hours today figuring out what the following error means when I try to call the function I've generated bindings for:

error[E0618]: expected function, found `__ykllvmwrap_irtrace_compile`
   --> yktrace/src/lib.rs:221:13
    |
221 |               ykllvmwrap::__ykllvmwrap_irtrace_compile(                                                                                              
    |  _____________-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
222 | |                 func_names.as_ptr(),
223 | |                 bbs.as_ptr(),
224 | |                 trace_len,
...   |
231 | |                 di_tmpname_c,
232 | |             )
    | |_____________- call expression requires function

Our codebase is a workspace. The crate ykllvmwrap is where I'm trying to replace C FFI functions with C++ ones. yktrace is the consuming crate in this instance.

At first I thought it was because I was doing a cross-crate call to a C++ function. Modified your demo code to have a workspace and do a cross-crate C++ call... It worked.

It was only when I read our code's generated docs that I stumbled on:

autocxx bindings couldn’t be generated: Names containing __ are reserved by C++ so not acceptable to cxx

yet the build of ykllvmwrap was successful.

Wouldn't it have been better if the build of the ykllvmwrap crate had failed at generation time, displaying that message? I did explicitly ask for that function to be generated:

include_cpp! {                                                                                                                              
      #include "ykllvmwrap.h"
      safety!(unsafe)
      generate!("__ykllvmwrap_irtrace_compile")
}                                                                                                                                                                                                                                          
pub use ffi::__ykllvmwrap_irtrace_compile;

Perhaps it would make sense to silently fail in scenarios where you are blanket generating bindings for an API...

(I'm going to bet there's a good technical reason that things are like this 😄 )

Thanks!

@vext01
Copy link
Author

vext01 commented Apr 13, 2023

I've just noticed that this behavior is in fact documented here:

(If a particular member function can't be generated, some placeholder item with explanatory documentation will be generated instead).

And [generate_ns!](https://docs.rs/autocxx/latest/autocxx/macro.generate_ns.html) would be an example where we'd be "blanket generating" an API.

So maybe it would be more ergonomic to fail the build if a generate! fails, but not a generate_ns!?

Or maybe you could have a parameter for each include_cpp! which indicates if it's ok for items to fail?

Cheers.

@vext01
Copy link
Author

vext01 commented Apr 13, 2023

And just found this sentence elsewhere in the docs:

(If you ask to generate bindings for a specific function, and it can't: the build will fail.

That appears to not be true?

Thanks

@adetaylor
Copy link
Collaborator

Thanks for the report.

The behavior you're seeing is a little surprising. If a give function is explicitly requested by generate! then indeed the build should fail. It sounds like that may no longer be the case - I'll try to reproduce it.

adetaylor added a commit that referenced this issue Apr 14, 2023
Fixes #1269.

generate! directives produce a hard error if code could not be generated.
However, previously we were checking for this only just after the bindgen
stage, instead of after all our analysis stages completed. Errors during those
later analysis stages did not result in a hard error.
@adetaylor
Copy link
Collaborator

I've been poking at this but it isn't a very easy fix.

We were (correctly) failing the build if a generate! didn't result in anything being spat out from the early bindgen-related phases. But, if problems were reported later (e.g. in this case the __ problem) then we did not generate a hard error.

I think we should do, but this is complicated by the fact that we do all sorts of name mangling, and by the end of the analysis, we no longer know the original API name, so we can't compare the successfully-generated APIs against the original allowlist from generate!. This is fixable but all the stuff related to naming is very complicated, so it's not going to be a quick fix.

@adetaylor adetaylor added the bug Something isn't working label Apr 14, 2023
adetaylor added a commit that referenced this issue Apr 14, 2023
Fixes #1269.

generate! directives produce a hard error if code could not be generated.
However, previously we were checking for this only just after the bindgen
stage, instead of after all our analysis stages completed. Errors during those
later analysis stages did not result in a hard error.
@vext01
Copy link
Author

vext01 commented Apr 17, 2023

Thanks for looking into this.

If you ping me when your PR is ready, I'd be happy to test it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants