Reactos

[CMAKE] Don't re-archive import libraries

Instead create an IMPORTED library from the output of dlltool.
This prevents binutils 2.40+ nested archive crash (bug #31614):

+40 -37
+2 -2
dll/win32/msvcrt/CMakeLists.txt
··· 204 204 # Let consumers of msvcrt have the right defines 205 205 target_compile_definitions(libmsvcrt INTERFACE _DLL __USE_CRTIMP) 206 206 207 - # Embed msvcrtex into libmsvcrt 208 - target_sources(libmsvcrt PRIVATE $<TARGET_OBJECTS:msvcrtex>) 207 + # Link libmsvcrt to msvcrtex 208 + target_link_libraries(libmsvcrt INTERFACE msvcrtex) 209 209 210 210 # Link GCC stack protector lib 211 211 if (STACK_PROTECTOR)
+1 -1
dll/win32/ucrtbase/CMakeLists.txt
··· 42 42 ) 43 43 44 44 # Implicitly link to vcstartup 45 - target_link_libraries(libucrtbase vcstartup) 45 + target_link_libraries(libucrtbase INTERFACE vcstartup) 46 46 47 47 if(MSVC) 48 48 target_link_libraries(ucrtbase runtmchk)
+1 -1
ntoskrnl/CMakeLists.txt
··· 25 25 26 26 if(CMAKE_C_COMPILER_ID STREQUAL "Clang") 27 27 # Clang optimises strcmp calls to memcmp. 28 - target_sources(libntoskrnl PRIVATE $<TARGET_OBJECTS:memcmp>) 28 + target_link_libraries(libntoskrnl INTERFACE memcmp) 29 29 endif() 30 30 31 31 if((CMAKE_C_COMPILER_ID STREQUAL "Clang") OR (CMAKE_C_COMPILER_ID STREQUAL "GNU"))
+22 -24
sdk/cmake/gcc.cmake
··· 443 443 DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} native-spec2def) 444 444 445 445 # With this, we let DLLTOOL create an import library 446 + # Note: previously we re-archived the import library created by dlltool into 447 + # a thin archive ('ar crT'). This is broken with binutils 2.40+ (bug #31614) 448 + # and leads to a linker crash. The new method of using an IMPORTED library 449 + # avoids this. It does no longer allow to embed new object files into the 450 + # import libraries, but this is replaced by linking the additinal libraries 451 + # to the import library. 446 452 set(LIBRARY_PRIVATE_DIR ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_libname}.dir) 447 453 add_custom_command( 448 454 OUTPUT ${LIBRARY_PRIVATE_DIR}/${_libname}.a 449 455 # ar just puts stuff into the archive, without looking twice. Just delete the lib, we're going to rebuild it anyway 450 - COMMAND ${CMAKE_COMMAND} -E rm -f $<TARGET_FILE:${_libname}> 456 + COMMAND ${CMAKE_COMMAND} -E rm -f ${LIBRARY_PRIVATE_DIR}/${_libname}.a 451 457 COMMAND ${CMAKE_DLLTOOL} --def ${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def --kill-at --output-lib=${_libname}.a -t ${_libname} 452 458 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def 453 459 WORKING_DIRECTORY ${LIBRARY_PRIVATE_DIR}) 454 460 455 - # We create a static library with the importlib thus created as object. AR will extract the obj files and archive it again as a thin lib 456 - set_source_files_properties( 457 - ${LIBRARY_PRIVATE_DIR}/${_libname}.a 458 - PROPERTIES 459 - EXTERNAL_OBJECT TRUE) 460 - _add_library(${_libname} STATIC EXCLUDE_FROM_ALL 461 - ${LIBRARY_PRIVATE_DIR}/${_libname}.a) 462 - set_target_properties(${_libname} 463 - PROPERTIES 464 - LINKER_LANGUAGE "C" 465 - PREFIX "") 461 + # Create a custom target for the import library generation 462 + add_custom_target(${_libname}_implib_target DEPENDS ${LIBRARY_PRIVATE_DIR}/${_libname}.a) 463 + 464 + # Create an IMPORTED library that references the dlltool output 465 + _add_library(${_libname} STATIC IMPORTED GLOBAL) 466 + set_target_properties(${_libname} PROPERTIES IMPORTED_LOCATION ${LIBRARY_PRIVATE_DIR}/${_libname}.a) 467 + add_dependencies(${_libname} ${_libname}_implib_target) 466 468 467 469 # Do the same with delay-import libs 468 470 set(LIBRARY_PRIVATE_DIR ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_libname}_delayed.dir) 469 471 add_custom_command( 470 472 OUTPUT ${LIBRARY_PRIVATE_DIR}/${_libname}_delayed.a 471 473 # ar just puts stuff into the archive, without looking twice. Just delete the lib, we're going to rebuild it anyway 472 - COMMAND ${CMAKE_COMMAND} -E rm -f $<TARGET_FILE:${_libname}_delayed> 474 + COMMAND ${CMAKE_COMMAND} -E rm -f ${LIBRARY_PRIVATE_DIR}/${_libname}_delayed.a 473 475 COMMAND ${CMAKE_DLLTOOL} --def ${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def --kill-at --output-delaylib=${_libname}_delayed.a -t ${_libname}_delayed 474 476 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def 475 477 WORKING_DIRECTORY ${LIBRARY_PRIVATE_DIR}) 476 478 477 - # We create a static library with the importlib thus created. AR will extract the obj files and archive it again as a thin lib 478 - set_source_files_properties( 479 - ${LIBRARY_PRIVATE_DIR}/${_libname}_delayed.a 480 - PROPERTIES 481 - EXTERNAL_OBJECT TRUE) 482 - _add_library(${_libname}_delayed STATIC EXCLUDE_FROM_ALL 483 - ${LIBRARY_PRIVATE_DIR}/${_libname}_delayed.a) 484 - set_target_properties(${_libname}_delayed 485 - PROPERTIES 486 - LINKER_LANGUAGE "C" 487 - PREFIX "") 479 + # Create a custom target for the delay-import library generation 480 + add_custom_target(${_libname}_delayed_implib_target DEPENDS ${LIBRARY_PRIVATE_DIR}/${_libname}_delayed.a) 481 + 482 + # Create an IMPORTED library for delay-import 483 + _add_library(${_libname}_delayed STATIC IMPORTED GLOBAL) 484 + set_target_properties(${_libname}_delayed PROPERTIES IMPORTED_LOCATION ${LIBRARY_PRIVATE_DIR}/${_libname}_delayed.a) 485 + add_dependencies(${_libname}_delayed ${_libname}_delayed_implib_target) 488 486 endfunction() 489 487 490 488 function(spec2def _dllname _spec_file)
+5 -2
sdk/lib/crt/msvcrtex.cmake
··· 90 90 set_source_files_properties(${MSVCRTEX_ASM_SOURCE} PROPERTIES COMPILE_DEFINITIONS "_DLL;_MSVCRTEX_") 91 91 add_asm_files(msvcrtex_asm ${MSVCRTEX_ASM_SOURCE}) 92 92 93 - add_library(msvcrtex OBJECT ${MSVCRTEX_SOURCE} ${msvcrtex_asm}) 93 + add_library(msvcrtex STATIC ${MSVCRTEX_SOURCE} ${msvcrtex_asm}) 94 94 target_compile_definitions(msvcrtex PRIVATE _DLL _MSVCRTEX_) 95 + 96 + # msvcrtex depends on msvcrt and kernel32 97 + target_link_libraries(msvcrtex INTERFACE libmsvcrt libkernel32) 95 98 96 99 if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") 97 100 target_compile_options(msvcrtex PRIVATE $<$<COMPILE_LANGUAGE:C>:-Wno-main>) ··· 105 108 startup/wcrtexe.c PROPERTIES COMPILE_DEFINITIONS _M_CEE_PURE) 106 109 107 110 if(NOT MSVC) 108 - target_link_libraries(msvcrtex oldnames) 111 + target_link_libraries(msvcrtex INTERFACE oldnames) 109 112 endif() 110 113 111 114 add_dependencies(msvcrtex psdk asm)
+9 -7
sdk/lib/crt/oldnames.cmake
··· 5 5 add_custom_command( 6 6 OUTPUT ${LIBRARY_PRIVATE_DIR}/oldnames.a 7 7 # ar just puts stuff into the archive, without looking twice. Just delete the lib, we're going to rebuild it anyway 8 - COMMAND ${CMAKE_COMMAND} -E rm -f $<TARGET_FILE:oldnames> 8 + COMMAND ${CMAKE_COMMAND} -E rm -f ${LIBRARY_PRIVATE_DIR}/oldnames.a 9 9 COMMAND ${CMAKE_DLLTOOL} --def ${CMAKE_CURRENT_SOURCE_DIR}/moldname-msvcrt.def --kill-at --output-lib=oldnames.a -t oldnames 10 10 DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/moldname-msvcrt.def 11 11 WORKING_DIRECTORY ${LIBRARY_PRIVATE_DIR}) 12 - set_source_files_properties( 13 - ${LIBRARY_PRIVATE_DIR}/oldnames.a 14 - PROPERTIES 15 - EXTERNAL_OBJECT TRUE) 16 12 17 - _add_library(oldnames STATIC EXCLUDE_FROM_ALL ${LIBRARY_PRIVATE_DIR}/oldnames.a) 18 - set_target_properties(oldnames PROPERTIES LINKER_LANGUAGE "C") 13 + # Create a custom target for the import library generation 14 + add_custom_target(oldnames_target DEPENDS ${LIBRARY_PRIVATE_DIR}/oldnames.a) 15 + 16 + # Create an IMPORTED library that references the dlltool output 17 + _add_library(oldnames STATIC IMPORTED GLOBAL) 18 + set_target_properties(oldnames PROPERTIES IMPORTED_LOCATION ${LIBRARY_PRIVATE_DIR}/oldnames.a) 19 + add_dependencies(oldnames oldnames_target) 20 + set_target_properties(oldnames PROPERTIES LINKER_LANGUAGE "C") 19 21 else() 20 22 add_asm_files(oldnames_asm oldnames-common.S oldnames-msvcrt.S) 21 23 add_library(oldnames ${oldnames_asm})