Skip to content

Commit

Permalink
feature: support compiler MSYS2-MinGW eProsima#5575 Signed-off-by: Ro…
Browse files Browse the repository at this point in the history
…okieCLY <[email protected]>
  • Loading branch information
cuily committed Jan 25, 2025
1 parent a59d32f commit fdbf704
Show file tree
Hide file tree
Showing 9 changed files with 237 additions and 12 deletions.
21 changes: 20 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
16 changes: 12 additions & 4 deletions include/fastdds/fastdds_dll.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
5 changes: 5 additions & 0 deletions include/fastdds/utils/TimedMutex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

#if defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 193632528
#include <mutex>
#elif defined(MINGW_COMPILER)
#include <mutex>
#else
#include <thread>
extern int clock_gettime(
Expand All @@ -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
{
Expand Down
24 changes: 23 additions & 1 deletion src/cpp/fastdds/xtypes/serializers/json/dynamic_data_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
// limitations under the License.

#include <bitset>
#include <codecvt>
#ifndef MINGW_COMPILER
#include <codecvt>
#endif // ifndef MINGW_COMPILER
#include <iomanip>
#include <iostream>
#include <string>
Expand Down Expand Up @@ -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<std::codecvt_utf8<wchar_t>> converter;
std::string utf8_value = converter.to_bytes(aux_wstring_value);

#endif // defined(MINGW_COMPILER)
json_insert(member_name, utf8_value, output);
}
else
Expand Down Expand Up @@ -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<std::codecvt_utf8<wchar_t>> converter;
std::string utf8_value = converter.to_bytes(value);
#endif // defined(MINGW_COMPILER)
json_insert(member_name, utf8_value, output);
}
else
Expand Down
10 changes: 9 additions & 1 deletion src/cpp/utils/SystemInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
12 changes: 9 additions & 3 deletions src/cpp/utils/TimedConditionVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
41 changes: 41 additions & 0 deletions src/cpp/utils/shared_memory/RobustExclusiveLock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#ifdef _MSC_VER
#include <io.h>
#elif defined(MINGW_COMPILER)
#include <io.h>
#else
#include <sys/file.h>
#endif // ifdef _MSC_VER
Expand Down Expand Up @@ -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(
Expand Down
114 changes: 114 additions & 0 deletions src/cpp/utils/shared_memory/RobustSharedLock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#ifdef _MSC_VER
#include <io.h>
#elif defined(MINGW_COMPILER)
#include <io.h>
#else
#include <sys/file.h>
#endif // ifdef _MSC_VER
Expand Down Expand Up @@ -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(
Expand Down
6 changes: 4 additions & 2 deletions thirdparty/filewatch/FileWatch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -404,7 +406,7 @@ namespace filewatch {
std::ratio_multiply<std::hecto, typename std::chrono::nanoseconds::period>>(
reinterpret_cast<ULARGE_INTEGER*>(&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;
}

Expand Down

0 comments on commit fdbf704

Please sign in to comment.