Repository: mesonbuild/meson

Issue:
dependency got using find_library is not deduplicated for static library builds
Simple test case attached. [Original issue found when porting DPDK project to meson, where we got errors due to too many parameters.]

Setup: liba, which depends on libdl, and pthreads. Libb which depends on liba. App which depends on both liba and libb

Shared build looks ok, no duplication seen with latest HEAD:
  ```
 $ ninja -v -j1
   <snip for brevity>
   [8/8] ccache cc  -o app/app 'app/app@exe/app.c.o' -Wl,--no-undefined -Wl,--as-needed -Wl,--start-group liba/liba.so libb/libb.so -pthread -ldl -Wl,--end-group -ldl '-Wl,-rpath,$ORIGIN/../liba:$ORIGIN/../libb' -Wl,-rpath-link,/home/bruce/temp/meson-test/shared_build/liba:/home/bruce/temp/meson-test/shared_build/libb
```

Static library shows a large amount of duplication for -ldl, but not pthreads, despite both being listed as dependencies in the same places:
   ```
 $ ninja -v -j1
    <snip for brevity>
    [6/6] ccache cc  -o app/app 'app/app@exe/app.c.o' -Wl,--no-undefined -Wl,--as-needed -Wl,--start-group liba/liba.a libb/libb.a -pthread -ldl -Wl,--end-group -ldl -ldl -ldl -ldl -ldl
```


