【问题标题】:Emscripten Link static Library error: wasm streaming compile fail: Import 'env.getTempRet0'Emscripten 链接静态库错误:wasm 流编译失败:导入'env.getTempRet0'
【发布时间】:2019-03-19 04:11:47
【问题描述】:

当我尝试将我的 wasm 代码与静态库、草根 DICOM 库链接时出错。

首先,我使用带有外部工具链的 cmake 编译 Grassroot DICOM,并从 /1.38.14/cmake/Modules/Platform

将 Windows 10 与 Visual Studio 2017 和 Windows 8.1 SDK 结合使用。

编译完成后。我有静态链接文件

libgdcmcharls.a
libgdcmCommon.a
libgdcmDICT.a
libgdcmDSED.a
....

然后我使用标志将这些文件链接到我的代码

-L<PATH-to-library>
-lgdcmcharls -lgdcmCommon -lgdcmDICT -lgdcmDSED ...

也使用:

-s WASM=1 -s SIDE_MODULE=1 -s EXPORT_ALL=1 

这些库可以链接但无法编译。错误是

multiprocessing.pool.RemoteTraceback: """ Traceback(最近一次调用 最后):文件 "C:\Users\WORK\AppData\Local\Programs\Python\Python37-32\lib\multiprocessing\pool.py", 第 121 行,在工人中 结果 = (True, func(*args, **kwds)) 文件 "C:\Users\I-w-I\AppData\Local\Programs\Python\Python37-32\lib\multiprocessing\pool.py", 第 44 行,在 mapstar 中 返回列表(map(*args))文件“C:\workspace\emsdk\emscripten\1.38.14\tools\shared.py”,第 1363 行,在 extract_archive_contents 断言不是 os.path.dirname(f) AssertionError .

然后我改变了我使用链接到 Grassroot DICOM 的方式

-s RUNTIME_LINKED_LIBS=['gdcmcharls.a']
-s RUNTIME_LINKED_LIBS=['gdcmCommon.a']
-s RUNTIME_LINKED_LIBS=['gdcmDICT.a']
-s RUNTIME_LINKED_LIBS=['gdcmDSED.a']
.....

我收到错误消息

wasm 流编译失败:LinkError: Import 'env.getTempRet0' is 无效的。预期类型函数

回退到 ArrayBuffer 实例化

并在控制台中显示此错误

LinkError:导入“env.getTempRet0”无效。预期类型函数

关于我的机器。我使用 Windows10 64 位和 emcc (Emscripten gcc/clang-like 替换) 1.38.14 我在网上搜索,但似乎没有人和我面临同样的问题

更新

现在我删除了所有动态链接标志,出现了新问题

emcc -std=c++17 -O3 --no-heap-copy -s WASM=1  -s USE_WEBGL2=1 -s FULL_ES3=1 -s ALLOW_MEMORY_GROWTH=1 -o hello.html  -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall', 'cwrap']"        libgdcmcharls.bc libgdcmCommon.bc libgdcmDICT.bc libgdcmDSED.bc libgdcmexpat.bc libgdcmIOD.bc libgdcmjpeg12.bc libgdcmjpeg16.bc libgdcmjpeg8.bc libgdcmMEXD.bc libgdcmMSFF.bc libgdcmopenjp2.bc libgdcmzlib.bc libsocketxx.bc main.cpp  -o hello.js

multiprocessing.pool.RemoteTraceback: """

Traceback(最近一次调用最后一次):文件 "C:\Users\WORK\AppData\Local\Programs\Python\Python37-32\lib\multiprocessing\pool.py", 第 121 行,在工人中 结果 = (True, func(*args, **kwds)) 文件 "C:\Users\WORK\AppData\Local\Programs\Python\Python37-32\lib\multiprocessing\pool.py", 第 44 行,在 mapstar 中 返回列表(map(*args))文件“C:\workspace\emsdk\emscripten\1.38.14\tools\shared.py”,第 1364 行,在 extract_archive_contents 断言不是 os.path.dirname(f) AssertionError """

上述异常是以下异常的直接原因:

Traceback(最近一次调用最后一次):文件 “C:\workspace\emsdk\emscripten\1.38.14\emcc.py”,第 3092 行,在 sys.exit(run()) 文件“C:\workspace\emsdk\emscripten\1.38.14\emcc.py”,第 1699 行,运行中 final = shared.Building.link(linker_inputs,DEFAULT_FINAL,force_archive_contents=force_archive_contents, temp_files=misc_temp_files, just_calculate=just_calculate) 文件 “C:\workspace\emsdk\emscripten\1.38.14\tools\shared.py”,第 2011 行,在 关联 Building.read_link_inputs([x for x in files if not x.startswith('-')]) 文件 “C:\workspace\emsdk\emscripten\1.38.14\tools\shared.py”,第 1852 行,在 读取链接输入 object_names_in_archives = pool.map(extract_archive_contents, archive_names) 文件 "C:\Users\WORK\AppData\Local\Programs\Python\Python37-32\lib\multiprocessing\pool.py", 第 268 行,在地图中 返回 self._map_async(func, iterable, mapstar, chunksize).get() 文件 "C:\Users\WORK\AppData\Local\Programs\Python\Python37-32\lib\multiprocessing\pool.py", 第 657 行,在获取 raise self._value AssertionError gmake: *** [build] Error 1

似乎python在库文件中找不到模块的问题

当我追踪错误在哪里时

它们来自 Python 函数调用

# This function creates a temporary directory specified by the 'dir' field in
# the returned dictionary. Caller is responsible for cleaning up those files
# after done.
def extract_archive_contents(archive_file):


assert not os.path.dirname(f)  #This line causes the trouble

【问题讨论】:

    标签: c++ linker emscripten webassembly


    【解决方案1】:

    RUNTIME_LINKED_LIBS 选项的正确使用方式应该是这样的:

    -s RUNTIME_LINKED_LIBS=['gdcmcharls.a', 'gdcmCommon.a', 'gdcmDICT.a', 'gdcmDSED.a']
    

    但是,这可能不是您想要的解决方案。因为您希望静态链接库,而不是动态链接。

    将它们一起编译的正确方法是将它们包含为编译目标。完整的emcc 选项如下所示:

    emcc --other-options-you-use \
         -s WASM=1 \
         gdcmcharls.a \
         gdcmCommon.a \
         gdcmDICT.a \
         gdcmDSED.a \
         your_other_source_files_1.c \
         your_other_source_files_2.cpp \
         -o output.js
    

    不要使用-s SIDE_MODULE=1 标志。这是用于动态链接。 -s EXPORT_ALL=1 可能不是你想要的。

    【讨论】:

    • 我不确定我编译代码的方式会导致这个问题。我使用 Visual Studio Release 32 位编译并使用 Release 64bit 进行测试。但两者都不起作用
    • 没有。您不应该使用任何 MS 工具链或 Unix,而是 Emscripten 的编译器。您应该在任何编译之前启用Emscripten SDK
    • 非常感谢。我认为这就是问题所在。
    • @MooMoo 没问题。所以 1. 通过source ./emsdk_env.sh 启用 emscripten 环境。 2. 通过emconfigure cmake 运行CMake(不仅仅是cmake!) 3. 通过emmake make 运行make(不仅仅是make!)。看看doc here
    猜你喜欢
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-24
    • 1970-01-01
    • 1970-01-01
    • 2015-11-18
    • 1970-01-01
    相关资源
    最近更新 更多