mirror of
https://github.com/reactos/reactos.git
synced 2025-04-04 04:26:32 +00:00
[CMAKE] Turn import libs into regular C static libs
Embed msvcrtex into libmsvcrt Idea taken from Thomas Faber
This commit is contained in:
parent
cad583967b
commit
b96e88894a
7 changed files with 109 additions and 60 deletions
|
@ -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)
|
||||
|
|
|
@ -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 "")
|
||||
# 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})
|
||||
|
||||
# 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 "")
|
||||
# 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})
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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>)
|
||||
|
|
|
@ -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})
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue