Skip to content

Commit ca4d867

Browse files
author
Christian Seiler
committed
CMake: properly fix build on macOS with Ninja (related to response files)
On macOS several build-related programs (`cc`, `ar`) will not accept the linker line if too many files have been added to it in the DYNAMIC_ARCH case. (This now occurs on all platforms where macOS runs / used to run, as there are enough ARM variants that are build with DYNAMIC_ARCH that the number of files exceeds the intrinsic limit on macOS.) The workaround for this is to use response files that contain the file list themselves, and pass these to the build system. For dynamic libraries this works fine, but for static libraries it doesn't because `ar` doesn't accept response files on macOS. For this reason there was previously a workaround in CMakeLists.txt to handle this, but the workaround didn't take into consideration that when building only a shared library it is not actually necessary, and when building static libraries the response file CMake generates for Ninja is at a different location than the response files CMake generates for Unix Makefiles. This commit cleans this all up by setting the necessary options for the response files to be properly generated, and adjusts the additional workaround to only be applicable in the case a static library is built. The workaround is also adjusted to handle the Ninja case. Fixes GitHub issue #5775
1 parent 3c553ef commit ca4d867

1 file changed

Lines changed: 38 additions & 13 deletions

File tree

CMakeLists.txt

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,30 @@ if (${DYNAMIC_ARCH})
243243
endforeach()
244244
endif ()
245245

246+
# Work around Apple issue with "argument list too long" when linking.
247+
# Seen for DYNAMIC_ARCH when there are a _LOT_ of variants build, previously
248+
# mostly with older versions on POWERPC or Intel CPUs, but with newer ARM
249+
# CPUs and newer compilers this will also occur on ARM.
250+
#
251+
# This must happen before the add_library() calls, otherwise this will have
252+
# no effect.
253+
#
254+
# Unfortunately, while this workaround will work for shared libraries (with
255+
# either Ninja oder Unix Makefiles), but not for static libraries, as ar
256+
# does not accept response files. So for the case where we (also) build
257+
# static libraries we need an additional workaround, see below. (The
258+
# generation of the response files by CMake must still be enabled, so this
259+
# is required regardless.)
260+
if(APPLE)
261+
set(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS ON)
262+
set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES ON)
263+
if(NOT NOFORTRAN)
264+
set(CMAKE_Fortran_USE_RESPONSE_FILE_FOR_OBJECTS ON)
265+
set(CMAKE_Fortran_USE_RESPONSE_FILE_FOR_LIBRARIES ON)
266+
endif()
267+
set(CMAKE_NINJA_FORCE_RESPONSE_FILE ON)
268+
endif()
269+
246270
# add objects to the openblas lib
247271
if(NOT NO_LAPACK)
248272
add_library(LAPACK_OVERRIDES OBJECT ${LA_SOURCES})
@@ -308,20 +332,22 @@ if (USE_OPENMP)
308332
endif()
309333
endif()
310334

311-
# Fix "Argument list too long" for macOS - mostly seen with older OS versions on POWERPC or Intel CPUs
312-
if(APPLE AND "${CMAKE_GENERATOR}" MATCHES ".*Makefiles")
313-
# Use response files to get around the ARG_MAX limit, unless using the Ninja generator
314-
set(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1)
335+
# Second part of "Argument list too long" fix when static libraries are
336+
# built. See above for details.
337+
if(APPLE AND BUILD_STATIC_LIBS)
315338
# Always build static library first
316-
if(BUILD_STATIC_LIBS)
317-
set(STATIC_PATH "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${OpenBLAS_LIBNAME}.a")
339+
set(STATIC_PATH "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${OpenBLAS_LIBNAME}.a")
340+
# Handle differences in how many response files are generated and/or where
341+
# they are stored for Ninja / Unix Makefiles.
342+
if("${CMAKE_GENERATOR}" MATCHES "Ninja")
343+
set(CREATE_STATIC_LIBRARY_COMMAND
344+
"sh -c 'cat ${CMAKE_BINARY_DIR}/CMakeFiles/openblas_static.rsp | xargs -n 1024 ${CMAKE_AR} -ru ${STATIC_PATH} && exit 0' "
345+
"sh -c '${CMAKE_AR} -rs ${STATIC_PATH} ${CMAKE_BINARY_DIR}/driver/others/CMakeFiles/driver_others.dir/xerbla.c.o && exit 0' ")
318346
else()
319-
add_library(${OpenBLAS_LIBNAME}_static STATIC ${TARGET_OBJS} ${OpenBLAS_DEF_FILE})
320-
set(STATIC_PATH "lib${OpenBLAS_LIBNAME}.a")
347+
set(CREATE_STATIC_LIBRARY_COMMAND
348+
"sh -c 'cat ${CMAKE_BINARY_DIR}/CMakeFiles/${OpenBLAS_LIBNAME}_static.dir/objects*.rsp | xargs -n 1024 ${CMAKE_AR} -ru ${STATIC_PATH} && exit 0' "
349+
"sh -c '${CMAKE_AR} -rs ${STATIC_PATH} ${CMAKE_BINARY_DIR}/driver/others/CMakeFiles/driver_others.dir/xerbla.c.o && exit 0' ")
321350
endif()
322-
set(CREATE_STATIC_LIBRARY_COMMAND
323-
"sh -c 'cat ${CMAKE_BINARY_DIR}/CMakeFiles/${OpenBLAS_LIBNAME}_static.dir/objects*.rsp | xargs -n 1024 ${CMAKE_AR} -ru ${STATIC_PATH} && exit 0' "
324-
"sh -c '${CMAKE_AR} -rs ${STATIC_PATH} ${CMAKE_BINARY_DIR}/driver/others/CMakeFiles/driver_others.dir/xerbla.c.o && exit 0' ")
325351
if(BUILD_SHARED_LIBS)
326352
add_dependencies(${OpenBLAS_LIBNAME}_shared ${OpenBLAS_LIBNAME}_static)
327353
set(SHARED_PATH "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libopenblas.${OpenBLAS_MAJOR_VERSION}.${OpenBLAS_MINOR_VERSION}.dylib")
@@ -332,8 +358,7 @@ if(APPLE AND "${CMAKE_GENERATOR}" MATCHES ".*Makefiles")
332358
set(OMP_LIB "")
333359
endif()
334360
if(NOT NOFORTRAN)
335-
set(CMAKE_Fortran_USE_RESPONSE_FILE_FOR_OBJECTS 1)
336-
set(CMAKE_Fortran_CREATE_STATIC_LIBRARY ${CREATE_STATIC_LIBRARY_COMMAND})
361+
set(CMAKE_Fortran_CREATE_STATIC_LIBRARY ${CREATE_STATIC_LIBRARY_COMMAND})
337362
if(BUILD_SHARED_LIBS)
338363
set(CMAKE_Fortran_CREATE_SHARED_LIBRARY
339364
"sh -c 'echo \"\" | ${CMAKE_Fortran_COMPILER} -o dummy.o -c -x f95-cpp-input - '"

0 commit comments

Comments
 (0)