<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/102490>102490</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [lld] ld.lld should allow explicitly setting a target (ignore other objects and linker scripts for other targets)
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            lld
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          chitao1234
      </td>
    </tr>
</table>

<pre>
    # Brief
When cross compiling, ld.lld `-m` option overwritten by host machine linker script, binutils ld handle this situation correctly.
# Detailed problem explanation
In a Linux system using glibc, `/lib/libc.so` is a linker script that sets `OUTPUT_FORMAT` to the host machine. 

Example libc.so:
```
/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily. */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( /usr/lib/libc.so.6 /usr/lib/libc_nonshared.a  AS_NEEDED ( /usr/lib/ld-linux-x86-64.so.2 ) )
```

When cross compiling using clang and lld, if set `-L` option incorrectly, lld would search host library first and load the linker script, such that lld would fail with a weird error message.
```
% ld.lld --sysroot=/usr/aarch64-linux-gnu -EL --hash-style=gnu --build-id --eh-frame-hdr -m aarch64linux -pie -dynamic-linker /lib/ld-linux-aarch64.so.1 -o a.out /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/../../../../aarch64-linux-gnu/lib/Scrt1.o /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/../../../../aarch64-linux-gnu/lib/crti.o /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/crtbeginS.o -L/lib -L/usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0 -L/usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/../../../../aarch64-linux-gnu/lib/../lib64 -L/usr/aarch64-linux-gnu/lib/../lib64 -L/usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/../../../../aarch64-linux-gnu/lib -L/usr/aarch64-linux-gnu/lib --verbose test.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/crtendS.o /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/../../../../aarch64-linux-gnu/lib/crtn.o 
ld.lld: set maximum concurrency to 16, specify --threads= to change
ld.lld: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/../../../../aarch64-linux-gnu/lib/Scrt1.o
ld.lld: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/../../../../aarch64-linux-gnu/lib/crti.o
ld.lld: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/crtbeginS.o
ld.lld: test.o
ld.lld: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/libgcc.a
ld.lld: /lib/libgcc_s.so
ld.lld: /lib/libgcc_s.so.1
ld.lld: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/libgcc.a
ld.lld: /lib/libc.so
ld.lld: /usr/lib/libc.so.6
ld.lld: /usr/lib/libc_nonshared.a
ld.lld: /usr/lib/ld-linux-x86-64.so.2
ld.lld: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/libgcc.a
ld.lld: /lib/libgcc_s.so
ld.lld: /lib/libgcc_s.so.1
ld.lld: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/libgcc.a
ld.lld: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/crtendS.o
ld.lld: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/../../../../aarch64-linux-gnu/lib/crtn.o
ld.lld: error: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/../../../../aarch64-linux-gnu/lib/Scrt1.o is incompatible with elf64-x86-64
ld.lld: error: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/../../../../aarch64-linux-gnu/lib/crti.o is incompatible with elf64-x86-64
ld.lld: error: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/crtbeginS.o is incompatible with elf64-x86-64
ld.lld: error: test.o is incompatible with elf64-x86-64
ld.lld: error: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/libgcc.a(cas_1_1.o) is incompatible with elf64-x86-64
ld.lld: error: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/libgcc.a(cas_2_1.o) is incompatible with elf64-x86-64
ld.lld: error: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/libgcc.a(cas_4_1.o) is incompatible with elf64-x86-64
ld.lld: error: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/libgcc.a(cas_8_1.o) is incompatible with elf64-x86-64
ld.lld: error: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/libgcc.a(cas_16_1.o) is incompatible with elf64-x86-64
ld.lld: error: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/libgcc.a(cas_1_2.o) is incompatible with elf64-x86-64
ld.lld: error: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/libgcc.a(cas_2_2.o) is incompatible with elf64-x86-64
ld.lld: error: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/libgcc.a(cas_4_2.o) is incompatible with elf64-x86-64
ld.lld: error: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/libgcc.a(cas_8_2.o) is incompatible with elf64-x86-64
ld.lld: error: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/libgcc.a(cas_16_2.o) is incompatible with elf64-x86-64
ld.lld: error: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/libgcc.a(cas_1_3.o) is incompatible with elf64-x86-64
ld.lld: error: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/libgcc.a(cas_2_3.o) is incompatible with elf64-x86-64
ld.lld: error: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/libgcc.a(cas_4_3.o) is incompatible with elf64-x86-64
ld.lld: error: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/libgcc.a(cas_8_3.o) is incompatible with elf64-x86-64
ld.lld: error: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/libgcc.a(cas_16_3.o) is incompatible with elf64-x86-64
ld.lld: error: /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/libgcc.a(cas_1_4.o) is incompatible with elf64-x86-64
ld.lld: error: too many errors emitted, stopping now (use --error-limit=0 to see all errors)
```
It's worth noting that binutils ld handle this case correctly, due to it being single targeted.
binutils ld behavior:
```
% aarch64-linux-gnu-ld --sysroot=/usr/aarch64-linux-gnu -EL --hash-style=gnu --build-id --eh-frame-hdr -m aarch64linux -pie -dynamic-linker /lib/ld-linux-aarch64.so.1 -o a.out /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/../../../../aarch64-linux-gnu/lib/Scrt1.o /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/../../../../aarch64-linux-gnu/lib/crti.o /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/crtbeginS.o -L/lib -L/usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0 -L/usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/../../../../aarch64-linux-gnu/lib/../lib64 -L/usr/aarch64-linux-gnu/lib/../lib64 -L/usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/../../../../aarch64-linux-gnu/lib -L/usr/aarch64-linux-gnu/lib test.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/crtendS.o /usr/bin/../lib64/gcc/aarch64-linux-gnu/14.1.0/../../../../aarch64-linux-gnu/lib/crtn.o 
aarch64-linux-gnu-ld: skipping incompatible /lib/libgcc_s.so.1 when searching for libgcc_s.so.1
aarch64-linux-gnu-ld: skipping incompatible /lib/libgcc_s.so.1 when searching for libgcc_s.so.1
aarch64-linux-gnu-ld: skipping incompatible /lib/libc.so when searching for -lc
aarch64-linux-gnu-ld: skipping incompatible /lib/libc.a when searching for -lc
aarch64-linux-gnu-ld: skipping incompatible /lib/libgcc_s.so.1 when searching for libgcc_s.so.1
aarch64-linux-gnu-ld: skipping incompatible /lib/libgcc_s.so.1 when searching for libgcc_s.so.1
```

