Skip to content

Commit 2369919

Browse files
authored
CXX-3180 address misc. mingw-w64 GCC compatibility issues (#1512)
* Extend BSONCXX_PRIVATE_IF_GCC to support mingw-w64 GCC targeting Windows * Avoid not-unique function address issues when linking with mingw-w64 * Use consistent error message for scoped_bson bson_concat failure * Fix implicit instantiation of v1::array::view via scoped_bson header * Remove stray export macros on inline function definitions * Address StringMaker<T>::convert() implicit instantiation issues * Use _WIN32 instead of _MSC_VER for <sys/wait.h> * Avoid C99 format specifier compatibility issues with mingw-w64 GCC
1 parent 5ae8dc8 commit 2369919

File tree

19 files changed

+83
-39
lines changed

19 files changed

+83
-39
lines changed

examples/api/bsoncxx/examples/oid/basic_usage.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ void example() {
4040
{
4141
std::time_t time = oid.get_time_t();
4242
char str[sizeof("YYYY-MM-DD HH:MM:SS")];
43-
EXPECT(std::strftime(str, sizeof(str), "%F %T", std::gmtime(&time)) == sizeof(str) - 1u);
43+
// Avoid %F and %T for mingw-w64 GCC compatibiility.
44+
EXPECT(std::strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", std::gmtime(&time)) == sizeof(str) - 1u);
4445
EXPECT(std::string(str) == "1970-01-01 00:00:00");
4546
}
4647

@@ -61,7 +62,8 @@ void example() {
6162
{
6263
std::time_t time = oid.get_time_t();
6364
char str[sizeof("YYYY-MM-DD HH:MM:SS")];
64-
EXPECT(std::strftime(str, sizeof(str), "%F %T", std::gmtime(&time)) == sizeof(str) - 1u);
65+
// Avoid %F and %T for mingw-w64 GCC compatibiility.
66+
EXPECT(std::strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", std::gmtime(&time)) == sizeof(str) - 1u);
6567
EXPECT(std::string(str) == "2000-01-01 23:59:59");
6668
}
6769

examples/api/runner.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,13 @@
4343

4444
#include <examples/macros.hh>
4545

46-
#if !defined(_MSC_VER)
46+
#if !defined(_WIN32)
4747

4848
#include <unistd.h>
4949

5050
#include <sys/wait.h>
5151

52-
#endif // !defined(_MSC_VER)
52+
#endif // !defined(_WIN32)
5353

5454
namespace {
5555

@@ -119,7 +119,7 @@ class runner_type {
119119

120120
action run_forking_components() {
121121
if (use_fork) {
122-
#if !defined(_MSC_VER)
122+
#if !defined(_WIN32)
123123
// Forking with threads is difficult and the number of components that require forking
124124
// are few in number. Run forking components sequentially.
125125
for (auto const& component : forking_components) {
@@ -167,7 +167,7 @@ class runner_type {
167167
}
168168

169169
return action::succeed;
170-
#endif // !defined(_MSC_VER)
170+
#endif // !defined(_WIN32)
171171
}
172172

173173
std::cout << "Skipping API examples that require forked processes" << std::endl;
@@ -484,7 +484,7 @@ void runner_register_forking_component(void (*fn)(), char const* name) {
484484
}
485485

486486
int EXAMPLES_CDECL main(int argc, char** argv)
487-
#if defined(_MSC_VER)
487+
#if defined(_WIN32)
488488
try
489489
#endif
490490
{
@@ -539,7 +539,7 @@ int EXAMPLES_CDECL main(int argc, char** argv)
539539

540540
return runner.run(); // Return directly from forked processes.
541541
}
542-
#if defined(_MSC_VER)
542+
#if defined(_WIN32)
543543
// Avoid popup dialog boxes or completely-absent CLI error messages on Windows.
544544
catch (std::exception const& ex) {
545545
std::cerr << "API runner failed due to uncaught exception: " << ex.what() << std::endl;

src/bsoncxx/include/bsoncxx/v1/detail/macros.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,16 @@
119119
//
120120
// MSVC: supports inline variables since 19.12 (with /std:c++latest), but behavior is broken for static data members
121121
// (multiple definitions) until 19.20 even when __cpp_inline_variables is defined.
122+
//
123+
// mingw-w64: this is an ancient bug/issue: https://sourceware.org/bugzilla/show_bug.cgi?id=9687. Use the
124+
// Windows-specific [[gnu::selectany]] attribute instead, which provides link-once semantics for global variables.
122125
#if ( \
123126
!defined(_MSC_VER) && \
124127
(__cplusplus >= 201703L || (defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L))) || \
125128
(defined(_MSC_VER) && _MSC_VER >= 1920 && defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
126129
#define BSONCXX_PRIVATE_INLINE_CXX17 inline
130+
#elif defined(__MINGW32__)
131+
#define BSONCXX_PRIVATE_INLINE_CXX17 [[gnu::selectany]]
127132
#else
128133
#define BSONCXX_PRIVATE_INLINE_CXX17 \
129134
BSONCXX_PRIVATE_IF_GCC([[gnu::weak]]) \

src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/string/view_or_value.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class view_or_value : public bsoncxx::v_noabi::view_or_value<stdx::string_view,
4848
///
4949
/// Default constructor, equivalent to using an empty string.
5050
///
51-
BSONCXX_ABI_EXPORT_CDECL() view_or_value() = default;
51+
view_or_value() = default;
5252

5353
///
5454
/// Construct a string::view_or_value using a null-terminated const char *.

src/bsoncxx/test/v1/element/view.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include <bsoncxx/test/v1/document/view.hh>
2020
#include <bsoncxx/test/v1/exception.hh>
2121
#include <bsoncxx/test/v1/types/value.hh>
22-
#include <bsoncxx/test/v1/types/view.hh>
2322

2423
#include <cstdint>
2524
#include <cstring>

src/bsoncxx/test/v1/oid.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ TEST_CASE("basic", "[bsoncxx][v1][oid]") {
147147
{
148148
std::time_t time = o.get_time_t();
149149
char str[sizeof("YYYY-MM-DD HH:MM:SS")];
150-
CHECK(std::strftime(str, sizeof(str), "%F %T", std::gmtime(&time)) == sizeof(str) - 1u);
150+
// Avoid %F and %T for mingw-w64 GCC compatibiility.
151+
CHECK(std::strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", std::gmtime(&time)) == sizeof(str) - 1u);
151152
CHECK(std::string(str) == "1970-01-01 00:00:00");
152153
}
153154

@@ -172,7 +173,8 @@ TEST_CASE("basic", "[bsoncxx][v1][oid]") {
172173
{
173174
std::time_t time = o.get_time_t();
174175
char str[sizeof("YYYY-MM-DD HH:MM:SS")];
175-
CHECK(std::strftime(str, sizeof(str), "%F %T", std::gmtime(&time)) == sizeof(str) - 1u);
176+
// Avoid %F and %T for mingw-w64 GCC compatibiility.
177+
CHECK(std::strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", std::gmtime(&time)) == sizeof(str) - 1u);
176178
CHECK(std::string(str) == "2000-01-01 23:59:59");
177179
}
178180

src/bsoncxx/test/v1/types/value.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
//
2020

21-
#include <bsoncxx/test/v1/types/view.hh>
21+
#include <bsoncxx/test/v1/types/view.hh> // IWYU pragma: export
2222

2323
#include <catch2/catch_tostring.hpp>
2424

src/bsoncxx/test/v_noabi/array.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
#include <bsoncxx/test/v1/array/view.hh>
16+
1517
#include <algorithm>
1618

1719
#include <bsoncxx/array/view.hpp>

src/bsoncxx/test/v_noabi/oid.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,12 @@ parsed_oid parse_oid(oid const& oid) {
7474
}
7575

7676
void compare_string(std::time_t const& t, bsoncxx::stdx::string_view time) {
77-
char time_str[48] = {};
78-
CHECK(0 != (std::strftime(time_str, sizeof(time_str), "%b %e, %Y %H:%M:%S UTC", std::gmtime(&t))));
79-
CHECK(time_str == time);
77+
char time_str[48];
78+
79+
// Avoid %e for MSVCRT-based mingw-w64 GCC compatibility.
80+
REQUIRE(0 != (strftime(time_str, sizeof(time_str), "%b %d, %Y %H:%M:%S UTC", std::gmtime(&t))));
81+
82+
REQUIRE(time_str == time);
8083
}
8184

8285
TEST_CASE("basic", "[bsoncxx][v_noabi][oid]") {
@@ -96,10 +99,10 @@ TEST_CASE("basic", "[bsoncxx][v_noabi][oid]") {
9699
REQUIRE(tc == 0x80000000);
97100
REQUIRE(td == 0xFFFFFFFF);
98101

99-
compare_string(ta, "Jan 1, 1970 00:00:00 UTC");
102+
compare_string(ta, "Jan 01, 1970 00:00:00 UTC");
100103
compare_string(tb, "Jan 19, 2038 03:14:07 UTC");
101104
compare_string(tc, "Jan 19, 2038 03:14:08 UTC");
102-
compare_string(td, "Feb 7, 2106 06:28:15 UTC");
105+
compare_string(td, "Feb 07, 2106 06:28:15 UTC");
103106
}
104107

105108
// Ensure that after a new process is created through a fork() or similar process creation operation, the "random
@@ -138,7 +141,8 @@ TEST_CASE("basic", "[bsoncxx][v_noabi][oid]") {
138141
{
139142
std::time_t time = o.get_time_t();
140143
char str[sizeof("YYYY-MM-DD HH:MM:SS")];
141-
CHECK(std::strftime(str, sizeof(str), "%F %T", std::gmtime(&time)) == sizeof(str) - 1u);
144+
// Avoid %F and %T for mingw-w64 GCC compatibiility.
145+
CHECK(std::strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", std::gmtime(&time)) == sizeof(str) - 1u);
142146
CHECK(std::string(str) == "2000-01-01 23:59:59");
143147
}
144148

src/mongocxx/include/mongocxx/v_noabi/mongocxx/client_session.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class client_session {
6868
MONGOCXX_ABI_EXPORT_CDECL(client_session&) operator=(client_session&&) noexcept;
6969

7070
client_session(client_session const&) = delete;
71-
MONGOCXX_ABI_EXPORT_CDECL(client_session&) operator=(client_session const&) = delete;
71+
client_session& operator=(client_session const&) = delete;
7272

7373
///
7474
/// Ends and destroys the session.

0 commit comments

Comments
 (0)