为什么添加链接器标志 `-save-temps` 可以解决 clang-8 错误:“无法创建临时文件”?

Dan*_*jel 5 c llvm clang clang++

我正在使用 Windows + Cygwin + Eclipse + LLVM 工具链来构建 C/C++ 项目。

这些文件可以使用clangC 编译器正常编译,但使用clang++多个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
Run Code Online (Sandbox Code Playgroud)

链接器为每个目标文件生成一个错误。

当我将-save-temps选项添加到链接器时,它工作正常!

可能是什么问题呢?

添加--verbose给出:

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
Run Code Online (Sandbox Code Playgroud)

我已经检查了TMPTEMP变量 - 一切似乎都正常。我尝试更改TMPTEMP以包含尾部斜杠,我还尝试使用反斜杠或正斜杠/的整个路径- 没有任何帮助。\/

这是更详细的输出。

-save-temps首先,这是带有标志和 的输出-###

 "/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"
Run Code Online (Sandbox Code Playgroud)

-save-temps这是不带,仅 的输出-###

 "/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"
Run Code Online (Sandbox Code Playgroud)

所以"-o" "my_files\\my_file1.s"vs"-o" ""似乎就是区别。有解释吗?

另外,还有一些带有 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"
Run Code Online (Sandbox Code Playgroud)

并且只有-###

"/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"
Run Code Online (Sandbox Code Playgroud)

因此,再次"my_files\\my_file1.o" "my_files\\my_file2.o" "my_files\\my_file3.o"丢失并用空字符串替换 "" "" ""

还有一件事,正如 clang 邮件列表中指出的那样:“驱动程序选项 -save-temps 和链接器选项 --save-temps(驱动程序选项 -Wl,--save-temps)都不尊重 TMP/TEMP/TMPDIR。临时文件是相对于当前工作目录保存的...”

所以,这与临时目录位置无关。

Zaa*_*ier 1

导致此失败的一个潜在原因是tmp环境变量被分配给不存在的路径。-save-temps(可能还有其他原因。)当传递参数时,不会触发错误,因为临时文件被写入当前工作目录,并且不采用clang++.exe使用的分支。tmp

unable to make temporary file: invalid argument接下来您可能会遇到错误。造成这种情况的一个常见原因是分配给 的路径周围有引号tmp。例如,您可能在批处理文件中编写了以下内容:

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
Run Code Online (Sandbox Code Playgroud)

在该批处理文件中,脚本目录被引用,以便从包含空格的路径运行时不会失败。这些引号会导致错误。为 赋值时不要包含它们tmp