iceoryx: Bindgen generating rust binding failed.

Required information

I am using rust bindgen to generate rust binding based on iceoryx-binding-c.

And found that the struct iox_notification_info_t defined here directly refers to hpp file iceoryx_posh/include/iceoryx_posh/popo/notification_info.hpp with class NotificationInfo

https://github.com/eclipse-iceoryx/iceoryx/blob/abca825cf4c56de44b548128a8bb4d917d456869/iceoryx_binding_c/include/iceoryx_binding_c/notification_info.h#L25

Observed result or behaviour:

The c-binding is not pure.

given wraper.h

#include "iceoryx_binding_c/api.h"

rust bindgen outputs error msgs as follows:

cargo:rerun-if-changed=wrapper.h

  --- stderr
  /usr/local/include/iceoryx_binding_c/wait_set.h:53:28: error: unknown type name 'iox_notification_info_t'
  /usr/local/include/iceoryx_binding_c/wait_set.h:66:22: error: unknown type name 'iox_notification_info_t'
  /usr/local/include/iceoryx_binding_c/wait_set.h:53:28: error: unknown type name 'iox_notification_info_t', err: true
  /usr/local/include/iceoryx_binding_c/wait_set.h:66:22: error: unknown type name 'iox_notification_info_t', err: true
  thread 'main' panicked at 'Unable to generate bindings: ()', build.rs:37:10
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Expected result or behaviour:

api expoting normally.

class NotificationInfo should be rewrite to the struct like this

https://github.com/eclipse-iceoryx/iceoryx/blob/abca825cf4c56de44b548128a8bb4d917d456869/iceoryx_binding_c/include/iceoryx_binding_c/wait_set.h#L31

Conditions where it occurred / Performed steps:

Not export c api in iceoryx_binding_c/wait_set.h make error msgs disapear.

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Comments: 23 (23 by maintainers)

Commits related to this issue

Most upvoted comments

@BH1SCW Thank you very much for finding the fix!

I created a PR, could you please take a look at #1420 and checkout if this fix solves your issue.

Patch verified, works like a charm.

The reason I adjusted it myself instead of adding

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")

was

  1. We have CMake macros in place which setup all libraries and executables in a unified fashion and this would be the place for this setting, see iox_add_library and iox_add_executable
  2. When you are setting a global cmake variable then this -fPIC flag is also added to every project which depends on iceoryx and you may force a setting there which is not wished. This can easily be solved by setting it for a target explicitly.
  3. Setting CMake flags directly does not work compiler- and platform-independent. MSVC in windows for instance has there completely different settings so the best approach is to set_target_properties with POSITION_INDEPENDENT_CODE.

Thanks for guiding me.

I thought it was quicker when I fix it myself then to let you go through our stony CMake path packed with obstacles but I wanted to give you as much insight as possible so the next cmake fix is yours to do 😄

yeah~~~

@BH1SCW

From the first look it seems like it is maybe a different issue

/usr/bin/ld: /usr/local/lib/libiceoryx_binding_c.a(c_subscriber.cpp.o): 
  relocation R_X86_64_PC32 against symbol `_ZN3iox12ErrorHandler7handlerE' 
  can not be used when making a shared object; recompile with -fPIC

We compile every library and application with -fPIC since we require position independent code and it looks like this is missing here. Could you try to add this flag and retry again if it solves your issue.

But if you are looking for a nice rust API for iceoryx you can also look at https://github.com/eclipse-iceoryx/iceoryx-rs where @elBoberido is currently creating one which we intend to release in the next weeks.

@BH1SCW Actually this issue was closed as rejected.

It seems that this bug still not be fixed yet?

No, the official tool rust-bindgen from rust is not supported by official iceoryx.

/usr/bin/ld: /usr/local/lib/libiceoryx_binding_c.a(c_subscriber.cpp.o): relocation R_X86_64_PC32 against symbol `_ZN3iox12ErrorHandler7handlerE’ can not be used when making a shared object; recompile with -fPIC

the issue you described is the fact that there are mangled and pure symbols mixed in libiceoryx_binding_c.a

Actually I made a patch https://github.com/ros2middleware/iceoryx/commit/e65780d2002beb5f79cabcd95278d5561988775b to make it a c style cpp api to make it easy to be accepted by c++ compiler and rust bindgen. As for now the publisher example works.

this patch e65780d2002beb5f79cabcd95278d5561988775b of iceoryx change all symbols become mangled in libiceoryx_binding_c.a

Please see iceoryx-rust

see the rust-bindgen usage if interested. https://github.com/ZhenshengLee/iceoryx-rust/blob/848bbbb0a9d3f27781b46db1c7db34e4421dc599/build.rs#L27-L35

@mossmaurice I think we either need to reopen it or create a new issue to wrap the content of the header in an extern "C" block. With the current approach one cannot include the header from the binding_c into a C++ project (yes, it’s weird but people do that) without wrapping the header itself into extern "C" which is nothing you would usually do and from my point of view has the same severity as if you do not include all the header you need and rely on the user of your header to include those.

cc @elfenpiff

@ZhenshengLee I think the proper solution here would be to have the extern "C" { ... } in the header file itself instead of just in the source file which includes the header. This ensures that there is no name mangling, no matter if a C or C++ compiler is used to compile a source file which includes this header. To test my theory, could wrap all the included header in wrapper.h in a extern "C" { ... } block and check if bindgen can still generate the bindings?