首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >交叉编译SystemC库并链接到它们

交叉编译SystemC库并链接到它们
EN

Stack Overflow用户
提问于 2021-09-14 02:25:57
回答 2查看 485关注 0票数 1

我从零开始,遵循以下主要步骤:

1.构建并安装交叉编译器工具链(主机Linux,目标Win64):

获取此MXE版本,仅用以下内容更改plugins/gcc6/gcc6-overlay.mk

代码语言:javascript
运行
复制
$(PKG)_VERSION  := 6.3.0
$(PKG)_CHECKSUM := f06ae7f3f790fbf0f018f6d40e844451e6bc3b7bc96e128e63b09825c1f8b29f

然后很简单(只需一些时间,使用make --jobs=X JOBS=Y来加快速度):

代码语言:javascript
运行
复制
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.交叉编译和安装 SystemC 2.3.3库

这也同样简单(但要快得多):

代码语言:javascript
运行
复制
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.构建一个简单的可执行

sc_main.cpp编写几行代码

代码语言:javascript
运行
复制
#include "systemc.h"

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

现在用最后一步进行建设:

代码语言:javascript
运行
复制
x86_64-w64-mingw32.static-g++ sc_main.cpp -I$SYSTEMC_STATICTOOLCHAIN_DEST/include -L$SYSTEMC_STATICTOOLCHAIN_DEST/lib-mingw64 -lsystemc

我得到了一堆

代码语言:javascript
运行
复制
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库,然后使用相同的命令行构建可执行文件:

代码语言:javascript
运行
复制
 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

代码语言:javascript
运行
复制
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库。有人能证实/否认吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-09-21 00:53:17

在过去的几天里,我学到了很多关于libtool和DLLEXPORT是如何以一致的方式使用的的知识。

它使我意识到,问题的根源是最终用户(我自己),一如既往.

公平地说,在configure脚本中,SystemC附带了一些不一致的内容。以下是:

代码语言:javascript
运行
复制
./configure --host=x86_64-w64-mingw32.static
  • 将按预期构建静态库(libsystemc.a)。
  • 但是它会很高兴地使用默认的共享库设置(假设是--enable-shared)。

它让最终用户相信一切都很好.但事实并非如此。

一旦理解并显式指定了与构建静态库一致的设置:

代码语言:javascript
运行
复制
./configure --host=x86_64-w64-mingw32.static --disable-shared

那一切都很正常。

SystemC cmake流更健壮。如果试图使用默认设置锁定Windows,则会引发错误,这使您别无选择,只能在命令行中指定-DBUILD_SHARED_LIBS=OFF

票数 0
EN

Stack Overflow用户

发布于 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>)。

此时,编译器将看到以下内容:

代码语言:javascript
运行
复制
#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.hmingw-w64-libraries/winpthreads/include/semaphore.h中有类似的代码

假设没有定义IN_WINPTHREAD (我猜在构建libwinpthread.dll时是正确的),则从SystemC库调用library被声明为'dllimport‘,这最终导致了臭名昭著的结果:

代码语言:javascript
运行
复制
libsystemc.a(sc_prim_channel.o):sc_prim_channel.cpp:(.text+0x44): undefined reference to `__imp_pthread_mutex_unlock'

我想知道混合W64头的意图是否有点不同,也许是这样的:

代码语言:javascript
运行
复制
#ifdef IN_WINPTHREAD
#    if defined DLL_EXPORT
#        define WINPTHREAD_API __declspec(dllexport)
#    else
#        define WINPTHREAD_API __declspec(dllimport)
#    endif
#else
#    define WINPTHREAD_API
#endif 

甚至是

代码语言:javascript
运行
复制
#if defined DLL_EXPORT
#      ifdef IN_WINPTHREAD
#            define WINPTHREAD_API __declspec(dllexport)
#      else
#            define WINPTHREAD_API
#      endif
#else
#      define WINPTHREAD_API
#endif

最终,我无法在以下两项之间作出决定:

  • SystemC是罪魁祸首,configure不应该定义DLL_EXPORT
  • 负责任的是MinGW-w64,pthread.h应该提供一种不同的机制,这样对perhaps的调用就不会自动转换为“dllimport”,而是默认为正常的静态链接(也可以引入带有DLL_IMPORT的显式机制)。
  • 以上两项
  • 一些其他的东西
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69171109

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档