Subject: bug#65723: GCC/Clang toolchain package ld wrapper on utf8 paths with LANG enviroment variable not utf8

From: "andy" <[email-masked]>
Date: Sat, 2 Sep 2023 22:57:11 -0500

This happens with both gcc-toolchain 12.3.0 or clang-toolchain 15.0.7.

$ echo $PWD
/home/testuser123/你好
$ echo $LANG
en_US.utf8
$ guile --version
guile (GNU Guile) 3.0.9
$ guix --version
guix (GNU Guix) 3335903d7d6d7ee93436d046b3037d433d06372b
$ ld --version
GNU ld (GNU Binutils) 2.38
...
$ clang --version
clang version 15.0.7
Target: x86_64-unknown-linux-gnu
...

To recreate write a hello world in C or C++ into main.cpp.

$ clang -c main.cpp -o main.o
$ ld main.o /gnu/store/2h51y9n2c96k4rxa6fl7irdwirw7q0z8-profile/lib/libc.so
This works fine
$ LANG="" ld main.o /gnu/store/2h51y9n2c96k4rxa6fl7irdwirw7q0z8-profile/lib/libc.so
And the above
$ ld main.o /gnu/store/2h51y9n2c96k4rxa6fl7irdwirw7q0z8-profile/lib/libc.so -o "$PWD/a.out"
And this works
But below fails
$ LANG="" ld main.o /gnu/store/2h51y9n2c96k4rxa6fl7irdwirw7q0z8-profile/lib/libc.so -o "$PWD/a.out"
ld: cannot open output file /home/testuser123/??????/a.out: No such file or directory

The gcc-toolchain and clang-toolchain seem to have identical "ld" files as "diff"ing them shows no difference. ld is a Guile file so I would assume somehow the script somehow looks at the LANG environment variable which messes up the character encodings of paths and replacing them with the question marks.

The ld wrapper depending on the LANG environment variable having utf8 for handling filenames has some problems. Some build systems like Rust's Cargo unset the LANG environment variable, causing ld to output those question marks in place of the utf8 bytes, which will break for any path that has Unicode. I don't think it is intended behavior for a linker to depend on the LANG to handle filenames.