[Boost-users] cross-compilation x86_64-w64-ming32: undefined reference to `InterlockedIncrement'

658 views
Skip to first unread message

Frédéric Bron

unread,
Aug 16, 2013, 3:40:59 AM8/16/13
to boost-users
Hi,

I am trying to cross-compile from linux 64 bits to windows 64 bits. I
am using fedora 19 with -std=c++11 and boost 1.53.0 that comes with
fedora. The compiler is x86_64-w64-mingw32-g++.
The compile flags I use: -O3 -DNDEBUG -DWINDOWS -std=c++11 -Wall
-Wextra -pipe -ffloat-store -DBOOST_DISABLE_ASSERTS
-DBOOST_FILESYSTEM_VERSION=3 -DBOOST_FILESYSTEM_NO_DEPRECATED
-DBOOST_THREAD_USE_LIB
and a typical link command:
$ x86_64-w64-mingw32-g++ -o foo.exe bar1.o bar2.o
-Wl,--enable-auto-import -static -lboost_system-mt
-lboost_filesystem-mt -lboost_thread-mt -lboost_chrono-mt -mthreads

I then get the following errors (each line multiple times with
different .text+0x###):
/usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libboost_thread-mt.a(thread.o):(.text+0x286):
undefined reference to `InterlockedIncrement'
/usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libboost_thread-mt.a(thread.o):(.text+0x3e7):
undefined reference to `InterlockedDecrement'
/usr/lib64/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld:
/usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libboost_thread-mt.a(thread.o):
bad reloc address 0x8 in section `.data'
collect2: error: ld returned 1 exit status
make: *** [mgw64-release/bin/transpose.exe] Erreur 1

I see that this may come from <boost/detail/interlocked.hpp> but I
have no idea what this header is used for.

This is what remains after the pre-processor phase (g++ -E):

# 1 "/usr/x86_64-w64-mingw32/sys-root/mingw/include/boost/detail/interlocked.hpp"
1 3 4
# 137 "/usr/x86_64-w64-mingw32/sys-root/mingw/include/boost/detail/interlocked.hpp"
3 4
namespace boost {
namespace detail {
extern "C" long InterlockedIncrement( long volatile * );
extern "C" long InterlockedDecrement( long volatile * );
extern "C" long InterlockedCompareExchange( long volatile *, long, long );
extern "C" long InterlockedExchange( long volatile *, long );
extern "C" long InterlockedExchangeAdd( long volatile *, long );
extern "C" void* InterlockedCompareExchangePointer( void* volatile *,
void*, void* );
extern "C" void* InterlockedExchangePointer( void* volatile *, void* );
}
}

Note that targeting windows 32 bits works allright but the result of
the pre-processor phase is slightly different:

# 1 "/usr/i686-w64-mingw32/sys-root/mingw/include/boost/detail/interlocked.hpp"
1 3 4
# 137 "/usr/i686-w64-mingw32/sys-root/mingw/include/boost/detail/interlocked.hpp"
3 4
namespace boost {
namespace detail {
extern "C" __attribute__((dllimport)) long
__attribute__((__stdcall__)) InterlockedIncrement( long volatile * );
extern "C" __attribute__((dllimport)) long
__attribute__((__stdcall__)) InterlockedDecrement( long volatile * );
extern "C" __attribute__((dllimport)) long
__attribute__((__stdcall__)) InterlockedCompareExchange( long volatile
*, long, long );
extern "C" __attribute__((dllimport)) long
__attribute__((__stdcall__)) InterlockedExchange( long volatile *,
long );
extern "C" __attribute__((dllimport)) long
__attribute__((__stdcall__)) InterlockedExchangeAdd( long volatile *,
long );
}
}

Frédéric
_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users

Frédéric Bron

unread,
Sep 7, 2013, 1:35:58 AM9/7/13
to Matt Clarkson, boost-users, boost...@googlegroups.com
> I have exactly the same issue with MinGW-builds gcc-4.8.1-x86_64-posix-seh
> building boost 1.54.0. It also crashes cxx1plus.exe as I build it (which is
> probably another problem).
> Did you manage to construct a workaround?

