0

​ Hi,

I've recently come across a link issue that I cannot explain.

Here is an example that couldn't really be simpler:

sc_main.cpp:

#include <systemc.h>

int sc_main (int argc, char* argv[])
{
  sc_start(SC_ZERO_TIME);
  return(0);
} 

I use the following to compile and link, with winlibs-x86_64-posix-seh-gcc-10.2.0-mingw-w64-8.0.0-r7.7z:

g++ -pthread main_sc.cpp -o main_sc.exe -s $(LDFLAGS) -I$(SYSTEMC_HOME)/include -L$(SYSTEMC_HOME)/lib-mingw64 -lsystemc

Now, because I'm targeting Win64, and because I want to make an executable without any dependence on MinGW-64 run-time libraries, there are a number of possible settings that I've been looking at:

Option 1 - LDFLAGS := -static
Option 2 - LDFLAGS := -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic
Option 3 - LDFLAGS := -static-libgcc -static-libstdc++ -Wl,-Bstatic,--whole-archive -lpthread -Wl,-Bdynamic -Wl,--no-whole-archive

At this point, sometimes it works, sometimes it doesn't, depending on the SystemC release I'm using:

SytemC 2.3.2 + Option 1 : fine
SytemC 2.3.3 + Option 1 : libsystemc.a(sc_prim_channel.o):sc_prim_channel.cpp:(.text+0x44): undefined reference to `__imp_pthread_mutex_unlock'
                          libsystemc.a(sc_prim_channel.o):sc_prim_channel.cpp:(.text$_ZN7sc_core13sc_host_mutex6unlockEv[_ZN7sc_core13sc_host_mutex6unlockEv]+0xa): undefined reference to `__imp_pthread_mutex_unlock'
                          libsystemc.a(sc_prim_channel.o):sc_prim_channel.cpp:(.text$_ZN7sc_core17sc_host_semaphore7trywaitEv[_ZN7sc_core17sc_host_semaphore7trywaitEv]+0x2f): undefined reference to `__imp_pthread_mutex_unlock'

but

SytemC 2.3.2 + Option 2 or 3 : fine
SytemC 2.3.3 + Option 2 or 3 : libpthread.dll.a(d000077.o):(.text+0x0): multiple definition of `pthread_mutex_unlock' ; mingw-w64-v8.0.0/mingw-w64-libraries/winpthreads/src/mutex.c:207: first defined here

 

Note that I the toolchain I am using is based on gcc 10.2.0 but that's not relevant. I only used this toolchain because it's based on the latest MinGW libraries (8.0.0)

In fact, I have generated my own (cross-compilation) toolchain (running on linux), based on the same MinGW 8.0.0 libraries and on gcc 6.3.0 and I'm seeing the exact same results.

Any idea what's going on ? Am I doing anything wrong ? I'm not too sure if the issue has to do with SystemC or with GCC/winpthreads, but I'm tempted to think that SystemC can be exonerated. So who's to blame, and is there a workaround ?

DaveC
  • 115
  • 8
  • Do not specify `-lpthread` among the `LDFLAGS`. The `-pthread` option to `g++` already tells it to link all libraries needed to support pthreads. – John Bollinger Feb 13 '21 at 17:28
  • The diagnostics for "SytemC 2.3.3 + Option 1" give the appearance that the SystemC static library you are trying to use was built against a version of libpthread that is incompatible with the one you are using. The diagnostics in the option 2 / 3 case could be related to having both `-pthread` and `-lpthread` on the link command line, but if so, then it is unclear to me why the link succeeds with SystemC 2.3.2 + option 2 / 3. – John Bollinger Feb 13 '21 at 17:35
  • Thanks for the suggestions... Unfortunately removing the (compile) option `-phread` and only leaving the (link) option `-lpthread` doesn't change the results. Exact same behavior. – DaveC Feb 16 '21 at 16:45
  • remove `-lpthread`. Keep `-pthread`. This is the right thing to do, even if it does not change the observed result in your particular case. – John Bollinger Feb 16 '21 at 17:59
  • Thanks ! what you're saying is consistent with what I just read [here](https://stackoverflow.com/questions/20673370/why-do-we-write-d-reentrant-while-compiling-c-code-using-threads/20673493#20673493) and [there](https://stackoverflow.com/questions/2127797/significance-of-pthread-flag-when-compiling). My example ended up with both `-pthread` and `-lpthread` because it's so simple (compiles and links at the same time) but my Makefile was initially more complicated as it had separate compile and link stages. – DaveC Feb 16 '21 at 21:22
  • I've just investigated the possibility that my SystemC static library was built against a version of libpthread that is incompatible with the one I am using. That seems pretty likely. This library was built (a long time ago) under MSys2, and the toolchain may have been based on a different version of the MinGW-64 libraries (which would explain the issue) – DaveC Feb 16 '21 at 21:35
  • Under MSys2 it's not it's not straightforward to use a very specific toolchain (e.g. [the one I'm using for my example](https://github.com/brechtsanders/winlibs_mingw/releases/download/10.2.0-11.0.0-8.0.0-r7/winlibs-x86_64-posix-seh-gcc-10.2.0-mingw-w64-8.0.0-r7.7z)). However it is straightforward to do that using CMake, so I embarked on the task to rebuild my SystemC library under CMake. Unfortunately, out of the box, the CMake infrastructure in SystemC doesn't support building with posix threads on Windows... But with a few hacks I managed to do it.... and my link issue is now gone :-) – DaveC Feb 16 '21 at 21:49
  • One mystery remains though. Using my cross-compilation toolchain (host linux, target win64), I'm still getting the behavior described in the OP, although the SystemC libraries were built with the exact same toolchain I'm using to compile & link the main_sc.cpp example. – DaveC Feb 16 '21 at 22:02
  • I'm glad you've made some progress, but I'm afraid I have no further insight for you. Except that with GCC, you should use `-pthread` (and not `-lpthread`) for both compiling and linking. Including if you have separate compile and link steps. – John Bollinger Feb 17 '21 at 00:29
  • As far as I know, the SystemC library builds on Windows using either MinGW/MSVC uses the Fiber implementation to handle user-space threading. You would encounter quite a lot of performance penalties for enabling the pthread implementation. – AmeyaVS Jun 08 '21 at 12:25

1 Answers1

0

The behavior reported in the OP is only observed when SystemC libraries are cross-compiled for Windows, using the configure based flow.

When the SystemC libraries are cross-compiled using the cmake based flow, or when they are natively compiled on Windows, then everything works as expected.

The different behavior between SytemC 2.3.2 and 2.3.3 is explained by the fact that 2.3.2 does not include <pthread.h> (but relies on Windows Semaphore), whereas 2.3.3 does (via the inclusion of <mutex>) which exposes the issue mentioned here.

DaveC
  • 115
  • 8