rustc does not understand linker scripts with GROUP statements

bcdf0e0
Opened by Raphael Cohn at 2023-09-14 17:01:03

I'm statically linking dpdk (libdpdk.a) to a rust rlib via Cargo. The compiler fails with failed to add native library /Volumes/Source/GitHub/lemonrock/dpdk/components/dpdk-sys/compile-dpdk.conf.d/temporary/destdir/usr/local/lib/libdpdk.a: failed to open archive. This archive is actually a linker script which contains a GROUP statement*. Such linker scripts occur when dealing with native C libraries from time-to-time, particularly on libraries only targeting Linux systems (which have historically used the GNU tools which supported them). I also recall them being used in the past for some ?glibc? .so files.

I'm surprised rustc fails on this - I'd incorrectly assumed it would have just passed the linked argument (-l static=dpdk) down to the linker (cc in this case). I think rustc should gain some knowledge of these scripts; technically a GROUP is supposed to be interpreted as -Wl,-( malarky IIRC.

I have a workaround I can implement via a build.rs for now, so this isn't critical to me - just open the linker script and spit out the contents to rustc as a bunch of links - but this probably isn't technically correct as I note above. Note, personally, I'm not a fan of linker scripts, but they have their place, I suppose; for those not authoring exotic alternatives to ELF or writing bare metal, they're handy for listing dependencies of dependencies when static linking. I just wish the original authors had used a different file extension for them...

* FYI, contents of libdpdk.a: GROUP ( librte_acl.a librte_cfgfile.a librte_cmdline.a librte_cryptodev.a librte_distributor.a librte_eal.a librte_efd.a librte_ethdev.a librte_hash.a librte_ip_frag.a librte_jobstats.a librte_kni.a librte_kvargs.a librte_lpm.a librte_mbuf.a librte_mempool.a librte_meter.a librte_net.a librte_pdump.a librte_pipeline.a librte_pmd_af_packet.a librte_pmd_bnxt.a librte_pmd_bond.a librte_pmd_cxgbe.a librte_pmd_e1000.a librte_pmd_ena.a librte_pmd_enic.a librte_pmd_fm10k.a librte_pmd_i40e.a librte_pmd_ixgbe.a librte_pmd_nfp.a librte_pmd_null.a librte_pmd_null_crypto.a librte_pmd_qede.a librte_pmd_ring.a librte_pmd_sfc_efx.a librte_pmd_tap.a librte_pmd_vhost.a librte_pmd_virtio.a librte_pmd_vmxnet3_uio.a librte_port.a librte_power.a librte_reorder.a librte_ring.a librte_sched.a librte_table.a librte_timer.a librte_vhost.a )

  1. I'd incorrectly assumed it would have just passed the linked argument (-l static=dpdk) down to the linker (cc in this case).

    It would, if you didn't use a kind of static. If you did -ldylib=dpdk (or the recently added yet unstable -lstatic-nobundle=dpdk), then it would have simply passed it along to the linker without any issues at all. The static kind causes the library to be bundled into the rlib, and the only time you'd ever want that behavior is if you're distributing prebuilt rlibs.

    Peter Atashian at 2017-03-13 19:05:24

  2. -lstatic-nobundle=dpdk seems to be preferable - I'd only ever want to link this dependency into a final binary. That would seem to make more sense as a default. It has to be statically linked because in this particular case there isn't a dynamic variant that is likely to link correctly runtime (DPDK is like nginx in this regard; there is a lot of possible variation).

    Raphael Cohn at 2017-03-13 19:12:49

  3. Triage: https://rust-lang.github.io/rfcs/2951-native-link-modifiers.html made a lot of changes in this area and it has been stabilized. Probably there is some solution for this now? (Would be nice to close this old issue.)

    If this is still a problem, can you provide an MCVE please?

    Martin Nordholts at 2023-09-14 17:00:42