function(configure_ssl_backend)
    set(options ENABLE_PROGRAMS ENABLE_TESTING GEN_FILES USE_STATIC_MBEDTLS_LIBRARY
        USE_SHARED_MBEDTLS_LIBRARY DISABLE_PACKAGE_CONFIG_AND_INSTALL MBEDTLS_CONFIG_FILE MBEDTLS_USER_CONFIG_FILE)
    foreach(option IN LISTS options)
        get_property(saved_${option}_exists CACHE ${option} PROPERTY TYPE SET)
        if(saved_${option}_exists)
            get_property(saved_${option}_type CACHE ${option} PROPERTY TYPE)
            get_property(saved_${option}_help CACHE ${option} PROPERTY HELPSTRING)
            get_property(saved_${option}_value CACHE ${option} PROPERTY VALUE)
        endif()
    endforeach()
    set(ENABLE_PROGRAMS OFF)
    set(ENABLE_TESTING OFF)
    set(GEN_FILES OFF)
    set(USE_STATIC_MBEDTLS_LIBRARY ON)
    set(USE_SHARED_MBEDTLS_LIBRARY OFF)
    set(DISABLE_PACKAGE_CONFIG_AND_INSTALL ON)
    set(MBEDTLS_CONFIG_FILE "")
    set(MBEDTLS_USER_CONFIG_FILE "${CMAKE_CURRENT_SOURCE_DIR}/MbedConfig.hpp")
    foreach(option IN LISTS options)
        if(option MATCHES "CONFIG_FILE$")
            set(${option} "${${option}}" CACHE FILEPATH "" FORCE)
        else()
            set(${option} "${${option}}" CACHE BOOL "" FORCE)
        endif()
    endforeach()
    if(NOT DEFINED CMAKE_POLICY_VERSION_MINIMUM OR CMAKE_POLICY_VERSION_MINIMUM VERSION_LESS 3.5)
        set(CMAKE_POLICY_VERSION_MINIMUM 3.5)
    endif()
    add_subdirectory(${CMAKE_SOURCE_DIR}/3rdparty/mbedtls ${CMAKE_BINARY_DIR}/3rdparty/mbedtls EXCLUDE_FROM_ALL)
    foreach(property LINK_LIBRARIES INTERFACE_LINK_LIBRARIES)
        get_target_property(libraries mbedcrypto ${property})
        if(libraries)
            list(REMOVE_ITEM libraries everest)
            set_property(TARGET mbedcrypto PROPERTY ${property} "${libraries}")
        endif()
    endforeach()
    set_target_properties(everest PROPERTIES EXCLUDE_FROM_ALL ON)
    foreach(option IN LISTS options)
        if(saved_${option}_exists)
            set(${option} "${saved_${option}_value}" CACHE ${saved_${option}_type} "${saved_${option}_help}" FORCE)
        else()
            unset(${option} CACHE)
        endif()
    endforeach()
endfunction()

configure_ssl_backend()
set_target_properties(mbedtls mbedcrypto mbedx509 p256m PROPERTIES POSITION_INDEPENDENT_CODE ON)
if(MINGW)
    target_compile_options(mbedtls PRIVATE -fno-asynchronous-unwind-tables)
    target_compile_options(mbedcrypto PRIVATE -fno-asynchronous-unwind-tables)
    target_compile_options(mbedx509 PRIVATE -fno-asynchronous-unwind-tables)
    target_compile_options(p256m PRIVATE -fno-asynchronous-unwind-tables)
endif()

add_library(libSceSsl SHARED EXCLUDE_FROM_ALL Export.cpp)
target_include_directories(libSceSsl PRIVATE ${LIBS_INCLUDE_DIR})
target_link_libraries(libSceSsl PRIVATE mbedtls mbedx509 mbedcrypto)
set_target_properties(libSceSsl PROPERTIES VISIBILITY_INLINES_HIDDEN ON)
if(MINGW OR CMAKE_SYSTEM_NAME STREQUAL "Linux")
    target_link_options(libSceSsl PRIVATE LINKER:--exclude-libs,ALL)
endif()
if(WIN32)
    target_link_libraries(libSceSsl PRIVATE bcrypt ws2_32)
endif()
configure_windows_unwind(libSceSsl)

if(BUILD_TESTING)
    add_test_executable(guest_ssl_tests ${LIBS_INCLUDE_DIR}/tests/GuestSsl.cpp)
    target_include_directories(guest_ssl_tests PRIVATE ${LIBS_INCLUDE_DIR})
    target_link_libraries(guest_ssl_tests PRIVATE libSceSsl libc)
    configure_windows_unwind(guest_ssl_tests)
    add_test(NAME guest_ssl COMMAND guest_ssl_tests)
    add_test_executable(guest_ssl_load_tests ${LIBS_INCLUDE_DIR}/tests/GuestSslLoad.cpp)
    target_include_directories(guest_ssl_load_tests PRIVATE ${LIBS_INCLUDE_DIR})
    target_link_libraries(guest_ssl_load_tests PRIVATE libSceSsl libc)
    configure_windows_unwind(guest_ssl_load_tests)
    add_test(NAME guest_ssl_load COMMAND guest_ssl_load_tests)
    add_test_executable(guest_ssl_transport_tests ${LIBS_INCLUDE_DIR}/tests/GuestSslTransport.cpp)
    target_include_directories(guest_ssl_transport_tests PRIVATE ${LIBS_INCLUDE_DIR})
    target_link_libraries(guest_ssl_transport_tests PRIVATE libSceSsl libSceNet libkernel libc mbedtls mbedx509 mbedcrypto)
    configure_windows_unwind(guest_ssl_transport_tests)
    foreach(table IN ITEMS kernel net)
        add_test(NAME guest_ssl_transport_${table} COMMAND guest_ssl_transport_tests ${table})
        set_tests_properties(guest_ssl_transport_${table} PROPERTIES TIMEOUT 30)
    endforeach()
    add_test_executable(guest_ssl_ps5_readers_tests ${LIBS_INCLUDE_DIR}/tests/GuestSslPs5Readers.cpp)
    target_include_directories(guest_ssl_ps5_readers_tests PRIVATE ${LIBS_INCLUDE_DIR})
    target_link_libraries(guest_ssl_ps5_readers_tests PRIVATE libSceSsl libc)
    configure_windows_unwind(guest_ssl_ps5_readers_tests)
    add_test(NAME guest_ssl_ps5_readers COMMAND guest_ssl_ps5_readers_tests)
    if(WIN32)
        target_link_libraries(guest_ssl_transport_tests PRIVATE bcrypt ws2_32)
        set_tests_properties(guest_ssl guest_ssl_load guest_ssl_ps5_readers guest_ssl_transport_kernel guest_ssl_transport_net PROPERTIES ENVIRONMENT_MODIFICATION
            "PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceSsl>;PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceNet>")
    endif()
endif()
