mirror of
https://github.com/opencv/opencv.git
synced 2024-11-27 12:40:05 +08:00
Merge pull request #25084 from EDVTAZ:emscripten-3.1.54-compat
Add compatibility with latest (3.1.54) emsdk version #25084 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [ ] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake ### Details I was following [this tutorial](https://docs.opencv.org/4.9.0/d4/da1/tutorial_js_setup.html) for building opencv with wasm target. The tutorial mentions that the last verified version of emscripten that is tested with opencv is 2.0.10, but I was curious if I could get it to work with more recent versions. I've run into a few issues with the latest version, for which fixes are included in this PR. I've found a few issues that have the same problems I encountered: - https://github.com/opencv/opencv/issues/24620 - https://github.com/opencv/opencv/issues/20313 - https://stackoverflow.com/questions/77469603/custom-opencv-js-wasm-using-cv-matfromarray-results-in-cv-mat-is-not-a-co - https://github.com/emscripten-core/emscripten/issues/14803 - https://github.com/opencv/opencv/issues/24572 - https://github.com/opencv/opencv/issues/19493#issuecomment-857167996 I used the docker image for building and comparing results with different emsdk versions. I tested by building with `--build_wasm` and `--build-test` flags and ran the tests in the browser. I addressed the following issues with newer versions of emscripten: - In newer versions `EMSCRIPTEN` environemnt variable was stopped being set. I added support for deriving location based on the `EMSDK` environment variable, as suggested [here](https://github.com/emscripten-core/emscripten/issues/14803) - In newer versions emcmake started passing `-DCMAKE...` arguments, however the opencv python script didn't know how to handle them. I added processing to the args that will forward all arguments to `cmake` that start with `-D`. I opted for this in hopes of being more futureproof, but another approach could be just ignoreing them, or explicitly forwarding them instead of matching anything starting with `-D`. These approches were suggested [here](https://github.com/opencv/opencv/issues/19493#issuecomment-855529448) - With [version 3.1.31](https://github.com/emscripten-core/emscripten/blob/main/ChangeLog.md#3131---012623) some previously exported functions stopped being automatically exported. Because of this, `_free` and `_malloc` were no longer available and had to be explicitly exported because of breaking tests. - With [version 3.1.42](https://github.com/emscripten-core/emscripten/compare/3.1.41...3.1.42#diff-e505aa80b2764c0197acfc9afd8179b3600f0ab5dd00ff77db01879a84515cdbL3875) the `post-js` code doesn't receive the module named as `EXPORT_NAME` anymore, but only as `moduleArg`/`Module`. This broke existing code in `helpers.js`, which was referencing exported functions through `cv.Mat`, etc. I changed all of these references to use `Module.Mat`, etc. If it is preferred, alternatively the `cv` variable could be reintroduced in `helper.js` as suggested [here](https://github.com/opencv/opencv/issues/24620) With the above changes in place, I can successfully build and run tests with the latest emscripten/emsdk docker image (also with 2.0.10 and most of the other older tags, except for a few that contain transient issues like [this](https://github.com/emscripten-core/emscripten/issues/17700)). This is my first time contributing to opencv, so I hope I got everything correct in this PR, but please let me know if I should change anything!
This commit is contained in:
parent
ae347ab493
commit
6f48cb78b6
@ -42,6 +42,10 @@ if (typeof Module.FS === 'undefined' && typeof FS !== 'undefined') {
|
||||
Module.FS = FS;
|
||||
}
|
||||
|
||||
if (typeof cv === 'undefined') {
|
||||
var cv = Module;
|
||||
}
|
||||
|
||||
Module['imread'] = function(imageSource) {
|
||||
var img = null;
|
||||
if (typeof imageSource === 'string') {
|
||||
|
@ -84,7 +84,6 @@ class Builder:
|
||||
"-DPYTHON_DEFAULT_EXECUTABLE=%s" % sys.executable,
|
||||
"-DENABLE_PIC=FALSE", # To workaround emscripten upstream backend issue https://github.com/emscripten-core/emscripten/issues/8761
|
||||
"-DCMAKE_BUILD_TYPE=Release",
|
||||
"-DCMAKE_TOOLCHAIN_FILE='%s'" % self.get_toolchain_file(),
|
||||
"-DCPU_BASELINE=''",
|
||||
"-DCMAKE_INSTALL_PREFIX=/usr/local",
|
||||
"-DCPU_DISPATCH=''",
|
||||
@ -145,6 +144,8 @@ class Builder:
|
||||
"-DBUILD_PERF_TESTS=ON"]
|
||||
if self.options.cmake_option:
|
||||
cmd += self.options.cmake_option
|
||||
if not self.options.cmake_option or all(["-DCMAKE_TOOLCHAIN_FILE" not in opt for opt in self.options.cmake_option]):
|
||||
cmd.append("-DCMAKE_TOOLCHAIN_FILE='%s'" % self.get_toolchain_file())
|
||||
if self.options.build_doc:
|
||||
cmd.append("-DBUILD_DOCS=ON")
|
||||
else:
|
||||
@ -194,6 +195,7 @@ class Builder:
|
||||
flags += self.options.build_flags
|
||||
if self.options.webnn:
|
||||
flags += "-s USE_WEBNN=1 "
|
||||
flags += "-s EXPORTED_FUNCTIONS=\"['_malloc', '_free']\""
|
||||
return flags
|
||||
|
||||
def config(self):
|
||||
@ -224,10 +226,12 @@ if __name__ == "__main__":
|
||||
|
||||
opencv_dir = os.path.abspath(os.path.join(SCRIPT_DIR, '../..'))
|
||||
emscripten_dir = None
|
||||
if "EMSCRIPTEN" in os.environ:
|
||||
if "EMSDK" in os.environ:
|
||||
emscripten_dir = os.path.join(os.environ["EMSDK"], "upstream", "emscripten")
|
||||
elif "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")
|
||||
log.warning("EMSCRIPTEN/EMSDK 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)")
|
||||
@ -256,7 +260,8 @@ if __name__ == "__main__":
|
||||
help="Specify configuration file with own list of exported into JS functions")
|
||||
parser.add_argument('--webnn', action="store_true", help="Enable WebNN Backend")
|
||||
|
||||
args = parser.parse_args()
|
||||
transformed_args = ["--cmake_option=%s".format(arg) if arg[:2] == "-D" else arg for arg in sys.argv[1:]]
|
||||
args = parser.parse_args(transformed_args)
|
||||
|
||||
log.debug("Args: %s", args)
|
||||
|
||||
@ -266,7 +271,7 @@ if __name__ == "__main__":
|
||||
del os.environ['EMMAKEN_JUST_CONFIGURE'] # avoid linker errors with NODERAWFS message then using 'emcmake' launcher
|
||||
|
||||
if args.emscripten_dir is None:
|
||||
log.error("Cannot get Emscripten path, please use 'emcmake' launcher or 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/EMSDK environment variable or --emscripten_dir option.")
|
||||
sys.exit(-1)
|
||||
|
||||
builder = Builder(args)
|
||||
|
Loading…
Reference in New Issue
Block a user