ornladios / ADIOS2

Next generation of ADIOS developed in the Exascale Computing Program
https://adios2.readthedocs.io/en/latest/index.html
Apache License 2.0
264 stars 121 forks source link

Build error on Windows (mingw) #4192

Open eschnett opened 1 month ago

eschnett commented 1 month ago

I am cross-building ADIOS2 2.10.1 for Windows ( x86_64-w64-mingw32) to create a DLL that can be used from Julia. See https://github.com/JuliaPackaging/Yggdrasil/pull/8535 for details.

Building for this architecture worked with ADIOS 2.9 with a few patches. Building ADIOS2 2.10 encounters many more problems. In particular the EVPath component is quite unhappy. I've tried to paper over the first few problems with some patches but this doesn't seem to help.

eisenhauer commented 1 month ago

Hi,

I'm guessing that there are a couple of things going on. First, yes, it used to be that there were several things that didn't get built on windows (FFS, EVPath) that were used in newer features of ADIOS including BP5 and SST. With 2.9 BP5 became the default file format and it required FFS, so we started building FFS unconditionally. We are working towards buliding and testing SST everywhere and some of the techniques being used to make EVPath build were used in FileHTTP.c. So that's why problems are popping up, we don't like losing functionality when switching platforms either, so we're changing things.

Second, unfortunately there are kind of a lot of ways to build on windows and the only thing we test in our CI is building with Visual Studio. This may lead things being missed, like an #ifdef _WIN32 that should be a _MSC_VER. This includes upstream packages like EVPath and FFS (for which I am a maintainer). We probably can't do a CI build on all the windows combinations, but maybe we could at least build with mingw (@vicentebolea ?). And we can try to work with you to resolve current issues so that maybe 2.10.2 will work where you need it to.

eschnett commented 1 month ago

Thanks for the pointers.

This helps me:

