Wlroots: C++ compatibility

Created on 26 Feb 2018  路  11Comments  路  Source: swaywm/wlroots

I noticed linking against wlroots fails when using a C++ compiler. Including the headers with extern "C" { ... } makes this (expectedly) work. Would it be a bad idea to use this common macro around the wlr header files?

#ifdef __cplusplus
extern "C" {
#endif

....

#ifdef __cplusplus
}
#endif

Most helpful comment

For the record, this is what i do to use wlroots in c++

// All includes used in wlr files
// This is done to make sure the keyword macros don't bleed into 
// these files, which are c++-aware, and may define namespaces etc
// 
// Generate:
// grep -rP "#include <(?\!wlr)" subprojects/wlroots/include/wlr | cut -d: -f2 | sort | uniq

#include <EGL/eglext.h>
#include <EGL/egl.h>
#include <errno.h>
#include <libinput.h>
#include <libudev.h>
#include <pixman.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <wayland-client.h>
#include <wayland-server.h>
#include <wayland-server-protocol.h>
#include <wayland-util.h>
#include <xcb/xcb.h>
#include <xkbcommon/xkbcommon.h>

// Rename fields which use reserved names
#define class class_
#define namespace namespace_

// Use C linkage
extern "C" {

#include <wlr/backend.h>
#include <wlr/backend/headless.h>
#include <wlr/backend/libinput.h>
#include <wlr/backend/multi.h>
#include <wlr/config.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_buffer.h>
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_export_dmabuf_v1.h>
#include <wlr/types/wlr_gamma_control.h>
#include <wlr/types/wlr_idle.h>
#include <wlr/types/wlr_idle_inhibit_v1.h>
#include <wlr/types/wlr_input_device.h>
#include <wlr/types/wlr_input_inhibitor.h>
#include <wlr/types/wlr_layer_shell.h>
#include <wlr/types/wlr_linux_dmabuf.h>
#include <wlr/types/wlr_list.h>
#include <wlr/types/wlr_matrix.h>
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_output_damage.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_primary_selection.h>
#include <wlr/types/wlr_screencopy_v1.h>
#include <wlr/types/wlr_screenshooter.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_server_decoration.h>
#include <wlr/types/wlr_virtual_keyboard_v1.h>
#include <wlr/types/wlr_wl_shell.h>
#include <wlr/types/wlr_xcursor_manager.h>
#include <wlr/types/wlr_xdg_output.h>
#include <wlr/types/wlr_xdg_shell.h>
#include <wlr/types/wlr_xdg_shell_v6.h>

#ifdef WLR_HAS_XWAYLAND
#include <wlr/xwayland.h>
#endif
}
// make sure to undefine these again
#undef class
#undef namespace

All 11 comments

Nope.

There are separate wrapper libraries for several languages--creating one of those would be a better idea.

extern "C" {
#include <wlr/types/wlr_output.h>
}

I get that the linkage is easilly fixed. Even the few c-only features like [static N] arrays can be easilly filtered out only in the header files.
The main issue though, is the use of c++ keywords, mainly the few places where a variable is called class. Is there any way you would want to avoid those, or should i create a wrapper lib just for those things?

You can just re-define the struct and change the problematic field name.

duh, of course, sorry :wink:

For future reference:
If anyone does decide to create a c++ wrapper lib, id like to be looped in!

@topisani #define the keywords just before the header and #undef them afterwards. I think that the way wlroots currently is, there is no real benefit from a cpp wrapping library

@ammen99 yep, thats what i ended up doing. I am currently porting rootson to c++, and except for these few things its not really an issue, except for the giant function names everywhere, which would be methods in C++, and a few C-isms which could be more elegant in C++. - but thats not nearly enough for me to write a wrapper lib.

For the record, this is what i do to use wlroots in c++

// All includes used in wlr files
// This is done to make sure the keyword macros don't bleed into 
// these files, which are c++-aware, and may define namespaces etc
// 
// Generate:
// grep -rP "#include <(?\!wlr)" subprojects/wlroots/include/wlr | cut -d: -f2 | sort | uniq

#include <EGL/eglext.h>
#include <EGL/egl.h>
#include <errno.h>
#include <libinput.h>
#include <libudev.h>
#include <pixman.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <wayland-client.h>
#include <wayland-server.h>
#include <wayland-server-protocol.h>
#include <wayland-util.h>
#include <xcb/xcb.h>
#include <xkbcommon/xkbcommon.h>

// Rename fields which use reserved names
#define class class_
#define namespace namespace_

// Use C linkage
extern "C" {

#include <wlr/backend.h>
#include <wlr/backend/headless.h>
#include <wlr/backend/libinput.h>
#include <wlr/backend/multi.h>
#include <wlr/config.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_buffer.h>
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_export_dmabuf_v1.h>
#include <wlr/types/wlr_gamma_control.h>
#include <wlr/types/wlr_idle.h>
#include <wlr/types/wlr_idle_inhibit_v1.h>
#include <wlr/types/wlr_input_device.h>
#include <wlr/types/wlr_input_inhibitor.h>
#include <wlr/types/wlr_layer_shell.h>
#include <wlr/types/wlr_linux_dmabuf.h>
#include <wlr/types/wlr_list.h>
#include <wlr/types/wlr_matrix.h>
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_output_damage.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_primary_selection.h>
#include <wlr/types/wlr_screencopy_v1.h>
#include <wlr/types/wlr_screenshooter.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_server_decoration.h>
#include <wlr/types/wlr_virtual_keyboard_v1.h>
#include <wlr/types/wlr_wl_shell.h>
#include <wlr/types/wlr_xcursor_manager.h>
#include <wlr/types/wlr_xdg_output.h>
#include <wlr/types/wlr_xdg_shell.h>
#include <wlr/types/wlr_xdg_shell_v6.h>

#ifdef WLR_HAS_XWAYLAND
#include <wlr/xwayland.h>
#endif
}
// make sure to undefine these again
#undef class
#undef namespace

@topsiani How do you deal with static array size declarations in the C headers?

@topsiani How do you deal with static array size declarations in the C headers?

#define static
Was this page helpful?
0 / 5 - 0 ratings

Related issues

dcz-purism picture dcz-purism  路  5Comments

emersion picture emersion  路  5Comments

fwSmit picture fwSmit  路  4Comments

acrisci picture acrisci  路  7Comments

Ferdi265 picture Ferdi265  路  5Comments