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

Using libc::[some c-struct] in function gets export without struct keyword #539

Open
johalun opened this issue Jul 6, 2020 · 6 comments

Comments

@johalun
Copy link

johalun commented Jul 6, 2020

Hi

I'm writing a Rust library with C interface where I'm using libc structs in function arguments. The generated header file then ends up with type like "sockaddr" instead of "struct sockaddr".

I solved this by renaming like this

[export.rename]
"sockaddr" = "struct sockaddr"

Is this the way to go or am I missing a "nicer" solution?

@emilio
Copy link
Collaborator

emilio commented Jul 6, 2020

What is the whole configuration you're using?

@johalun
Copy link
Author

johalun commented Jul 6, 2020

autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */"
language = "C"
includes = []
no_includes = false
sys_includes = ["stdint.h", "sys/epoll.h", "sys/socket.h"]

[parse]
parse_deps = false

[export.rename]
"epoll_event" = "struct epoll_event"
"sockaddr" = "struct sockaddr"

@emilio
Copy link
Collaborator

emilio commented Jul 6, 2020

Hmm, right... I think the issue is that cbindgen is not parsing epoll_event / sockaddr so it doesn't really know it's a struct rather than e.g. an enum.

We could conceptually get some knowledge about libc in cbindgen, but that seems a bit brittle and lacking that... I don't think there's an straight-forward solution.

Does using parse_deps = true get the right info?

@johalun
Copy link
Author

johalun commented Jul 6, 2020

Does using parse_deps = true get the right info?

Nope... It's fine, it's a minor issue and renaming works fine. A bigger issue with build.rs is that cbindgen runs before rustc so any build errors are detected by cbindgen instead of rustc so I moved it to a Makefile instead. I wish we had pre/post build script support in cargo...

@emilio
Copy link
Collaborator

emilio commented Jul 7, 2020

Yeah... in practice in Firefox we use cbindgen from the cli interface for these kinds of things.

@aidanhs
Copy link
Contributor

aidanhs commented Nov 10, 2023

I was unable to get renaming working because cbindgen has apparently become clever in the last few years and knows that e.g. struct in_addr is not a valid name and so replaces the space with an underscore, making it struct_in_addr in my header.

I have managed to 'trick' cbindgen into working by:

lib.rs

/// cbindgen:no-export=true
#[allow(non_camel_case_types, unused)]
struct in_addr;

fn x() -> libc::in_addr { ... }

cbindgen then:

  • sees x requires an in_addr definition
  • spots an opaque (i.e. not repr(C)) struct that matches in_addr and so knows it's a struct
  • does not actually emit an opaque struct declaration (i.e. typedef struct in_addr in_addr;) because of the no-export annotation

Which ends up with correct usage of in_addr without creating a definition that conflicts with the header file.

no-export was undocumented, which I have a PR to fix at #897.

Note that this workaround may break if #7 gets fixed.

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

3 participants