MingGW data import from a dll from another dll

I just got bitten by what _looked_ like a bug in mingw, but actually
turned out to be an error in the accidental incorrect use of
__declspec(export) and __declspec(import).

example source.

The situation is this:

dll1:
    int x;
    int *get_x_by_addr() { return &x; }

dll2:
    test()
    {
        printf("%d\n", x);
        printf("%d\n", *get_x_by_addr());
    }

test.exe:
    main()
    {
        test();
        printf("%d\n", x);
        printf("%d\n", *get_x_by_addr());
    }

In other words, there's a first dll with a variable x that you want
to access from the second dll and also from the main executable.

Initial tests gave a completely screwed up address for x, in the
second dll.  Looking at the assembly code (see Makefile:
gcc -S test.c -o test.S) showed that yes, whilst test.exe was using a
reference to __imp_x, dll2.S showed something _completely_ wild:
--export:x,data references at the end of the assembly-code output,
and direct reference to "x" - no mention of __imp_x at all.

I was doing the usual "-DBUILD_CORE" trick which enables adding
of __declspec(dllexport) or __declspec(dllimport) around variables,
such that you define BUILD_CORE for the build of the dll and _don't_
define BUILD_CORE for when you access it.... so what the heck was wrong?

Well, it turns out that I was enabling the __declspec(dllexport)
on x *inside dll2* as WELL as inside dll1, and given that x is ONLY
exported from dll1, that's clearly wrong.

The same error, it turns out, is "coped with" on functions.  If you
accidentally do the wrong thing on exported functions,  mingw magically
sorts itself out and still manages to call __imp_{yourfunction}, but
for data, it does what you ask: declares a data export reference to
the variable which is _actually_ in another dll.

The reason why I'm writing this up is because it's very rare that
data is exported from dlls.  Standard practice is to create and
export a function which returns a pointer to the address of the
data.  It's even _more_ rare to have data in one dll that is
used by another dll, and, if you get it wrong, mingw won't give
you *any* assistance, it will cheerfully let you shoot yourself
in the foot.

The solution is to create _two_ -DBUILD_CORE_XXX #defines: one
for dll1, and one for dll2.  It sounds obvious - but it certainly
didn't _seem_ obvious at the time.  The first -DBUILD_CORE_DLL1
should only be enabled for building dll1, and, apparently-obviously,
-DBUILD_CORE_DLL2 for the second.

It's dll2 where things get interesting, because you end up with
__declspec(dllimport) around the variable x, and __declspec(dllexport)
around the function test().  Which, when you think about it, is
the correct thing to do!

So - word to the wise: take care of your dllimports and dllexports!