[meson-test.zip](https://github.com/mesonbuild/meson/files/1194545/meson-test.zip)



Discussion:
I also see the same problem with DPDK code if I put in '-ldl' in the link_args of declare_dependency, rather than passing it as a dependency explicitly.
This is affecting me as well; I have a project in which 5 dynamic libraries, obtained using `find_library` and depended upon transitively via static libraries built within the project, explode into 151(!) `-l` flags.
This issue is still not fixed from my point of view. Even the basic test case discussed in the original bug report still shows 4 copies of "-ldl" listed in the build.ninja file. When building DPDK having converted our "-lm" and "-ldl" project linker flags to proper dependencies fails to build properly for static builds due to us exceeding the open files threshold.

ccache gcc  -o examples/dpdk-vm_power_manager 'examples/c590b3c@@dpdk-vm_power_manager@exe/vm_power_manager_channel_manager.c.o' 'examples/c590b3c@@dpdk-vm_power_manager@exe/vm_power_manager_channel_monitor.c.o' 'examples/c590b3c@@dpdk-vm_power_manager@exe/vm_power_manager_main.c.o' 'examples/c590b3c@@dpdk-vm_power_manager@exe/vm_power_manager_parse.c.o' 'examples/c590b3c@@dpdk-vm_power_manager@exe/vm_power_manager_power_manager.c.o' 'examples/c590b3c@@dpdk-vm_power_manager@exe/vm_power_manager_vm_power_cli.c.o' 'examples/c590b3c@@dpdk-vm_power_manager@exe/vm_power_manager_oob_monitor_x86.c.o' -Wl,--no-undefined -Wl,--as-needed -Wl,-O1 -Wl,--whole-archive -Wl,--start-group drivers/librte_common_cpt.a drivers/librte_common_dpaax.a drivers/librte_common_octeontx.a drivers/librte_bus_dpaa.a drivers/librte_bus_fslmc.a drivers/librte_bus_ifpga.a drivers/librte_bus_pci.a drivers/librte_bus_vdev.a drivers/librte_bus_vmbus.a drivers/librte_mempool_bucket.a drivers/librte_mempool_dpaa.a drivers/librte_mempool_dpaa2.a drivers/librte_mempool_octeontx.a drivers/librte_mempool_ring.a drivers/librte_mempool_stack.a drivers/librte_pmd_af_packet.a drivers/librte_pmd_ark.a drivers/librte_pmd_atlantic.a drivers/librte_pmd_avp.a drivers/librte_pmd_axgbe.a drivers/librte_pmd_bond.a drivers/librte_pmd_bnx2x.a drivers/librte_pmd_bnxt.a drivers/librte_pmd_cxgbe.a drivers/librte_pmd_dpaa.a drivers/librte_pmd_dpaa2.a drivers/librte_pmd_e1000.a drivers/librte_pmd_ena.a drivers/librte_pmd_enetc.a drivers/librte_pmd_enic.a drivers/librte_pmd_failsafe.a drivers/librte_pmd_fm10k.a drivers/librte_pmd_i40e.a drivers/librte_pmd_iavf.a drivers/librte_pmd_ice.a drivers/librte_pmd_ifc.a drivers/librte_pmd_ixgbe.a drivers/librte_pmd_kni.a drivers/librte_pmd_liquidio.a drivers/librte_pmd_netvsc.a drivers/librte_pmd_nfp.a drivers/librte_pmd_null.a drivers/librte_pmd_octeontx.a drivers/librte_pmd_pcap.a drivers/librte_pmd_qede.a drivers/librte_pmd_ring.a drivers/librte_pmd_sfc.a drivers/librte_pmd_softnic.a drivers/librte_pmd_szedata2.a drivers/librte_pmd_tap.a drivers/librte_pmd_thunderx.a drivers/librte_pmd_vdev_netvsc.a drivers/librte_pmd_vhost.a drivers/librte_pmd_virtio.a drivers/librte_pmd_vmxnet3.a drivers/librte_pmd_aesni_gcm.a drivers/librte_pmd_aesni_mb.a drivers/librte_pmd_caam_jr.a drivers/librte_pmd_ccp.a drivers/librte_pmd_dpaa_sec.a drivers/librte_pmd_dpaa2_sec.a drivers/librte_pmd_null_crypto.a drivers/librte_pmd_octeontx_crypto.a drivers/librte_pmd_openssl.a drivers/librte_pmd_crypto_scheduler.a drivers/librte_pmd_virtio_crypto.a drivers/librte_pmd_octeontx_compress.a drivers/librte_pmd_qat.a drivers/librte_pmd_zlib.a drivers/librte_pmd_dpaa_event.a drivers/librte_pmd_dpaa2_event.a drivers/librte_pmd_octeontx_event.a drivers/librte_pmd_opdl_event.a drivers/librte_pmd_skeleton_event.a drivers/librte_pmd_sw_event.a drivers/librte_pmd_dsw_event.a drivers/librte_pmd_bbdev_null.a drivers/librte_pmd_skeleton_rawdev.a drivers/librte_pmd_dpaa2_cmdif.a drivers/librte_pmd_dpaa2_qdma.a drivers/librte_pmd_ifpga_rawdev.a -Wl,--no-whole-archive -Wl,--no-as-needed -lnuma lib/librte_eal.so.9.1 lib/librte_kvargs.so.1.1 lib/librte_mempool.so.5.1 lib/librte_ring.so.2.1 lib/librte_net.so.1.1 lib/librte_mbuf.so.5.1 lib/librte_ethdev.so.11.1 lib/librte_cmdline.so.2.1 lib/librte_meter.so.2.1 drivers/librte_pmd_bnxt.so.2.1 drivers/librte_bus_pci.so.2.1 lib/librte_pci.so.1.1 drivers/librte_bus_vdev.so.2.1 drivers/librte_pmd_i40e.so.2.1 lib/librte_hash.so.2.1 drivers/librte_pmd_ixgbe.so.2.1 lib/librte_security.so.2.1 lib/librte_cryptodev.so.6.1 lib/librte_power.so.1.1 lib/librte_timer.so.1.1 drivers/librte_common_dpaax.so.1.1 lib/librte_eventdev.so.6.1 lib/librte_rawdev.so.1.1 drivers/librte_bus_dpaa.so.2.1 drivers/librte_bus_fslmc.so.2.1 drivers/librte_common_octeontx.so.1.1 lib/librte_sched.so.2.1 lib/librte_ip_frag.so.1.1 drivers/librte_mempool_dpaa.so.1.1 drivers/librte_mempool_dpaa2.so.2.1 lib/librte_vhost.so.4.1 lib/librte_kni.so.2.1 drivers/librte_bus_vmbus.so.2.1 drivers/librte_mempool_octeontx.so.1.1 lib/librte_pipeline.so.3.1 lib/librte_port.so.3.1 lib/librte_table.so.3.1 lib/librte_lpm.so.2.1 lib/librte_acl.so.2.1 lib/librte_gso.so.1.1 drivers/librte_common_cpt.so.1.1 lib/librte_reorder.so.1.1 lib/librte_compressdev.so.1.1 drivers/librte_pmd_dpaa.so.1.1 drivers/librte_pmd_dpaa2.so.2.1 drivers/librte_pmd_dpaa2_sec.so.2.1 drivers/librte_pmd_octeontx.so.1.1 lib/librte_bbdev.so.1.1 drivers/librte_bus_ifpga.so.2.1 -Wl,--no-as-needed -lvirt /usr/lib64/libjansson.so -lm -ldl /usr/lib64/libbsd.so -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl /usr/lib64/libz.so -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lpcap -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lsze2 -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lIPSec_MB -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lIPSec_MB -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl /usr/lib64/libcrypto.so -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -lm -ldl -Wl,--end-group -pthread '-Wl,-rpath,$ORIGIN/../lib:$ORIGIN/../drivers' -Wl,-rpath-link,/home/bruce/prototypes/both_libraries/build-gcc-static/lib:/home/bruce/prototypes/both_libraries/build-gcc-static/drivers
/usr/bin/ld: cannot open linker script file /usr/lib/gcc/x86_64-redhat-linux/8/../../../../lib64/libm.so: Too many open files

Sigh, this keeps cropping up over and over. `-pthread` is getting de-duplicated but not `-ldl` and `-lm`.
the following change seems to help here, i.e. it fixes things for me in DPDK, but we still have some duplication in the artifical test case I started. The one thing I'm wondering about is if there is ever a valid reason to have the one dependency appear twice in the dependency list? Do we need to be able to have -la -lb -la for external deps?

```
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index d456ab86..20f0cdb2 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -1030,8 +1030,9 @@ This will become a hard error in a future Meson release.''')
                 # Deps of deps.
                 self.add_deps(dep.ext_deps)
             elif isinstance(dep, dependencies.Dependency):
-                self.external_deps.append(dep)
-                self.process_sourcelist(dep.get_sources())
+                if dep not in self.external_deps:
+                    self.external_deps.append(dep)
+                    self.process_sourcelist(dep.get_sources())
             elif isinstance(dep, BuildTarget):
                 raise InvalidArguments('''Tried to use a build target as a dependency.
 You probably should put it in link_with instead.''')
```


Resolving patch:
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -35,6 +35,7 @@
     get_largefile_args,
     gnu_winlibs,
     msvc_winlibs,
+    unixy_compiler_internal_libs,
     vs32_instruction_set_args,
     vs64_instruction_set_args,
     ArmCompiler,
@@ -52,8 +53,6 @@
     CcrxCompiler,
 )
 
