cmake_minimum_required(VERSION 3.22)

set(MSVCIRT_GENERATED_STUBS ${CMAKE_CURRENT_BINARY_DIR}/generated_stubs.c)
set(MSVCIRT_DEF ${CMAKE_CURRENT_BINARY_DIR}/msvcirt.def)
set(MSVCRT_IMPORT_DEF ${CMAKE_CURRENT_BINARY_DIR}/msvcrt_import.def)
set(MSVCRT_IMPORT_LIB ${CMAKE_CURRENT_BINARY_DIR}/msvcrt.lib)

add_custom_command(
    OUTPUT ${MSVCIRT_GENERATED_STUBS}
    COMMAND ${Python3_EXECUTABLE} ${GENERATE_STUBS_TOOL}
        --arch i386
        ${CMAKE_CURRENT_SOURCE_DIR}/msvcirt.spec
        ${MSVCIRT_GENERATED_STUBS}
    DEPENDS
        ${CMAKE_CURRENT_SOURCE_DIR}/msvcirt.spec
        ${GENERATE_STUBS_TOOL}
        ${SPEC_PARSER_LIB}
    COMMENT "Generating msvcirt stubs"
    VERBATIM
)

add_custom_command(
    OUTPUT ${MSVCIRT_DEF}
    COMMAND ${Python3_EXECUTABLE} ${GENERATE_DEF_TOOL}
        --arch i386
        --no-stdcall-suffix
        ${CMAKE_CURRENT_SOURCE_DIR}/msvcirt.spec
        ${MSVCIRT_DEF}
    DEPENDS
        ${CMAKE_CURRENT_SOURCE_DIR}/msvcirt.spec
        ${GENERATE_DEF_TOOL}
        ${SPEC_PARSER_LIB}
    COMMENT "Generating msvcirt.def"
    VERBATIM
)

add_custom_command(
    OUTPUT ${MSVCRT_IMPORT_DEF}
    COMMAND ${Python3_EXECUTABLE} ${GENERATE_DEF_TOOL}
        --arch i386
        --imports-only
        ${PROJECT_SOURCE_DIR}/dlls/msvcrt/msvcrt.spec
        ${MSVCRT_IMPORT_DEF}
    DEPENDS
        ${PROJECT_SOURCE_DIR}/dlls/msvcrt/msvcrt.spec
        ${GENERATE_DEF_TOOL}
        ${SPEC_PARSER_LIB}
    COMMENT "Generating msvcrt import def"
    VERBATIM
)

add_custom_command(
    OUTPUT ${MSVCRT_IMPORT_LIB}
    COMMAND llvm-dlltool -m i386 -k -d ${MSVCRT_IMPORT_DEF} -l ${MSVCRT_IMPORT_LIB}
    DEPENDS ${MSVCRT_IMPORT_DEF}
    COMMENT "Generating msvcrt import library"
    VERBATIM
)

add_custom_target(msvcrt_import_for_msvcirt ALL DEPENDS ${MSVCRT_IMPORT_LIB})

add_library(msvcrt_import_lib STATIC IMPORTED GLOBAL)
set_target_properties(msvcrt_import_lib PROPERTIES
    IMPORTED_LOCATION ${MSVCRT_IMPORT_LIB}
)
add_dependencies(msvcrt_import_lib msvcrt_import_for_msvcirt)

add_library(msvcirt SHARED
    ../msvcp90/exception.c
    msvcirt.c
    ${MSVCIRT_GENERATED_STUBS}
    ../winecrt0/crt_dllmain.c
    ../winecrt0/setjmp.c
    ../winecrt0/exception.c
    ${MSVCIRT_DEF}
)

set_target_properties(msvcirt PROPERTIES
    PREFIX ""
    OUTPUT_NAME msvcirt
)

target_compile_definitions(msvcirt
    PRIVATE
        _CRTIMP=
        _MSVCIRT
        _NO_CRT_STDIO_INLINE
        _NTSYSTEM_
        __WINE_PE_BUILD
)

target_compile_options(msvcirt
    PRIVATE
        -fno-builtin
        -fno-strict-aliasing
        -fno-omit-frame-pointer
        -Wno-deprecated-declarations
        -Wno-unused-parameter
        -Wno-missing-braces
        -Wno-ignored-qualifiers
)

target_link_options(msvcirt
    PRIVATE
        -Wl,--enable-stdcall-fixup
)

target_include_directories(msvcirt
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}
        ${PROJECT_SOURCE_DIR}/dlls/msvcp90
        ${PROJECT_SOURCE_DIR}/dlls/msvcrt
        ${PROJECT_SOURCE_DIR}/include
        ${PROJECT_SOURCE_DIR}/include/msvcrt
        ${PROJECT_SOURCE_DIR}/include/wine
)

target_link_libraries(msvcirt
    PRIVATE
        msvcrt_import_lib
        kernel32_import_lib
        ntdll_import_lib
)

if (CMAKE_C_COMPILER_ID MATCHES "Clang")
    target_link_libraries(msvcirt
        PRIVATE
            ${CMAKE_SOURCE_DIR}/vendor/libclang_rt.builtins-i386.a
    )
endif()
