Cross-compiling from Windows with a Linux-GCC toolchain exceeds max command line length during linking
This issue was created automatically from an original Mantis Issue. Further discussion may take place here.
When compiling using GCC on Windows as a non-cross-compile, CMake has code in the platform files for using a response file to pass the objects to GCC's linker. When cross-compiling to a Linux toolchain, this workaround is not used. I was hitting this issue at around the 200-300 file count.
It seems that GCC supports the usage of response files across all OSes. Additionally, it seems that there are some cases that on certain Linux configurations (compiling natively) that they can run into the same issue as Windows. I believe CMake should use response files under the situation I am seeing (cross-compiling on Windows) and perhaps more universally.
I cross-compiled the GenICam GenAPI reference implementation from Windows to an ARM/Linux target. GenApi's source includes components Xerces and Xalan, both which have hundreds of files and hit this error. The error shown is an unterminated string in sh.exe because the line is truncated.
To work around this I added the following into the macro section of Linux-GNU.cmake
(copied from the Windows version of that file):
set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_OBJECTS 1)
set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_INCLUDES 1)
# We prefer "@" for response files but it is not supported by gcc 3.
execute_process(COMMAND ${CMAKE_${lang}_COMPILER} --version OUTPUT_VARIABLE _ver ERROR_VARIABLE _ver)
if("${_ver}" MATCHES "\\(GCC\\) 3\\.")
if("${lang}" STREQUAL "Fortran")
# The GNU Fortran compiler reports an error:
# no input files; unwilling to write output files
# when the response file is passed with "-Wl,@".
set(CMAKE_Fortran_USE_RESPONSE_FILE_FOR_OBJECTS 0)
else()
# Use "-Wl,@" to pass the response file to the linker.
set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "-Wl,@")
endif()
# The GNU 3.x compilers do not support response files (only linkers).
set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_INCLUDES 0)
elseif(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_OBJECTS)
# Use "@" to pass the response file to the front-end.
set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "@")
endif()