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 9 months ago

hzhangxyz commented 9 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 9 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 9 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 9 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 9 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 9 months ago

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