diff --git a/bindings/C/adios2/c/adios2_c_io.h b/bindings/C/adios2/c/adios2_c_io.h
index c790cd064..3236dc353 100644
--- a/bindings/C/adios2/c/adios2_c_io.h
+++ b/bindings/C/adios2/c/adios2_c_io.h
@@ -181,7 +181,7 @@ adios2_attribute *adios2_define_attribute(adios2_io *io, const char *name, const
                                           const void *value);

 /**
- * @brief Define an attribute array inside io
+ * @brief Define an attributeo array inside io
  * @param io handler that owns the attribute
  * @param name unique attribute name inside IO handler
  * @param type primitive type from enum adios2_type in adios2_c_types.h
diff --git a/source/adios2/engine/bp5/BP5Reader.cpp b/source/adios2/engine/bp5/BP5Reader.cpp
index 5a1a581cf..dc5aa592d 100644
--- a/source/adios2/engine/bp5/BP5Reader.cpp
+++ b/source/adios2/engine/bp5/BP5Reader.cpp
@@ -1276,7 +1276,6 @@ void BP5Reader::DoClose(const int transportIndex)

 #if defined(_WIN32)
 #include <windows.h>
-#define getpid() GetCurrentProcessId();
 #elif defined(__linux) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__) ||    \
     defined(__NetBSD__) || defined(__DragonFly__) || defined(__CYGWIN__)
 #include <sys/types.h>
diff --git a/source/utils/bpls/bpls.cpp b/source/utils/bpls/bpls.cpp
index 66398ad15..cfa4d035d 100644
--- a/source/utils/bpls/bpls.cpp
+++ b/source/utils/bpls/bpls.cpp
@@ -1630,7 +1630,7 @@ int doList(std::string path)
     core::IO &io = adios.DeclareIO("bpls");
     if (timestep)
     {
-        // BP4 can process metadata in chuncks to conserve memory
+        // BP4 can process metadata in chunks to conserve memory
         io.SetParameter("StreamReader", "true");
     }
     core::Engine *fp = nullptr;
diff --git a/thirdparty/EVPath/EVPath/cm.c b/thirdparty/EVPath/EVPath/cm.c
index e1bb4fdc9..babfc7655 100644
--- a/thirdparty/EVPath/EVPath/cm.c
+++ b/thirdparty/EVPath/EVPath/cm.c
@@ -3968,7 +3968,7 @@ int offset_compare(const void* lhsv, const void* rhsv)
      return lhs->offset.tv_usec - rhs->offset.tv_usec;
  }

-#ifdef _MSC_VER
+#ifdef _WIN32
 static inline void timeradd(struct timeval *a, struct timeval *b,
                            struct timeval *res)
 {
diff --git a/thirdparty/EVPath/EVPath/cm_internal.h b/thirdparty/EVPath/EVPath/cm_internal.h
index 173a1ce36..c9126ad8f 100644
--- a/thirdparty/EVPath/EVPath/cm_internal.h
+++ b/thirdparty/EVPath/EVPath/cm_internal.h
@@ -572,15 +572,6 @@ extern void INT_CMTrace_file_id(int ID);
 #ifdef _MSC_VER
 #include <process.h>
 #include <time.h>
-#define CLOCK_MONOTONIC 1
-static int clock_gettime(int cl, struct timespec* spec)
-{
-    __int64 wintime; GetSystemTimeAsFileTime((FILETIME*)&wintime);
-    wintime -= 116444736000000000i64;  //1jan1601 to 1jan1970
-    spec->tv_sec = (long)(wintime / 10000000i64);           //seconds
-    spec->tv_nsec = wintime % 10000000i64 * 100;      //nano-seconds
-    return 0;
-}
 #define HAVE_CLOCK_GETTIME
 #endif
 #ifdef HAVE_CLOCK_GETTIME
diff --git a/thirdparty/EVPath/EVPath/cm_schedule.h b/thirdparty/EVPath/EVPath/cm_schedule.h
index 8b2132b37..dfd08c23f 100644
--- a/thirdparty/EVPath/EVPath/cm_schedule.h
+++ b/thirdparty/EVPath/EVPath/cm_schedule.h
@@ -7,7 +7,7 @@
 extern "C" {
 #endif

-#ifdef _MSC_VER
+#ifdef _WIN32
 #define FD_SETSIZE 1024
 #include <winsock2.h>
 #endif
diff --git a/thirdparty/EVPath/EVPath/cmenet.c b/thirdparty/EVPath/EVPath/cmenet.c
index b33989de5..1b4b563e0 100644
--- a/thirdparty/EVPath/EVPath/cmenet.c
+++ b/thirdparty/EVPath/EVPath/cmenet.c
@@ -189,9 +189,6 @@ extern void ZPLENETdummy() {  // for warning suppression
 #define INTERFACE_NAME(NAME) libcmenet_LTX_ ## NAME
 #include <enet/enet.h>
 #endif
-#ifndef _MSC_VER
-#include <arpa/inet.h>
-#endif
 #include <time.h>
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
diff --git a/thirdparty/EVPath/EVPath/cmmulticast.c b/thirdparty/EVPath/EVPath/cmmulticast.c
index 3d0e1f089..15e77aec4 100644
--- a/thirdparty/EVPath/EVPath/cmmulticast.c
+++ b/thirdparty/EVPath/EVPath/cmmulticast.c
@@ -2,13 +2,15 @@
 #include "config.h"
 #include <sys/types.h>

+#ifdef _WIN32
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#endif
 #ifdef HAVE_WINDOWS_H
 #define FD_SETSIZE 1024
 #include <winsock2.h>
 #include <ws2ipdef.h>
 #include <windows.h>
-#define getpid()   _getpid()
-#define close(x) closesocket(x)
 #else
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
@@ -419,7 +421,7 @@ extern int
 libcmmulticast_LTX_writev_func(CMtrans_services svc, mcast_conn_data_ptr mcd, struct iovec *iov, int iovcnt, attr_list attrs)
 {
     SOCKET fd = mcd->output_fd;
-#ifndef _MSC_VER
+#ifndef _WIN32
     // no real equivalent on windows
     struct sockaddr_in addr = mcd->output_addr;
     struct msghdr msg;
diff --git a/thirdparty/EVPath/EVPath/cmsockets.c b/thirdparty/EVPath/EVPath/cmsockets.c
index a054fd452..2b5262fe8 100644
--- a/thirdparty/EVPath/EVPath/cmsockets.c
+++ b/thirdparty/EVPath/EVPath/cmsockets.c
@@ -2,6 +2,10 @@
 #include "config.h"
 #include <sys/types.h>

+#ifdef _WIN32
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#endif
 #ifdef HAVE_WINDOWS_H
 #define FD_SETSIZE 1024
 #include <winsock2.h>
@@ -856,7 +860,7 @@ static void
 set_block_state(CMtrans_services svc, socket_conn_data_ptr scd,
        socket_block_state needed_block_state)
 {
-#ifndef _MSC_VER
+#ifndef _WIN32
     int fdflags = fcntl(scd->fd, F_GETFL, 0);
     if (fdflags == -1) {
    perror("getflags\n");
@@ -886,7 +890,7 @@ extern ssize_t
 libcmsockets_LTX_read_to_buffer_func(CMtrans_services svc, socket_conn_data_ptr scd, void *buffer, ssize_t requested_len, int non_blocking)
 {
     ssize_t left, iget;
-#ifndef _MSC_VER
+#ifndef _WIN32
     // GSE
     int fdflags = fcntl(scd->fd, F_GETFL, 0);
     if (fdflags == -1) {
diff --git a/thirdparty/EVPath/EVPath/cmudp.c b/thirdparty/EVPath/EVPath/cmudp.c
index 4c6815f2a..9bc66b6e1 100644
--- a/thirdparty/EVPath/EVPath/cmudp.c
+++ b/thirdparty/EVPath/EVPath/cmudp.c
@@ -6,7 +6,6 @@
 #define FD_SETSIZE 1024
 #include <winsock2.h>
 #include <windows.h>
-#define getpid()   _getpid()
 #else
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
@@ -203,7 +202,7 @@ libcmudp_LTX_shutdown_conn(CMtrans_services svc, udp_conn_data_ptr ucd)

 #include "qual_hostname.c"

-#ifdef _MSC_VER
+#ifdef _WIN32
 static int inet_aton(const char* cp, struct in_addr* addr)
 {
     addr->s_addr = inet_addr(cp);
@@ -627,7 +626,7 @@ libcmudp_LTX_writev_func(CMtrans_services svc, udp_conn_data_ptr ucd, struct iov
     fd = ucd->utd->socket_fd;
     svc->trace_out(ucd->utd->cm, "CMUdp writev of %d vectors on fd %d",
           iovcnt, fd);
-#ifndef _MSC_VER
+#ifndef _WIN32
     struct sockaddr_in addr = ucd->dest_addr;
     struct msghdr msg;
     memset(&msg, 0, sizeof(msg));
diff --git a/thirdparty/EVPath/EVPath/dlloader.c b/thirdparty/EVPath/EVPath/dlloader.c
index 8cc58134d..312e77d69 100644
--- a/thirdparty/EVPath/EVPath/dlloader.c
+++ b/thirdparty/EVPath/EVPath/dlloader.c
@@ -1,5 +1,5 @@
 #include "config.h"
-#ifndef _MSC_VER
+#ifndef _WIN32
 #include <dlfcn.h>
 #endif
 #include <stdio.h>
@@ -8,7 +8,7 @@
 #include "dlloader.h"

 static char **search_list = NULL;
-#ifdef _MSC_VER
+#ifdef _WIN32
 #include <windows.h>

 static struct {
diff --git a/thirdparty/EVPath/EVPath/dlloader.h b/thirdparty/EVPath/EVPath/dlloader.h
index e0e063097..6e6535fdf 100644
--- a/thirdparty/EVPath/EVPath/dlloader.h
+++ b/thirdparty/EVPath/EVPath/dlloader.h
@@ -1,5 +1,5 @@

-#ifndef _MSC_VER
+#ifndef _WIN32
 #include <dlfcn.h>
 #else
 #define RTLD_GLOBAL 0x100 /* do not hide entries in this module */
