diff --git a/sdk/cmake/gcc.cmake b/sdk/cmake/gcc.cmake index 668e2b56398..df283873494 100644 --- a/sdk/cmake/gcc.cmake +++ b/sdk/cmake/gcc.cmake @@ -579,8 +579,8 @@ add_library(libsupc++ STATIC IMPORTED GLOBAL) execute_process(COMMAND ${GXX_EXECUTABLE} -print-file-name=libsupc++.a OUTPUT_VARIABLE LIBSUPCXX_LOCATION) string(STRIP ${LIBSUPCXX_LOCATION} LIBSUPCXX_LOCATION) set_target_properties(libsupc++ PROPERTIES IMPORTED_LOCATION ${LIBSUPCXX_LOCATION}) -# libsupc++ requires libgcc -target_link_libraries(libsupc++ INTERFACE libgcc) +# libsupc++ requires libgcc and stdc++compat +target_link_libraries(libsupc++ INTERFACE libgcc stdc++compat) add_library(libmingwex STATIC IMPORTED) execute_process(COMMAND ${GXX_EXECUTABLE} -print-file-name=libmingwex.a OUTPUT_VARIABLE LIBMINGWEX_LOCATION) diff --git a/sdk/lib/CMakeLists.txt b/sdk/lib/CMakeLists.txt index 21540af06a5..7c751ab8976 100644 --- a/sdk/lib/CMakeLists.txt +++ b/sdk/lib/CMakeLists.txt @@ -17,6 +17,8 @@ add_subdirectory(cryptlib) if(MSVC) add_subdirectory(cpprt) add_subdirectory(RunTmChk) +else() + add_subdirectory(gcc-compat) endif() add_subdirectory(delayimp) diff --git a/sdk/lib/gcc-compat/CMakeLists.txt b/sdk/lib/gcc-compat/CMakeLists.txt new file mode 100644 index 00000000000..ef0f86354c2 --- /dev/null +++ b/sdk/lib/gcc-compat/CMakeLists.txt @@ -0,0 +1,15 @@ + +include_directories( + ${REACTOS_SOURCE_DIR}/sdk/lib/crt/include) + +list(APPEND SOURCE + __mingw_vsprintf.c + __throw_out_of_range_fmt.cpp + StringCchCopyNA.c) + +add_library(stdc++compat ${SOURCE}) +set_target_cpp_properties(stdc++compat WITH_EXCEPTIONS) +add_dependencies(stdc++compat xdk) +target_link_libraries(stdc++compat libmsvcrt) +remove_target_compile_option(stdc++compat "$<$,$>>>:-nostdinc>") +target_compile_definitions(stdc++compat PRIVATE "$<$:PAL_STDCPP_COMPAT>") diff --git a/sdk/lib/gcc-compat/StringCchCopyNA.c b/sdk/lib/gcc-compat/StringCchCopyNA.c new file mode 100644 index 00000000000..62953a1916e --- /dev/null +++ b/sdk/lib/gcc-compat/StringCchCopyNA.c @@ -0,0 +1,23 @@ +/* + * PROJECT: GCC c++ support library + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: StringCchCopyNA implementation + * COPYRIGHT: Copyright 2024 Timo Kreuzer + */ + +#include +#define StringCchCopyNA _StringCchCopyNA +#include + +#undef StringCchCopyNA + +HRESULT +WINAPI +StringCchCopyNA( + _Out_writes_(cchDest) _Always_(_Post_z_) STRSAFE_LPSTR pszDest, + _In_ size_t cchDest, + _In_reads_or_z_(cchToCopy) STRSAFE_LPCSTR pszSrc, + _In_ size_t cchToCopy) +{ + return _StringCchCopyNA(pszDest, cchDest, pszSrc, cchToCopy); +} diff --git a/sdk/lib/gcc-compat/__mingw_vsprintf.c b/sdk/lib/gcc-compat/__mingw_vsprintf.c new file mode 100644 index 00000000000..46166345230 --- /dev/null +++ b/sdk/lib/gcc-compat/__mingw_vsprintf.c @@ -0,0 +1,13 @@ +/* + * PROJECT: GCC c++ support library + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: __mingw_vsprintf implementation + * COPYRIGHT: Copyright 2024 Timo Kreuzer + */ + +#include + +int __cdecl __mingw_vsprintf(char* dest, const char* format, va_list arglist) +{ + return vsprintf(dest, format, arglist); +} diff --git a/sdk/lib/gcc-compat/__throw_out_of_range_fmt.cpp b/sdk/lib/gcc-compat/__throw_out_of_range_fmt.cpp new file mode 100644 index 00000000000..b2c093b7506 --- /dev/null +++ b/sdk/lib/gcc-compat/__throw_out_of_range_fmt.cpp @@ -0,0 +1,42 @@ +/* + * PROJECT: GCC c++ support library + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: __throw_out_of_range_fmt implementation + * COPYRIGHT: Copyright 2024 Timo Kreuzer + */ + +#include +#include +#include +#include + +namespace std { + +class out_of_range_error : public exception +{ + char* m_msg; +public: + explicit out_of_range_error(const char* msg) noexcept + { + size_t len = strlen(msg) + 1; + m_msg = (char*)malloc(len); + strcpy(m_msg, msg); + } + virtual ~out_of_range_error() { free(m_msg); }; + virtual const char* what() const noexcept { return m_msg; } +}; + +void __throw_out_of_range_fmt(const char *format, ...) +{ + char buffer[1024]; + va_list argptr; + + va_start(argptr, format); + _vsnprintf(buffer, sizeof(buffer), format, argptr); + buffer[sizeof(buffer) - 1] = 0; + va_end(argptr); + + throw out_of_range_error(buffer); +} + +} // namespace std