Latest tip build fails with mingw


#1

I’m building juce (latest git) with latest mingw snapshot, and the core module fails with:
In file included from …/source/modules/juce_core/juce_core.cpp:177:0:
…/source/modules/juce_core/native/juce_win32_ComSmartPtr.h: In member function ‘HRESULT juce::ComBaseClassHelper::QueryInterface(const IID&, void**)’:
…/source/modules/juce_core/native/juce_win32_ComSmartPtr.h:137:20: error: ‘castToType’ was not declared in this scope
…/source/modules/juce_core/native/juce_win32_ComSmartPtr.h:137:40: error: expected primary-expression before ‘>’ token
make[2]: *** [intermediate/Release/juce_core.o] Error 1

I’m not used to c++ templates so I’m unsure how to fix this.
It seems a very weird error to me… :?


#2

the answer was right above my nose…

here’s a patch:

[code]diff --git a/modules/juce_core/native/juce_win32_ComSmartPtr.h b/modules/juce_core/native/juce_win32_ComSmartPtr.h
index e8d940d…05e2ac0 100644
— a/modules/juce_core/native/juce_win32_ComSmartPtr.h
+++ b/modules/juce_core/native/juce_win32_ComSmartPtr.h
@@ -134,7 +134,7 @@ public:
JUCE_COMRESULT QueryInterface (REFIID refId, void** result)
{
if (refId == __uuidof (ComClass))

  •        return castToType <ComClass> (result);
    
  •        return ComBaseClassHelperBase <ComClass>::castToType (result);
    
       return ComBaseClassHelperBase <ComClass>::QueryInterface (refId, result);
    
    }
    [/code]

#3

It’s slightly simpler to write it as

return this->castToType <ComClass> (result);

…but either way gets the job done, thanks!


#4

Jules, the fix you have committed does not work here (but the one suggested by falkTX works)

update: it is more complicated than that – maybe it is my version of mingw that is wrong, or a subtle rule involving templates, but it is failing later when being used inside juce_gui_basics.cpp

I got it to build by definining a non-template version in juce_win32_ComSmartPtr :

JUCE_COMRESULT castToType__NOTEMPLATE(void** result) { this->AddRef(); *result = dynamic_cast <ComClass*> (this); return S_OK; }

and call this function in the QueryInterface method instance of the template one.


#5

You’re not trying to build with an old GCC3 version or something, are you?


#6

