mstorsjo/msvc-wine

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.

The original issue here, about ninja not handling the dependencies, should be fixed by baf2d3c.