DynamixelSDK icon indicating copy to clipboard operation
DynamixelSDK copied to clipboard

extern variables in .h : linking error since gcc-10

Open yohanlediraison opened this issue 3 years ago • 5 comments

Hi,

System : Linux Debian 64 bits - but it's a problem linked to gcc & g++

Problem: several variables are not explicity declared "extern" in several .h files and cause a linking error since gcc 10

  • port_handler.h, line 47 & 48 : g_used_port_num & *g_is_using
  • packet_handler.h, line 82 : PacketData *packetData;

the error is then, in the linking part (sorry for the french):

g++-10 -shared -fPIC -m64 -o ./libdxl_x64_c.so ./.objects/group_bulk_read.o ./.objects/group_bulk_write.o ./.objects/group_sync_read.o ./.objects/group_sync_write.o ./.objects/packet_handler.o ./.objects/port_handler.o ./.objects/protocol1_packet_handler.o ./.objects/protocol2_packet_handler.o ./.objects/port_handler_linux.o -lrt

/usr/bin/ld : ./.objects/group_bulk_write.o:/tmp/DynamixelSDK-3.7.31/c/build/linux64/../../include/dynamixel_sdk/port_handler.h:48 : définitions multiples de « g_is_using »; ./.objects/group_bulk_read.o:/tmp/DynamixelSDK-3.7.31/c/build/linux64/../../include/dynamixel_sdk/port_handler.h:48 : défini pour la première fois ici

with gcc-9, no error, since it's ignoring this error. The problem and the solution is described here, in the 1st part: https://gcc.gnu.org/gcc-10/porting_to.html

Just have to declare this variables external. in port_handler.h

47  extern int     g_used_port_num;
48  extern uint8_t    *g_is_using;

in packet_handler.h: 82 extern PacketData *packetData;

yohanlediraison avatar Jan 21 '22 11:01 yohanlediraison

Hi @yohanlediraison Thanks for reporting the issue. This change will be applied in the next release.

ROBOTIS-Will avatar Jan 24 '22 06:01 ROBOTIS-Will

Hi,

I had given half of the solution. You need to declare the 3 variables in the corresponding .c file as: in packet_handler.c 36 PacketData *packetData;

in port_handler.c, apparently at the bottom out of the #if ...#endif

95 int     g_used_port_num;
96 uint8_t    *g_is_using;

or, as in the "Porting to GCC 10" notes, add the option -fcomon to the library makefile compil options.

I had try both, and both are working. But I think the "extern" solution in .h + declaration in .c is the "state of the art" way...

Hope it's complete now.

yohanlediraison avatar Jan 24 '22 14:01 yohanlediraison

@yohanlediraison Thank you for checking the update! Right, I think the "extern" would be more reasonable modification. I haven't tried compiling these changes yet, but applied them first so that I wouldn't miss them. Before I merge them to the master for the release, I'll make sure to run the test with the gcc 10 on my local machines. Thanks!

ROBOTIS-Will avatar Jan 25 '22 00:01 ROBOTIS-Will

Hello,

I am facing a similar issue w/ a Linux SBC, 32-bit w/ compiling for the C language. Python3 and C++ compile just fine.

I started an updated issue in this repo. in case others are having similar concerns.

Seth

P.S. Has the new release ever come to be?

silver2row avatar Jun 07 '22 00:06 silver2row

This commit doesn't completely fix the issue at hand. Declaring the variable as extern suppresses the issue at compile time, but the issue pops up at run time instead. The patch I just submitted addresses this.

To elaborate, declaring the variables as extern promises the linker that the code will define (and thus create storage) for the extern'ed variables elsewhere. However, the original fix does not define the variables elsewhere.

The core issue that causes this is that the #ifndef guards in the include files don't work as intended. I don't know the full reason why (something having to do with translation units?). That said, putting a #warning "here" below the erroneous globals (within the code protected by the #ifndefs) shows that these files are included multiple times and thus the variables are defined multiple times.

a-gavin avatar Jan 13 '23 00:01 a-gavin