rui314 / mold

Mold: A Modern Linker 🦠
MIT License
13.69k stars 448 forks source link

Dependency file has references to temporary file #1258

Closed LarsGullik closed 1 month ago

LarsGullik commented 1 month ago

In our project we use --dependency-file as an argument to the supported linkers. This works fine, except with mold since it also outputs temporary files into the file. Resulting in this part of the build always being dirty since the temporary file is removed after linking is finished.

Typical output in dependency file:

binary: /tmp/cc0vlGjM  ...
rui314 commented 1 month ago

Did you know who created that temporary file?

If you run mold with the environment variable MOLD_DEBUG set to 1, the linker will record the command line given to it in the .comment section of an output file, which you can see with readelf -p .comment your-executable-file. You may want to do that to see how that temporary file is passed to the linker.

LarsGullik commented 1 month ago

I am pretty certain it is GCC that creates the temporary file. I'll try to verify.

LarsGullik commented 1 month ago

The relevant part from the .comment section (I had to remove some details.)

String dump of section '.comment':                                                                                  
  [     0]  mold command line: -plugin /usr/libexec/gcc/x86_64-redhat-linux/13/liblto_plugin.so -plugin-opt=/usr/li\
bexec/gcc/x86_64-redhat-linux/13/lto-wrapper -plugin-opt=-fresolution=/tmp/ccEfFUxB.res -plugin-opt=-pass-through=-\
lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lpthread -plugin-opt=-pass-through=-lc -plugin-op\
t=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu \
-m elf_x86_64 -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -o test -z noexecstack -z relro -z n\
ow /usr/lib/gcc/x86_64-redhat-linux/13/../../../../lib64/Scrt1.o /usr/lib/gcc/x86_64-redhat-linux/13/../../../../li\
b64/crti.o /usr/lib/gcc/x86_64-redhat-linux/13/crtbeginS.o -L/usr/lib/gcc/x86_64-redhat-linux/13 -L/usr/lib/gcc/x86\
_64-redhat-linux/13/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/13/../\
../.. a.cpp.o b.cpp.o c.cpp.o d.cpp.o lib1.a lib2.a lib3.a -ldl lib4.a e.cpp.o f.cpp.o g.cpp.o h.cpp.o lib5.a lib6.\
a lib7.a -lrt --thread-count=4 -Map=test.map --dependency-file=test.d -lstdc++ -lm -lgcc_s -lgcc -lpthread -lc -lgc\
c_s -lgcc /usr/lib/gcc/x86_64-redhat-linux/13/crtendS.o /usr/lib/gcc/x86_64-redhat-linux/13/../../../../lib64/crtn.\
o                                                                                                                   

The temporary file mentioned in the dependency file is test: /tmp/ccSTKqic ..., which is not mentioned on the command line. Either created by mold or by one of the GCC scripts?

rui314 commented 1 month ago

Interesting. Can you try to run the linker again with the --repro flag, which generates test.repro.tar, and share the generated tar file with me? With that, I can run mold with the exact inputs on my local machine.

LarsGullik commented 1 month ago

Ahh found it. Where the temporary file comes from: an resource file.
mold-link.zip

Still the other linkers does not output a dependency to the resource file. (gold,ld,lld)

rui314 commented 1 month ago

Unfortunately I couldn't reproduce the issue with the zip file you provided. Could you upload a tar file generated by mold as I explained in the previous comment?

LarsGullik commented 1 month ago

Unfortunately I couldn't reproduce the issue with the zip file you provided. Could you upload a tar file generated by mold as I explained in the previous comment?

I can. I am a bit surprised that you cannot reproduce. From reading the mold sources it seems quite clear that a response file (@file), is added to the mf_pool in the Context. And when that file happens to be a temporary file things fall down.

For me a (with the code in the zip file), all subsequent invocations of ninja will rerun the linker step. Where it should just say "no work to do". Easy way for me to see why this happens is to run ninja as ninja -d explain where the temporary file is reported as the culprit for why re-link is needed.

Anyway, the repro file:

repro.zip

(zipped tgz file, githug does not like tar nor tgz.)

I am afraid that you will not be able to reprocue with this either as the response file has been resolved and does not participate in the reported command line invocation anymore.

rui314 commented 1 month ago

The above commit should fix the issue.