# CMake build rules for the OCaml language.
# Assumes FindOCaml is used.
# http://ocaml.org/
#
# Example usage:
#
# add_ocaml_library(pkg_a OCAML mod_a OCAMLDEP pkg_b C mod_a_stubs PKG ctypes LLVM core)
#
# Unnamed parameters:
#
#   * Library name.
#
# Named parameters:
#
# OCAML     OCaml module names. Imply presence of a corresponding .ml and .mli files.
# OCAMLDEP  Names of libraries this library depends on.
# C         C stub sources. Imply presence of a corresponding .c file.
# CFLAGS    Additional arguments passed when compiling C stubs.
# PKG       Names of ocamlfind packages this library depends on.
# LLVM      Names of LLVM libraries this library depends on.
# NOCOPY    Do not automatically copy sources (.c, .ml, .mli) from the source directory,
#           e.g. if they are generated.
#

function(add_ocaml_library name)
  CMAKE_PARSE_ARGUMENTS(ARG "NOCOPY" "" "OCAML;OCAMLDEP;C;CFLAGS;PKG;LLVM" ${ARGN})

  set(src ${CMAKE_CURRENT_SOURCE_DIR})
  set(bin ${CMAKE_CURRENT_BINARY_DIR})

  set(ocaml_pkgs)
  foreach( ocaml_pkg ${ARG_PKG} )
    list(APPEND ocaml_pkgs "-package" "${ocaml_pkg}")
  endforeach()

  set(sources)

  set(ocaml_inputs)

  set(ocaml_outputs "${bin}/${name}.cma")
  if( ARG_C )
    list(APPEND ocaml_outputs
         "${bin}/lib${name}${CMAKE_STATIC_LIBRARY_SUFFIX}")
    if ( BUILD_SHARED_LIBS )
      list(APPEND ocaml_outputs
           "${bin}/dll${name}${CMAKE_SHARED_LIBRARY_SUFFIX}")
    endif()
  endif()
  if( HAVE_OCAMLOPT )
    list(APPEND ocaml_outputs
         "${bin}/${name}.cmxa"
         "${bin}/${name}${CMAKE_STATIC_LIBRARY_SUFFIX}")
  endif()

  set(ocaml_flags "-lstdc++" "-ldopt" "-L${LLVM_LIBRARY_DIR}"
                  "-ccopt" "-L\\$CAMLORIGIN/../.."
                  "-ccopt" "-Wl,-rpath,\\$CAMLORIGIN/../.."
                  ${ocaml_pkgs})

  foreach( ocaml_dep ${ARG_OCAMLDEP} )
    get_target_property(dep_ocaml_flags "ocaml_${ocaml_dep}" OCAML_FLAGS)
    list(APPEND ocaml_flags ${dep_ocaml_flags})
  endforeach()

  if( NOT BUILD_SHARED_LIBS )
    list(APPEND ocaml_flags "-custom")
  endif()

  explicit_map_components_to_libraries(llvm_libs ${ARG_LLVM})
  foreach( llvm_lib ${llvm_libs} )
    list(APPEND ocaml_flags "-l${llvm_lib}" )
  endforeach()

  get_property(system_libs TARGET LLVMSupport PROPERTY LLVM_SYSTEM_LIBS)
  foreach(system_lib ${system_libs})
    if (system_lib MATCHES "^-")
      # If it's an option, pass it without changes.
      list(APPEND ocaml_flags "${system_lib}" )
    else()
      # Otherwise assume it's a library name we need to link with.
      list(APPEND ocaml_flags "-l${system_lib}" )
    endif()
  endforeach()

  string(REPLACE ";" " " ARG_CFLAGS "${ARG_CFLAGS}")
  set(c_flags "${ARG_CFLAGS} ${LLVM_DEFINITIONS}")
  foreach( include_dir ${LLVM_INCLUDE_DIR} ${LLVM_MAIN_INCLUDE_DIR} )
    set(c_flags "${c_flags} -I${include_dir}")
  endforeach()
  # include -D/-UNDEBUG to match dump function visibility
  # regex from HandleLLVMOptions.cmake
  string(REGEX MATCH "(^| )[/-][UD] *NDEBUG($| )" flag_matches
         "${CMAKE_C_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${CMAKE_C_FLAGS}")
  set(c_flags "${c_flags} ${flag_matches}")

  foreach( ocaml_file ${ARG_OCAML} )
    list(APPEND sources "${ocaml_file}.mli" "${ocaml_file}.ml")

    list(APPEND ocaml_inputs "${bin}/${ocaml_file}.mli" "${bin}/${ocaml_file}.ml")

    list(APPEND ocaml_outputs "${bin}/${ocaml_file}.cmi" "${bin}/${ocaml_file}.cmo")
    if( HAVE_OCAMLOPT )
      list(APPEND ocaml_outputs
           "${bin}/${ocaml_file}.cmx"
           "${bin}/${ocaml_file}${CMAKE_C_OUTPUT_EXTENSION}")
    endif()
  endforeach()

  foreach( c_file ${ARG_C} )
    list(APPEND sources "${c_file}.c")

    list(APPEND c_inputs  "${bin}/${c_file}.c")
    list(APPEND c_outputs "${bin}/${c_file}${CMAKE_C_OUTPUT_EXTENSION}")
  endforeach()

  if( NOT ARG_NOCOPY )
    foreach( source ${sources} )
      add_custom_command(
          OUTPUT "${bin}/${source}"
          COMMAND "${CMAKE_COMMAND}" "-E" "copy" "${src}/${source}" "${bin}"
          DEPENDS "${src}/${source}"
          COMMENT "Copying ${source} to build area")
    endforeach()
  endif()

  foreach( c_input ${c_inputs} )
    get_filename_component(basename "${c_input}" NAME_WE)
    add_custom_command(
      OUTPUT "${basename}${CMAKE_C_OUTPUT_EXTENSION}"
      COMMAND "${OCAMLFIND}" "ocamlc" "-c" "${c_input}" -ccopt ${c_flags}
      DEPENDS "${c_input}"
      COMMENT "Building OCaml stub object file ${basename}${CMAKE_C_OUTPUT_EXTENSION}"
      VERBATIM)
  endforeach()

  set(ocaml_params)
  foreach( ocaml_input ${ocaml_inputs} ${c_outputs})
    get_filename_component(filename "${ocaml_input}" NAME)
    list(APPEND ocaml_params "${filename}")
  endforeach()

  if( APPLE )
    set(ocaml_rpath "@executable_path/../../../lib${LLVM_LIBDIR_SUFFIX}")
  elseif( UNIX )
    set(ocaml_rpath "\\$ORIGIN/../../../lib${LLVM_LIBDIR_SUFFIX}")
  endif()
  list(APPEND ocaml_flags "-ldopt" "-Wl,-rpath,${ocaml_rpath}")

  add_custom_command(
    OUTPUT ${ocaml_outputs}
    COMMAND "${OCAMLFIND}" "ocamlmklib" "-o" "${name}" ${ocaml_flags} ${ocaml_params}
    DEPENDS ${ocaml_inputs} ${c_outputs}
    COMMENT "Building OCaml library ${name}"
    VERBATIM)

  add_custom_command(
    OUTPUT "${bin}/${name}.odoc"
    COMMAND "${OCAMLFIND}" "ocamldoc"
            "-I" "${bin}"
            "-I" "${LLVM_LIBRARY_DIR}/ocaml/llvm/"
            "-dump" "${bin}/${name}.odoc"
            ${ocaml_pkgs} ${ocaml_inputs}
    DEPENDS ${ocaml_inputs} ${ocaml_outputs}
    COMMENT "Building OCaml documentation for ${name}"
    VERBATIM)

  add_custom_target("ocaml_${name}" ALL DEPENDS ${ocaml_outputs} "${bin}/${name}.odoc")

  set_target_properties("ocaml_${name}" PROPERTIES
    OCAML_FLAGS "-I;${bin}")
  set_target_properties("ocaml_${name}" PROPERTIES
    OCAML_ODOC "${bin}/${name}.odoc")

  foreach( ocaml_dep ${ARG_OCAMLDEP} )
    add_dependencies("ocaml_${name}" "ocaml_${ocaml_dep}")
  endforeach()

  if( NOT LLVM_OCAML_OUT_OF_TREE )
    foreach( llvm_lib ${llvm_libs} )
      add_dependencies("ocaml_${name}" "${llvm_lib}")
    endforeach()
  endif()

  add_dependencies("ocaml_all" "ocaml_${name}")

  set(install_files)
  set(install_shlibs)
  foreach( ocaml_output ${ocaml_inputs} ${ocaml_outputs} )
    get_filename_component(ext "${ocaml_output}" EXT)

    if( NOT (ext STREQUAL ".cmo" OR
             ext STREQUAL ".ml" OR
             ext STREQUAL CMAKE_C_OUTPUT_EXTENSION OR
             ext STREQUAL CMAKE_SHARED_LIBRARY_SUFFIX) )
      list(APPEND install_files "${ocaml_output}")
    elseif( ext STREQUAL CMAKE_SHARED_LIBRARY_SUFFIX)
      list(APPEND install_shlibs "${ocaml_output}")
    endif()
  endforeach()

  install(FILES ${install_files}
          DESTINATION "${LLVM_OCAML_INSTALL_PATH}/llvm")
  install(FILES ${install_shlibs}
          PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
                      GROUP_READ GROUP_EXECUTE
                      WORLD_READ WORLD_EXECUTE
          DESTINATION "${LLVM_OCAML_INSTALL_PATH}/stublibs")

  foreach( install_file ${install_files} ${install_shlibs} )
    get_filename_component(filename "${install_file}" NAME)
    add_custom_command(TARGET "ocaml_${name}" POST_BUILD
      COMMAND "${CMAKE_COMMAND}" "-E" "copy" "${install_file}"
                                             "${LLVM_LIBRARY_DIR}/ocaml/llvm/"
      COMMENT "Copying OCaml library component ${filename} to intermediate area"
      VERBATIM)
    add_dependencies("ocaml_${name}" ocaml_make_directory)
  endforeach()
endfunction()

add_custom_target(ocaml_make_directory
  COMMAND "${CMAKE_COMMAND}" "-E" "make_directory" "${LLVM_LIBRARY_DIR}/ocaml/llvm")
add_custom_target("ocaml_all")
set_target_properties(ocaml_all PROPERTIES FOLDER "Misc")
set_target_properties(ocaml_make_directory PROPERTIES FOLDER "Misc")
