From af71b030007770ba118058ff861edf9c34027226 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Mon, 14 Dec 2020 04:42:15 +0000 Subject: [PATCH] js: update documentation and builds scripts - support modern Emscripten build process - replaced Docker image - replaced Emscripten's web URLs --- .../js_setup/js_intro/js_intro.markdown | 4 +- .../js_setup/js_setup/js_setup.markdown | 61 ++++++++++--------- .../js_setup/js_usage/js_usage.markdown | 4 +- platforms/js/README.md | 4 +- platforms/js/build_js.py | 12 +++- 5 files changed, 48 insertions(+), 37 deletions(-) diff --git a/doc/js_tutorials/js_setup/js_intro/js_intro.markdown b/doc/js_tutorials/js_setup/js_intro/js_intro.markdown index 416aa3ded5..01a123c5f4 100644 --- a/doc/js_tutorials/js_setup/js_intro/js_intro.markdown +++ b/doc/js_tutorials/js_setup/js_intro/js_intro.markdown @@ -13,7 +13,7 @@ OpenCV.js: OpenCV for the JavaScript programmer Web is the most ubiquitous open computing platform. With HTML5 standards implemented in every browser, web applications are able to render online video with HTML5 video tags, capture webcam video via WebRTC API, and access each pixel of a video frame via canvas API. With abundance of available multimedia content, web developers are in need of a wide array of image and vision processing algorithms in JavaScript to build innovative applications. This requirement is even more essential for emerging applications on the web, such as Web Virtual Reality (WebVR) and Augmented Reality (WebAR). All of these use cases demand efficient implementations of computation-intensive vision kernels on web. -[Emscripten](http://kripken.github.io/emscripten-site) is an LLVM-to-JavaScript compiler. It takes LLVM bitcode - which can be generated from C/C++ using clang, and compiles that into asm.js or WebAssembly that can execute directly inside the web browsers. . Asm.js is a highly optimizable, low-level subset of JavaScript. Asm.js enables ahead-of-time compilation and optimization in JavaScript engine that provide near-to-native execution speed. WebAssembly is a new portable, size- and load-time-efficient binary format suitable for compilation to the web. WebAssembly aims to execute at native speed. WebAssembly is currently being designed as an open standard by W3C. +[Emscripten](https://emscripten.org/) is an LLVM-to-JavaScript compiler. It takes LLVM bitcode - which can be generated from C/C++ using clang, and compiles that into asm.js or WebAssembly that can execute directly inside the web browsers. . Asm.js is a highly optimizable, low-level subset of JavaScript. Asm.js enables ahead-of-time compilation and optimization in JavaScript engine that provide near-to-native execution speed. WebAssembly is a new portable, size- and load-time-efficient binary format suitable for compilation to the web. WebAssembly aims to execute at native speed. WebAssembly is currently being designed as an open standard by W3C. OpenCV.js is a JavaScript binding for selected subset of OpenCV functions for the web platform. It allows emerging web applications with multimedia processing to benefit from the wide variety of vision functions available in OpenCV. OpenCV.js leverages Emscripten to compile OpenCV functions into asm.js or WebAssembly targets, and provides a JavaScript APIs for web application to access them. The future versions of the library will take advantage of acceleration APIs that are available on the Web such as SIMD and multi-threaded execution. @@ -42,4 +42,4 @@ Below is the list of contributors of OpenCV.js bindings and tutorials. - Gang Song (GSoC student, Shanghai Jiao Tong University) - Wenyao Gan (Student intern, Shanghai Jiao Tong University) - Mohammad Reza Haghighat (Project initiator & sponsor, Intel Corporation) -- Ningxin Hu (Students' supervisor, Intel Corporation) \ No newline at end of file +- Ningxin Hu (Students' supervisor, Intel Corporation) diff --git a/doc/js_tutorials/js_setup/js_setup/js_setup.markdown b/doc/js_tutorials/js_setup/js_setup/js_setup.markdown index 435f06fe02..89e7acd96b 100644 --- a/doc/js_tutorials/js_setup/js_setup/js_setup.markdown +++ b/doc/js_tutorials/js_setup/js_setup/js_setup.markdown @@ -7,12 +7,12 @@ You don't have to build your own copy if you simply want to start using it. Refe Installing Emscripten ----------------------------- -[Emscripten](https://github.com/kripken/emscripten) is an LLVM-to-JavaScript compiler. We will use Emscripten to build OpenCV.js. +[Emscripten](https://github.com/emscripten-core/emscripten) is an LLVM-to-JavaScript compiler. We will use Emscripten to build OpenCV.js. @note While this describes installation of required tools from scratch, there's a section below also describing an alternative procedure to perform the same build using docker containers which is often easier. -To Install Emscripten, follow instructions of [Emscripten SDK](https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html). +To Install Emscripten, follow instructions of [Emscripten SDK](https://emscripten.org/docs/getting_started/downloads.html). For example: @code{.bash} @@ -21,24 +21,29 @@ For example: ./emsdk activate latest @endcode -@note -To compile to [WebAssembly](http://webassembly.org), you need to install and activate [Binaryen](https://github.com/WebAssembly/binaryen) with the `emsdk` command. Please refer to [Developer's Guide](http://webassembly.org/getting-started/developers-guide/) for more details. -After install, ensure the `EMSCRIPTEN` environment is setup correctly. +After install, ensure the `EMSDK` environment is setup correctly. For example: @code{.bash} source ./emsdk_env.sh -echo ${EMSCRIPTEN} +echo ${EMSDK} @endcode -The version 1.39.16 of emscripten is verified for latest WebAssembly. Please check the version of emscripten to use the newest features of WebAssembly. +Modern versions of Emscripten requires to use `emcmake` / `emmake` launchers: + +@code{.bash} +emcmake sh -c 'echo ${EMSCRIPTEN}' +@endcode + + +The version 2.0.10 of emscripten is verified for latest WebAssembly. Please check the version of Emscripten to use the newest features of WebAssembly. For example: @code{.bash} ./emsdk update -./emsdk install 1.39.16 -./emsdk activate 1.39.16 +./emsdk install 2.0.10 +./emsdk activate 2.0.10 @endcode Obtaining OpenCV Source Code @@ -71,8 +76,7 @@ Building OpenCV.js from Source For example, to build in `build_js` directory: @code{.bash} - cd opencv - python ./platforms/js/build_js.py build_js + emcmake python ./opencv/platforms/js/build_js.py build_js @endcode @note @@ -82,14 +86,14 @@ Building OpenCV.js from Source For example, to build wasm version in `build_wasm` directory: @code{.bash} - python ./platforms/js/build_js.py build_wasm --build_wasm + emcmake python ./opencv/platforms/js/build_js.py build_wasm --build_wasm @endcode -# [Optional] To build the OpenCV.js loader, append `--build_loader`. For example: @code{.bash} - python ./platforms/js/build_js.py build_js --build_loader + emcmake python ./opencv/platforms/js/build_js.py build_js --build_loader @endcode @note @@ -114,7 +118,7 @@ Building OpenCV.js from Source For example: @code{.bash} - python ./platforms/js/build_js.py build_js --build_doc + emcmake python ./opencv/platforms/js/build_js.py build_js --build_doc @endcode @note @@ -124,7 +128,7 @@ Building OpenCV.js from Source For example: @code{.bash} - python ./platforms/js/build_js.py build_js --build_test + emcmake python ./opencv/platforms/js/build_js.py build_js --build_test @endcode Running OpenCV.js Tests @@ -186,7 +190,7 @@ node tests.js For example: @code{.bash} - python ./platforms/js/build_js.py build_js --build_wasm --threads + emcmake python ./opencv/platforms/js/build_js.py build_js --build_wasm --threads @endcode The default threads number is the logic core number of your device. You can use `cv.parallel_pthreads_set_threads_num(number)` to set threads number by yourself and use `cv.parallel_pthreads_get_threads_num()` to get the current threads number. @@ -198,7 +202,7 @@ node tests.js For example: @code{.bash} - python ./platforms/js/build_js.py build_js --build_wasm --simd + emcmake python ./opencv/platforms/js/build_js.py build_js --build_wasm --simd @endcode The simd optimization is experimental as wasm simd is still in development. @@ -222,7 +226,7 @@ node tests.js For example: @code{.bash} - python ./platforms/js/build_js.py build_js --build_wasm --simd --build_wasm_intrin_test + emcmake python ./opencv/platforms/js/build_js.py build_js --build_wasm --simd --build_wasm_intrin_test @endcode For wasm intrinsics tests, you can use the following function to test all the cases: @@ -250,7 +254,7 @@ node tests.js For example: @code{.bash} - python ./platforms/js/build_js.py build_js --build_perf + emcmake python ./opencv/platforms/js/build_js.py build_js --build_perf @endcode To run performance tests, launch a local web server in \/bin folder. For example, node http-server which serves on `localhost:8080`. @@ -271,25 +275,25 @@ Building OpenCV.js with Docker Alternatively, the same build can be can be accomplished using [docker](https://www.docker.com/) containers which is often easier and more reliable, particularly in non linux systems. You only need to install [docker](https://www.docker.com/) on your system and use a popular container that provides a clean well tested environment for emscripten builds like this, that already has latest versions of all the necessary tools installed. -So, make sure [docker](https://www.docker.com/) is installed in your system and running. The following shell script should work in linux and MacOS: +So, make sure [docker](https://www.docker.com/) is installed in your system and running. The following shell script should work in Linux and MacOS: @code{.bash} git clone https://github.com/opencv/opencv.git cd opencv -docker run --rm --workdir /code -v "$PWD":/code "trzeci/emscripten:latest" python ./platforms/js/build_js.py build +docker run --rm -v $(pwd):/src -u $(id -u):$(id -g) emscripten/emsdk emcmake python3 ./dev/platforms/js/build_js.py build_js @endcode In Windows use the following PowerShell command: @code{.bash} -docker run --rm --workdir /code -v "$(get-location):/code" "trzeci/emscripten:latest" python ./platforms/js/build_js.py build +docker run --rm --workdir /src -v "$(get-location):/src" "emscripten/emsdk" emcmake python3 ./dev/platforms/js/build_js.py build_js @endcode @warning -The example uses latest version of emscripten. If the build fails you should try a version that is known to work fine which is `1.38.32` using the following command: +The example uses latest version of emscripten. If the build fails you should try a version that is known to work fine which is `2.0.10` using the following command: @code{.bash} -docker run --rm --workdir /code -v "$PWD":/code "trzeci/emscripten:sdk-tag-1.38.32-64bit" python ./platforms/js/build_js.py build +docker run --rm -v $(pwd):/src -u $(id -u):$(id -g) emscripten/emsdk:2.0.10 emcmake python3 ./dev/platforms/js/build_js.py build_js @endcode ### Building the documentation with Docker @@ -297,10 +301,11 @@ docker run --rm --workdir /code -v "$PWD":/code "trzeci/emscripten:sdk-tag-1.38. To build the documentation `doxygen` needs to be installed. Create a file named `Dockerfile` with the following content: ``` -FROM trzeci/emscripten:sdk-tag-1.38.32-64bit +FROM emscripten/emsdk:2.0.10 -RUN apt-get update -y -RUN apt-get install -y doxygen +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends doxygen \ + && rm -rf /var/lib/apt/lists/* ``` Then we build the docker image and name it `opencv-js-doc` with the following command (that needs to be run only once): @@ -312,5 +317,5 @@ docker build . -t opencv-js-doc Now run the build command again, this time using the new image and passing `--build_doc`: @code{.bash} -docker run --rm --workdir /code -v "$PWD":/code "opencv-js-doc" python ./platforms/js/build_js.py build --build_doc +docker run --rm -v $(pwd):/src -u $(id -u):$(id -g) "opencv-js-doc" emcmake python3 ./dev/platforms/js/build_js.py build_js --build_doc @endcode diff --git a/doc/js_tutorials/js_setup/js_usage/js_usage.markdown b/doc/js_tutorials/js_setup/js_usage/js_usage.markdown index 5f9f338f2d..ffdfca2882 100644 --- a/doc/js_tutorials/js_setup/js_usage/js_usage.markdown +++ b/doc/js_tutorials/js_setup/js_usage/js_usage.markdown @@ -129,7 +129,7 @@ function onOpenCvReady() { @endcode -@note You have to call delete method of cv.Mat to free memory allocated in Emscripten's heap. Please refer to [Memory management of Emscripten](https://kripken.github.io/emscripten-site/docs/porting/connecting_cpp_and_javascript/embind.html#memory-management) for details. +@note You have to call delete method of cv.Mat to free memory allocated in Emscripten's heap. Please refer to [Memory management of Emscripten](https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#memory-management) for details. Try it ------ @@ -137,4 +137,4 @@ Try it -\endhtmlonly \ No newline at end of file +\endhtmlonly diff --git a/platforms/js/README.md b/platforms/js/README.md index 1db8a84a4b..17c17ee1f7 100644 --- a/platforms/js/README.md +++ b/platforms/js/README.md @@ -1,11 +1,11 @@ Building OpenCV.js by Emscripten ==================== -[Download and install Emscripten](https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html). +[Download and install Emscripten](https://emscripten.org/docs/getting_started/downloads.html). Execute `build_js.py` script: ``` -python /platforms/js/build_js.py +emcmake python /platforms/js/build_js.py ``` If everything is fine, a few minutes later you will get `/bin/opencv.js`. You can add this into your web pages. diff --git a/platforms/js/build_js.py b/platforms/js/build_js.py index cd22db0f02..afe37c6949 100644 --- a/platforms/js/build_js.py +++ b/platforms/js/build_js.py @@ -206,15 +206,19 @@ class Builder: #=================================================================================================== if __name__ == "__main__": + log.basicConfig(format='%(message)s', level=log.DEBUG) + opencv_dir = os.path.abspath(os.path.join(SCRIPT_DIR, '../..')) emscripten_dir = None if "EMSCRIPTEN" in os.environ: emscripten_dir = os.environ["EMSCRIPTEN"] + else: + log.warning("EMSCRIPTEN environment variable is not available. Please properly activate Emscripten SDK and consider using 'emcmake' launcher") parser = argparse.ArgumentParser(description='Build OpenCV.js by Emscripten') parser.add_argument("build_dir", help="Building directory (and output)") parser.add_argument('--opencv_dir', default=opencv_dir, help='Opencv source directory (default is "../.." relative to script location)') - parser.add_argument('--emscripten_dir', default=emscripten_dir, help="Path to Emscripten to use for build") + parser.add_argument('--emscripten_dir', default=emscripten_dir, help="Path to Emscripten to use for build (deprecated in favor of 'emcmake' launcher)") parser.add_argument('--build_wasm', action="store_true", help="Build OpenCV.js in WebAssembly format") parser.add_argument('--disable_wasm', action="store_true", help="Build OpenCV.js in Asm.js format") parser.add_argument('--threads', action="store_true", help="Build OpenCV.js with threads optimization") @@ -238,13 +242,15 @@ if __name__ == "__main__": args = parser.parse_args() - log.basicConfig(format='%(message)s', level=log.DEBUG) log.debug("Args: %s", args) os.environ["OPENCV_JS_WHITELIST"] = args.config + if 'EMMAKEN_JUST_CONFIGURE' in os.environ: + del os.environ['EMMAKEN_JUST_CONFIGURE'] # avoid linker errors with NODERAWFS message then using 'emcmake' launcher + if args.emscripten_dir is None: - log.info("Cannot get Emscripten path, please specify it either by EMSCRIPTEN environment variable or --emscripten_dir option.") + log.error("Cannot get Emscripten path, please use 'emcmake' launcher or specify it either by EMSCRIPTEN environment variable or --emscripten_dir option.") sys.exit(-1) builder = Builder(args)