PortAudio / portaudio

PortAudio is a cross-platform, open-source C language library for real-time audio input and output.
Other
1.46k stars 303 forks source link

compile error in pa_win_wasapi.c (cross compile for win32) #354

Closed retorquere closed 3 years ago

retorquere commented 3 years ago

Describe the bug I'm trying to cross-compile performous according to this recipe, and the build ends with the message in the attached log message.txt (see below)

To Reproduce

Run the build workflow

Expected behavior

The source tests against WIN64 at pa_win_wasapi.c:171:24. Maybe it should also test against WIN32? I'm not too familiar with Windows alas.

Actual behavior

Error messages or logs longer than a page should be attached as a .txt file.

Desktop (please complete the following information):

The error messages are:

<command-line>:0:0: note: this is the location of the previous definition
../portaudio/src/hostapi/wasapi/pa_win_wasapi.c:171:24: error: redefinition of 'struct _BYTE_BLOB'
         typedef struct _BYTE_BLOB
                        ^
In file included from /home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/combaseapi.h:153:0,
                 from /home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/objbase.h:14,
                 from /home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/ole2.h:17,
                 from /home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/wtypes.h:12,
                 from /home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/winscard.h:10,
                 from /home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/windows.h:97,
                 from ../portaudio/src/hostapi/wasapi/pa_win_wasapi.c:46:
/home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/wtypesbase.h:316:16: note: originally defined here
 typedef struct _BYTE_BLOB {
                ^
../portaudio/src/hostapi/wasapi/pa_win_wasapi.c:175:15: error: conflicting types for 'BYTE_BLOB'
         }     BYTE_BLOB;
               ^
In file included from /home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/combaseapi.h:153:0,
                 from /home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/objbase.h:14,
                 from /home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/ole2.h:17,
                 from /home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/wtypes.h:12,
                 from /home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/winscard.h:10,
                 from /home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/windows.h:97,
                 from ../portaudio/src/hostapi/wasapi/pa_win_wasapi.c:46:
/home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/wtypesbase.h:319:3: note: previous declaration of 'BYTE_BLOB' was here
 } BYTE_BLOB;
   ^
../portaudio/src/hostapi/wasapi/pa_win_wasapi.c:176:65: error: conflicting types for 'UP_BYTE_BLOB'
         typedef /* [unique] */  __RPC_unique_pointer BYTE_BLOB *UP_BYTE_BLOB;
                                                                 ^
In file included from /home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/combaseapi.h:153:0,
                 from /home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/objbase.h:14,
                 from /home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/ole2.h:17,
                 from /home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/wtypes.h:12,
                 from /home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/winscard.h:10,
                 from /home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/windows.h:97,
                 from ../portaudio/src/hostapi/wasapi/pa_win_wasapi.c:46:
/home/runner/work/performous/performous/win32/performous-mxe/mxe/usr/i686-w64-mingw32.shared/include/wtypesbase.h:321:20: note: previous declaration of 'UP_BYTE_BLOB' was here
 typedef BYTE_BLOB *UP_BYTE_BLOB;
mgeier commented 3 years ago

I was trying to upgrade the PortAudio package of https://mxe.cc/, but I stumbled over the same error: https://github.com/mxe/mxe/pull/2631.

Any ideas how to fix this?

dmitrykos commented 3 years ago

If you check the WASAPI source code file then you can find out that conflicting declarations comes from this section:

    #ifdef WIN64
        #include <wtypes.h>
        #define FASTCALL
        #include <oleidl.h>
        #include <objidl.h>
    #else
        typedef struct _BYTE_BLOB
        {
            unsigned long clSize;
            unsigned char abData[ 1 ];
        }     BYTE_BLOB;
        typedef /* [unique] */  __RPC_unique_pointer BYTE_BLOB *UP_BYTE_BLOB;
        typedef LONGLONG REFERENCE_TIME;
        #define NONAMELESSUNION
    #endif

BYTE_BLOB declaration is needed to support the original MinGW32 32-bit compiler which is gcc version 6.3.0 (MinGW.org GCC-6.3.0-1). What I can propose is to add the check for the compiler version and exclude these additional declarations.

Would you please modify it to such way and check if source compiles correctly:

    #ifdef WIN64
        #include <wtypes.h>
        #define FASTCALL
        #include <oleidl.h>
        #include <objidl.h>
    #elif defined(__GNUC__) && (__GNUC__ <= 6)
        typedef struct _BYTE_BLOB
        {
            unsigned long clSize;
            unsigned char abData[ 1 ];
        }     BYTE_BLOB;
        typedef /* [unique] */  __RPC_unique_pointer BYTE_BLOB *UP_BYTE_BLOB;
        typedef LONGLONG REFERENCE_TIME;
        #define NONAMELESSUNION
    #endif
mgeier commented 3 years ago

Thanks @dmitrykos, but this doesn't seem to work with https://mxe.cc/.

The GCC version of the cross-compiler seems to be this:

i686-w64-mingw32.static-gcc (GCC) 5.5.0

The package list at https://mxe.cc/#packages also mentions GCC version 5.5.0.

dmitrykos commented 3 years ago

@mgeier, ok, I see. Does w64 define any specific to w64 project define which we could use to differentiate? Or, could you please find the source code where BYTE_BLOB is defined and check what specific defines to this structure are defined. We could ifdef this block in PA WASAPI.

dmitrykos commented 3 years ago

@mgeier, I found the needed file https://github.com/mirror/mingw-w64/blob/master/mingw-w64-headers/include/wtypesbase.h and there is _BLOB_DEFINED defined while it is not defined in MinGW32 version I was referencing earlier.

So, let's try to use it as such:

    #ifdef WIN64
        #include <wtypes.h>
        #define FASTCALL
        #include <oleidl.h>
        #include <objidl.h>
    #else
        #ifndef _BLOB_DEFINED
            typedef struct _BYTE_BLOB
            {
                unsigned long clSize;
                unsigned char abData[ 1 ];
            }     BYTE_BLOB;
            typedef /* [unique] */  __RPC_unique_pointer BYTE_BLOB *UP_BYTE_BLOB;
        #endif
        typedef LONGLONG REFERENCE_TIME;
        #define NONAMELESSUNION
    #endif

Will this workaround work for you?

mgeier commented 3 years ago

Very nice, that works!

I didn't test if the generated library actually runs on Windows (I'm not a Windows user myself), but at least it compiles without error.

BTW, there is a warning about another preprocessor definition:

src/hostapi/dsound/pa_win_ds.c:54:0: warning: "_WIN32_WINNT" redefined
 #define _WIN32_WINNT 0x0400 /* required to get waitable timer APIs */
 ^
[...]/mxe/usr/i686-w64-mingw32.static/include/_mingw.h:233:0: note: this is the location of the previous definition
 #define _WIN32_WINNT 0x502
 ^

I have no idea whether that matters or not, I just thought I'd mention it while we are at it ...

dmitrykos commented 3 years ago

This warning comes from the DirectSound interface, not WASAPI but it looks fine. May be it makes sense to adjust it to:

#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0400)
    #undef _WIN32_WINNT
    #define _WIN32_WINNT 0x0400 /* required to get waitable timer APIs */
#endif

@RossBencina, could probably comment on that. I will handle a fix of WASAPI case in a separate PR.

RossBencina commented 3 years ago

@dmitrykos I am not sure about redefining _WIN32_WINNT if it is already defined. I think it is better to move the define further up the file.

In any case, I created a new ticket #549