diff --git a/thirdparty/EVPath/EVPath/gen_interface.pl b/thirdparty/EVPath/EVPath/gen_interface.pl
index d79335ea5..a8f7fa115 100755
--- a/thirdparty/EVPath/EVPath/gen_interface.pl
+++ b/thirdparty/EVPath/EVPath/gen_interface.pl
@@ -646,8 +646,10 @@ extern void* dlsym(void* handle, const char* name);
 extern const char* dlerror(void);

 #else
+#ifndef _WIN32
 #include <dlfcn.h>
 #endif
+#endif

 #define lt_dlopen(x) dlopen(x, 0)
 #define lt_dlsym(x, y) dlsym(x, y)
diff --git a/thirdparty/EVPath/EVPath/ip_config.c b/thirdparty/EVPath/EVPath/ip_config.c
index e07b4ecd8..1d1a279d1 100644
--- a/thirdparty/EVPath/EVPath/ip_config.c
+++ b/thirdparty/EVPath/EVPath/ip_config.c
@@ -9,7 +9,7 @@
 #ifdef HAVE_WINDOWS_H
 #define FD_SETSIZE 1024
 #include <winsock2.h>
-#include <Ws2def.h>
+#include <ws2def.h>
 #include <ws2tcpip.h>
 #define __ANSI_CPP__
 #ifndef INET_ADDRSTRLEN