Well I stopped working on that. I was expecting that somebody could
help with the content of <boost/detail/interlocked.hpp> but got no
answer.

I imagine that
extern "C" long InterlockedIncrement( long volatile * );
should be
extern "C" __attribute__((dllimport)) long
__attribute__((__stdcall__)) InterlockedIncrement( long volatile * );
as it is in 32 bits.

I have now looked a bit further: among the preprocessor variable
checked in <boost/detail/interlocked.hpp>, here are the differences
when compiling with i686-w64-mingw32-g++ or x86_64-w64-mingw32-g++:

1. in both cases, the following variables are undefined:
WIN32 __CYGWIN__ MINGW64 _M_IA64 BOOST_MSVC BOOST_INTEL_WIN _WIN32_WCE _MSC_VER

2. in both cases, the following variables are defined with value 1:
_WIN32 __WIN32

3. variable _M_AMD64 is undefined with i686-w64-mingw32-g++ and
defined with value 100 with x86_64-w64-mingw32-g++.

Does this help? In particular, is it normal that _WIN32 and __WIN32
are defined when targetting win64? Is it normal that MINGW64 is always
undefined although I use a W64 compiler?

Vicente J. Botet Escriba

unread,
Sep 7, 2013, 3:31:41 AM9/7/13
to boost...@lists.boost.org
Le 07/09/13 07:35, Frédéric Bron a écrit :
Hi,

I suspect you mean __MINGW64__.

#if defined(__MINGW64__)
#define BOOST_INTERLOCKED_IMPORT
#else
#define BOOST_INTERLOCKED_IMPORT __declspec(dllimport)
#endif

If not. Could you check if __MINGW64__ is defined?

Best,
Vicente

Frédéric Bron

unread,
Sep 7, 2013, 6:33:09 AM9/7/13
to boost-users
>> 1. in both cases, the following variables are undefined:
>> WIN32 __CYGWIN__ MINGW64 _M_IA64 BOOST_MSVC BOOST_INTEL_WIN _WIN32_WCE
>> _MSC_VER
>>
>> 2. in both cases, the following variables are defined with value 1:
>> _WIN32 __WIN32
>>
>> 3. variable _M_AMD64 is undefined with i686-w64-mingw32-g++ and
>> defined with value 100 with x86_64-w64-mingw32-g++.
>>
>> Does this help? In particular, is it normal that _WIN32 and __WIN32
>> are defined when targetting win64? Is it normal that MINGW64 is always
>> undefined although I use a W64 compiler?
>>
> I suspect you mean __MINGW64__.
>
> If not. Could you check if __MINGW64__ is defined?

sorry, you're right __MINGW64__ is used in the code and it is
undefined with i686-w64-mingw32-g++ and defined and equal to 1 with
x86_64-w64-mingw32-g++.

Cheers,

Frédéric

Vicente J. Botet Escriba

