5

I am using Windows + Cygwin + Eclipse + LLVM toolchain to build a C/C++ project.

The files compile fine with clang C compiler, but linking with clang++ fails with multiple error: unable to make temporary file: No such file or directory.

clang++ -o test "source1.bc" "source2.bc" "source3.bc" 
clang-8: error: unable to make temporary file: No such file or directory
clang-8: error: unable to make temporary file: No such file or directory
clang-8: error: unable to make temporary file: No such file or directory

Linker generates one error per each object file.

When I add the -save-temps option to linker, it works OK!

What could be the problem?

Adding --verbose gives:

clang version 8.0.1 (tags/RELEASE_801/final) Target: x86_64-unknown-windows-cygnus
Thread model: posix
InstalledDir: /usr/bin
clang-8: error: unable to make temporary file: No such file or directory
clang-8: error: unable to make temporary file: No such file or directory
clang-8: error: unable to make temporary file: No such file or directory

I have checked the TMP and TEMP variables - everything seems OK. I tried changing the TMP and TEMP to include trailing slash /, I also tried the whole path with backslashes \ or forward slashes / - nothing helped.

Here is a more verbose outputs.

First, here is the outputs with flags -save-temps and -###:

 "/usr/bin/clang-8" "-cc1" "-triple" "x86_64-unknown-windows-cygnus" "-S" "-save-temps=cwd" "-disable-free" "-disable-llvm-verifier" "-discard-value-names" "-main-file-name" "my_files\\my_file1.bc" "-mrelocation-model" "pic" "-pic-level" "2" "-mthread-model" "posix" "-fmath-errno" "-masm-verbose" "-mconstructor-aliases" "-munwind-tables" "-target-cpu" "x86-64" "-dwarf-column-info" "-debugger-tuning=gdb" "-momit-leaf-frame-pointer" "-v" "-resource-dir" "/usr/lib/clang/8.0.1" "-fdebug-compilation-dir" "/cygdrive/c/my_projects/prj1/Debug" "-ferror-limit" "19" "-fmessage-length" "0" "-fobjc-runtime=gcc" "-fseh-exceptions" "-fdiagnostics-show-option" "-o" "my_files\\my_file1.s" "-x" "ir" "my_files\\my_file1.bc" "-faddrsig"

Here is the output without -save-temps, just -###:

 "/usr/bin/clang-8" "-cc1" "-triple" "x86_64-unknown-windows-cygnus" "-emit-obj" "-mrelax-all" "-disable-free" "-disable-llvm-verifier" "-discard-value-names" "-main-file-name" "my_files\\my_file1.bc" "-mrelocation-model" "pic" "-pic-level" "2" "-mthread-model" "posix" "-fmath-errno" "-masm-verbose" "-mconstructor-aliases" "-munwind-tables" "-target-cpu" "x86-64" "-dwarf-column-info" "-debugger-tuning=gdb" "-momit-leaf-frame-pointer" "-v" "-resource-dir" "/usr/lib/clang/8.0.1" "-fdebug-compilation-dir" "/cygdrive/c/my_projects/prj1/Debug" "-ferror-limit" "19" "-fmessage-length" "0" "-fobjc-runtime=gcc" "-fseh-exceptions" "-fdiagnostics-show-option" "-o" "" "-x" "ir" "my_files\\my_file1.bc" "-faddrsig"

So the "-o" "my_files\\my_file1.s" vs "-o" "" seems to be the difference. Is there an explanation?

Also, some more output with flags -save-temps, -###:

"/usr/bin/ld" "-m" "i386pep" "--wrap" "_Znwm" "--wrap" "_Znam" "--wrap" "_ZnwmRKSt9nothrow_t" "--wrap" "_ZnamRKSt9nothrow_t" "--wrap" "_ZdlPv" "--wrap" "_ZdaPv" "--wrap" "_ZdlPvRKSt9nothrow_t" "--wrap" "_ZdaPvKSt9nothrow_t" "-Bdynamic" "--tsaware" "-o" "myexecutable" "/usr/lib/crt0.o" "/usr/lib/gcc/x86_64-pc-cygwin/10/crtbegin.o" "-LC:/mylibraries" "-L/usr/lib/gcc/x86_64-pc-cygwin/10" "-L/usr/x86_64-pc-cygwin/lib" "-L/usr/lib" "-L/usr/lib/w32api" "my_files\\my_file1.o" "my_files\\my_file2.o" " my_files\\my_file3.o" "-lnaturedsp" "-lgcc_s" "-gcc" "-lcygwin" "-ladvapi32" "-lshell32" "-luser32" "-lkernel32" "/usr/lib/default-manifest.o" "/usr/lib/gcc/x86_64-pc-cygwin/10/crtend.o"

and with only -###:

