Backslashes confuse CMake's dependency scanning
Closed this issue · 6 comments
CMake's dependency scanning for MSVC involves it passing the /showIncludes
flag to cl
, which results in it printing
Note: including file: \opt\msvc\vc\tools\msvc\14.29.30133\include\string
Note: including file: \opt\msvc\vc\tools\msvc\14.29.30133\include\yvals_core.h
Note: including file: \opt\msvc\vc\tools\msvc\14.29.30133\include\vcruntime.h
etc. to stdout. Unfortunately the backslashes confuse it, meaning that it ends up recompiling the whole project every time.
Changing the third line of /opt/msvc/bin/x64/cl
to
$(dirname $0)/wine-msvc.sh $BINDIR/cl.exe "$@" | sed "s/\\\\/\//g" -
fixes this, but it's not a very elegant way of doing it. It probably should say "for every line beginning 'Note: including file:', replace backslashes with slashes" - however you express that in sed.
Have a look at (the topmost commit in) https://github.com/mstorsjo/msvc-wine/commits/cmake - that contains an example of building a lightly patched cmake and ninja, which then should work fine with respect to dependency tracking. Unfortunately, those patches aren't entirely fit to upstream...
It turns out this is the correct syntax for sed:
#!/bin/bash
. $(dirname $0)/msvcenv.sh
$(dirname $0)/wine-msvc.sh $BINDIR/cl.exe "$@" | sed "/Note: including file:/ s/\\\\/\//g" -
Works fine for me on vanilla CMake 3.21.3, with both make and ninja.
Do you want me to submit a patch?
Thanks! I actually have a similar patch in a local test branch since some time (with a few minor tweaks to the regex, mine is '/^Note:/s,\\,/,g'
(but I had applied it in wine-msvc.sh
, while keeping it in the cl
wrapper only is a better idea.
I'll try to refresh my memory with what I concluded about it and why I didn't go forward with it, whether it interfered with some of my other build setups or not... But meanwhile, I don't mind taking a patch for it!
This issue was discussed a bit in ninja-build/ninja#1735, and in ninja-build/ninja#1735 (comment) I seem to have concluded that it seemed to work fine that far...
Hi! First: FANTASTIC WORK! It's amazing.
Second: Happy new year.
Third: I'm hit by this issue and the proposed solution works (i.e. ninja no longer starts from scratch) but I'm seeing a similar problem with RC. The generated rules.ninja contain:
#############################################
# Rule for compiling RC files.
rule RC_COMPILER__OgreMain_Release
depfile = $DEP_FILE
deps = gcc
command = "" RC $in $DEP_FILE $out "Note: including file: " "/opt/msvc/bin/x64/cl" /opt/msvc/bin/x64/rc $DEFINES $INCLUDES $FLAGS /fo $out $in
description = Building RC object $out
Which works if I manually edit it to:
#############################################
# Rule for compiling RC files.
rule RC_COMPILER__OgreMain_Release
depfile = $DEP_FILE
deps = msvc
command = /opt/msvc/bin/x64/rc $DEFINES $INCLUDES $FLAGS /fo $out $in
description = Building RC object $out
But obviously it reverts if I run CMake again. Any ideas? I tried the suggested solution by patching rc but it doesn't seem to work. Maybe the syntax for sed must be different
Update
Appears to be a Ninja problem. With GNU Make generator the problem is not there.
Btw even in ninja, the CMake variable CMAKE_RC_COMPILER:FILEPATH=/opt/msvc/bin/x64/rc
is properly set
Third: I'm hit by this issue and the proposed solution works (i.e. ninja no longer starts from scratch) but I'm seeing a similar problem with RC.
Update
Appears to be a Ninja problem. With GNU Make generator the problem is not there. Btw even in ninja, the CMake variable
CMAKE_RC_COMPILER:FILEPATH=/opt/msvc/bin/x64/rc
is properly set
I've reproduced this now (this also was reported in #22, but I never got back to looking into that at the time), which has got a link to the upstream issue, https://gitlab.kitware.com/cmake/cmake/-/issues/21760. See #22 for further insights into the issue and how one could go try to go about fixing it.