ryanking13 / auditwheel-emscripten

auditwheel-like tool for Pyodide
Mozilla Public License 2.0
4 stars 4 forks source link

Cannot find symbol from dynamic link library when running the program. #24

Open hzhangxyz opened 11 months ago

hzhangxyz commented 11 months ago

Hello, I am using auditwheel to repair a wheel of my package. But when executing the program, an error occur as following:

Error: Dynamic linking error: cannot resolve symbol dgemm_
    at stubs.<computed> (/home/hzhangxyz/Cloud/Desktop/TAT/PyTAT/node_modules/pyodide/pyodide.asm.js:9:146779)
    at wasm://wasm/0421fa02:wasm-function[4551]:0x57c7c3
    at wasm://wasm/0421fa02:wasm-function[4719]:0x5d0d29
    at wasm://wasm/0421fa02:wasm-function[4744]:0x5e6f7d
    at wasm://wasm/0421fa02:wasm-function[4690]:0x5bafb7
    at wasm://wasm/0421fa02:wasm-function[1122]:0x1165d6
    at _PyEM_TrampolineCall_JS (/home/hzhangxyz/Cloud/Desktop/TAT/PyTAT/node_modules/pyodide/pyodide.asm.js:9:122202)
    at wasm://wasm/02258cda:wasm-function[2074]:0x1e4b41
    at _PyEM_TrampolineCall_JS (/home/hzhangxyz/Cloud/Desktop/TAT/PyTAT/node_modules/pyodide/pyodide.asm.js:9:122202)
    at wasm://wasm/02258cda:wasm-function[1083]:0x1a3486 {
  pyodide_fatal_error: true
}

Node.js v21.4.0

I am building my wheel by the following script

# Prepare the environment
pip install pyodide-build==0.25.0a2
git clone https://github.com/emscripten-core/emsdk.git
PYODIDE_EMSCRIPTEN_VERSION=$(pyodide config get emscripten_version)
cd emsdk
./emsdk install ${PYODIDE_EMSCRIPTEN_VERSION}
./emsdk activate ${PYODIDE_EMSCRIPTEN_VERSION}
source ./emsdk_env.sh
cd ..

# This two variable is used in building library
export SKBUILD_CMAKE_DEFINE=TAT_MATH_LIBRARIES=$PWD/.pyodide-xbuildenv/xbuildenv/pyodide-root/packages/.libs/lib/libopenblas.so
export CMAKE_BUILD_PARALLEL_LEVEL=6

# Build and repair
pyodide build --exports pyinit
pyodide auditwheel repair dist/*.whl --libdir .pyodide-xbuildenv/xbuildenv/pyodide-root/packages/.libs/lib

I check the output wheel, unzip it and it has

.
├── pytat-0.3.13a5.dev6+g9a59a452.dist-info
│   ├── entry_points.txt
│   ├── METADATA
│   ├── RECORD
│   └── WHEEL
├── pytat.libs
│   └── libopenblas.so
└── TAT.cpython-311-wasm32-emscripten.so

Where wasm-objdump -x TAT.cpython-311-wasm32-emscripten.so gives

TAT.cpython-311-wasm32-emscripten.so:   file format wasm 0x1

Section Details:

Custom:
 - name: "dylink.0"
 - mem_size     : 383544
 - mem_p2align  : 4
 - table_size   : 24052
 - table_p2align: 0
 - needed_dynlibs[1]:
  - pytat.libs/libopenblas.so
 - exports[0]:
 - imports[0]:
...

and wasm-objdump -x pytat.libs/libopenblas.so gives

libopenblas.so: file format wasm 0x1

Section Details:

Custom:
 - name: "dylink.0"
 - mem_size     : 56536
 - mem_p2align  : 4
 - table_size   : 5
 - table_p2align: 0
 - exports[0]:
 - imports[0]:
...
Function[3671]:
...
 - func[222] sig=9 <dgemm_>
...
Export[3728]:
...
 - func[222] <dgemm_> -> "dgemm_"
...
Code[3671]:
...
 - func[222] size=442 <dgemm_>
...

Is there any one know why the program cannot resolves symbol dgemm_?

ryanking13 commented 11 months ago

Could you try pyodide auditwheel copy not pyodide auditwheel repair? Repair command is quite broken (I should remove it from the docs...)

hzhangxyz commented 11 months ago

I try to use pyodide autitwheel copy without any other change to repair the wheel, but when importing, I get the error as following:

PythonError: Traceback (most recent call last):
  File "<exec>", line 7, in main
  File "/lib/python3.11/site-packages/micropip/_commands/install.py", line 176, in install
    await asyncio.gather(*wheel_promises)
  File "/lib/python3.11/site-packages/micropip/transaction.py", line 168, in install
    await self.load_libraries(target)
  File "/lib/python3.11/site-packages/micropip/transaction.py", line 159, in load_libraries
    await asyncio.gather(*map(lambda dynlib: loadDynlib(dynlib, False), dynlibs))
pyodide.ffi.JsException: Error: Didn't expect to load any more file_packager files!

It seems it cannot find libopenblas.so when loading.

ryanking13 commented 11 months ago

What happens if you try pyodide.loadPackage instead of micropip.install? micropip.install does not search .libs directory when loading a package (needs to be fixed).

hzhangxyz commented 11 months ago

What happens if you try pyodide.loadPackage instead of micropip.install? micropip.install does not search .libs directory when loading a package (needs to be fixed).

Ohh, thanks very much, pyodide.loadPackage works well when loading. But my package depends on openblas and numpy. openblas is embeded, and numpy is a python dependency. micropip.install can resolve numpy but not openblas, pyodide.loadPackage can resolve openblas but not numpy.

ryanking13 commented 11 months ago

I see. I'll try to improve micropip when I have bandwidth. Until then, sorry but please manually load the necessary dependencies.