Currently in lld, `-m` option is used by clang to set target, `-m` sets the `config->emulation`, but linker script sets `config->bfdname`, lld would always prefer using `bfdname` as the target, casuing the aforementioned cryptic error message.

This situation is quite common unfortuantely, due to some build tool not handling cross compilation well enough (like `libtool`). It would be nice for lld to behave the same as binutils ld in this situation, both for compatibility and robustness.

# Additional infomation:
## Versions:
```
LLD 18.1.8 (compatible with GNU linkers)

clang version 18.1.8
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

GNU ld (GNU Binutils) 2.42.0
Copyright (C) 2024 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.
```
Linux distro: EndeavourOS

# Steps for reproducing:
```shell
# linker error
echo 'int main(){}' | clang -target aarch64-linux-gnu -xc --sysroot=/usr/aarch64-linux-gnu -L/lib -fuse-ld=lld -
# no error
echo 'int main(){}' | clang -target aarch64-linux-gnu -xc --sysroot=/usr/aarch64-linux-gnu -L/lib -
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWt1u2zoSfhrlZiDBkh3_XPgireODAtnT4qTdvQwocizNliK1JBVHb78gKcc_cXZ7TtuNFyhQqIE8M_w4HA4_DYdZS5VCXCbX75Lr1RXrXK3NktfkmM6L8eSq1KJfJsUY3hnCTTJaJaObf9SogBttLXDdtCRJVUnxHqTIpBSQTEdpk0xHoFtHWoF-RLM15BwqKHuotXXQMF6TQpCkvqIByw21ztsoSXWOpAUpoGZKSARXkwVLrmPBHNfGIHeyzyIaD26FjpFEAa3RpcQG8KmVTAWFKPVBAYM7Ut0T2N46bKCzpCqoJJXcD5xMR0mxllTGJ8-s9nMgC-wYJbiaObDorNf5-OXzpy-fH9Yf__jbzWev4DS4Go9mmcGANDxvn1jTSj_1OMh4eO8BxH_DtNZJcQO__f7Fu2JwUPgFAL5YDKPYmhkU3pRhpg_-6xxY3SBsOsX99C0wg6CV7IHUs4Gg7JgjfqhsNTjT7ybItRLMkOwzSIqAJ2gfz7iYo9xMJ-nTfJpOJ0mxiEK__fHxyydIijkkxbqz5tS12fTcDw9KqziljAHc3D_8fnu7ul2dtSNS6VdzGNibLCApFvAM4dSfr4buEAlcMlUBUwKkFN4btPGrHML57iCcST1HYAh6KWCrO79GyAyv48oPToUNGeuiUc1EcPuLkLcdr6PP97Y2jCRsydXAYItkBKAx2kCD1rIKs1dC5nq3B9PU9tZo7ZLx6tlzzOObTgbHVaqD9PYO0rRmtk6t6yUm41V4nZYdSZGSN4R1ujGswbQWBtIGBivBCKQtIaSiV6whng5Te7lIg45fpRxSDSzTndsvaUkqKdZZFhV9GK0rzs8hTop1PsnybLSTP3mcU4hY7rlxeab_t4Ny4-j7x-TGlViRus80pHdRN_7xl61-p_qfdsTe-uHIf1b-pyP9BnCQpo9oSu0zMFrnl0RWnEOaMpsqRIEivnmwkKZKH73m3y78_TGDSty_QcArP2bIRzEXJeObkEcb9kRN1wDXinfGoOK9PyzzaciBLXLa9JCmrjbIhE3GK_8rr5mq8NTcWySON8UQ88gPhnCQVk4tx8j-weNJKivOM3bG7DMFCFvBs6JvkMnyNwDIz4M7S3G-Qe6Q8fw38TOM59cK_aidEJPlW29y9RJC4H1vlfT854_nu03LHJUSIyU9YvwXAXfgWW-G9pCh_XUQA594s1k8765izpl9yB_8sVcsLgZQcWmAJpcGaH5pgPLpxSF6KC4LUHFpgCaXBmh-aYDy6cUhehhfFqDi0gBNLg3Q_NIA5dOLQ_Qw-V5ATmtomOrjGwvYkHMY6rvW6bYlVYHSW0iKeWcR0jTIpZIacsl4Fer5FhGYlIOJ1wrMH1xSzCxstXE1KO285VDVfe1KgzOLcFRLFh368chBiV7dkqq8NDMVOhRD1ffQXok1e6Qw1VdLwi88nv4qEP8qEP8qEP-sAvGvsvB_Lgufy0ehSPyVYj4-SvXn60qwrVENN25eZaMNnCk8_V8MxTOrzw2SSv79ptlPsnzJS3H25vd9uHNw4Rp8d8N72qlAFjqLAsp-uA0Oh78bDuAjjXD_72r0b7hWG6rSZHyLTSdj08F0tLuNP24e2PUN7HXKjVCswUFjfwXM5Jb1FlqDGzTDHXUyHe3FgUUEe3Sc2S7SDgS20QYbVB4NCuCmbx3x89fI4fn5uM2CLPyrI-cZStNoBZ3aaOM6phwekZXQbBDYgOda0jOfyHLCnfrBTXs0u0VPpJTuqtpzLklfgwsllV47OGGRwQc3OKFEUMQxrnQYIlKeof2BNei9cMiISJ00jIR10K4ONnYhRpJcH-7ljS476xRae-SNpBjDjRDkLTAJpDa6iebGewkv9Hc0lrSyrzGwu7sV5PMsz-Z-vqccNrR3hAA54JXhGQPwMVofLAwLFdd7fANP8-nDdJK2_CDlDmtpkAlotEDpBVtt6WnXCGMdkxLFil4y9oPxh8aTpJj7v94NHvZkvMgmRTbM7r1ue0NV7bna_H34dVRMYG0Q4V5v3JYZhLXulHheiw-KZwcR1xpdGdb4eNt4LTtoJeN30OsOGtaDQUHWGSo7h54dd0qgibGPprGgh8Yk_8aj_Q0VGibhU1dK4nBHHJXFZ2eOQXsOOmfOj2CG3e_BM5DModlJnsNZMwustFp2fiOA0rBlxjDl-vNNGbHnKODX3t-3SiB71J35eH8ab_cOWxvC1GBrtOg4qeplXNkapdxrDfklfvGEt8hrf77PSDlomD_e5z64Zu-S2SopZpDM3g_5LY254-UnAqRP_Ju_EZ4Z56azGNL6KvSg7DEqfRH4Thx5JZZjsRgv2BUu81kxzsej69nkql7mQggcL8Tsej6bcSzKKRc4n-Sz2WKEuMivaOnDfDQfzfProrieZDOc89FiOlnM8HqTT0fJZIQNI5lJ-dhk2lRXZG2Hy3xUTBajK8lKlDZ03RVFOIyK5Hp1ZZZePC27yiaTkSTr7N6AIydDo56Xv17tOn1sPZwWUm9D2xtx8qecRRc-QdlwPviAp0ppg6BdjQZ0-U_kzsbmpMMzKoZgFIq6fttfdUYua-fakOmKtaeJ5OquzLhuvIPl4-6_tDXa206KdZi19cQxTvxxWfw7AAD__166dFg">