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?
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
--enable-shared
)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.