"/usr/bin/ld" "-m" "i386pep" "--wrap" "_Znwm" "--wrap" "_Znam" "--wrap" "_ZnwmRKSt9nothrow_t" "--wrap" "_ZnamRKSt9nothrow_t" "--wrap" "_ZdlPv" "--wrap" "_ZdaPv" "--wrap" "_ZdlPvRKSt9nothrow_t" "--wrap" "_ZdaPvKSt9nothrow_t" "-Bdynamic" "--tsaware" "-o" "myexecutable" "/usr/lib/crt0.o" "/usr/lib/gcc/x86_64-pc-cygwin/10/crtbegin.o" "-LC:/mylibraries" "-L/usr/lib/gcc/x86_64-pc-cygwin/10" "-L/usr/x86_64-pc-cygwin/lib" "-L/usr/lib" "-L/usr/lib/w32api" "" "" "" "-lnaturedsp" "-lgcc_s" "-lgcc" "-lcygwin" "-ladvapi32" "-lshell32" "-luser32" "-lkernel32" "/usr/lib/default-manifest.o" "/usr/lib/gcc/x86_64-pc-cygwin/10/crtend.o"

So, again "my_files\\my_file1.o" "my_files\\my_file2.o" "my_files\\my_file3.o" are lost and substituted with empty strings "" "" "".

One more thing, as pointed out on the clang mailing list: "Neither the driver option -save-temps nor the linker option --save-temps (driver option -Wl,--save-temps) respects TMP/TEMP/TMPDIR. The temporary files are saved relative to the current working directory..."

So, it's not about temporary directory location.

Danijel
  • 8,198
  • 18
  • 69
  • 133
  • 1
    Try this: https://stackoverflow.com/a/44005867/13912132 (I know it's about git, but maybe it's the same root cause???) – JCWasmx86 Jul 24 '20 at 17:10
  • @JCWasmx86 Trailing slash did not help. – Danijel Aug 11 '20 at 12:25
  • Did you try to enable verbose output to get for context? What did you get? Please [edit] your question when adding new information. – the busybee Sep 14 '20 at 09:59
  • @thebusybee Adding `-verbose` gives: `clang version 8.0.1 (tags/RELEASE_801/final) Target: x86_64-unknown-windows-cygnus Thread model: posix InstalledDir: /usr/bin clang-8: error: unable to make temporary file: No such file or directory clang-8: error: unable to make temporary file: No such file or directory clang-8: error: unable to make temporary file: No such file or directory` – Danijel Sep 21 '20 at 13:12
  • As I said, please add new informations to your question, don't post them here in the comments where they become lost and unread. -- If I add `-v` or `--verbose` to the call of clang++, I get a lot more of output, including the command lines of called underlying tools. But my installation might differ from yours. You might have a general problem with your system, for example missing `TMP` and/or `TEMP` environment variables or if you have them, pointing to non-existent or non-accessible paths. – the busybee Sep 21 '20 at 13:30
  • What does your research on existence and rights of the path for the temporary file reveal? Did you try to find out where clang tries to create that file? Are you able to create a file at the same place? – the busybee Oct 01 '20 at 13:47
  • Verbose option doesn't give too much info. Have in mind that the linking step is the problem - compiling goes OK. Also, it is the linker option `-save-temps` that helps resolve the case. However, linking with this option is terribly slow. – Danijel Oct 02 '20 at 10:23
  • Tried to get more info with `-###`, maybe that helps. – Danijel Oct 05 '20 at 13:55
  • This is observed in a number of places but much less attention. – Dr. Essen Oct 04 '21 at 09:30

1 Answers1

1

One potential cause of this failure is the tmp environment variable is assigned to a path that does not exist. (There may be other causes.) The error isn't tripped when the -save-temps argument is passed to clang++.exe because the temporary files are instead written to the current working directory and the branch that uses tmp isn't taken.

You may run into the error unable to make temporary file: invalid argument next. One common cause of that is having quotation marks around the path assigned to tmp. For example, you might have written the following in a Batch file:

REM  This is the quoted, fully-qualified path to this script.
set script_directory=%~dp0:~0,-1%
set script_directory="%script_directory%"

REM  clang++.exe requires a writable temporary directory.
set tmp=%script_directory%

%script_directory%\bin\clang++.exe ^
    my_program.exe ^
   -Xclang -main-file-name %script_directory%\src\main.cpp

In that Batch file, the script directory is quoted so that it won't fail when run from a path that contains spaces. Those quotation marks will cause an error. Don't include them when assigning a value to tmp.

Zaaier
  • 685
  • 8
  • 22
  • I'm very happy with Jonathan Blow's work on moving very nearly all of this kind of configuration into the source code of the language he's been developing. Build metadata ending up in a soupy mess spread across Batch scripts, environment variables, filesystem state, and the registry leads to endless variations on this kind of cryptic "works on my machine" error. – Zaaier Apr 17 '23 at 06:37