mingw-w64systemcmxe

Cross-compiling SystemC libraries and linking to them


I'm starting from scratch and am following the main steps below:

1. Build and install a cross-compiler toolchain (host Linux, target Win64):

Get this MXE version, only changing plugins/gcc6/gcc6-overlay.mk with:

$(PKG)_VERSION  := 6.3.0
$(PKG)_CHECKSUM := f06ae7f3f790fbf0f018f6d40e844451e6bc3b7bc96e128e63b09825c1f8b29f

Then it's simple (only takes some time, use make --jobs=X JOBS=Y to speed up):

setenv MXE_SRC /path/to/where/you/extracted/mxe

cd $MXE_SRC
make MXE_TARGETS='x86_64-w64-mingw32.shared x86_64-w64-mingw32.static' MXE_PLUGIN_DIRS=plugins/gcc6 pthreads
setenv PATH $MXE_SRC/usr/bin:$PATH

2. Cross-compile and install the SystemC 2.3.3 libraries

This is just as simple (but a lot quicker!):

setenv SYSTEMC_SRC                  /path/to/where/you/extracted/systemc/
setenv SYSTEMC_STATICTOOLCHAIN_DEST /this/is/your/choice

cd $SYSTEMC_SRC
./configure --prefix=$SYSTEMC_STATICTOOLCHAIN_DEST --host=x86_64-w64-mingw32.static
make install

3. Build a trivial executable

Write a few lines of code in sc_main.cpp:

#include "systemc.h"

int sc_main (int argc, char* argv[])
{
  sc_clock clk("CLOCK", 1, SC_NS, 0.5);
  sc_start();
  return 0;
}

Now building with one final step:

x86_64-w64-mingw32.static-g++ sc_main.cpp -I$SYSTEMC_STATICTOOLCHAIN_DEST/include -L$SYSTEMC_STATICTOOLCHAIN_DEST/lib-mingw64 -lsystemc

I get a whole bunch of

libsystemc.a(sc_prim_channel.o):sc_prim_channel.cpp:(.text+0x44): undefined reference to `__imp_pthread_mutex_unlock'

(and variants of the same).

Can anyone reproduce and explain what's going on?

When the SystemC configure completes, it clearly says that it's not going to use Posix threads but WinFiber instead, so I'm a bit surprised to see these unresolved dependencies to phread (for the record, adding -lpthread at the end of the command line still produces the same result)

4. Bonus experiments building SystemC libraries in different ways

If I use a native Win64 toolchain to build SystemC libraries and then build my executable with the same command line:

 setenv SYSTEMC_NATIVETOOLCHAIN_DEST /path/to/systemc/libraries/built/with/native/toolchain
 x86_64-w64-mingw32.static-g++ sc_main.cpp -I$SYSTEMC_NATIVETOOLCHAIN_DEST/include -L$SYSTEMC_NATIVETOOLCHAIN_DEST/lib-mingw64 -lsystemc

then everything works nicely, as expected.

Also, if I cross-compile and install the SystemC libraries using cmake rather than configure:

cd $SYSTEMC_SRC
mkdir build && cd build && x86_64-w64-mingw32.static-cmake .. -DBUILD_SHARED_LIBS=OFF -DCMAKE_CXX_STANDARD=14 -DINSTALL_TO_LIB_TARGET_ARCH_DIR=ON -DCMAKE_INSTALL_PREFIX=$SYSTEMC_STATICTOOLCHAIN_DEST
make install

x86_64-w64-mingw32.static-g++ sc_main.cpp -I$SYSTEMC_STATICTOOLCHAIN_DEST/include -L$SYSTEMC_STATICTOOLCHAIN_DEST/lib-mingw64 -lsystemc

then, again, everything works nicely, as expected.

I have a suspicion that SystemC libraries aren't generated properly when cross-compiled. Can anyone confirm/deny?


Solution

  • In the last couple of days I've learnt a lot about libtool and how DLLEXPORT is meant to be used in a consistent manner.

    It has made me realize that the root cause of the problem is the end-user (myself), as always...

    To be fair, there is something inconsistent in the configure script that ships with SystemC. The below:

    ./configure --host=x86_64-w64-mingw32.static
    

    It makes the end-user believe that everything is fine... when it isn't.

    Once you understand that and you explicitly specify settings that are consistent with building a static library:

    ./configure --host=x86_64-w64-mingw32.static --disable-shared
    

    then everything works just fine.

    The SystemC cmake flow is more robust. It throws an error if you try to target Windows using the default settings, which leaves you no choice but to specify -DBUILD_SHARED_LIBS=OFF on the command line.