Spurious issues with accessing files on network mounts
I have tested a code of my own in the following options:
- X64 VC++ MSVC
- X64 MinGW GCC
- X64 Linux
- X64 MinGW Clang
and my project compiled successfully in all the above targets except the latter. I am getting a bunch of the following errors:
In file included from <some HPP file>.HPP:<some file line number>:
In file included from <some HPP file>.HPP:<some file line number>:
In file included from <some HPP file>.HPP:<some file line number>:
In file included from <some HPP file>.HPP:<some file line number>:
...
<some HPP file>.HPP:<some file line number>:<some column number>: error: #include nested too deeply.
My project is a CMake project. Sometimes running parallel builds many times results in a successful build. Also, I am using a Ninja generator, and I am building directly on Windows.
As this is a private code, I cannot share code snippets here, but I am happy to have a private chat with you in a different chat channel regarding this matter.
Could you provide any minimal sample code or project to reproduce the issue?
let me try to create a sample project that can repro the same problem, and ill link you to it
For the time being, I have added @Biswa96 and @mstorsjo to my private repo for investigation.
Try to rebuild with GCC/G++ MinGW as CC/CXX vs Clang/Clang++ (e.g. both either from MSYS2 or clang/clang++ from release of llvm-mingw ... I tried both). Also, I noticed that Clang does not respect _setmode(_fileno(stdout), _O_U16TEXT); to set the output to unicode (I can't print using std::wcout for e.g.).
I can not reproduce your original issue with llvm-mingw. I have used the llvm-mingw-20230130-ucrt-x86_64.zip file, extract it in a directory, add that to PATH environment variable. Then compiled it with cmake + ninja + llvm-mingw without any problem.
Hmm weird. By the way, I am running the build from SSH to a Windows VM. Could this be a problem?
Also, what are your versions of CMake and Ninja?
My CMake is 3.26.0-rc3 My Ninja is 1.11.1
I'm using it in msys2 mingw environment in bare metal Windows 10.
- cmake: https://packages.msys2.org/base/mingw-w64-cmake
- ninja: https://packages.msys2.org/base/mingw-w64-ninja
I'm not sure if the environment have any effect on preprocessing CPP files.
Can you also try to change some simple logic in any of the files and try to rebuild? For some reason the build errors seems to be intermittent. Sometimes the build goes through, sometimes I see aforementioned bug above.
Tried it, can't reproduce any issue. If you want clean build environment the Docker image may help. Docker Hub link is in README file.
@Biswa96 If possible, can you try to build on Win 11 as well? I am using Win 11 pro VM btw.
I have tried in bare metal Windows 11 installation as well. Same result, no issue or compiler error.
I have just tried a Windows 10 Pro installation and same problem happens. Here is what I did:
- I download CMake 3.25.2 from official site: https://cmake.org/download/.
- I downloaded Ninja from official github release site from: https://github.com/ninja-build/ninja/releases/tag/v1.11.1.
- I download LLVM-MinGW from: https://github.com/mstorsjo/llvm-mingw/releases/tag/20220906.
- I installed CMake and set the path for all users.
- I put ninja somewhere and set path to it.
- Same thing for LLVM-MinGW's top bin folder.
- I set CC = x86_64-w64-mingw32-clang and CXX = x86_64-w64-mingw32-clang++.
- I did cmake <project full path dir> -DCMAKE_INSTALL_PREFIX=<some custom install dir full path> -GNinja
- I did "ninja install".
and same problem I see in my Win 10 pure installation.
@Biswa96 what do you mean by bare metal windows btw here? like IoT windows version?
can you please describe all the steps you have taken perform a clean build (also including how did you setup ur environment)? maybe I am missing something here.
bare metal means like normal installation on actual drive, no VM, no hypervisor. I am using msys2 (https://www.msys2.org/) project. But discussing about that would be off-topic here. You can use CI or container image to build your project with llvm-mingw.
I cannot reproduce any such build problem with the repo you provided.
To get a third party reproducible setup, I would recommend trying to reproduce the issue in e.g. GitHub Actions builds. If you manage to show a failure there, anybody else with a copy of the same repo should be able to reproduce the bug in the same way.
I am getting different results in VirtualBox VM (above results) and bare metal Windows 11. On bare metal, I am now getting the following output:
cmd.exe /C "cd . && "C:\Program Files\CMake\bin\cmake.exe" -E rm -f lib\lib<Some Lib>.a && C:\PROGRA~1\LLVMMI~1\20230130\msvcrt\bin\X8FE23~1.EXE qc lib\lib<Some Lib>.a lib/CMakeFiles/<Some Dir>.dir/__/common/LongPathSupport.rc.res lib/CMakeFiles/<Some Dir>.dir/Common.cpp.obj lib/CMakeFiles/<Some Dir>.dir/<Some File>.cpp.obj lib/CMakeFiles/<Some Dir>.dir/<Some File>.cpp.obj lib/CMakeFiles/<Some Dir>.dir/<Some File>.cpp.obj && C:\PROGRA~1\LLVMMI~1\20230130\msvcrt\bin\X8396E~1.EXE lib\lib<Some Lib>.a && cd ."
C:\PROGRA~1\LLVMMI~1\20230130\msvcrt\bin\llvm-X8FE23~1: Invalid argument
ninja: build stopped: subcommand failed.
This is how I set the environment before calling CMake build and install (testing on release 20220906 (I found the same issue with Clang-15 and Clang-16) with msvcrt) [testing on PowerShell Core]:
$env:Path = "C:\Program Files\LLVM MinGW\20220906\msvcrt\bin;$env:Path"; $env:CC = "x86_64-w64-mingw32uwp-clang.exe"; $env:CXX = "x86_64-w64-mingw32uwp-clang++.exe".
Then, I do cmake <Project full path> -DCMAKE_INSTALL_PREFIX=<Install full path> -GNinja and ninja install on the build directory.
It is weird why I am getting different outputs on different setups (same Windows setup, just different way of running it (bare metal/VM)).
Don't put anything in a path containing space characters. It is often a source of all kinds of weird issues.
But, C:\Program Files is by default having spaces, which is where more most binaries reside (e.g. default install path for CMake). Not handling spaces in my opinion is a bug (a bug that I did not find earlier when playing around with the toolchain like 2-3 years ago).
Hmm, having ninja and the LLVM MinGW toolchain in a path no spaces has no errors.
What happens if you use the 8.3 name in your powershell script?
Instead of:
$env:Path = "C:\Program Files\LLVM MinGW\20220906\msvcrt\bin;$env:Path";
use
$env:Path = "C:\PROGRA~1\LLVMMI~1\20230130\msvcrt\bin;$env:Path";
CMake uses 8.3 old dos naming for Ninja files in order to overcome any space issues.
Edit: I've noticed that there are two dates here in the LLVM MinGW paths, make sure you have the same version for the 8.3 test.
If I am to guess, it is possible that the llvm-mingw wrapper doesn't know how to handle 8.3 module names.
With the tools placed in a path with spaces, I can indeed reproduce issues. And the issues are most probably caused by the wrapper executables indeed.
If I am to guess, it is possible that the llvm-mingw wrapper doesn't know how to handle 8.3 module names.
Yeah, that looks like it. Or more precisely - when the tool has been executed as C:\PROGRA~1\LLVMMI~1\20230130\msvcrt\bin\X8FE23~1.EXE, the tool tries to inspect X8FE23~1.EXE to see what executable to invoke, but can't figure it out - while it would have expected something like x86_64-w64-mingw32-ar.exe (which it parses and then invokes llvm-ar.exe).
When I try it out, I run into a case where it fails to link, since it executes C:\code\16rc1\PATHWI~1\bin\C__~1.EXE, and the wrapper doesn't detect that C__~1.EXE is meant to be another name for c++.exe, i.e. it should link in C++ mode.
I guess some step that doesn't look at argv[0] but instead resolves the name of the executable, would be necessary. (The LLVM based tools do this internally.)
The current approach of using argv[0] would be better, though, if we would be using symlinks. E.g. it would allow us to have both clang.exe and clang++.exe be symlinks to clang-target-wrapper.exe; by looking at argv[0], we should be able to figure out which name the user used for the symlink. If we resolve it to the actual name of the exe, we'd only see clang-target-wrapper.exe.
Or are there other ways to ask the filesystem to reverse-map the mangled file name in argv[0] into a full pathname?
(Or as a separate sidetrack - is there any way to ask the CMake generator to not flatten paths to 8.3 paths, trusting that the tools themselves can handle arguments/paths with spaces correctly?)
One can disable the 8.3 file naming on NTFS as seen at https://learn.microsoft.com/en-US/troubleshoot/windows-server/performance/stop-error-code-0x00000019
fsutil behavior set disable8dot3 1
If CMake and Ninja doesn't work afterwards then it's a valid CMake bug 🙂
I think it would be easier to use something like GetLongPathName and / or GetShortPathName.
The current approach of using
argv[0]would be better, though, if we would be using symlinks. E.g. it would allow us to have bothclang.exeandclang++.exebe symlinks toclang-target-wrapper.exe; by looking atargv[0], we should be able to figure out which name the user used for the symlink. If we resolve it to the actual name of the exe, we'd only seeclang-target-wrapper.exe.
It seems like I misremembered about this; we do see the name of the symlink instead of the main executable from GetModuleFileName.
The usecase I thought about was to fake the behaviour of symlinks without having them; you could do the equivalent of execl(/*file*/ "actual-executable.exe", /*argv[0]*/ "<triple-prefix>-toolname.exe", /*other-args*/...), where you pass a fake executable name in argv[0] - that would essentially get the effect of having symlinks, without needing to have physical files corresponding to that file name (which would be nice on Windows, where symlinks still are a bit problematic.) I don't think anything relies on that though. (And if it does, it'd be simple to add support for it, in the form of dirname(GetModuleFileName())/basename(argv[0]).)
I think it would be easier to use something like GetLongPathName and / or GetShortPathName.
Thanks, that seems to do the trick - see https://github.com/mstorsjo/llvm-mingw/commit/829aad161faea2f357ef840c130837a34e90d53b. (I'm currently test running this a bit; I'll push it to the master branch once it looks good. Freel free to comment on it!) I see that LLVM already was doing pretty much exactly the same too: https://github.com/llvm/llvm-project/blob/llvmorg-16.0.0-rc3/llvm/lib/Support/Windows/Process.inc#L209-L219
@mstorsjo if possible, can you also try the current LLVM MinGW wrappers in Windows inside VirtualBox? I have seen different results there. Not sure if it also applies o other VMs.