Error compiling latest JUCE in GCC, with solution


#1

Hello,

I’ve pulled the latest JUCE changes as today. I’ve found a problem when compiling the library in Windows with GCC (MinGW / GCC 4.4.1). The methods from the Atomic class are defined twice, so the compiler stops with error:

src/core/juce_Atomic.h

[code]#elif JUCE_GCC // Linux…

//==============================================================================
inline void Atomic::increment (int32& variable) { __sync_add_and_fetch (&variable, 1); }
[…][/code]
This conflicts with the definitions in the file juce_win32_Threads.cpp

#if ! JUCE_USE_INTRINSICS // In newer compilers, the inline versions of these are used (in juce_Atomic.h), but in // older ones we have to actually call the ops as win32 functions.. void Atomic::increment (int32& variable) { InterlockedIncrement (reinterpret_cast <volatile long*> (&variable)); } [...]
As GCC can also be used in Win32, the #elif JUCE_GCC conditional is applied and the conflict occurs. I’ve changed the file src/core/juce_Atomic.h as follows:

[code]#elif JUCE_LINUX // Linux…

//==============================================================================
inline void Atomic::increment (int32& variable) { __sync_add_and_fetch (&variable, 1); }
[…][/code]
Not sure if changing JUCE_GCC to JUCE_LINUX is the most appropiated fix (actually I’m not testing other platforms/compilers), but at least now in Win32/GCC both the library and the Juce Demo application compile and work properly.


#2

Ah, good old mingw.

Perhaps a better fix would be to let it use the intrinsics and just get rid of the fallback code:

//============================================================================== #if ! (JUCE_USE_INTRINSICS || JUCE_GCC) // In newer compilers, the inline versions of these are used (in juce_Atomic.h), but in // older ones we have to actually call the ops as win32 functions.. void Atomic::increment (int32& variable) { InterlockedIncrement (reinterpret_cast <volatile long*> (&variable)); }


#3

It doesn’t work. The JUCE library compiles properly, but compiling the JUCE Demo produces errors when linking. It cannot find the functions __sync_add_and_fetch and __sync_val_compare_and_swap (used at the file src/core/juce_Atomic.h). I performed a text search inside the GCC libraries to see if some .a file should be added to the project in order to link these functions, but I found nothing.

I think the problem is at the file src/core/juce_Atomic.h. The code inside “#elif JUCE_GCC” (line 66) seems to be intended for Linux, but JUCE_GCC could also be defined in Windows.

EDIT: I meant juce_Atomic.h, not .cpp


#4

Drat. Ok, thanks, I’ll go with your original suggestion!


#5

Hi guys, I’m having trouble with this one.

My Mingw (gcc 4.5.0) on Vista cannot find these intrinsic functions, where are they defined? I’ve looked everywhere I can think of and even online I see no header file for any of their definitions. If they don’t need to be defined by nature of their being intrinsic, I cannot see why gcc complains the functions are out of scope. :S

On my xp machine (also gcc 4.5.0) they seem to compile and link fine (so long as I specify -march=i686 in my cxxflags).

However, even then I do not trust that they are working as intended because timer threads will always callback ONLY every 2000 milliseconds, which looking at the juce_timer.cpp code here:

[code]
if (callbackNeeded.compareAndSetBool (1, 0))
{
postMessage (new Message());

				/* Sometimes our message can get discarded by the OS (e.g. when running as an RTAS
				   when the app has a modal loop), so this is how long to wait before assuming the
				   message has been lost and trying again.
				*/
				const uint32 messageDeliveryTimeout = now + 2000;

				while (callbackNeeded.get() != 0)
				{
					wait (4);

					if (threadShouldExit())
						return;

					if (Time::getMillisecondCounter() > messageDeliveryTimeout)
						break;
				}
			}[/code]

…implies that ‘callbackNeeded.compareAndSetBool (1, 0)’ is always returning true, and this function delegates to the atomic intrinsics.

Juce is version 1.52.97


#6

I’m afraid you’re on your own with mingw - I’m happy to support it when people let me know about minor tweaks that will keep the code compatible with it, but I don’t test with it myself.

The intrinsics are certainly something that the compiler generates itself, so the header file error is probably spurious. If you want to test it properly, there are some unit tests for the atomic ops - search the codebase for “AtomicTests”…


#7

Man I’m such an clutz.I changed all the JUCE_ATOMICS_GCC’s to JUCE_LINUX on the authority of the first post but then changed all of them back when the change didn’t work EXCEPT I missed reverting the change to the get() call. And by nature of c++'s dubious allowance of no return values in non-void function, it didn’t break anything.
I guess rookie mistakes and bad luck build character, at least.