cmake(js): update js targets
authorAlexander Alekhin <alexander.a.alekhin@gmail.com>
Mon, 30 Nov 2020 03:41:21 +0000 (03:41 +0000)
committerAlexander Alekhin <alexander.a.alekhin@gmail.com>
Thu, 3 Dec 2020 14:18:54 +0000 (14:18 +0000)
- unconditional js bindings source code generation
- use common name for tests: opencv_test_js

cmake/platforms/OpenCV-Emscripten.cmake [new file with mode: 0644]
modules/js/CMakeLists.txt
modules/js/common.cmake [new file with mode: 0644]
modules/js/generator/CMakeLists.txt [new file with mode: 0644]
modules/js/generator/embindgen.py [moved from modules/js/src/embindgen.py with 99% similarity]
modules/js/generator/templates.py [moved from modules/js/src/templates.py with 100% similarity]
modules/js/src/core_bindings.cpp
platforms/js/build_js.py

diff --git a/cmake/platforms/OpenCV-Emscripten.cmake b/cmake/platforms/OpenCV-Emscripten.cmake
new file mode 100644 (file)
index 0000000..ec15fba
--- /dev/null
@@ -0,0 +1 @@
+set(OPENCV_SKIP_LINK_AS_NEEDED 1)
index f3a625b..d82e4a2 100644 (file)
@@ -1,13 +1,19 @@
 # ----------------------------------------------------------------------------
 #  CMake file for js support
 # ----------------------------------------------------------------------------
-set(the_description "The js bindings")
+if(OPENCV_INITIAL_PASS)
+  # generator for Objective-C source code and documentation signatures
+  add_subdirectory(generator)
+endif()
 
 if(NOT BUILD_opencv_js)  # should be enabled explicitly (by build_js.py script)
-  ocv_module_disable(js)
+  return()
 endif()
 
+set(the_description "The JavaScript(JS) bindings")
+
 set(OPENCV_JS "opencv.js")
