Skip to content

Linking RT modules, C++20 and Bullseye #3413

@BsAtHome

Description

@BsAtHome

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 : * ; };

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions