https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b96e88894a4d55f5e8b94430deeb0f086151b24f

commit b96e88894a4d55f5e8b94430deeb0f086151b24f
Author:     Jérôme Gardou <[email protected]>
AuthorDate: Mon Nov 2 10:51:08 2020 +0100
Commit:     Jérôme Gardou <[email protected]>
CommitDate: Mon Dec 28 12:13:30 2020 +0100

    [CMAKE] Turn import libs into regular C static libs
    
    Embed msvcrtex into libmsvcrt
    
    Idea taken from Thomas Faber
---
 dll/win32/msvcrt/CMakeLists.txt    | 17 +++++------
 sdk/cmake/gcc.cmake                | 54 +++++++++++++++++++++++++++-------
 sdk/cmake/msvc.cmake               | 59 ++++++++++++++++++--------------------
 sdk/lib/crt/msvcrtex.cmake         | 12 +++++---
 sdk/lib/crt/oldnames.cmake         | 19 ++++++++++--
 win32ss/gdi/gdi32/CMakeLists.txt   |  5 +++-
 win32ss/user/user32/CMakeLists.txt |  5 ++--
 7 files changed, 110 insertions(+), 61 deletions(-)

diff --git a/dll/win32/msvcrt/CMakeLists.txt b/dll/win32/msvcrt/CMakeLists.txt
index 2e0c6625971..61ae9432d74 100644
--- a/dll/win32/msvcrt/CMakeLists.txt
+++ b/dll/win32/msvcrt/CMakeLists.txt
@@ -1,14 +1,12 @@
 
 include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/crt/include)
-spec2def(msvcrt.dll msvcrt.spec)
+spec2def(msvcrt.dll msvcrt.spec ADD_IMPORTLIB)
 
-# The msvcrt <-> msvcrtex trick
-generate_import_lib(libmsvcrt_real msvcrt.dll msvcrt.spec)
-add_library(libmsvcrt INTERFACE)
+# Let consumers of msvcrt have the right defines
 target_compile_definitions(libmsvcrt INTERFACE _DLL __USE_CRTIMP)
-# if the linked module is one of win32gui;win32cui;win32dll;win32ocx;cpl link 
it with msvcrtex, which itself is linked to libmsvcrt_real
-# Otherwise, just link to libmsvcrt_real
-target_link_libraries(libmsvcrt INTERFACE 
"$<IF:$<IN_LIST:$<TARGET_PROPERTY:REACTOS_MODULE_TYPE>,win32gui;win32cui;win32dll;win32ocx;cpl>,msvcrtex,libmsvcrt_real>")
+# Embed msvcrtex into libmsvcrt
+target_sources(libmsvcrt PRIVATE $<TARGET_OBJECTS:msvcrtex>)
+
 
 add_definitions(
     -DUSE_MSVCRT_PREFIX
@@ -35,7 +33,10 @@ target_link_libraries(msvcrt crt wine ${PSEH_LIB})
 if(MSVC)
     # export of deleting destructor "name"
     target_link_options(msvcrt PRIVATE "/ignore:4102")
-    set_property(TARGET libmsvcrt_real APPEND PROPERTY STATIC_LIBRARY_OPTIONS 
"/ignore:4102")
+    set_property(TARGET libmsvcrt APPEND PROPERTY STATIC_LIBRARY_OPTIONS 
"/ignore:4102")
+    if(ARCH STREQUAL "i386")
+        target_sources(libmsvcrt PRIVATE $<TARGET_OBJECTS:ftol2_sse>)
+    endif()
 endif()
 
 add_importlibs(msvcrt kernel32 ntdll)
diff --git a/sdk/cmake/gcc.cmake b/sdk/cmake/gcc.cmake
index 938bc0e2454..bec502d75c7 100644
--- a/sdk/cmake/gcc.cmake
+++ b/sdk/cmake/gcc.cmake
@@ -322,20 +322,52 @@ function(generate_import_lib _libname _dllname _spec_file)
         OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def
         COMMAND native-spec2def -n=${_dllname} -a=${ARCH2} ${ARGN} --implib 
-d=${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def 
${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file}
         DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} native-spec2def)