+set(JS_HELPER "${CMAKE_CURRENT_SOURCE_DIR}/src/helpers.js")
 
 find_path(EMSCRIPTEN_INCLUDE_DIR
           emscripten/bind.h
@@ -28,59 +34,18 @@ if(NOT EMSCRIPTEN_INCLUDE_DIR OR NOT PYTHON_DEFAULT_AVAILABLE)
   ocv_module_disable(js)
 endif()
 
-ocv_add_module(js BINDINGS)
+ocv_add_module(js BINDINGS PRIVATE_REQUIRED opencv_js_bindings_generator)
 
 ocv_module_include_directories(${EMSCRIPTEN_INCLUDE_DIR})
 
-# get list of modules to wrap
-# message(STATUS "Wrapped in js:")
-set(OPENCV_JS_MODULES)
-foreach(m ${OPENCV_MODULES_BUILD})
-  if(";${OPENCV_MODULE_${m}_WRAPPERS};" MATCHES ";js;" AND HAVE_${m})
-    list(APPEND OPENCV_JS_MODULES ${m})
-    # message(STATUS "\t${m}")
-  endif()
-endforeach()
-
-set(opencv_hdrs "")
-foreach(m ${OPENCV_JS_MODULES})
-  list(APPEND opencv_hdrs ${OPENCV_MODULE_${m}_HEADERS})
-endforeach(m)
-
-# header blacklist
-ocv_list_filterout(opencv_hdrs "modules/.*.h$")
-ocv_list_filterout(opencv_hdrs "modules/core/.*/cuda")
-ocv_list_filterout(opencv_hdrs "modules/core/.*/opencl")
-ocv_list_filterout(opencv_hdrs "modules/core/include/opencv2/core/opengl.hpp")
-ocv_list_filterout(opencv_hdrs "modules/core/include/opencv2/core/ocl.hpp")
-ocv_list_filterout(opencv_hdrs "modules/cuda.*")
-ocv_list_filterout(opencv_hdrs "modules/cudev")
-ocv_list_filterout(opencv_hdrs "modules/core/.*/hal/")
-ocv_list_filterout(opencv_hdrs "modules/.*/detection_based_tracker.hpp") # Conditional compilation
-ocv_list_filterout(opencv_hdrs "modules/core/include/opencv2/core/utils/.*")
-
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/headers.txt" "${opencv_hdrs}")
-
-set(bindings_cpp "${CMAKE_CURRENT_BINARY_DIR}/bindings.cpp")
-
-set(scripts_hdr_parser "${CMAKE_CURRENT_SOURCE_DIR}/../python/src2/hdr_parser.py")
-
-set(JS_HELPER "${CMAKE_CURRENT_SOURCE_DIR}/src/helpers.js")
-
-add_custom_command(
-   OUTPUT ${bindings_cpp}
-   COMMAND ${PYTHON_DEFAULT_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/src/embindgen.py" ${scripts_hdr_parser} ${bindings_cpp} "${CMAKE_CURRENT_BINARY_DIR}/headers.txt" "${CMAKE_CURRENT_SOURCE_DIR}/src/core_bindings.cpp"
-   DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/core_bindings.cpp
-   DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/embindgen.py
-   DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/templates.py
-   DEPENDS ${scripts_hdr_parser}
-   #(not needed - generated by CMake) DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/headers.txt
-   DEPENDS ${opencv_hdrs}
-   DEPENDS ${JS_HELPER})
-
 add_definitions("-std=c++11")
 
-link_libraries(${OPENCV_MODULE_${the_module}_DEPS})
+set(deps ${OPENCV_MODULE_${the_module}_DEPS})
+list(REMOVE_ITEM deps opencv_js_bindings_generator)  # don't add dummy module
+link_libraries(${deps})
+
+set(bindings_cpp "${OPENCV_JS_BINDINGS_DIR}/gen/bindings.cpp")
+set_source_files_properties(${bindings_cpp} PROPERTIES GENERATED TRUE)
 
 OCV_OPTION(BUILD_WASM_INTRIN_TESTS "Build WASM intrin tests" OFF )
 if(BUILD_WASM_INTRIN_TESTS)
@@ -94,12 +59,17 @@ else()
   ocv_add_executable(${the_module} ${bindings_cpp})
 endif()
 
+add_dependencies(${the_module} gen_opencv_js_source)
+
 set_target_properties(${the_module} PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes")
 
+#set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s NODERAWFS=0")
 set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} --memory-init-file 0 -s TOTAL_MEMORY=128MB -s WASM_MEM_MAX=1GB -s ALLOW_MEMORY_GROWTH=1")
 set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s MODULARIZE=1 -s SINGLE_FILE=1")
 set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s EXPORT_NAME=\"'cv'\" -s DEMANGLE_SUPPORT=1")
 set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s FORCE_FILESYSTEM=1 --use-preload-plugins --bind --post-js ${JS_HELPER} -Wno-missing-prototypes")
+#set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} --use-preload-plugins --bind --post-js ${JS_HELPER} -Wno-missing-prototypes")
+#set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s FORCE_FILESYSTEM=1 --bind --post-js ${JS_HELPER} -Wno-missing-prototypes")
 set_target_properties(${the_module} PROPERTIES LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS}")
 
 # add UMD wrapper
@@ -150,7 +120,7 @@ add_custom_command(OUTPUT "${opencv_test_js_bin_dir}/${test_data}"
                   )
 list(APPEND opencv_test_js_file_deps "${test_data_path}" "${opencv_test_js_bin_dir}/${test_data}")
 
-add_custom_target(${PROJECT_NAME}_test ALL
+add_custom_target(${PROJECT_NAME}_test
                   DEPENDS ${OCV_JS_PATH} ${opencv_test_js_file_deps})
 
 # perf
@@ -173,7 +143,7 @@ foreach(f ${perf_files})
   list(APPEND opencv_perf_js_file_deps "${perf_dir}/${f}" "${opencv_perf_js_bin_dir}/${f}")
 endforeach()
 
-add_custom_target(${PROJECT_NAME}_perf ALL
+add_custom_target(${PROJECT_NAME}_perf
                   DEPENDS ${OCV_JS_PATH} ${opencv_perf_js_file_deps})
 
 #loader
@@ -193,4 +163,6 @@ add_custom_command(
 list(APPEND opencv_loader_js_file_deps "${loader_dir}/loader.js" "${opencv_loader_js_bin_dir}/loader.js")
 
 add_custom_target(${PROJECT_NAME}_loader ALL
-                  DEPENDS ${OCV_JS_PATH} ${opencv_loader_js_file_deps})
\ No newline at end of file
+                  DEPENDS ${OCV_JS_PATH} ${opencv_loader_js_file_deps})
+
+add_custom_target(opencv_test_js ALL DEPENDS opencv_js_test opencv_js_perf opencv_js_loader)
diff --git a/modules/js/common.cmake b/modules/js/common.cmake
new file mode 100644 (file)
index 0000000..192bcca
--- /dev/null
@@ -0,0 +1,13 @@
+# get list of modules to wrap
+if(HAVE_opencv_js)
+  message(STATUS "Wrapped in JavaScript(js):")
+endif()
+set(OPENCV_JS_MODULES "")
+foreach(m ${OPENCV_MODULES_BUILD})
+  if(";${OPENCV_MODULE_${m}_WRAPPERS};" MATCHES ";js;" AND HAVE_${m})
+    list(APPEND OPENCV_JS_MODULES ${m})
+    if(HAVE_opencv_js)
+      message(STATUS "    ${m}")
+    endif()
+  endif()
+endforeach()
diff --git a/modules/js/generator/CMakeLists.txt b/modules/js/generator/CMakeLists.txt
new file mode 100644 (file)
index 0000000..75c8a03
--- /dev/null
@@ -0,0 +1,74 @@
+set(MODULE_NAME "js_bindings_generator")
+set(OPENCV_MODULE_IS_PART_OF_WORLD FALSE)
+ocv_add_module(${MODULE_NAME} INTERNAL)
+
+set(OPENCV_JS_BINDINGS_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE INTERNAL "")
+file(REMOVE_RECURSE "${OPENCV_JS_BINDINGS_DIR}/gen")
+file(MAKE_DIRECTORY "${OPENCV_JS_BINDINGS_DIR}/gen")
+file(REMOVE "${OPENCV_DEPHELPER}/gen_opencv_js_source")  # force re-run after CMake
+
+# This file is included from a subdirectory
+set(JS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
+include(${JS_SOURCE_DIR}/common.cmake)  # fill OPENCV_JS_MODULES
+
+set(opencv_hdrs "")
+foreach(m ${OPENCV_JS_MODULES})
+  list(APPEND opencv_hdrs ${OPENCV_MODULE_${m}_HEADERS})
+endforeach(m)
+
+# header blacklist
+ocv_list_filterout(opencv_hdrs "modules/.*.h$")
+ocv_list_filterout(opencv_hdrs "modules/core/.*/cuda")
+ocv_list_filterout(opencv_hdrs "modules/core/.*/opencl")
+ocv_list_filterout(opencv_hdrs "modules/core/include/opencv2/core/opengl.hpp")
+ocv_list_filterout(opencv_hdrs "modules/core/include/opencv2/core/ocl.hpp")
+ocv_list_filterout(opencv_hdrs "modules/cuda.*")
+ocv_list_filterout(opencv_hdrs "modules/cudev")
+ocv_list_filterout(opencv_hdrs "modules/core/.*/hal/")
+ocv_list_filterout(opencv_hdrs "modules/.*/detection_based_tracker.hpp") # Conditional compilation
+ocv_list_filterout(opencv_hdrs "modules/core/include/opencv2/core/utils/.*")
+
+ocv_update_file("${CMAKE_CURRENT_BINARY_DIR}/headers.txt" "${opencv_hdrs}")
+
+set(bindings_cpp "${OPENCV_JS_BINDINGS_DIR}/gen/bindings.cpp")
+
+set(scripts_hdr_parser "${JS_SOURCE_DIR}/../python/src2/hdr_parser.py")
+
+if(DEFINED ENV{OPENCV_JS_WHITELIST})
+  set(OPENCV_JS_WHITELIST_FILE "$ENV{OPENCV_JS_WHITELIST}")
+else()
+  set(OPENCV_JS_WHITELIST_FILE "${OpenCV_SOURCE_DIR}/platforms/js/opencv_js.config.py")
+endif()
+
+add_custom_command(
+  OUTPUT ${bindings_cpp} "${OPENCV_DEPHELPER}/gen_opencv_js_source"
+  COMMAND
+      ${PYTHON_DEFAULT_EXECUTABLE}
+      "${CMAKE_CURRENT_SOURCE_DIR}/embindgen.py"
+      "${scripts_hdr_parser}"
+      "${bindings_cpp}"
+      "${CMAKE_CURRENT_BINARY_DIR}/headers.txt"
+      "${JS_SOURCE_DIR}/src/core_bindings.cpp"
+      "${OPENCV_JS_WHITELIST_FILE}"
+  COMMAND
+      ${CMAKE_COMMAND} -E touch "${OPENCV_DEPHELPER}/gen_opencv_js_source"
+  WORKING_DIRECTORY
+      "${CMAKE_CURRENT_BINARY_DIR}/gen"
+  DEPENDS
+      ${JS_SOURCE_DIR}/src/core_bindings.cpp
+      ${CMAKE_CURRENT_SOURCE_DIR}/embindgen.py
+      ${CMAKE_CURRENT_SOURCE_DIR}/templates.py
+      ${scripts_hdr_parser}
+      #(not needed - generated by CMake) ${CMAKE_CURRENT_BINARY_DIR}/headers.txt
+      ${opencv_hdrs}
+  COMMENT "Generate source files for JavaScript bindings"
+)
+
+add_custom_target(gen_opencv_js_source
+  # excluded from all: ALL
+  DEPENDS ${bindings_cpp} "${OPENCV_DEPHELPER}/gen_opencv_js_source"
+  SOURCES
+      ${JS_SOURCE_DIR}/src/core_bindings.cpp
+      ${CMAKE_CURRENT_SOURCE_DIR}/embindgen.py
+      ${CMAKE_CURRENT_SOURCE_DIR}/templates.py
+)
similarity index 99%
rename from modules/js/src/embindgen.py
rename to modules/js/generator/embindgen.py
index 0ec4488..6e2bac7 100644 (file)
@@ -104,8 +104,6 @@ def makeWhiteList(module_list):
     return wl
 
 white_list = None
-exec(open(os.environ["OPENCV_JS_WHITELIST"]).read())
-assert(white_list)
 
 # Features to be exported
 export_enums = False
@@ -891,10 +889,10 @@ class JSWrapperGenerator(object):
 
 
 if __name__ == "__main__":
-    if len(sys.argv) < 4:
+    if len(sys.argv) < 5:
         print("Usage:\n", \
             os.path.basename(sys.argv[0]), \
-            "<full path to hdr_parser.py> <bindings.cpp> <headers.txt> <core_bindings.cpp>")
+            "<full path to hdr_parser.py> <bindings.cpp> <headers.txt> <core_bindings.cpp> <opencv_js.config.py>")
         print("Current args are: ", ", ".join(["'"+a+"'" for a in sys.argv]))
         exit(0)
 
@@ -908,5 +906,9 @@ if __name__ == "__main__":
     bindingsCpp = sys.argv[2]
     headers = open(sys.argv[3], 'r').read().split(';')
     coreBindings = sys.argv[4]
+    whiteListFile = sys.argv[5]
+    exec(open(whiteListFile).read())
+    assert(white_list)
+
     generator = JSWrapperGenerator()
     generator.gen(bindingsCpp, headers, coreBindings)
index ceeb641..a43fb72 100644 (file)
@@ -87,7 +87,7 @@ namespace hal {
 using namespace emscripten;
 using namespace cv;
 #ifdef HAVE_OPENCV_DNN
-using namespace dnn;
+using namespace cv::dnn;
 #endif
 
 namespace binding_utils
index 38e988a..cd22db0 100644 (file)
@@ -129,11 +129,9 @@ class Builder:
                "-DBUILD_opencv_superres=OFF",
                "-DBUILD_opencv_stitching=OFF",
                "-DBUILD_opencv_java=OFF",
-               "-DBUILD_opencv_java_bindings_generator=OFF",
                "-DBUILD_opencv_js=ON",
                "-DBUILD_opencv_python2=OFF",
                "-DBUILD_opencv_python3=OFF",
-               "-DBUILD_opencv_python_bindings_generator=OFF",
                "-DBUILD_EXAMPLES=OFF",
                "-DBUILD_PACKAGE=OFF",
                "-DBUILD_TESTS=OFF",