记一次 OpenCV.js 编译错误的解决 : pthreads Emscripten path

ubuntu下用Emscripten从源码编译 OpenCV.js
opencv 版本 : 4.1.2
emscripten 版本 : 1.38.43

Emscripten path 错误

OpenCV.js官方教程: https://docs.opencv.org/master/d4/da1/tutorial_js_setup.html
Emscripten 安装官方教程: https://emscripten.org/docs/getting_started/downloads.html

首先安装Emscripten:

  1. git clone https://github.com/emscripten-core/emsdk.git
  2. cd emsdk
  3. ./emsdk install latest
  4. ./emsdk activate latest
  5. source ./emsdk_env.sh

下载OpenCV源码并开始编译:

  1. git clone https://github.com/opencv/opencv.git
  2. cd opencv
  3. python ./platforms/js/build_js.py build_js

结果出现如下错误:

Cannot get Emscripten path, please specify it either by EMSCRIPTEN environment variable or --emscripten_dir option.

原因分析:
本来在 source ./emsdk_env.sh 之后,应该有EMSCRIPTEN环境变量,但是echo ${EMSCRIPTEN}并没有值,说明新版Emscripten SDK的安装后emsdk_env.sh没有添加这个变量。
这时有两种解决方法:

  1. 自己添加EMSCRIPTEN变量
  2. 编译脚本时设置 --emscripten-dir 选项

我采用第二种方法来解决,设置 --emscripten-dir

python ./platforms/js/build_js.py --emscripten_dir ../emsdk build_js

上面使用../emsdk,是因为我的emsdkopencv目录是同级目录,也可以使用绝对路径。我不知道--emscripten-dir应该设置成哪一个目录,就设成了emsdk的顶级目录。
结果编译还是报错:

CMake Error at /usr/share/cmake-3.5/Modules/CMakeDetermineSystem.cmake:104 (message):
  Could not find toolchain file:
  /home/temp/workspace/emsdk/cmake/Modules/Platform/Emscripten.cmake
Call Stack (most recent call first):
  CMakeLists.txt:99 (enable_language)


CMake Error: CMAKE_CXX_COMPILER not set, after EnableLanguage
CMake Error: CMAKE_C_COMPILER not set, after EnableLanguage

应该是--emscripten-dir设置错了,通过搜索Emscripten.cmake,猜测路径应该是../emsdk/fastcomp/emscripten,于是再设置再编译

python ./platforms/js/build_js.py --emscripten_dir ../emsdk/fastcomp/emscripten build_js

果真,修改之后就正常编译了。

pthreads 问题

然后,编译到最后报错了:

root:WARNING: USE_PTHREADS + ALLOW_MEMORY_GROWTH may run non-wasm code slowly, see https://github.com/WebAssembly/design/issues/1271
shared:ERROR: If pthreads and memory growth are enabled, WASM_MEM_MAX must be set

...

Traceback (most recent call last):
  File "./platforms/js/build_js.py", line 235, in 
    builder.build_opencvjs()
  File "./platforms/js/build_js.py", line 170, in build_opencvjs
    execute(["make", "-j", str(multiprocessing.cpu_count()), "opencv.js"])
  File "./platforms/js/build_js.py", line 23, in execute
    raise Fail("Child returned: %s" % retcode)
__main__.Fail: Child returned: 2

网上搜索,发现有issue如下:
https://github.com/opencv/opencv/issues/14691
其中说到一个解决方法:
在编译脚本build_js.py155行的位置添加flags += "-s USE_PTHREADS=0 "
问题原因可能是最新版的Emscripten默认使能了pthred:

the latest version of emscripten seems to enable pthread by default, which is also the root cause of this issue.

如上修改之后,顺利编译完成,得到opencv.js文件

总结

总结能成功编译的步骤如下:

安装Emscripten:

  1. git clone https://github.com/emscripten-core/emsdk.git
  2. cd emsdk
  3. ./emsdk install latest
  4. ./emsdk activate latest
  5. source ./emsdk_env.sh

下载OpenCV源码并编译:

  1. git clone https://github.com/opencv/opencv.git
  2. cd opencv
  3. 修改编译脚本build_js.py,在155行左右的位置添加flags += "-s USE_PTHREADS=0 "
  4. python ./platforms/js/build_js.py --emscripten_dir ../emsdk/fastcomp/emscripten build_js

上述路径视自己下载位置而定。

你可能感兴趣的:(记一次 OpenCV.js 编译错误的解决 : pthreads Emscripten path)