-    
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def 
PROPERTIES EXTERNAL_OBJECT TRUE)
 
-    # Create normal importlib
-    _add_library(${_libname} STATIC EXCLUDE_FROM_ALL 
${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def)
-    set_target_properties(${_libname} PROPERTIES LINKER_LANGUAGE "IMPLIB" 
PREFIX "")
-
-    # Create delayed importlib
-    _add_library(${_libname}_delayed STATIC EXCLUDE_FROM_ALL 
${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def)
-    set_target_properties(${_libname}_delayed PROPERTIES LINKER_LANGUAGE 
"IMPLIB_DELAYED" PREFIX "")
+    # With this, we let DLLTOOL create an import library
+    set(LIBRARY_PRIVATE_DIR 
${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_libname}.dir)
+    add_custom_command(
+        OUTPUT ${LIBRARY_PRIVATE_DIR}/${_libname}.a
+        # ar just puts stuff into the archive, without looking twice. Just 
delete the lib, we're going to rebuild it anyway
+        COMMAND ${CMAKE_COMMAND} -E rm -f $<TARGET_FILE:${_libname}>
+        COMMAND ${CMAKE_DLLTOOL} --def 
${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def --kill-at 
--output-lib=${_libname}.a -t ${_libname}
+        DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def
+        WORKING_DIRECTORY ${LIBRARY_PRIVATE_DIR})
+
+    # 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
+    set_source_files_properties(
+        ${LIBRARY_PRIVATE_DIR}/${_libname}.a
+        PROPERTIES
+        EXTERNAL_OBJECT TRUE)
+    _add_library(${_libname} STATIC EXCLUDE_FROM_ALL
+        ${LIBRARY_PRIVATE_DIR}/${_libname}.a)
+    set_target_properties(${_libname}
+        PROPERTIES
+        LINKER_LANGUAGE "C"
+        PREFIX "")
+
+    # Do the same with delay-import libs
+    set(LIBRARY_PRIVATE_DIR 
${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_libname}_delayed.dir)
+    add_custom_command(
+        OUTPUT ${LIBRARY_PRIVATE_DIR}/${_libname}_delayed.a
+        # ar just puts stuff into the archive, without looking twice. Just 
delete the lib, we're going to rebuild it anyway
+        COMMAND ${CMAKE_COMMAND} -E rm -f $<TARGET_FILE:${_libname}_delayed>
+        COMMAND ${CMAKE_DLLTOOL} --def 
${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def --kill-at 
--output-delaylib=${_libname}_delayed.a -t ${_libname}_delayed
+        DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def
+        WORKING_DIRECTORY ${LIBRARY_PRIVATE_DIR})
+
+    # We create a static library with the importlib thus created. AR will 
extract the obj files and archive it again as a thin lib
+    set_source_files_properties(
+        ${LIBRARY_PRIVATE_DIR}/${_libname}_delayed.a
+        PROPERTIES
+        EXTERNAL_OBJECT TRUE)
+    _add_library(${_libname}_delayed STATIC EXCLUDE_FROM_ALL
+        ${LIBRARY_PRIVATE_DIR}/${_libname}_delayed.a)
+    set_target_properties(${_libname}_delayed
+        PROPERTIES
+        LINKER_LANGUAGE "C"
+        PREFIX "")
 endfunction()
 
-# Cute little hack to produce import libs
-set(CMAKE_IMPLIB_CREATE_STATIC_LIBRARY "${CMAKE_DLLTOOL} --def <OBJECTS> 
--kill-at --output-lib=<TARGET>")
-set(CMAKE_IMPLIB_DELAYED_CREATE_STATIC_LIBRARY "${CMAKE_DLLTOOL} --def 
<OBJECTS> --kill-at --output-delaylib=<TARGET>")
 function(spec2def _dllname _spec_file)
 
     cmake_parse_arguments(__spec2def 
"ADD_IMPORTLIB;NO_PRIVATE_WARNINGS;WITH_RELAY" "VERSION" "" ${ARGN})
diff --git a/sdk/cmake/msvc.cmake b/sdk/cmake/msvc.cmake
index 10beb82f704..1601805404a 100644
--- a/sdk/cmake/msvc.cmake
+++ b/sdk/cmake/msvc.cmake
@@ -264,9 +264,6 @@ function(set_module_type_toolchain MODULE TYPE)
 
 endfunction()
 
-# Define those for having real libraries
-set(CMAKE_IMPLIB_CREATE_STATIC_LIBRARY "LINK /LIB /NOLOGO <LINK_FLAGS> 
/OUT:<TARGET> <OBJECTS>")
-
 if(ARCH STREQUAL "arm")
     set(CMAKE_STUB_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -nologo -o 
<OBJECT> <SOURCE>")
 else()
@@ -299,41 +296,41 @@ function(generate_import_lib _libname _dllname _spec_file)
     set(_def_file ${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def)
     set(_asm_stubs_file ${CMAKE_CURRENT_BINARY_DIR}/${_libname}_stubs.asm)
 
-    # Generate the asm stub file and the def file for import library
+    # Generate the def and asm stub files
     add_custom_command(
         OUTPUT ${_asm_stubs_file} ${_def_file}
         COMMAND native-spec2def --ms -a=${SPEC2DEF_ARCH} --implib 
-n=${_dllname} -d=${_def_file} -l=${_asm_stubs_file} 
${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file}
         DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} native-spec2def)
 
-    if(MSVC_IDE)
-        # Compile the generated asm stub file
-        if(ARCH STREQUAL "arm")
-            set(_asm_stub_command ${CMAKE_ASM_COMPILER} -nologo -o 
${_asm_stubs_file}.obj ${_asm_stubs_file})
-        else()
-            set(_asm_stub_command ${CMAKE_ASM_COMPILER} /Cp 
/Fo${_asm_stubs_file}.obj /c /Ta ${_asm_stubs_file})
-        endif()
-        add_custom_command(
-            OUTPUT ${_asm_stubs_file}.obj
-            COMMAND ${_asm_stub_command}
-            DEPENDS ${_asm_stubs_file})
+    # Compile the generated asm stub file
+    if(ARCH STREQUAL "arm")
+        set(_asm_stub_command ${CMAKE_ASM_COMPILER} -nologo -o 
${_asm_stubs_file}.obj ${_asm_stubs_file})
     else()
-        # Be clear about the "language"
-        # Thanks MS for creating a stupid linker
-        set_source_files_properties(${_asm_stubs_file} PROPERTIES LANGUAGE 
"STUB_ASM")
+        set(_asm_stub_command ${CMAKE_ASM_COMPILER} /nologo /Cp 
/Fo${_asm_stubs_file}.obj /c /Ta ${_asm_stubs_file})
     endif()
+    add_custom_command(
+        OUTPUT ${_asm_stubs_file}.obj
+        COMMAND ${_asm_stub_command}
+        DEPENDS ${_asm_stubs_file})
 
-    # Add our library
-    if(MSVC_IDE)
-        add_library(${_libname} STATIC EXCLUDE_FROM_ALL ${_asm_stubs_file}.obj)
-        set_source_files_properties(${_asm_stubs_file}.obj PROPERTIES 
EXTERNAL_OBJECT TRUE)
-        set_target_properties(${_libname} PROPERTIES LINKER_LANGUAGE "C")
-    else()
-        # NOTE: as stub file and def file are generated in one pass, depending 
on one is like depending on the other
-        add_library(${_libname} STATIC EXCLUDE_FROM_ALL ${_asm_stubs_file})
-        # set correct "link rule"
-        set_target_properties(${_libname} PROPERTIES LINKER_LANGUAGE "IMPLIB")
-    endif()
-    set_target_properties(${_libname} PROPERTIES STATIC_LIBRARY_FLAGS 
"/DEF:${_def_file}")
+    # generate the intermediate import lib
+    set(_libfile_tmp ${CMAKE_CURRENT_BINARY_DIR}/${_libname}_tmp.lib)
+    set(_static_lib_options )
+
+    add_custom_command(
+        OUTPUT ${_libfile_tmp}
+        COMMAND
+            LINK /LIB ∕NOLOGO /MACHINE:${WINARCH}
+                $<TARGET_PROPERTY:${_libname},STATIC_LIBRARY_FLAGS> 
$<TARGET_PROPERTY:${_libname},STATIC_LIBRARY_OPTIONS>
+                ∕DEF:${_def_file} /OUT:${_libfile_tmp} ${_asm_stubs_file}.obj
+        DEPENDS ${_asm_stubs_file}.obj ${_def_file})
+
+    # By giving the import lib as an object input, LIB extracts the relevant 
object files and make a new library.
+    # This allows us to treat the implib as a regular static library
+    set_source_files_properties(${_libfile_tmp} PROPERTIES EXTERNAL_OBJECT 
TRUE)
+    add_library(${_libname} STATIC ${_libfile_tmp})
+
+    set_target_properties(${_libname} PROPERTIES LINKER_LANGUAGE "C")
 endfunction()
 
 if(ARCH STREQUAL "amd64")
@@ -376,7 +373,7 @@ function(spec2def _dllname _spec_file)
     if(__spec2def_ADD_IMPORTLIB)
         generate_import_lib(lib${_file} ${_dllname} ${_spec_file})
         if(__spec2def_NO_PRIVATE_WARNINGS)
-            add_target_property(lib${_file} STATIC_LIBRARY_FLAGS 
"/ignore:4104")
+            set_property(TARGET lib${_file} APPEND PROPERTY 
STATIC_LIBRARY_OPTIONS /ignore:4104)
         endif()
     endif()
 endfunction()
diff --git a/sdk/lib/crt/msvcrtex.cmake b/sdk/lib/crt/msvcrtex.cmake
index 0b6bff8520d..f720b977534 100644
--- a/sdk/lib/crt/msvcrtex.cmake
+++ b/sdk/lib/crt/msvcrtex.cmake
@@ -49,7 +49,6 @@ if(ARCH STREQUAL "i386")
     list(APPEND MSVCRTEX_ASM_SOURCE
         except/i386/chkstk_asm.s
         except/i386/chkstk_ms.s
-        math/i386/ftol2_asm.s
         math/i386/alldiv_asm.s)
     list(APPEND MSVCRTEX_SOURCE
         math/i386/ci.c
@@ -102,11 +101,16 @@ endif()
 set_source_files_properties(${MSVCRTEX_ASM_SOURCE} PROPERTIES 
COMPILE_DEFINITIONS "_DLL;_MSVCRTEX_")
 add_asm_files(msvcrtex_asm ${MSVCRTEX_ASM_SOURCE})
 
-add_library(msvcrtex ${MSVCRTEX_SOURCE} ${msvcrtex_asm})
+add_library(msvcrtex OBJECT ${MSVCRTEX_SOURCE} ${msvcrtex_asm})
 target_compile_definitions(msvcrtex PRIVATE _DLL _MSVCRTEX_)
 
-# Link msvcrtex to the "real" msvcrt.dll library. See msvcrt.dll 
CMakeLists.txt to see what really happens here
-target_link_libraries(msvcrtex libmsvcrt_real libkernel32)
+if(MSVC AND (ARCH STREQUAL "i386"))
+    # user32.dll needs this as a stand-alone object file
+    add_asm_files(ftol2_asm math/i386/ftol2_asm.s)
+    add_library(ftol2_sse OBJECT ${ftol2_asm})
+    target_compile_definitions(ftol2_sse PRIVATE 
$<TARGET_PROPERTY:msvcrtex,COMPILE_DEFINITIONS>)
+endif()
+
 
 if(GCC OR CLANG)
     target_compile_options(msvcrtex PRIVATE $<$<COMPILE_LANGUAGE:C>:-Wno-main>)
diff --git a/sdk/lib/crt/oldnames.cmake b/sdk/lib/crt/oldnames.cmake
index 806ada3570b..c1b2a98999a 100644
--- a/sdk/lib/crt/oldnames.cmake
+++ b/sdk/lib/crt/oldnames.cmake
@@ -1,8 +1,21 @@
 
 if(NOT MSVC)
-    _add_library(oldnames STATIC EXCLUDE_FROM_ALL 
${CMAKE_CURRENT_SOURCE_DIR}/moldname-msvcrt.def)
-    
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/moldname-msvcrt.def 
PROPERTIES EXTERNAL_OBJECT TRUE)
-    set_target_properties(oldnames PROPERTIES LINKER_LANGUAGE "IMPLIB" PREFIX 
"")
+    # Use the same trick as with the other import libs. See gcc.cmake --> 
generate_import_lib function
+    set(LIBRARY_PRIVATE_DIR 
${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/oldnames.dir)
+    add_custom_command(
+        OUTPUT ${LIBRARY_PRIVATE_DIR}/oldnames.a
+        # ar just puts stuff into the archive, without looking twice. Just 
delete the lib, we're going to rebuild it anyway
+        COMMAND ${CMAKE_COMMAND} -E rm -f $<TARGET_FILE:oldnames>
+        COMMAND ${CMAKE_DLLTOOL} --def 
${CMAKE_CURRENT_SOURCE_DIR}/moldname-msvcrt.def --kill-at 
--output-lib=oldnames.a -t oldnames
+        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/moldname-msvcrt.def
+        WORKING_DIRECTORY ${LIBRARY_PRIVATE_DIR})
+    set_source_files_properties(
+        ${LIBRARY_PRIVATE_DIR}/oldnames.a
+        PROPERTIES
+        EXTERNAL_OBJECT TRUE)
+
+    _add_library(oldnames STATIC EXCLUDE_FROM_ALL 
${LIBRARY_PRIVATE_DIR}/oldnames.a)
+    set_target_properties(oldnames PROPERTIES LINKER_LANGUAGE "C")
 else()
     add_asm_files(oldnames_asm oldnames-msvcrt.S)
     add_library(oldnames ${oldnames_asm})
diff --git a/win32ss/gdi/gdi32/CMakeLists.txt b/win32ss/gdi/gdi32/CMakeLists.txt
index e1f1644cbd6..4c9d32368bc 100644
--- a/win32ss/gdi/gdi32/CMakeLists.txt
+++ b/win32ss/gdi/gdi32/CMakeLists.txt
@@ -60,10 +60,13 @@ target_link_libraries(gdi32
     wine 
     win32ksys
     dxguid
-    msvcrtex
     atan2
     ${PSEH_LIB})
 
+if(MSVC AND (ARCH STREQUAL "i386"))
+    target_sources(gdi32 PRIVATE $<TARGET_OBJECTS:ftol2_sse>)
+endif()
+
 add_importlibs(gdi32 user32 advapi32 kernel32 ntdll)
 add_pch(gdi32 include/precomp.h SOURCE)
 add_dependencies(gdi32 psdk)
diff --git a/win32ss/user/user32/CMakeLists.txt 
b/win32ss/user/user32/CMakeLists.txt
index 0d38852d684..fb2655dcf6c 100644
--- a/win32ss/user/user32/CMakeLists.txt
+++ b/win32ss/user/user32/CMakeLists.txt
@@ -82,9 +82,8 @@ set_module_type(user32 win32dll ENTRYPOINT DllMain 12 UNICODE)
 target_link_libraries(user32 user32_wsprintf wine win32ksys ${PSEH_LIB})
 add_dependencies(user32 asm)
 
-if(MSVC)
-    # for __ftol2_sse, float to int cast helper
-    target_link_libraries(user32 msvcrtex)
+if(MSVC AND (ARCH STREQUAL "i386"))
+    target_sources(user32 PRIVATE $<TARGET_OBJECTS:ftol2_sse>)
 endif()
 
 add_delay_importlibs(user32 imm32 usp10)

Reply via email to