<div>Hello,</div><div><br></div><div>I posted a mail here [1] but have yet to receive any replies. I think my last</div><div>message was too long and detailed so let me summarize:</div><div>* Command line length is limited on Windows.</div>
<div>* To alleviate this, CMake places object files into a response file, but the</div><div> same is not done for libraries.</div><div>* This can pose a problem when the link line becomes too long.</div><div><br></div><div>
I am primarily interested in a solution for the Ninja generator, although this</div><div>issue affects other generators too. My previous mail contains a testcase and</div><div>proposed solution. In the interim another issue [2] was posted, but that is</div>
<div>orthogonal and does not solve what is discussed here.</div><div><br></div><div>Kind regards,</div><div><br></div><div><i>--Zaheer</i><br></div><div><i><br></i></div><div>[1]: <a href="http://www.cmake.org/pipermail/cmake/2012-June/051065.html">http://www.cmake.org/pipermail/cmake/2012-June/051065.html</a></div>
<div>[2]: <a href="http://public.kitware.com/Bug/view.php?id=13366">http://public.kitware.com/Bug/view.php?id=13366</a></div><div><br></div><div class="gmail_quote">On Thu, Jun 28, 2012 at 3:50 PM, Zaheer Chothia <span dir="ltr"><<a href="mailto:zaheer.chothia@gmail.com" target="_blank">zaheer.chothia@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello,<br>
<br>
I encountered an issue while building a CMake project where one target is linked<br>
against a large number of libraries. Unlike object files, libraries are not<br>
placed into a response file, which can lead to build commands which exceed the<br>
length limits on Windows. For reference, I am using the CMake 2.8.9-rc1 and<br>
Ninja generator with Microsoft compilers.<br>
<br>
Following this mail is a testcase generator [1] to demonstrate this issue<br>
(sample project attached for convenience). The build fails with this error (for<br>
readibility I replaced a long sequence of libraries with <...>):<br>
<br>
FAILED: cmd.exe /c cd. && "C:\Program Files<br>
(x86)\CMake\bin\cmake.exe" -E vs_link_exe<br>
C:\PROGRA~2\MICROS~3.0\VC\bin\cl.exe /nologo @hello.exe.rsp /DWIN32<br>
/D_WINDOWS /W3 /Zm1000 /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1 /Fehello.exe<br>
/Fdhello.pdb -link /implib:hello.lib /version:0.0 /STACK:10000000<br>
/machine:X86 /debug /INCREMENTAL /subsystem:console<br>
src\abcdefghijklmnopqrstuvwxyz0123456789\library1.lib<br>
src\abcdefghijklmnopqrstuvwxyz0123456789\library2.lib <...><br>
kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib<br>
oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd.<br>
The command line is too long.<br>
<br>
ninja: build stopped: subcommand failed.<br>
<br>
Although this example may seem artificial, with the use case I refer to (i)<br>
libraries are are specified by absolute paths so they are indeed reasonably long<br>
and (ii) since there are third-party libraries involved I would not be able to<br>
simply combine source files into one large library as is possible here. I<br>
should also mention that this issue does not affect the Visual Studio<br>
generators, however it is present with the following: Ninja, MinGW<br>
Makefiles, NMake Makefiles, MSYS Makefiles. For Ninja I suspect that the<br>
indirection via cmd.exe imposes a maximum command length of 8192 KB, whereas for<br>
the others this will likely be 32 KB (CreateProcess).<br>
<br>
I would be quite content if this is fixed for the Ninja generator. A simple fix<br>
would be to adapt the build rules by moving $LINK_LIBRARIES from 'command' to<br>
'rspfile_content':<br>
<br>
--- rules.ninja.bak 2012-06-28 15:23:35 +0100<br>
+++ rules.ninja 2012-06-28 15:38:09 +0100<br>
@@ -40,10 +40,10 @@<br>
# Rule for linking C executable.<br>
<br>
rule C_EXECUTABLE_LINKER_RSPFILE<br>
- command = cmd.exe /c $PRE_LINK && "C:\Program Files<br>
(x86)\CMake\bin\cmake.exe" -E vs_link_exe<br>
C:\PROGRA~2\MICROS~3.0\VC\bin\cl.exe /nologo @$out.rsp $FLAGS<br>
/Fe$out /Fd$TARGET_PDB -link /implib:$TARGET_IMPLIB /version:0.0<br>
$LINK_FLAGS $LINK_LIBRARIES && $POST_BUILD<br>
+ command = cmd.exe /c $PRE_LINK && "C:\Program Files<br>
(x86)\CMake\bin\cmake.exe" -E vs_link_exe<br>
C:\PROGRA~2\MICROS~3.0\VC\bin\cl.exe /nologo @$out.rsp $FLAGS<br>
/Fe$out /Fd$TARGET_PDB -link /implib:$TARGET_IMPLIB /version:0.0<br>
$LINK_FLAGS && $POST_BUILD<br>
description = Linking C executable $out<br>
rspfile = $out.rsp<br>
- rspfile_content = $in<br>
+ rspfile_content = $in $LINK_LIBRARIES<br>
<br>
Best,<br>
<br>
--Zaheer<br>
<br>
---- [1]: BEGIN: testcase.sh ---------------------------------------------------<br>
#!/bin/bash -e<br>
<br>
NUM_LIBRARIES=500<br>
# Use a long path to quickly exhaust the command-line length limit.<br>
SRC_DIR=src/abcdefghijklmnopqrstuvwxyz0123456789<br>
<br>
# Root directory: application and CMakeLists.txt<br>
echo "int main() { return 0; }" > hello.c<br>
<br>
cat << EOF > CMakeLists.txt<br>
cmake_minimum_required(VERSION 2.8)<br>
<br>
project(Hello)<br>
<br>
add_subdirectory($SRC_DIR)<br>
<br>
add_executable(hello hello.c)<br>
target_link_libraries(hello<br>
EOF<br>
<br>
for ((i = 1; i <= $NUM_LIBRARIES; i++)); do<br>
echo " library$i" >> "CMakeLists.txt"<br>
done<br>
<br>
echo ")" >> "CMakeLists.txt"<br>
<br>
# Libraries: sources and CMakeLists.txt<br>
mkdir -p "$SRC_DIR"<br>
[[ -f "$SRC_DIR/CMakeLists.txt" ]] && rm "$SRC_DIR/CMakeLists.txt"<br>
for ((i = 1; i <= $NUM_LIBRARIES; i++)); do<br>
echo "int function$i() { return $i; }" > "$SRC_DIR/function$i.c"<br>
echo "add_library(library$i function$i.c)" >> "$SRC_DIR/CMakeLists.txt"<br>
done<br>
<br>
echo "Testcase has been setup: now build with CMake and Ninja generator."<br>
---- [1]: END: testcase.sh ---------------------------------------------------<br>
</blockquote></div><br>