Проблема со связью в Windows с pthreads — виноваты gcc или SystemC?

​ Hi,

Недавно я столкнулся с проблемой связи, которую не могу объяснить.

Вот пример, который не может быть проще:

sc_main.cpp:

#include <systemc.h>

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

Я использую следующее для компиляции и связывания с winlibs-x86_64-posix-seh-gcc-10.2.0-mingw-w64-8.0.0- р7.7з:

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

Теперь, поскольку я ориентируюсь на Win64 и хочу создать исполняемый файл без какой-либо зависимости от библиотек времени выполнения MinGW-64, есть ряд возможных настроек, которые я рассматривал:

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

На данный момент иногда это работает, иногда нет, в зависимости от версии SystemC, которую я использую:

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'

но

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

 

Обратите внимание, что набор инструментов, который я использую, основан на gcc 10.2.0, но это не имеет значения. Я использовал этот набор инструментов только потому, что он основан на последних библиотеках MinGW (8.0.0).

На самом деле, я создал свой собственный (кросс-компиляционный) набор инструментов (работающий в Linux), основанный на тех же библиотеках MinGW 8.0.0 и gcc 6.3.0, и я вижу точно такие же результаты.

Любая идея, что происходит? Я делаю что-то не так? Я не слишком уверен, связана ли проблема с SystemC или с GCC/winpthreads, но я склонен думать, что SystemC можно реабилитировать. Так кто виноват, и есть ли обходной путь?


person DaveC    schedule 13.02.2021    source источник
comment
Не указывайте -lpthread среди LDFLAGS. Параметр -pthread для g++ уже говорит ему связать все библиотеки, необходимые для поддержки pthreads.   -  person John Bollinger    schedule 13.02.2021
comment
Диагностика для SytemC 2.3.3 + вариант 1 создает впечатление, что статическая библиотека SystemC, которую вы пытаетесь использовать, была создана для версии libpthread, несовместимой с той, которую вы используете. Диагностика в случае варианта 2/3 могла быть связана с наличием и -pthread, и -lpthread в командной строке ссылки, но если это так, то мне непонятно, почему ссылка успешно работает с SystemC 2.3.2 + вариант 2/3.   -  person John Bollinger    schedule 13.02.2021
comment
Спасибо за предложения... К сожалению, удаление опции (компиляции) -phread и оставление только опции (ссылки) -lpthread не меняет результаты. Точно такое же поведение.   -  person DaveC    schedule 16.02.2021
comment
удалить -lpthread. Держите -pthread. Это правильно, даже если это не меняет наблюдаемый результат в вашем конкретном случае.   -  person John Bollinger    schedule 16.02.2021
comment
Спасибо ! то, что вы говорите, согласуется с тем, что я только что прочитал -threads/20673493#20673493">здесь и здесь. Мой пример закончился как -pthread, так и -lpthread, потому что он такой простой (компилирует и связывает одновременно), но мой Makefile изначально был более сложным, поскольку имел отдельные этапы компиляции и компоновки.   -  person DaveC    schedule 17.02.2021
comment
Я только что исследовал возможность того, что моя статическая библиотека SystemC была создана для версии libpthread, несовместимой с той, которую я использую. Это кажется вполне вероятным. Эта библиотека была построена (давно) под MSys2, и цепочка инструментов могла быть основана на другой версии библиотек MinGW-64 (что объясняет проблему).   -  person DaveC    schedule 17.02.2021
comment
В MSys2 не так просто использовать очень конкретную цепочку инструментов (например, тот, который я использую для своего примера). Однако это легко сделать с помощью CMake, поэтому я приступил к задаче по перестройке моей библиотеки SystemC под CMake. К сожалению, стандартная инфраструктура CMake в SystemC не поддерживает сборку с потоками posix в Windows... Но с помощью нескольких хаков мне удалось это сделать.... и моя проблема со ссылками исчезла :-)   -  person DaveC    schedule 17.02.2021
comment
Однако остается одна загадка. Используя мою цепочку инструментов для кросс-компиляции (хост linux, целевой win64), я все еще получаю поведение, описанное в OP, хотя библиотеки SystemC были созданы с использованием той же самой цепочки инструментов, которую я использую для компиляции и связывания примера main_sc.cpp. .   -  person DaveC    schedule 17.02.2021
comment
Я рад, что вы добились некоторого прогресса, но, боюсь, у меня нет для вас дальнейших идей. За исключением того, что с GCC вы должны использовать -pthread (а не -lpthread) как для компиляции, так и для компоновки. В том числе, если у вас есть отдельные этапы компиляции и компоновки.   -  person John Bollinger    schedule 17.02.2021
comment
Насколько я знаю, библиотека SystemC построена на Windows с использованием MinGW/MSVC, использующих реализацию Fiber для обработки потоков в пользовательском пространстве. Вы столкнетесь с довольно большим снижением производительности при включении реализации pthread.   -  person AmeyaVS    schedule 08.06.2021