@@ -484,7 +484,7 @@ dump_output(int length_estimate, char *format, ...)
 #ifndef HOST_NAME_MAX
 #define HOST_NAME_MAX 255
 #endif
-#ifdef _MSC_VER
+#ifdef _WIN32
 static int inet_aton(const char* cp, struct in_addr* addr)
 {
     addr->s_addr = inet_addr(cp);
diff --git a/thirdparty/EVPath/EVPath/metrics.c b/thirdparty/EVPath/EVPath/metrics.c
index fdfc365f6..cf9c64380 100644
--- a/thirdparty/EVPath/EVPath/metrics.c
+++ b/thirdparty/EVPath/EVPath/metrics.c
@@ -603,7 +603,7 @@ double dgettimeofday( void )

 /**************OS FUNCTIONS**************/
 char*  os_type() {
-#ifndef _MSC_VER
+#ifndef _WIN32
   static struct utsname output;
   static int first = 1;
   if (first) {
@@ -617,7 +617,7 @@ char*  os_type() {
 }

 char*  os_release() {
-#ifndef _MSC_VER
+#ifndef _WIN32
   static struct utsname output;
   static int first = 1;
   if (first) {
diff --git a/thirdparty/EVPath/EVPath/response.c b/thirdparty/EVPath/EVPath/response.c
index fad8f71ca..c4d75ec87 100644
--- a/thirdparty/EVPath/EVPath/response.c
+++ b/thirdparty/EVPath/EVPath/response.c
@@ -1700,7 +1700,7 @@ internal_cod_submit(cod_exec_context ec, int port, void *data, void *type_info)
     internal_cod_submit_general(ec, port, data, type_info, NULL, NULL);
 }

-#ifdef _MSC_VER
+#ifdef _WIN32
 static long lrand48()
 {
     return rand();
@@ -1709,12 +1709,16 @@ static long lrand48()
 static double drand48() {
     return (double)(rand()) / (double)(RAND_MAX);
 }
+#endif
+
+#ifdef _MSC_VER
 static void
 sleep(int t)
 {
     Sleep(t * 1000);
 }
 #endif
+
 static void
 add_standard_routines(stone_type stone, cod_parse_context context)
 {
diff --git a/thirdparty/enet/enet/win32.c b/thirdparty/enet/enet/win32.c
index 0953466a3..5a84228b6 100644
--- a/thirdparty/enet/enet/win32.c
+++ b/thirdparty/enet/enet/win32.c
@@ -9,6 +9,7 @@
 #include <windows.h>
 #include <mmsystem.h>
 #include <ws2ipdef.h>
+#include <ws2tcpip.h>

 static enet_uint32 timeBase = 0;

diff --git a/thirdparty/ffs/ffs/cod/standard.c b/thirdparty/ffs/ffs/cod/standard.c
index df9c7145d..95c82dc1e 100644
--- a/thirdparty/ffs/ffs/cod/standard.c
+++ b/thirdparty/ffs/ffs/cod/standard.c
@@ -527,7 +527,7 @@ int  strxfrm(char *s1, const char *s2, int size);\n\

 static cod_extern_entry strings_externs[] = 
 {
-#ifndef _MSC_VER
+#ifndef _WIN32
     {"bcmp", (void*)(intptr_t)bcmp},
     {"bcopy", (void*)(intptr_t)bcopy},
     {"bzero", (void*)(intptr_t)bzero},
diff --git a/thirdparty/ffs/ffs/ffs/ffs_file.c b/thirdparty/ffs/ffs/ffs/ffs_file.c
index 9fbf77dff..0da27ed14 100644
--- a/thirdparty/ffs/ffs/ffs/ffs_file.c
+++ b/thirdparty/ffs/ffs/ffs/ffs_file.c
@@ -7,7 +7,7 @@
 #include "string.h"
 #include "stdio.h"
 #include "stdlib.h"
-#ifndef _MSC_VER
+#ifndef _WIN32
 #include "unistd.h"
 #include <arpa/inet.h>
 #else
diff --git a/thirdparty/ffs/ffs/fm/fm_formats.c b/thirdparty/ffs/ffs/fm/fm_formats.c
index 83ff1604c..e725cc3e0 100755
--- a/thirdparty/ffs/ffs/fm/fm_formats.c
+++ b/thirdparty/ffs/ffs/fm/fm_formats.c
@@ -3160,10 +3160,10 @@ extern int
 unix_timeout_read_func(void *conn, void *buffer, int length, 
               int *errno_p, char **result_p);

-#ifdef _MSC_VER
+#ifdef _WIN32
 #define srand48(x) srand((int)(x))
 #define drand48() ((double)rand()/RAND_MAX)
-#define sleep(sec)  Sleep(1000 * sec)
+#define sleep(sec)  Sleep(1000 * (sec))
 #endif

 extern int
diff --git a/thirdparty/ffs/ffs/fm/fm_internal.h b/thirdparty/ffs/ffs/fm/fm_internal.h
index 1fd7abc0c..457015b06 100755
--- a/thirdparty/ffs/ffs/fm/fm_internal.h
+++ b/thirdparty/ffs/ffs/fm/fm_internal.h
@@ -286,6 +286,8 @@ struct  iovec {
 #endif
 #endif

+#ifndef _TYPEDEF_IOINTERFACE_FUNCV
+#define _TYPEDEF_IOINTERFACE_FUNCV
 typedef int (*IOinterface_funcv)(void *conn, struct iovec *iov, 
                 int icount, int *errno_p, 
                 char **result_p);
@@ -299,6 +301,7 @@ typedef void *(*IOinterface_open)(const char *path,
                    int *input, int *output);
 typedef int (*IOinterface_lseek)(void* conn, size_t pos, int cmd);
 typedef void (*IOinterface_init)(void );
+#endif

 extern IOinterface_func ffs_server_read_func;
 extern IOinterface_func ffs_server_write_func;
diff --git a/thirdparty/ffs/ffs/fm/io_interface.h b/thirdparty/ffs/ffs/fm/io_interface.h
index d17200cfa..80af5dfa8 100644
--- a/thirdparty/ffs/ffs/fm/io_interface.h
+++ b/thirdparty/ffs/ffs/fm/io_interface.h
@@ -11,6 +11,8 @@ struct    iovec {
 #endif

 #ifndef FM_INTERNAL_H
+#ifndef _TYPEDEF_IOINTERFACE_FUNCV
+#define _TYPEDEF_IOINTERFACE_FUNCV
 typedef int (*IOinterface_func)(void *conn, void *buffer, size_t length,
                      int *errno_p, char **result_p);

@@ -26,6 +28,7 @@ typedef void *(*IOinterface_open)(const char *path, const char *flag_str, int *i
 typedef void (*IOinterface_init)(void );
 typedef int (*IOinterface_lseek)(void* conn, size_t pos, int cmd);
 #endif
+#endif

 extern IOinterface_func ffs_file_read_func;
 extern IOinterface_func ffs_file_write_func;
eisenhauer commented 1 month ago

If this patch works for you to build on mingw, I can take it and put it in a PR to see if it causes regressions on Visual Studio. (On quick inspections, I suspect that it does. Changes like this one in BP5Reader.cpp are likely to regress:

 #include <windows.h>
-#define getpid() GetCurrentProcessId();
 #elif defined(__linux) || defined(__APPLE__)

I'm assuming that getpid() was necessary for visual studio, so killing outright is a problem. But such a PR would give us a way to work through issues without having a mingw entry in ADIOS CI. Of course all changes under 'thirdparty' have to be merged upstream and pulled back down before finalization, but we'll sort that when we come to it.

eschnett commented 1 month ago

Yes, this patch makes things work for us. I also expect things to not work for you, for the reasons you mentioned.

eisenhauer commented 2 weeks ago

I have a tentative mingw environment that I'm playing with, but I'm getting a different set of errors than I see here (including failures in KWSys, which is upstream of us). Can you share CMake arguments or environment variables you're running with?

eschnett commented 2 weeks ago

The build script is contained in the file build_tarballs.jl at https://github.com/JuliaPackaging/Yggdrasil/tree/38a8c9dd73fae3b39ec76fee0bb96162a1b6f138/A/ADIOS2 in the string variable script. The patches we are applying are located in the directory bundled/patches in the same directory. The dependencies we are installing before building are listed in the variable dependencies.

Any comments you might have on our build setup would be appreciated!

eisenhauer commented 2 weeks ago

Can you give me the CMAKE_TARGET_TOOLCHAIN file used there?

eschnett commented 2 weeks ago

The toolchains are located as https://github.com/JuliaPackaging/Yggdrasil/tree/master/B/BaseCompilerShard/cmake_toolchains . The gcc one should be the default.

eisenhauer commented 2 weeks ago

OK, I don't think I can easily replicate your whole environment, but let me see if I can take the cmake line and go from there...