-gnu_compiler_internal_libs = ('m', 'c', 'pthread', 'dl', 'rt')
-
 
 class CCompiler(Compiler):
     # TODO: Replace this manual cache with functools.lru_cache
@@ -61,7 +60,7 @@ class CCompiler(Compiler):
     program_dirs_cache = {}
     find_library_cache = {}
     find_framework_cache = {}
-    internal_libs = gnu_compiler_internal_libs
+    internal_libs = unixy_compiler_internal_libs
 
     @staticmethod
     def attribute_check_func(name):
@@ -912,8 +911,10 @@ def get_library_naming(self, env, libtype, strict=False):
         priority
         '''
         stlibext = ['a']
-        # We've always allowed libname to be both `foo` and `libfoo`,
-        # and now people depend on it
+        # We've always allowed libname to be both `foo` and `libfoo`, and now
+        # people depend on it. Also, some people use prebuilt `foo.so` instead
+        # of `libfoo.so` for unknown reasons, and may also want to create
+        # `foo.so` by setting name_prefix to ''
         if strict and not isinstance(self, VisualStudioCCompiler): # lib prefix is not usually used with msvc
             prefixes = ['lib']
         else:
@@ -1375,7 +1376,7 @@ def get_option_compile_args(self, options):
 class VisualStudioCCompiler(CCompiler):
     std_warn_args = ['/W3']
     std_opt_args = ['/O2']
-    ignore_libs = gnu_compiler_internal_libs
+    ignore_libs = unixy_compiler_internal_libs
     internal_libs = ()
 
     crt_args = {'none': [],
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -81,6 +81,9 @@
                   'vala': 'VALAFLAGS',
                   'rust': 'RUSTFLAGS'}
 
+# execinfo is a compiler lib on BSD
+unixy_compiler_internal_libs = ('m', 'c', 'pthread', 'dl', 'rt', 'execinfo')
+
 # All these are only for C-linkable languages; see `clink_langs` above.
 
 def sort_clink(lang):
@@ -659,6 +662,9 @@ class CompilerArgs(list):
     # Only UNIX shared libraries require this. Others have a fixed extension.
     dedup1_regex = re.compile(r'([\/\\]|\A)lib.*\.so(\.[0-9]+)?(\.[0-9]+)?(\.[0-9]+)?$')
     dedup1_args = ('-c', '-S', '-E', '-pipe', '-pthread')
+    # In generate_link() we add external libs without de-dup, but we must
+    # *always* de-dup these because they're special arguments to the linker
+    always_dedup_args = tuple('-l' + lib for lib in unixy_compiler_internal_libs)
     compiler = None
 
     def _check_args(self, args):
@@ -793,7 +799,7 @@ def extend_preserving_lflags(self, iterable):
         normal_flags = []
         lflags = []
         for i in iterable:
-            if i.startswith('-l') or i.startswith('-L'):
+            if i not in self.always_dedup_args and (i.startswith('-l') or i.startswith('-L')):
                 lflags.append(i)
             else:
                 normal_flags.append(i)
diff --git a/run_unittests.py b/run_unittests.py
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -3893,7 +3893,7 @@ def test_ignore_libs(self):
         if cc.get_argument_syntax() != 'msvc':
             raise unittest.SkipTest('Not using MSVC')
         # To force people to update this test, and also test
-        self.assertEqual(set(cc.ignore_libs), {'c', 'm', 'pthread', 'dl', 'rt'})
+        self.assertEqual(set(cc.ignore_libs), {'c', 'm', 'pthread', 'dl', 'rt', 'execinfo'})
         for l in cc.ignore_libs:
             self.assertEqual(cc.find_library(l, env, []), [])
 
@@ -5043,6 +5043,19 @@ def test_ldflag_dedup(self):
                 max_count = max(max_count, line.count(search_term))
         self.assertEqual(max_count, 1, 'Export dynamic incorrectly deduplicated.')
 
+    def test_compiler_libs_static_dedup(self):
+        testdir = os.path.join(self.unit_test_dir, '55 dedup compiler libs')
+        self.init(testdir)
+        build_ninja = os.path.join(self.builddir, 'build.ninja')
+        with open(build_ninja, 'r', encoding='utf-8') as f:
+            lines = f.readlines()
+        for lib in ('-ldl', '-lm', '-lc', '-lrt'):
+            for line in lines:
+                if lib not in line:
+                    continue
+                # Assert that
+                self.assertEqual(len(line.split(lib)), 2, msg=(lib, line))
+
 
 def should_run_cross_arm_tests():
     return shutil.which('arm-linux-gnueabihf-gcc') and not platform.machine().lower().startswith('arm')


Test patch:
diff --git a/test cases/unit/55 dedup compiler libs/app/app.c b/test cases/unit/55 dedup compiler libs/app/app.c
new file mode 100644
--- /dev/null
+++ b/test cases/unit/55 dedup compiler libs/app/app.c	
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <liba.h>
+#include <libb.h>
+
+int
+main(void)
+{
+  printf("start value = %d\n", liba_get());
+  liba_add(2);
+  libb_mul(5);
+  printf("end value = %d\n", liba_get());
+  return 0;
+}
diff --git a/test cases/unit/55 dedup compiler libs/app/meson.build b/test cases/unit/55 dedup compiler libs/app/meson.build
new file mode 100644
--- /dev/null
+++ b/test cases/unit/55 dedup compiler libs/app/meson.build	
@@ -0,0 +1,2 @@
+executable('app', 'app.c',
+  dependencies: [liba_dep, libb_dep])
diff --git a/test cases/unit/55 dedup compiler libs/liba/liba.c b/test cases/unit/55 dedup compiler libs/liba/liba.c
new file mode 100644
--- /dev/null
+++ b/test cases/unit/55 dedup compiler libs/liba/liba.c	
@@ -0,0 +1,18 @@
+#include "liba.h"
+
+static int val;
+
+void liba_add(int x)
+{
+  val += x;
+}
+
+void liba_sub(int x)
+{
+  val -= x;
+}
+
+int liba_get(void)
+{
+  return val;
+}
diff --git a/test cases/unit/55 dedup compiler libs/liba/liba.h b/test cases/unit/55 dedup compiler libs/liba/liba.h
new file mode 100644
--- /dev/null
+++ b/test cases/unit/55 dedup compiler libs/liba/liba.h	
@@ -0,0 +1,8 @@
+#ifndef LIBA_H_
+#define LIBA_H_
+
+void liba_add(int x);
+void liba_sub(int x);
+int liba_get(void);
+
+#endif
diff --git a/test cases/unit/55 dedup compiler libs/liba/meson.build b/test cases/unit/55 dedup compiler libs/liba/meson.build
new file mode 100644
--- /dev/null
+++ b/test cases/unit/55 dedup compiler libs/liba/meson.build	
@@ -0,0 +1,8 @@
+deps = [dependency('threads'), cc.find_library('dl'), cc.find_library('m')]
+
+liba = library('a', 'liba.c',
+  dependencies: deps)
+
+liba_dep = declare_dependency(link_with: liba,
+  include_directories: include_directories('.'),
+  dependencies: deps)
diff --git a/test cases/unit/55 dedup compiler libs/libb/libb.c b/test cases/unit/55 dedup compiler libs/libb/libb.c
new file mode 100644
--- /dev/null
+++ b/test cases/unit/55 dedup compiler libs/libb/libb.c	
@@ -0,0 +1,7 @@
+#include <liba.h>
+#include "libb.h"
+
+void libb_mul(int x)
+{
+  liba_add(liba_get() * (x - 1));
+}
diff --git a/test cases/unit/55 dedup compiler libs/libb/libb.h b/test cases/unit/55 dedup compiler libs/libb/libb.h
new file mode 100644
--- /dev/null
+++ b/test cases/unit/55 dedup compiler libs/libb/libb.h	
@@ -0,0 +1,6 @@
+#ifndef _LIBB_H_
+#define _LIBB_H_
+
+void libb_mul(int x);
+
+#endif
diff --git a/test cases/unit/55 dedup compiler libs/libb/meson.build b/test cases/unit/55 dedup compiler libs/libb/meson.build
new file mode 100644
--- /dev/null
+++ b/test cases/unit/55 dedup compiler libs/libb/meson.build	
@@ -0,0 +1,6 @@
+libb = library('b', 'libb.c',
+  dependencies: liba_dep)
+
+libb_dep = declare_dependency(link_with: libb,
+  include_directories: include_directories('.'),
+  dependencies: liba_dep)
diff --git a/test cases/unit/55 dedup compiler libs/meson.build b/test cases/unit/55 dedup compiler libs/meson.build
new file mode 100644
--- /dev/null
+++ b/test cases/unit/55 dedup compiler libs/meson.build	
@@ -0,0 +1,7 @@
+project('temp', 'c')
+
+cc = meson.get_compiler('c')
+
+subdir('liba')
+subdir('libb')
+subdir('app')