Compiling master on Bullseye (Debian 11) works when you use clang-13/clang++-13 or clang-16/clang++-16, ... almost. The first is a small change to detect C++ version "2a" in m4/ax_cxx_compile_stdcxx.m4.
The real problem is not one of compiler, but a LinuxCNC build problem how the RT modules are linked. The exported names in the modules are extracted using these rules (Makefile:1248 and similar in Makefile.modinc:120):
../rtlib/%.so:
$(Q)ld -d -r -o objects/$*.tmp $^
$(Q)objcopy -j .rtapi_export -O binary objects/$*.tmp objects/$*.sym
$(Q)(echo '{ global : '; tr -s '\0' < objects/$*.sym | xargs -r0 printf '%s;\n' | grep .; echo 'local : * ; };') > objects/$*.ver
$(Q)$(CC) -shared -Bsymbolic -Wl,--version-script,objects/$*.ver -o $@ $^ -lm $(LDFLAGS)
The problem is in the conversion of the binary output of objcopy into a version script ($*.ver file) for exporting globals in the .so link stage. It blindly uses tr to squeeze NULs and the assumes that there is no other binary data in there. However, with clang there is other data in there, primarily bytes 0x0f, 0x1f and 0x40 (@) have been seen and they cause the link to fail.
My suggestion is to change the objcopy to objdump to print the section in readable form and then use awk to mangle it into the right format:
$(Q)objdump -w -j .rtapi_export -t objects/$*.tmp \
| awk 'BEGIN{print "{ global :"} /rtapi_exported_/{printf("%s;\n", substr($$6,16))} END{print "local : * ; };"}' \
> object/$*.ver
IMO, this change should be made to both master and 2.9 because using objcopy and binary fiddling is too fragile.
Note on format:
Objdump presents:
objects/abs_s32.tmp: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l d .rtapi_export 0000000000000000 .rtapi_export
0000000000000120 g O .rtapi_export 0000000000000017 rtapi_exported_rtapi_info_linuxcnc_22
00000000000001e0 g O .rtapi_export 0000000000000019 rtapi_exported_rtapi_info_address_names
0000000000000040 g O .rtapi_export 0000000000000017 rtapi_exported_rtapi_info_linuxcnc_15
...
What you need is:
{ global :
rtapi_info_linuxcnc_22;
rtapi_info_description_names;
rtapi_info_linuxcnc_15;
...
local : * ; };
Compiling master on Bullseye (Debian 11) works when you use clang-13/clang++-13 or clang-16/clang++-16, ... almost. The first is a small change to detect C++ version "2a" in m4/ax_cxx_compile_stdcxx.m4.
The real problem is not one of compiler, but a LinuxCNC build problem how the RT modules are linked. The exported names in the modules are extracted using these rules (Makefile:1248 and similar in Makefile.modinc:120):
The problem is in the conversion of the binary output of
objcopyinto a version script ($*.ver file) for exporting globals in the .so link stage. It blindly usestrto squeeze NULs and the assumes that there is no other binary data in there. However, with clang there is other data in there, primarily bytes 0x0f, 0x1f and 0x40 (@) have been seen and they cause the link to fail.My suggestion is to change the
objcopytoobjdumpto print the section in readable form and then use awk to mangle it into the right format:IMO, this change should be made to both master and 2.9 because using objcopy and binary fiddling is too fragile.
Note on format:
Objdump presents:
What you need is: