opencv/modules/js/CMakeLists.txt
Wenzhao Xiang c2096771cb Merge pull request #15371 from Wenzhao-Xiang:gsoc_2019
[GSoC 2019] Improve the performance of JavaScript version of OpenCV (OpenCV.js)

* [GSoC 2019]

Improve the performance of JavaScript version of OpenCV (OpenCV.js):
1. Create the base of OpenCV.js performance test:
     This perf test is based on benchmark.js(https://benchmarkjs.com). And first add `cvtColor`, `Resize`, `Threshold` into it.
2. Optimize the OpenCV.js performance by WASM threads:
     This optimization is based on Web Worker API and SharedArrayBuffer, so it can be only used in browser.
3. Optimize the OpenCV.js performance by WASM SIMD:
     Add WASM SIMD backend for OpenCV Universal Intrinsics. It's experimental as WASM SIMD is still in development.

* [GSoC2019] 

1. use short license header
2. fix documentation node issue
3. remove the unused `hasSIMD128()` api

* [GSoC2019]

1. fix emscripten define
2. use fallback function for f16

* [GSoC2019]

Fix rebase issue
2019-09-24 16:30:42 +03:00

178 lines
7.2 KiB
CMake

# ----------------------------------------------------------------------------
# CMake file for js support
# ----------------------------------------------------------------------------
set(the_description "The js bindings")
if(NOT BUILD_opencv_js) # should be enabled explicitly (by build_js.py script)
ocv_module_disable(js)
endif()
set(OPENCV_JS "opencv.js")
find_path(EMSCRIPTEN_INCLUDE_DIR
emscripten/bind.h
PATHS
ENV EMSCRIPTEN_ROOT
PATH_SUFFIXES system/include include
DOC "Location of Emscripten SDK")
if(NOT EMSCRIPTEN_INCLUDE_DIR OR NOT PYTHON_DEFAULT_AVAILABLE)
set(DISABLE_MSG "Module 'js' disabled because the following dependencies are not found:")
if(NOT EMSCRIPTEN_INCLUDE_DIR)
set(DISABLE_MSG "${DISABLE_MSG} Emscripten")
endif()
if(NOT PYTHON_DEFAULT_AVAILABLE)
set(DISABLE_MSG "${DISABLE_MSG} Python")
endif()
message(STATUS ${DISABLE_MSG})
ocv_module_disable(js)
endif()
ocv_add_module(js BINDINGS)
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})
OCV_OPTION(BUILD_WASM_INTRIN_TESTS "Build WASM intrin tests" OFF )
if(BUILD_WASM_INTRIN_TESTS)
add_definitions(-DTEST_WASM_INTRIN)
ocv_module_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../ts/include")
ocv_module_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../imgcodecs/include")
ocv_module_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../videoio/include")
ocv_module_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../highgui/include")
ocv_add_executable(${the_module} ${bindings_cpp} "${CMAKE_CURRENT_SOURCE_DIR}/../ts/src/ts_gtest.cpp")
else()
ocv_add_executable(${the_module} ${bindings_cpp})
endif()
set_target_properties(${the_module} PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes")
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_target_properties(${the_module} PROPERTIES LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS}")
# add UMD wrapper
set(MODULE_JS_PATH "${OpenCV_BINARY_DIR}/bin/${the_module}.js")
set(OCV_JS_PATH "${OpenCV_BINARY_DIR}/bin/${OPENCV_JS}")
add_custom_command(
OUTPUT ${OCV_JS_PATH}
COMMAND ${PYTHON_DEFAULT_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/src/make_umd.py" ${MODULE_JS_PATH} "${OCV_JS_PATH}"
DEPENDS ${the_module}
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/make_umd.py")
add_custom_target(${OPENCV_JS} ALL
DEPENDS ${OCV_JS_PATH}
DEPENDS ${the_module})
# test
set(opencv_test_js_bin_dir "${EXECUTABLE_OUTPUT_PATH}")
set(test_dir ${CMAKE_CURRENT_SOURCE_DIR}/test)
set(opencv_test_js_file_deps "")
# message(STATUS "${opencv_test_js_bin_dir}")
# make sure the build directory exists
file(MAKE_DIRECTORY "${opencv_test_js_bin_dir}")
# gather and copy specific files for js test
file(GLOB_RECURSE test_files RELATIVE "${test_dir}" "${test_dir}/*")
foreach(f ${test_files})
# message(STATUS "copy ${test_dir}/${f} ${opencv_test_js_bin_dir}/${f}")
add_custom_command(OUTPUT "${opencv_test_js_bin_dir}/${f}"
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${test_dir}/${f}" "${opencv_test_js_bin_dir}/${f}"
DEPENDS "${test_dir}/${f}"
COMMENT "Copying ${f}"
)
list(APPEND opencv_test_js_file_deps "${test_dir}/${f}" "${opencv_test_js_bin_dir}/${f}")
endforeach()
# copy test data
set(test_data "haarcascade_frontalface_default.xml")
set(test_data_path "${PROJECT_SOURCE_DIR}/../../data/haarcascades/${test_data}")
add_custom_command(OUTPUT "${opencv_test_js_bin_dir}/${test_data}"
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${test_data_path}" "${opencv_test_js_bin_dir}/${test_data}"
DEPENDS "${test_data_path}"
COMMENT "Copying ${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
DEPENDS ${OCV_JS_PATH} ${opencv_test_js_file_deps})
# perf
set(opencv_perf_js_bin_dir "${EXECUTABLE_OUTPUT_PATH}/perf")
set(perf_dir ${CMAKE_CURRENT_SOURCE_DIR}/perf)
set(opencv_perf_js_file_deps "")
# make sure the build directory exists
file(MAKE_DIRECTORY "${opencv_perf_js_bin_dir}")
# gather and copy specific files for js perf
file(GLOB_RECURSE perf_files RELATIVE "${perf_dir}" "${perf_dir}/*")
foreach(f ${perf_files})
add_custom_command(OUTPUT "${opencv_perf_js_bin_dir}/${f}"
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${perf_dir}/${f}" "${opencv_perf_js_bin_dir}/${f}"
DEPENDS "${perf_dir}/${f}"
COMMENT "Copying ${f}"
)
list(APPEND opencv_perf_js_file_deps "${perf_dir}/${f}" "${opencv_perf_js_bin_dir}/${f}")
endforeach()
add_custom_target(${PROJECT_NAME}_perf ALL
DEPENDS ${OCV_JS_PATH} ${opencv_perf_js_file_deps})