unread,
Sep 7, 2013, 8:48:45 AM9/7/13
to boost...@lists.boost.org
Le 07/09/13 12:33, Frédéric Bron a écrit :
>>> 1. in both cases, the following variables are undefined:
>>> WIN32 __CYGWIN__ MINGW64 _M_IA64 BOOST_MSVC BOOST_INTEL_WIN _WIN32_WCE
>>> _MSC_VER
>>>
>>> 2. in both cases, the following variables are defined with value 1:
>>> _WIN32 __WIN32
>>>
>>> 3. variable _M_AMD64 is undefined with i686-w64-mingw32-g++ and
>>> defined with value 100 with x86_64-w64-mingw32-g++.
>>>
>>> Does this help? In particular, is it normal that _WIN32 and __WIN32
>>> are defined when targetting win64? Is it normal that MINGW64 is always
>>> undefined although I use a W64 compiler?
>>>
>> I suspect you mean __MINGW64__.
>>
>> If not. Could you check if __MINGW64__ is defined?
> sorry, you're right __MINGW64__ is used in the code and it is
> undefined with i686-w64-mingw32-g++ and defined and equal to 1 with
> x86_64-w64-mingw32-g++.
>
I have no idea why this was added
(https://svn.boost.org/trac/boost/changeset/70383).

Could you try commenting so that

#define BOOST_INTERLOCKED_IMPORT __declspec(dllimport)

?

Could some one clarify why this was needed?

Best,
Vicente

Frédéric Bron

unread,
Sep 7, 2013, 4:21:25 PM9/7/13
to boost-users
> Could you try commenting so that
> #define BOOST_INTERLOCKED_IMPORT __declspec(dllimport)
> ?

So I forced that:
#define BOOST_INTERLOCKED_IMPORT __declspec(dllimport)
I rebuilt boost with the following commands:
CC=x86_64-w64-mingw32-gcc\
CXX=x86_64-w64-mingw32-g++\
./bootstrap.sh --without-icu --prefix=build --with-toolset=gcc
echo "using gcc : : x86_64-w64-mingw32-g++ :
<compileflags>-DBOOST_THREAD_USE_LIB ;" > user-config.jam
mkdir build
./b2 -d2 -j8 --layout=system --user-config=user-config.jam
--without-mpi --without-python\
link=static\
threading=multi\
runtime-link=shared\
address-model=64\
instruction-set=nocona\
target-os=windows\
threadapi=win32\
variant=release\
install > build/build.log 2>&1


but still got the following error:
x86_64-w64-mingw32-g++ -o mgw64-release/obj/Tests/xuxu2.o -c -O3
-DNDEBUG -DWINDOWS -std=c++11 -Wall -Wextra -pipe -ffloat-store
-I/home/fred/boost-1.54.0/include -DBOOST_DISABLE_ASSERTS
-DBOOST_FILESYSTEM_VERSION=3 -DBOOST_FILESYSTEM_NO_DEPRECATED
-DBOOST_THREAD_USE_LIB -I. Tests/xuxu2.cc
x86_64-w64-mingw32-g++ -o mgw64-release/bin/xuxu2.exe
mgw64-release/obj/Tests/xuxu2.o -Wl,--enable-auto-import -static
-L/home/fred/boost-1.54.0/lib -lboost_thread-mt -lboost_system-mt
-mthreads
mgw64-release/obj/Tests/xuxu2.o:xuxu2.cc:(.text$_ZN5boost6threadD1Ev[_ZN5boost6threadD1Ev]+0x1a):
undefined reference to `InterlockedDecrement'
mgw64-release/obj/Tests/xuxu2.o:xuxu2.cc:(.text.startup+0xf6):
undefined reference to `InterlockedIncrement'
/usr/lib64/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld:
mgw64-release/obj/Tests/xuxu2.o: bad reloc address 0xf6 in section
`.text.startup'
collect2: error: ld returned 1 exit status

I have also made a minimal example so that anybody can test:
#include <iostream>
#include <boost/thread.hpp>
struct Runner {
void operator()() const { std::cout<<"Runner::operator()\n"; }
};
int main(int, char*[]) {
Runner r;
boost::thread t1(r);
t1.join();
return 0;
}

Cheers,

Frédéric

Vitaly Budovski

unread,
Sep 8, 2013, 1:11:02 AM9/8/13
to boost...@lists.boost.org
On 8 September 2013 06:21, Frédéric Bron <freder...@m4x.org> wrote:
mgw64-release/obj/Tests/xuxu2.o:xuxu2.cc:(.text$_ZN5boost6threadD1Ev[_ZN5boost6threadD1Ev]+0x1a):
undefined reference to `InterlockedDecrement'
mgw64-release/obj/Tests/xuxu2.o:xuxu2.cc:(.text.startup+0xf6):
undefined reference to `InterlockedIncrement'
/usr/lib64/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld:
mgw64-release/obj/Tests/xuxu2.o: bad reloc address 0xf6 in section
`.text.startup'
collect2: error: ld returned 1 exit status

I have also made a minimal example so that anybody can test:
#include <iostream>
#include <boost/thread.hpp>
struct Runner {
                void operator()() const { std::cout<<"Runner::operator()\n"; }
};
int main(int, char*[]) {
        Runner r;
        boost::thread t1(r);
        t1.join();
        return 0;
}

Cheers,

Frédéric

Hi,

It looks like boost needs to handle the mingw case differently. See this thread and the patch within it.
http://sourceforge.net/mailarchive/message.php?msg_id=31189847

I haven't had time to test whether it resolves the issue, but try it out and let us know.


Cheers,

Vitaly

Frédéric Bron

unread,
Sep 8, 2013, 4:18:58 PM9/8/13
to boost-users
> It looks like boost needs to handle the mingw case differently. See this
> thread and the patch within it.
> http://sourceforge.net/mailarchive/message.php?msg_id=31189847
>
> I haven't had time to test whether it resolves the issue, but try it out and
> let us know.

So I tried to apply this patch to 1.54.0:
http://sourceforge.net/mailarchive/attachment.php?list_name=mingw-w64-public&message_id=1374418938.8920.43.camel%40erik-laptop.terneuzen.vanpienbroek.nl&counter=1

But this did not solve my issue with "undefined reference to
`InterlockedDecrement'".

Frédéric Bron

unread,
Sep 19, 2013, 3:39:04 PM9/19/13
to Matt Clarkson, boost-users, boost...@googlegroups.com
> Solved this by adding define=BOOST_USE_WINDOWS_H and that forces the include
> of windows.h and as such the different types of InterlockedIncrement.

I tried that and it worked until I realized that including windows.h
causes me lots of troubles in another library (wxWidgets) so that I
cannot use this solution. What is in windows.h that should be copied
in interlocked.hpp? I start to be desperate to build a 64 bit version
of my program with mingw-w64... also, it is difficult because I have
absolutly no idea of what these interlocked... mean.

Regards,

Frédéric Bron

unread,
Sep 23, 2013, 6:13:51 AM9/23/13
to boost-users, bo...@lists.boost.org
So I eventually managed to fix the issue with interlocked.hpp and
mingw-w64: both i686 and x86_64 now work.
Attached is a patch against 1.54.0.
Is it possible to include this in 1.55.0?
Regards,
Frédéric
interlocked.diff

Frédéric Bron

unread,
Sep 23, 2013, 6:46:39 AM9/23/13
to bo...@lists.boost.org, boost-users
> I probably missed the original problem, but the patch doesn't look correct
> to me. The section guarded with "defined( BOOST_MSVC ) || defined(
> BOOST_INTEL_WIN )" is obviously targeted for compilers supporting
> interlocked intrinsics, which gcc isn't. MinGW should probably be handled
> by the last section of the #if/elif/endif sequence. Anyway, what problem
> are you trying to fix?

Here is what I get when build an application with boost and mingw-w64
targeting x86_64:

/usr/x86_64-w64-mingw32/sys-
root/mingw/lib/../lib/libboost_thread-mt.a(thread.o):(.text+0x286):
undefined reference to `InterlockedIncrement'
/usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libboost_thread-mt.a(thread.o):(.text+0x3e7):
undefined reference to `InterlockedDecrement'
/usr/lib64/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld:
/usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libboost_thread-mt.a(thread.o):
bad reloc address 0x8 in section `.data'

I have been able to solve this by defining BOOST_USE_WINDOWS_H but
this creates issues with Unicode when I also use wxWidgets. The patch
proposed solves the issue. I recognise that I say that gcc should be
considered as MSVC with regards to these Interlocked things which I do
not understand. It may seem strange but it works. What's wrong with
it? Basically, I just #include <intrin.h>; what's wrong with that?
Reply all
Reply to author
Forward
0 new messages