From fdbf70443bec6891a20ef27c2bf1daf4982c9f03 Mon Sep 17 00:00:00 2001 From: cuily Date: Sat, 25 Jan 2025 15:28:13 +0800 Subject: [PATCH] feature: support compiler MSYS2-MinGW #5575 Signed-off-by: RookieCLY <2238379153@qq.com> --- CMakeLists.txt | 21 +++- include/fastdds/fastdds_dll.hpp | 16 ++- include/fastdds/utils/TimedMutex.hpp | 5 + .../serializers/json/dynamic_data_json.cpp | 24 +++- src/cpp/utils/SystemInfo.cpp | 10 +- src/cpp/utils/TimedConditionVariable.cpp | 12 +- .../shared_memory/RobustExclusiveLock.hpp | 41 +++++++ .../utils/shared_memory/RobustSharedLock.hpp | 114 ++++++++++++++++++ thirdparty/filewatch/FileWatch.hpp | 6 +- 9 files changed, 237 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 823d11f94af..87e2d107dea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -395,7 +395,26 @@ endif() ############################################################################### # Tools default setup ############################################################################### -option(COMPILE_TOOLS "Build tools" ON) +if(WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + execute_process( + COMMAND ${CMAKE_CXX_COMPILER} -dumpmachine + OUTPUT_VARIABLE COMPILER_MACHINE + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(COMPILER_MACHINE MATCHES "mingw") + message(STATUS "Using MinGW compiler.") + option(COMPILE_TOOLS "Build tools" OFF) + add_definitions(-DMINGW_COMPILER=1) + set(CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} -Wno-attributes -Wno-stringop-overread -Wno-builtin-macro-redefined -Wno-cast-function-type -Wno-unused-variable -Wno-unused-parameter -Wno-unused-function -Wno-missing-field-initializers") + target_link_libraries(fastdds PUBLIC ws2_32 mswsock) + else() + message(STATUS "Using a GNU compiler on Windows but not MinGW.") + endif() +else() + message(STATUS "Not using a GNU compiler on Windows.") + option(COMPILE_TOOLS "Build tools" ON) +endif() if(EPROSIMA_BUILD) set(COMPILE_TOOLS ON) diff --git a/include/fastdds/fastdds_dll.hpp b/include/fastdds/fastdds_dll.hpp index e27e8be884a..e98dcfe2e17 100644 --- a/include/fastdds/fastdds_dll.hpp +++ b/include/fastdds/fastdds_dll.hpp @@ -44,11 +44,19 @@ #if defined(_WIN32) #if defined(EPROSIMA_ALL_DYN_LINK) || defined(FASTDDS_DYN_LINK) -#if defined(fastdds_EXPORTS) -#define FASTDDS_EXPORTED_API __declspec( dllexport ) +#if defined(MINGW_COMPILER) + #if defined(fastdds_EXPORTS) + #define FASTDDS_EXPORTED_API __declspec( dllexport ) + #else + #define FASTDDS_EXPORTED_API __attribute__((visibility("default"))) + #endif // FASTDDS_SOURCE #else -#define FASTDDS_EXPORTED_API __declspec( dllimport ) -#endif // FASTDDS_SOURCE + #if defined(fastdds_EXPORTS) + #define FASTDDS_EXPORTED_API __declspec( dllexport ) + #else + #define FASTDDS_EXPORTED_API __declspec( dllimport ) + #endif // FASTDDS_SOURCE +#endif // if defined(MINGW_COMPILER) #else #define FASTDDS_EXPORTED_API #endif // if defined(EPROSIMA_ALL_DYN_LINK) || defined(FASTDDS_DYN_LINK) diff --git a/include/fastdds/utils/TimedMutex.hpp b/include/fastdds/utils/TimedMutex.hpp index 2315e11eeff..6007447abea 100644 --- a/include/fastdds/utils/TimedMutex.hpp +++ b/include/fastdds/utils/TimedMutex.hpp @@ -26,6 +26,8 @@ #if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 193632528 #include +#elif defined(MINGW_COMPILER) +#include #else #include extern int clock_gettime( @@ -47,6 +49,9 @@ namespace fastdds { #if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 193632528 using TimedMutex = std::timed_mutex; using RecursiveTimedMutex = std::recursive_timed_mutex; +#elif defined(MINGW_COMPILER) +using TimedMutex = std::timed_mutex; +using RecursiveTimedMutex = std::recursive_timed_mutex; #else class TimedMutex { diff --git a/src/cpp/fastdds/xtypes/serializers/json/dynamic_data_json.cpp b/src/cpp/fastdds/xtypes/serializers/json/dynamic_data_json.cpp index 9234376c0e7..fb45cb59436 100644 --- a/src/cpp/fastdds/xtypes/serializers/json/dynamic_data_json.cpp +++ b/src/cpp/fastdds/xtypes/serializers/json/dynamic_data_json.cpp @@ -13,7 +13,9 @@ // limitations under the License. #include -#include +#ifndef MINGW_COMPILER + #include +#endif // ifndef MINGW_COMPILER #include #include #include @@ -744,9 +746,20 @@ ReturnCode_t json_serialize_basic_member( if (RETCODE_OK == ret) { // Insert UTF-8 converted value +#if defined(MINGW_COMPILER) + std::wstring aux_wstring_value({value}); + std::string utf8_value; + int size_needed = std::wcstombs(nullptr, aux_wstring_value.data(), 0); + if (size_needed > 0) { + utf8_value.resize(size_needed); + std::wcstombs(&utf8_value[0], aux_wstring_value.data(), size_needed); + } +#else std::wstring aux_wstring_value({value}); std::wstring_convert> converter; std::string utf8_value = converter.to_bytes(aux_wstring_value); + +#endif // defined(MINGW_COMPILER) json_insert(member_name, utf8_value, output); } else @@ -776,8 +789,17 @@ ReturnCode_t json_serialize_basic_member( if (RETCODE_OK == ret) { // Insert UTF-8 converted value +#ifdef MINGW_COMPILER + std::string utf8_value; + int size_needed = std::wcstombs(nullptr, value.data(), 0); + if (size_needed > 0) { + utf8_value.resize(size_needed); + std::wcstombs(&utf8_value[0], value.data(), size_needed); + } +#else std::wstring_convert> converter; std::string utf8_value = converter.to_bytes(value); +#endif // defined(MINGW_COMPILER) json_insert(member_name, utf8_value, output); } else diff --git a/src/cpp/utils/SystemInfo.cpp b/src/cpp/utils/SystemInfo.cpp index 8fafd33fe3a..78bce5d7dad 100644 --- a/src/cpp/utils/SystemInfo.cpp +++ b/src/cpp/utils/SystemInfo.cpp @@ -155,9 +155,17 @@ fastdds::dds::ReturnCode_t SystemInfo::get_username( bool SystemInfo::file_exists( const std::string& filename) { +#ifdef _WIN32 + // modify for mingw + DWORD fileAttributes = GetFileAttributesA(filename.c_str()); + if (fileAttributes == INVALID_FILE_ATTRIBUTES) { + return false; + } + return !(fileAttributes & FILE_ATTRIBUTE_DIRECTORY); +#else struct stat s; - // Check existence and that it is a regular file (and not a folder) return (stat(filename.c_str(), &s) == 0 && s.st_mode & S_IFREG); +#endif } bool SystemInfo::wait_for_file_closure( diff --git a/src/cpp/utils/TimedConditionVariable.cpp b/src/cpp/utils/TimedConditionVariable.cpp index f51eb382bbd..9f6d07e8d37 100644 --- a/src/cpp/utils/TimedConditionVariable.cpp +++ b/src/cpp/utils/TimedConditionVariable.cpp @@ -50,9 +50,15 @@ return 0; } */ -#define exp7 10000000i64 //1E+7 //C-file part -#define exp9 1000000000i64 //1E+9 -#define w2ux 116444736000000000i64 //1.jan1601 to 1.jan1970 +#ifdef MINGW_COMPILER + #define exp7 10000000LL //1E+7 //C-file part + #define exp9 1000000000LL //1E+9 + #define w2ux 116444736000000000LL //1.jan1601 to 1.jan1970 +#else + #define exp7 10000000i64 //1E+7 //C-file part + #define exp9 1000000000i64 //1E+9 + #define w2ux 116444736000000000i64 //1.jan1601 to 1.jan1970 +#endif void unix_time( struct timespec* spec) { diff --git a/src/cpp/utils/shared_memory/RobustExclusiveLock.hpp b/src/cpp/utils/shared_memory/RobustExclusiveLock.hpp index c7e67bf8b08..013adb0241a 100644 --- a/src/cpp/utils/shared_memory/RobustExclusiveLock.hpp +++ b/src/cpp/utils/shared_memory/RobustExclusiveLock.hpp @@ -17,6 +17,8 @@ #ifdef _MSC_VER #include +#elif defined(MINGW_COMPILER) +#include #else #include #endif // ifdef _MSC_VER @@ -165,6 +167,45 @@ class RobustExclusiveLock } } +#elif defined(MINGW_COMPILER) + static int open_and_lock_file( + const std::string& file_path, + bool* was_lock_created) + { + int test_exist; + auto ret = _sopen_s(&test_exist, file_path.c_str(), O_RDONLY, 0x0010, _S_IREAD | _S_IWRITE); + + if (ret == 0) + { + *was_lock_created = false; + return test_exist; + } + + int fd; + ret = _sopen_s(&fd, file_path.c_str(), O_CREAT | O_RDONLY, 0x0010, _S_IREAD | _S_IWRITE); + + if (ret != 0) + { + return -1; + } + + *was_lock_created = true; + + return fd; + } + + static void unlock_and_close( + int fd, + const std::string& name) + { + _close(fd); + + if (0 != std::remove(SharedDir::get_lock_path(name).c_str())) + { + EPROSIMA_LOG_WARNING(RTPS_TRANSPORT_SHM, "Failed to remove " << SharedDir::get_lock_path(name)); + } + } + #else static int open_and_lock_file( diff --git a/src/cpp/utils/shared_memory/RobustSharedLock.hpp b/src/cpp/utils/shared_memory/RobustSharedLock.hpp index 68f18316ebb..5819c3bd69b 100644 --- a/src/cpp/utils/shared_memory/RobustSharedLock.hpp +++ b/src/cpp/utils/shared_memory/RobustSharedLock.hpp @@ -17,6 +17,8 @@ #ifdef _MSC_VER #include +#elif defined(MINGW_COMPILER) +#include #else #include #endif // ifdef _MSC_VER @@ -230,6 +232,118 @@ class RobustSharedLock return lock_status; } +#elif defined(MINGW_COMPILER) + int open_and_lock_file( + const std::string& file_path, + bool* was_lock_created, + bool* was_lock_released) + { + int test_exist; + + // Try open exclusive + auto ret = _sopen_s(&test_exist, file_path.c_str(), _O_WRONLY, 0x0010, _S_IREAD | _S_IWRITE); + + if (ret == 0) + { + *was_lock_created = false; + + if (was_lock_released) + { + *was_lock_released = true; + } + + _close(test_exist); + } + else + { + // Try open shared + ret = _sopen_s(&test_exist, file_path.c_str(), _O_RDONLY, 0x0010, _S_IREAD | _S_IWRITE); + + if (ret == 0) + { + if (was_lock_released) + { + *was_lock_released = false; + } + + *was_lock_created = false; + + return test_exist; + } + else + { + if (was_lock_released) + { + *was_lock_released = true; + } + + *was_lock_created = true; + } + } + + int fd; + // Open or create shared + ret = _sopen_s(&fd, file_path.c_str(), O_CREAT | _O_RDONLY, 0x0010, _S_IREAD | _S_IWRITE); + + if (ret != 0) + { + char errmsg[1024]; + strerror_s(errmsg, sizeof(errmsg), errno); + throw std::runtime_error("failed to open/create " + file_path + " " + std::string(errmsg)); + } + + return fd; + } + + void unlock_and_close() + { + _close(fd_); + + test_lock(SharedDir::get_lock_path(name_), true); + } + + static LockStatus test_lock( + const std::string& file_path, + bool remove_if_unlocked = false) + { + LockStatus lock_status; + + int fd; + auto ret = _sopen_s(&fd, file_path.c_str(), _O_RDONLY, 0x0010, _S_IREAD | _S_IWRITE); + + if (ret == 0) + { + lock_status = LockStatus::NOT_LOCKED; + + _close(fd); + + // Lock exclusive + ret = _sopen_s(&fd, file_path.c_str(), _O_WRONLY, 0x0010, _S_IREAD | _S_IWRITE); + if (ret != 0) + { + lock_status = LockStatus::LOCKED; + } + else + { + _close(fd); + } + } + else + { + lock_status = LockStatus::OPEN_FAILED; + } + + if (lock_status == LockStatus::NOT_LOCKED && remove_if_unlocked) + { + if (0 != std::remove(file_path.c_str())) + { + EPROSIMA_LOG_WARNING(RTPS_TRANSPORT_SHM, "Failed to remove " << file_path); + } + } + + return lock_status; + } + #else int open_and_lock_file( diff --git a/thirdparty/filewatch/FileWatch.hpp b/thirdparty/filewatch/FileWatch.hpp index 375de5f76ba..3d0ea0df3d7 100644 --- a/thirdparty/filewatch/FileWatch.hpp +++ b/thirdparty/filewatch/FileWatch.hpp @@ -30,7 +30,9 @@ #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN -#define stat _stat +#ifndef MINGW_COMPILER + #define stat _stat // do not use stat in windows +#endif // ifndef MINGW_COMPILER #ifndef NOMINMAX #define NOMINMAX #endif @@ -404,7 +406,7 @@ namespace filewatch { std::ratio_multiply>( reinterpret_cast(&att.ftLastWriteTime)->QuadPart - base_.first.QuadPart); - if (bytes_returned == 0 || (current_time == last_write_time_) && current_size == last_size_ ) { + if (bytes_returned == 0 || ((current_time == last_write_time_) && current_size == last_size_ )) { break; }