CMake hangs on select() call when starting MSVC link.exe via Wine
So we have a somewhat peculiar setup:
- Linux
- with LVM image file mounted
-
chroot
in system in this mount - CMake in said chroot
- uses wrapper shell-scripts specified in Toolchain file
- to call VS 2013 toolchain utilities cl.exe, link.exe, etc.
- via Wine emulator.
And at some point something in this chain fails.
When building our VS2013 project (couple dozens .dll
s) some linker calls hang indefinitely after the linker itself finishes. So while there is a linked library file in my build directory, there is also a process in form of cmake -E vs_link_dll --intdir=project/CMakeFiles/grabSimpleIP.dir --rc=/WineMSVC/bin/wx-rc --mt=/WineMSVC/bin/wx-mt --manifests -- /WineMSVC/bin/wx-link /nologo ...
waiting for something.
The issue is always caused by the same library, with other 30 being built just fine. However if I comment it out from my CMakeLists.txt
, the problem reappears on some other library, which leads me to assumption that there is nothing wrong with the library itself (or there is something else fundamentally wrong).
Our wx-link
wrapper:
source _msvc_wine_wrapper_common.sh # transforms /unix/paths to Z:\windows\paths
wine link.exe ${MSVC_TO_ARGS}
RC=$?
if [[ ! $RC -eq 0 ]]
then
printf "====COMMAND: wine link.exe ${MSVC_TO_ARGS}\n"
printf "====ORIG_ARGS-D: wx-link ${ORIG_ARGS}\n"
echo "Returned code: $RC"
exit $RC
fi
exit 0
If I run said cmake -E vs_link_dll
under strace
, it tells me that the process waits on select(6, [5], NULL, NULL, NULL
.
I digged down to very kwsysProcessWaitForPipe
in CMake/Source/kwsys/ProcessUNIX.c
, and yes, there is
while (((numReady = select(max + 1, &cp->PipeSet, 0, 0, timeout)) < 0) && ...
that causes CMake to hang.
The call stack in question:
kwsysProcessWaitForPipe @ Source/kwsys/ProcessUNIX.c
kwsysProcess_WaitForData @ Source/kwsys/ProcessUNIX.c
cmSystemTools::RunSingleCommand @ Source/cmSystemTools.cxx
RunCommand @ Source/cmcmd.cxx
cmVSLink::LinkNonIncremental @ Source/cmcmd.cxx
cmVSLink::Link @ Source/cmcmd.cxx
cmcmd::VisualStudioLink @ Source/cmcmd.cxx
In RunSingleCommand
there is cmsysProcess_WaitForData
being called that resolves to kwsysProcess_WaitForData
, due to some preprocessing magic, apparently.
Looking at RunSingleCommand
one can see that at the point of WaitForData
the process itself has finished fine - which explains why there is a built library, so the problem happens somewhere in output processing. It happens even if the linker fails and returns non-zero exit code, and even if I make the wrapper completely silent by redirecting wine link.exe ${MSVC_TO_ARGS} 1>/dev/null 2>/dev/null
.