https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b96e88894a4d55f5e8b94…
commit b96e88894a4d55f5e8b94430deeb0f086151b24f
Author: Jérôme Gardou <jerome.gardou(a)reactos.org>
AuthorDate: Mon Nov 2 10:51:08 2020 +0100
Commit: Jérôme Gardou <zefklop(a)users.noreply.github.com>
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)