我从零开始,遵循以下主要步骤:
1.构建并安装交叉编译器工具链(主机Linux,目标Win64):
获取此MXE版本,仅用以下内容更改plugins/gcc6/gcc6-overlay.mk:
$(PKG)_VERSION := 6.3.0
$(PKG)_CHECKSUM := f06ae7f3f790fbf0f018f6d40e844451e6bc3b7bc96e128e63b09825c1f8b29f然后很简单(只需一些时间,使用make --jobs=X JOBS=Y来加快速度):
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:$PATH2.交叉编译和安装 SystemC 2.3.3库
这也同样简单(但要快得多):
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 install3.构建一个简单的可执行
用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;
}现在用最后一步进行建设:
x86_64-w64-mingw32.static-g++ sc_main.cpp -I$SYSTEMC_STATICTOOLCHAIN_DEST/include -L$SYSTEMC_STATICTOOLCHAIN_DEST/lib-mingw64 -lsystemc我得到了一堆
libsystemc.a(sc_prim_channel.o):sc_prim_channel.cpp:(.text+0x44): undefined reference to `__imp_pthread_mutex_unlock'(及同一变体)。
有人能复制并解释发生了什么吗?
当SystemC configure完成时,它明确表示它不会使用Posix线程,而是使用WinFiber,所以我有点惊讶地看到这些未解决的依赖项被phread读取(对于记录,在命令行末尾添加-lpthread仍然产生相同的结果)
4.以不同方式构建SystemC库的额外实验()
如果我使用原生Win64工具链构建SystemC库,然后使用相同的命令行构建可执行文件:
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然后一切运行良好,正如预期的那样。
另外,如果我交叉编译和安装SystemC库,则使用cmake而不是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然后,再一次,一切运行良好,正如预期。
我怀疑在交叉编译时没有正确生成SystemC库。有人能证实/否认吗?
发布于 2021-09-21 00:53:17
在过去的几天里,我学到了很多关于libtool和DLLEXPORT是如何以一致的方式使用的的知识。
它使我意识到,问题的根源是最终用户(我自己),一如既往.
公平地说,在configure脚本中,SystemC附带了一些不一致的内容。以下是:
./configure --host=x86_64-w64-mingw32.static--enable-shared)。它让最终用户相信一切都很好.但事实并非如此。
一旦理解并显式指定了与构建静态库一致的设置:
./configure --host=x86_64-w64-mingw32.static --disable-shared那一切都很正常。
SystemC cmake流更健壮。如果试图使用默认设置锁定Windows,则会引发错误,这使您别无选择,只能在命令行中指定-DBUILD_SHARED_LIBS=OFF。
发布于 2021-09-16 15:13:18
这不是一个正确的答案,但至少我可以描述导致问题的端到端机制。我还不太熟悉MingW,winpthread等的所有错综复杂之处.说出到底是谁做错了什么,但我会让专家来做;-)
所以,这一切都是从SystemC的configure开始的,它生成了定义DLL_EXPORT的Makefiles菜谱。乍一看,定义DLL_EXPORT似乎是相当合法的,因为目标是构建一个库。
但是实际上,在SystemC的代码中没有引用DLL_EXPORT,所以不太清楚它的意图是什么(事实上,SystemC的cmake-based flow并没有定义它)。不过,如果我相信configure中的评论,这是一种有充分理由的黑客攻击。
接下来,在编译SystemC源文件时,mingw-w64-libraries/winpthreads/include/pthread.h会在某个时候被包含(通过sc_host_mutex.h和<mutex>)。
此时,编译器将看到以下内容:
#if defined DLL_EXPORT
# ifdef IN_WINPTHREAD
# define WINPTHREAD_API __declspec(dllexport)
# else
# define WINPTHREAD_API __declspec(dllimport)
# endif
#else
# define WINPTHREAD_API
#endif注意,mingw-w64-libraries/winpthreads/include/sched.h和mingw-w64-libraries/winpthreads/include/semaphore.h中有类似的代码
假设没有定义IN_WINPTHREAD (我猜在构建libwinpthread.dll时是正确的),则从SystemC库调用library被声明为'dllimport‘,这最终导致了臭名昭著的结果:
libsystemc.a(sc_prim_channel.o):sc_prim_channel.cpp:(.text+0x44): undefined reference to `__imp_pthread_mutex_unlock'我想知道混合W64头的意图是否有点不同,也许是这样的:
#ifdef IN_WINPTHREAD
# if defined DLL_EXPORT
# define WINPTHREAD_API __declspec(dllexport)
# else
# define WINPTHREAD_API __declspec(dllimport)
# endif
#else
# define WINPTHREAD_API
#endif 甚至是
#if defined DLL_EXPORT
# ifdef IN_WINPTHREAD
# define WINPTHREAD_API __declspec(dllexport)
# else
# define WINPTHREAD_API
# endif
#else
# define WINPTHREAD_API
#endif最终,我无法在以下两项之间作出决定:
configure不应该定义DLL_EXPORTpthread.h应该提供一种不同的机制,这样对perhaps的调用就不会自动转换为“dllimport”,而是默认为正常的静态链接(也可以引入带有DLL_IMPORT的显式机制)。https://stackoverflow.com/questions/69171109
复制相似问题