nope its a mingw-w32 g++ 4.7.0 cross compiler for darwin – anyway the compilation is finally failing at the link step , on stuff like ‘undefined reference to `_GUID const& __mingw_uuidof()’ so I think this is a bit hopeless…


#7

Ok. Well, I don’t know. Your non-templated suggestion isn’t correct, because the type can’t just be ignored, but I’ve no idea why gcc would complain, the code looks fine to me.


#8

It turns out the correct syntax is:

(see http://stackoverflow.com/questions/1682844/templates-template-function-not-playing-well-with-classs-template-member-funct )


#9

Blimey. Well, you learn something every day!


#10

I wonder how many people are successfully building JUCE apps with mingw ? Using the version 4.7.2 from http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/rubenvb/gcc-4.7-release/ I was getting link errors with __mingw_uuidof<…> , apparently the uuid of a few COM interfaces used by juce are not available in mingw headers. I had to link the application with the following file in order to fix these link errors:

[code]#ifdef WIN32
#include <windows.h>
#include <shobjidl.h>

#ifndef MSC_VER
#define UUID_DECL(type,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)
extern “C++” {
static const IID uuid
##type = {l,w1,w2, {b1,b2,b3,b4,b5,b6,b7,b8}};
template<> const GUID &_mingw_uuidof() {
return uuid
##type;
}
template<> const GUID &__mingw_uuidof<type*>() {
return __mingw_uuidof();
}
}

UUID_DECL(IDataObject, 0x0000010e, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
UUID_DECL(IShellLinkW, 0x000214f9, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
UUID_DECL(IPersistFile, 0x0000010b, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
UUID_DECL(IDropSource, 0x00000121, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
UUID_DECL(IDropTarget, 0x00000122, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
UUID_DECL(IEnumFORMATETC, 0x00000103, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
UUID_DECL(IOleClientSite, 0x00000118, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
UUID_DECL(IOleInPlaceSite, 0x00000119, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
UUID_DECL(IOleInPlaceFrame, 0x00000116, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
UUID_DECL(IStorage, 0x0000000b, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
#endif
#endif
[/code]

But I wonder why nobody else did run into this issue ?


#11

I think the question is as well why would anybody use mingw when there is free version of Visual C++


#12

I did ran into that issue, but then got busy with something else and haven’t tried it again.


#13

Reason #1 is that I don’t like Windows myself, so I use mingw to cross compile Juce (and then Wine for a quick test).


#14

Sometimes switching between compilers helps to spot bugs, and in my experience gcc is much better than msvc at generating optimized code, especially when dealing with sse intrinsics. And also, as falktx said, it is quite nice to be able to cross-compile on linux or macos.


#15

[quote=“jpo”]I wonder how many people are successfully building JUCE apps with mingw ? Using the version 4.7.2 from http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/rubenvb/gcc-4.7-release/ I was getting link errors with __mingw_uuidof<…> , apparently the uuid of a few COM interfaces used by juce are not available in mingw headers. I had to link the application with the following file in order to fix these link errors:

[code]#ifdef WIN32
#include <windows.h>
#include <shobjidl.h>

#ifndef MSC_VER
#define UUID_DECL(type,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)
extern “C++” {
static const IID uuid
##type = {l,w1,w2, {b1,b2,b3,b4,b5,b6,b7,b8}};
template<> const GUID &_mingw_uuidof() {
return uuid
##type;
}
template<> const GUID &__mingw_uuidof<type*>() {
return __mingw_uuidof();
}
}

UUID_DECL(IDataObject, 0x0000010e, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
UUID_DECL(IShellLinkW, 0x000214f9, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
UUID_DECL(IPersistFile, 0x0000010b, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
UUID_DECL(IDropSource, 0x00000121, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
UUID_DECL(IDropTarget, 0x00000122, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
UUID_DECL(IEnumFORMATETC, 0x00000103, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
UUID_DECL(IOleClientSite, 0x00000118, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
UUID_DECL(IOleInPlaceSite, 0x00000119, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
UUID_DECL(IOleInPlaceFrame, 0x00000116, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
UUID_DECL(IStorage, 0x0000000b, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
#endif
#endif
[/code]

But I wonder why nobody else did run into this issue ?[/quote]

Hi,
I can’t compile this file, it returns “error: expected identifier or ‘(’ before string constant” on all UUID_DECL calls.
tried with gcc and g++, several ming error handling configs, sjlj, dw2, even 64bit seh.
I’m new to c++, and I want to stick with gnu for desktop apps, but I’m a little experiencied with c++ macros yet.
Whats the trick to make this work?

Thanks,
Regards


#16

I don’t know, it may depend on the version of win32 runtime that is bundled with your mingw installation. I’m using versions 4.7.2 and 4.6.2 of mingw-w64 , 32-bit, or even the version 4.5.3 that comes with cygwin, and it builds fine with this command line:


#17

I tested with 4 versions, none compiled. All are latest.


#18

In case anyone else struggles with

undefined reference to `_GUID const& __mingw_uuidof<IPersistFile>()'

-type of errors, here's what worked for me:

 

[kjetil@ttlush pluginhost]$ git diff JuceLibraryCode/modules/juce_core/native/juce_win32_ComSmartPtr.h
diff --git a/pluginhost/JuceLibraryCode/modules/juce_core/native/juce_win32_ComSmartPtr.h b/pluginhost/JuceLibraryCode/modules/juce_core/native/juce_win32_ComSmartPtr.h
index 0dc0efc..fa24516 100644
--- a/pluginhost/JuceLibraryCode/modules/juce_core/native/juce_win32_ComSmartPtr.h
+++ b/pluginhost/JuceLibraryCode/modules/juce_core/native/juce_win32_ComSmartPtr.h
@@ -29,7 +29,11 @@
 #ifndef JUCE_WIN32_COMSMARTPTR_H_INCLUDED
 #define JUCE_WIN32_COMSMARTPTR_H_INCLUDED
 
-#if ! (defined (_MSC_VER) || defined (__uuidof))
+#ifdef __uuidof
+#undef __uuidof
+#endif
+
+#if 1 //! (defined (_MSC_VER) || defined (__uuidof))
 template<typename Type> struct UUIDGetter { static CLSID get() { jassertfalse; return CLSID(); } };
 #define __uuidof(x)  UUIDGetter<x>::get()
 #endif

 

 

I'm cross compiling on linux, using mingw gcc 4.7.2.


#19

ok, but obviously that'll stomp all over the compiler's implementation when running on MSVC, which isn't a good idea.

You seem to be suggesting that the issue here is that on mingw __uuidof is defined, but that their version doesn't work correctly?


#20

It was 5 minutes ago and It compiles Introjucer without any problem.

Enviroment: Windows 7 + Mingw (GCC 4.8.1) + Codeblocks 13.12.

 

I use MinGW + Eclipse/Codeblocks + Juce a lot in a comfortably way since some years.

I use Mingw + Eclipse instead MSVS because I feel better with this enviroment.