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:
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh
下载OpenCV源码并开始编译:
git clone https://github.com/opencv/opencv.git
cd opencv
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
没有添加这个变量。
这时有两种解决方法:
- 自己添加
EMSCRIPTEN
变量 - 编译脚本时设置
--emscripten-dir
选项
我采用第二种方法来解决,设置 --emscripten-dir
python ./platforms/js/build_js.py --emscripten_dir ../emsdk build_js
上面使用../emsdk
,是因为我的emsdk
和opencv
目录是同级目录,也可以使用绝对路径。我不知道--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.py
155行的位置添加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:
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh
下载OpenCV源码并编译:
git clone https://github.com/opencv/opencv.git
cd opencv
- 修改编译脚本
build_js.py
,在155行左右的位置添加flags += "-s USE_PTHREADS=0 "
python ./platforms/js/build_js.py --emscripten_dir ../emsdk/fastcomp/emscripten build_js
上述路径视自己下载位置而定。