set(the_description "All the selected OpenCV modules in a single binary")
set(OPENCV_MODULE_IS_PART_OF_WORLD FALSE)
set(BUILD_opencv_world_INIT OFF)

if(IOS OR NOT BUILD_SHARED_LIBS)
  set(OPENCV_MODULE_TYPE STATIC)
  set(OPENCV_WORLD_FLAGS_PROPERTY STATIC_LIBRARY_FLAGS)
else()
  set(OPENCV_WORLD_FLAGS_PROPERTY LINK_FLAGS)
endif()

ocv_add_module(world opencv_core)

if(MSVC)
  foreach(_var CMAKE_EXE_LINKER_FLAGS_RELEASE CMAKE_MODULE_LINKER_FLAGS_RELEASE CMAKE_SHARED_LINKER_FLAGS_RELEASE
               CMAKE_EXE_LINKER_FLAGS_DEBUG   CMAKE_MODULE_LINKER_FLAGS_DEBUG   CMAKE_SHARED_LINKER_FLAGS_DEBUG)
    string(REPLACE "/INCREMENTAL:NO" "/INCREMENTAL:YES" ${_var} "${${_var}}")
  endforeach()
endif()

ocv_glob_module_sources()
ocv_module_include_directories()
ocv_create_module(SKIP_LINK)

#TODO: try to use try_compile to find real object file extension/location
if(CMAKE_GENERATOR MATCHES "^Visual.*$")
  set(have_cfg 1)
  set(objpath0 "<MODULE_NAME>.dir/<CONFIGURATION>/<SRC_NAME_WE>.obj")
elseif (CMAKE_GENERATOR MATCHES Xcode)
  set(have_cfg 1)
  set(objpath0 "OpenCV.build/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/<MODULE_NAME>.build/Objects-normal/$(CURRENT_ARCH)/<SRC_NAME_WE>.o")
else()
  set(have_cfg 0)
  set(objpath0 "CMakeFiles/<MODULE_NAME>.dir/<RELATIVE_SRC_NAME>.o")
  if(MINGW OR MSVC)
    set(objpath0 "${objpath0}bj")
  endif()
endif()

set(objlist "")
foreach(m ${OPENCV_MODULE_${the_module}_DEPS})
  # build order dependencies
  add_dependencies(${the_module} ${m})
  # link dependencies
  string(REGEX REPLACE "(general|debug|optimized);opencv_[^;]*(;|$)" "" _link_deps "${${m}_LIB_DEPENDS}")
  if(_link_deps)
    target_link_libraries(${the_module} ${_link_deps})
  endif()

  string(REGEX REPLACE "<MODULE_NAME>" "${m}" objpath1 "${${m}_BINARY_DIR}/${objpath0}")
  foreach(srcname ${OPENCV_MODULE_${m}_SOURCES})
    if(srcname MATCHES "\\.(cpp|mm|c|cxx|cc|o|obj)$")
      if(srcname MATCHES "\\.(o|obj)$")
        if(IS_ABSOLUTE "${srcname}")
          set(objpath3 "${srcname}")
        else()
          set(objpath3 "${${m}_SOURCE_DIR}/${srcname}")
        endif()
      else()
        if(IS_ABSOLUTE "${srcname}")
          if(srcname MATCHES "/(qrc|moc)_[^/]*\\.cxx$")
            # QT generated sources
            file(RELATIVE_PATH srcname "${${m}_BINARY_DIR}" "${srcname}")
          else()
            file(RELATIVE_PATH srcname "${OPENCV_MODULE_${m}_LOCATION}" "${srcname}")
          endif()
        endif()
        string(REPLACE ".." "__" srcname "${srcname}")
        #NAME_WE intentionally not used since it interprets first period as start of extension (http://cmake.org/Bug/view.php?id=12282)
        get_filename_component(srcname_we "${srcname}" NAME)
        string(REGEX REPLACE "\\.[^.]+$" "" srcname_we "${srcname_we}")
        string(REGEX REPLACE <SRC_NAME_WE> "${srcname_we}" objpath2 "${objpath1}")
        string(REGEX REPLACE <RELATIVE_SRC_NAME> "${srcname}" objpath3 "${objpath2}")
      endif()
      if(CMAKE_GENERATOR MATCHES Makefiles)
        file(RELATIVE_PATH objpath4 "${CMAKE_CURRENT_BINARY_DIR}" "${objpath3}")
      else()
        set(objpath4 ${objpath3})
      endif()
      list(APPEND objlist "\"${objpath4}\"")
    endif()
  endforeach()
endforeach()


macro(ios_include_3party_libs)
  foreach(l ${ARGN})
    add_dependencies(${the_module} ${l})
    string(REGEX REPLACE "<MODULE_NAME>" "${l}" objpath1 "${CMAKE_BINARY_DIR}/3rdparty/${l}/${objpath0}")
    file(GLOB sources ${CMAKE_SOURCE_DIR}/3rdparty/${l}/*.c)
    foreach(srcname ${sources})
      if(IS_ABSOLUTE "${srcname}")
        file(RELATIVE_PATH srcname "${CMAKE_SOURCE_DIR}/3rdparty/${l}" "${srcname}")
      endif()

      string(REPLACE ".." "__" srcname "${srcname}")
      #NAME_WE intentionally not used since it interprets first period as start of extension (http://cmake.org/Bug/view.php?id=12282)
      get_filename_component(srcname_we "${srcname}" NAME)
      string(REGEX REPLACE "\\.[^.]+$" "" srcname_we "${srcname_we}")
      string(REGEX REPLACE <SRC_NAME_WE> "${srcname_we}" objpath2 "${objpath1}")
      string(REGEX REPLACE <RELATIVE_SRC_NAME> "${srcname}" objpath3 "${objpath2}")

      list(APPEND objlist "\"${objpath3}\"")
    endforeach() # (srcname ${sources})
  endforeach()
  ocv_list_filterout(objlist jmemansi) # <<= dirty fix
endmacro()

if(IOS AND WITH_PNG)
  ios_include_3party_libs(zlib libpng)
endif()

if(IOS AND WITH_JPEG)
  ios_include_3party_libs(libjpeg)
endif()

string(REPLACE ";" " " objlist "${objlist}")

if(have_cfg)
  string(REGEX REPLACE "<CONFIGURATION>" "Debug" objlist_dbg "${objlist}")
  string(REGEX REPLACE "<CONFIGURATION>" "Release" objlist_rls "${objlist}")
  set_target_properties(${the_module} PROPERTIES
    ${OPENCV_WORLD_FLAGS_PROPERTY}_DEBUG ${objlist_dbg}
    ${OPENCV_WORLD_FLAGS_PROPERTY}_RELEASE ${objlist_rls})
else()
  file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/world_objects.list" "${objlist}")
  execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_BINARY_DIR}/world_objects.list" "${CMAKE_CURRENT_BINARY_DIR}/world_objects.rsp" OUTPUT_QUIET)
  set_target_properties(${the_module} PROPERTIES
    ${OPENCV_WORLD_FLAGS_PROPERTY} "@${CMAKE_CURRENT_BINARY_DIR}/world_objects.rsp")
endif()

ocv_add_precompiled_headers(${the_module})
