[OCaml] [cmake] Add CMake buildsystem for OCaml.
authorPeter Zotov <whitequark@whitequark.org>
Mon, 1 Dec 2014 19:50:23 +0000 (19:50 +0000)
committerPeter Zotov <whitequark@whitequark.org>
Mon, 1 Dec 2014 19:50:23 +0000 (19:50 +0000)
Closes PR15325.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223071 91177308-0d34-0410-b5e6-96231b3b80d8

24 files changed:
CMakeLists.txt
bindings/ocaml/CMakeLists.txt [new file with mode: 0644]
bindings/ocaml/all_backends/CMakeLists.txt [new file with mode: 0644]
bindings/ocaml/analysis/CMakeLists.txt [new file with mode: 0644]
bindings/ocaml/backends/CMakeLists.txt [new file with mode: 0644]
bindings/ocaml/bitreader/CMakeLists.txt [new file with mode: 0644]
bindings/ocaml/bitwriter/CMakeLists.txt [new file with mode: 0644]
bindings/ocaml/executionengine/CMakeLists.txt [new file with mode: 0644]
bindings/ocaml/irreader/CMakeLists.txt [new file with mode: 0644]
bindings/ocaml/linker/CMakeLists.txt [new file with mode: 0644]
bindings/ocaml/llvm/CMakeLists.txt [new file with mode: 0644]
bindings/ocaml/target/CMakeLists.txt [new file with mode: 0644]
bindings/ocaml/transforms/CMakeLists.txt [new file with mode: 0644]
bindings/ocaml/transforms/ipo/CMakeLists.txt [new file with mode: 0644]
bindings/ocaml/transforms/passmgr_builder/CMakeLists.txt [new file with mode: 0644]
bindings/ocaml/transforms/scalar_opts/CMakeLists.txt [new file with mode: 0644]
bindings/ocaml/transforms/vectorize/CMakeLists.txt [new file with mode: 0644]
cmake/config-ix.cmake
cmake/modules/AddOCaml.cmake [new file with mode: 0644]
cmake/modules/FindOCaml.cmake [new file with mode: 0644]
docs/CMakeLists.txt
test/Bindings/OCaml/lit.local.cfg
test/CMakeLists.txt
test/lit.cfg

index 6691189..ef07bfa 100644 (file)
@@ -561,6 +561,12 @@ if(LLVM_INCLUDE_TESTS)
   add_subdirectory(utils/unittest)
 endif()
 
+foreach( binding ${LLVM_BINDINGS_LIST} )
+  if( EXISTS "${LLVM_MAIN_SRC_DIR}/bindings/${binding}/CMakeLists.txt" )
+    add_subdirectory(bindings/${binding})
+  endif()
+endforeach()
+
 add_subdirectory(projects)
 
 if(WITH_POLLY)
diff --git a/bindings/ocaml/CMakeLists.txt b/bindings/ocaml/CMakeLists.txt
new file mode 100644 (file)
index 0000000..2058368
--- /dev/null
@@ -0,0 +1,11 @@
+add_subdirectory(llvm)
+add_subdirectory(all_backends)
+add_subdirectory(analysis)
+add_subdirectory(backends)
+add_subdirectory(bitreader)
+add_subdirectory(bitwriter)
+add_subdirectory(irreader)
+add_subdirectory(linker)
+add_subdirectory(target)
+add_subdirectory(transforms)
+add_subdirectory(executionengine)
diff --git a/bindings/ocaml/all_backends/CMakeLists.txt b/bindings/ocaml/all_backends/CMakeLists.txt
new file mode 100644 (file)
index 0000000..716a49c
--- /dev/null
@@ -0,0 +1,5 @@
+add_ocaml_library(llvm_all_backends
+  OCAML    llvm_all_backends
+  OCAMLDEP llvm
+  C        all_backends_ocaml
+  LLVM     ${LLVM_TARGETS_TO_BUILD})
diff --git a/bindings/ocaml/analysis/CMakeLists.txt b/bindings/ocaml/analysis/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f8ca84d
--- /dev/null
@@ -0,0 +1,5 @@
+add_ocaml_library(llvm_analysis
+  OCAML    llvm_analysis
+  OCAMLDEP llvm
+  C        analysis_ocaml
+  LLVM     analysis)
diff --git a/bindings/ocaml/backends/CMakeLists.txt b/bindings/ocaml/backends/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b660c1d
--- /dev/null
@@ -0,0 +1,27 @@
+foreach(TARGET ${LLVM_TARGETS_TO_BUILD})
+  set(OCAML_LLVM_TARGET ${TARGET})
+
+  foreach( ext ml mli )
+    configure_file(
+        "${CMAKE_CURRENT_SOURCE_DIR}/llvm_backend.${ext}.in"
+        "${CMAKE_CURRENT_BINARY_DIR}/llvm_${TARGET}.${ext}")
+  endforeach()
+
+  configure_file(
+    "${CMAKE_CURRENT_SOURCE_DIR}/backend_ocaml.c"
+    "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_ocaml.c")
+
+  add_ocaml_library(llvm_${TARGET}
+    OCAML    llvm_${TARGET}
+    C        ${TARGET}_ocaml
+    CFLAGS   -DTARGET=${TARGET}
+    LLVM     ${TARGET}
+    NOCOPY)
+
+  configure_file(
+    "${CMAKE_CURRENT_SOURCE_DIR}/META.llvm_backend.in"
+    "${LLVM_LIBRARY_OUTPUT_INTDIR}/ocaml/META.llvm_${TARGET}")
+
+  install(FILES "${LLVM_LIBRARY_OUTPUT_INTDIR}/ocaml/META.llvm_${TARGET}"
+          DESTINATION lib/ocaml)
+endforeach()
diff --git a/bindings/ocaml/bitreader/CMakeLists.txt b/bindings/ocaml/bitreader/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8d16103
--- /dev/null
@@ -0,0 +1,5 @@
+add_ocaml_library(llvm_bitreader
+  OCAML    llvm_bitreader
+  OCAMLDEP llvm
+  C        bitreader_ocaml
+  LLVM     bitreader)
diff --git a/bindings/ocaml/bitwriter/CMakeLists.txt b/bindings/ocaml/bitwriter/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5a14498
--- /dev/null
@@ -0,0 +1,5 @@
+add_ocaml_library(llvm_bitwriter
+  OCAML    llvm_bitwriter
+  OCAMLDEP llvm
+  C        bitwriter_ocaml
+  LLVM     bitwriter)
diff --git a/bindings/ocaml/executionengine/CMakeLists.txt b/bindings/ocaml/executionengine/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ae9af08
--- /dev/null
@@ -0,0 +1,6 @@
+add_ocaml_library(llvm_executionengine
+  OCAML    llvm_executionengine
+  OCAMLDEP llvm llvm_target
+  C        executionengine_ocaml
+  LLVM     executionengine mcjit native
+  PKG      ctypes)
diff --git a/bindings/ocaml/irreader/CMakeLists.txt b/bindings/ocaml/irreader/CMakeLists.txt
new file mode 100644 (file)
index 0000000..87d269b
--- /dev/null
@@ -0,0 +1,5 @@
+add_ocaml_library(llvm_irreader
+  OCAML    llvm_irreader
+  OCAMLDEP llvm
+  C        irreader_ocaml
+  LLVM     irreader)
diff --git a/bindings/ocaml/linker/CMakeLists.txt b/bindings/ocaml/linker/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b6bc8ac
--- /dev/null
@@ -0,0 +1,5 @@
+add_ocaml_library(llvm_linker
+  OCAML    llvm_linker
+  OCAMLDEP llvm
+  C        linker_ocaml
+  LLVM     linker)
diff --git a/bindings/ocaml/llvm/CMakeLists.txt b/bindings/ocaml/llvm/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0d0fe3b
--- /dev/null
@@ -0,0 +1,11 @@
+add_ocaml_library(llvm
+  OCAML llvm
+  C     llvm_ocaml
+  LLVM  core transformutils support)
+
+configure_file(
+  "${CMAKE_CURRENT_SOURCE_DIR}/META.llvm.in"
+  "${LLVM_LIBRARY_OUTPUT_INTDIR}/ocaml/META.llvm")
+
+install(FILES "${LLVM_LIBRARY_OUTPUT_INTDIR}/ocaml/META.llvm"
+        DESTINATION lib/ocaml)
diff --git a/bindings/ocaml/target/CMakeLists.txt b/bindings/ocaml/target/CMakeLists.txt
new file mode 100644 (file)
index 0000000..adee0fc
--- /dev/null
@@ -0,0 +1,5 @@
+add_ocaml_library(llvm_target
+  OCAML    llvm_target
+  OCAMLDEP llvm
+  C        target_ocaml
+  LLVM     target)
diff --git a/bindings/ocaml/transforms/CMakeLists.txt b/bindings/ocaml/transforms/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8693ffb
--- /dev/null
@@ -0,0 +1,4 @@
+add_subdirectory(ipo)
+add_subdirectory(passmgr_builder)
+add_subdirectory(scalar_opts)
+add_subdirectory(vectorize)
diff --git a/bindings/ocaml/transforms/ipo/CMakeLists.txt b/bindings/ocaml/transforms/ipo/CMakeLists.txt
new file mode 100644 (file)
index 0000000..4b8784f
--- /dev/null
@@ -0,0 +1,5 @@
+add_ocaml_library(llvm_ipo
+  OCAML    llvm_ipo
+  OCAMLDEP llvm
+  C        ipo_ocaml
+  LLVM     ipo)
diff --git a/bindings/ocaml/transforms/passmgr_builder/CMakeLists.txt b/bindings/ocaml/transforms/passmgr_builder/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b012863
--- /dev/null
@@ -0,0 +1,5 @@
+add_ocaml_library(llvm_passmgr_builder
+  OCAML    llvm_passmgr_builder
+  OCAMLDEP llvm
+  C        passmgr_builder_ocaml
+  LLVM     ipo)
diff --git a/bindings/ocaml/transforms/scalar_opts/CMakeLists.txt b/bindings/ocaml/transforms/scalar_opts/CMakeLists.txt
new file mode 100644 (file)
index 0000000..98c7c68
--- /dev/null
@@ -0,0 +1,5 @@
+add_ocaml_library(llvm_scalar_opts
+  OCAML    llvm_scalar_opts
+  OCAMLDEP llvm
+  C        scalar_opts_ocaml
+  LLVM     scalaropts)
diff --git a/bindings/ocaml/transforms/vectorize/CMakeLists.txt b/bindings/ocaml/transforms/vectorize/CMakeLists.txt
new file mode 100644 (file)
index 0000000..af0ffce
--- /dev/null
@@ -0,0 +1,5 @@
+add_ocaml_library(llvm_vectorize
+  OCAML    llvm_vectorize
+  OCAMLDEP llvm
+  C        vectorize_ocaml
+  LLVM     vectorize)
index 5204f6c..abee8b6 100755 (executable)
@@ -516,3 +516,25 @@ else()
     endif()
   endif()
 endif()
+
+include(FindOCaml)
+include(AddOCaml)
+if(WIN32)
+  message(STATUS "OCaml bindings disabled.")
+else()
+  find_package(OCaml)
+  if( NOT OCAML_FOUND )
+    message(STATUS "OCaml bindings disabled.")
+  else()
+    if( OCAML_VERSION VERSION_LESS "4.00.0" )
+      message(STATUS "OCaml bindings disabled, need OCaml >=4.00.0.")
+    else()
+      message(STATUS "OCaml bindings enabled.")
+      find_ocamlfind_package(ctypes VERSION 0.3)
+      find_ocamlfind_package(oUnit VERSION 2 OPTIONAL)
+      set(LLVM_BINDINGS "${LLVM_BINDINGS} ocaml")
+    endif()
+  endif()
+endif()
+
+string(REPLACE " " ";" LLVM_BINDINGS_LIST "${LLVM_BINDINGS}")
diff --git a/cmake/modules/AddOCaml.cmake b/cmake/modules/AddOCaml.cmake
new file mode 100644 (file)
index 0000000..4babaf6
--- /dev/null
@@ -0,0 +1,199 @@
+# 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_OUTPUT_INTDIR}"
+                  ${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})
+    list(APPEND ocaml_flags "-l${system_lib}" )
+  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()
+
+  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")
+  elseif( UNIX )
+    set(ocaml_rpath "\\$ORIGIN/../../lib")
+  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_OUTPUT_INTDIR}/ocaml/"
+            "-dump" "${bin}/${name}.odoc"
+            ${ocaml_pkgs} ${ocaml_inputs}
+    DEPENDS ${ocaml_inputs}
+    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()
+
+  foreach( llvm_lib ${llvm_libs} )
+    add_dependencies("ocaml_${name}" "${llvm_lib}")
+  endforeach()
+
+  set(install_files)
+  set(install_shlibs)
+  foreach( ocaml_output ${ocaml_outputs} )
+    get_filename_component(ext "${ocaml_output}" EXT)
+
+    if( NOT (ext STREQUAL ".cmo" 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 lib/ocaml)
+  install(FILES ${install_shlibs}
+          PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
+                      GROUP_READ GROUP_EXECUTE
+                      WORLD_READ WORLD_EXECUTE
+          DESTINATION lib/ocaml)
+
+  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_OUTPUT_INTDIR}/ocaml/"
+      COMMENT "Copying OCaml library component ${filename} to intermediate area"
+      VERBATIM)
+  endforeach()
+endfunction()
diff --git a/cmake/modules/FindOCaml.cmake b/cmake/modules/FindOCaml.cmake
new file mode 100644 (file)
index 0000000..8eba212
--- /dev/null
@@ -0,0 +1,103 @@
+# CMake find_package() module for the OCaml language.
+# Assumes ocamlfind will be used for compilation.
+# http://ocaml.org/
+#
+# Example usage:
+#
+# find_package(OCaml)
+#
+# If successful, the following variables will be defined:
+# OCAMLFIND
+# OCAML_VERSION
+# OCAML_STDLIB_PATH
+# HAVE_OCAMLOPT
+#
+# Also provides find_ocamlfind_package() macro.
+#
+# Example usage:
+#
+# find_ocamlfind_package(ctypes)
+#
+# In any case, the following variables are defined:
+#
+# HAVE_OCAML_${pkg}
+#
+# If successful, the following variables will be defined:
+#
+# OCAML_${pkg}_VERSION
+
+include( FindPackageHandleStandardArgs )
+
+find_program(OCAMLFIND
+             NAMES ocamlfind)
+
+if( OCAMLFIND )
+  execute_process(
+    COMMAND ${OCAMLFIND} ocamlc -version
+    OUTPUT_VARIABLE OCAML_VERSION
+    OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+  execute_process(
+    COMMAND ${OCAMLFIND} ocamlc -where
+    OUTPUT_VARIABLE OCAML_STDLIB_PATH
+    OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+  execute_process(
+    COMMAND ${OCAMLFIND} ocamlc -version
+    OUTPUT_QUIET
+    RESULT_VARIABLE find_ocaml_result)
+  if( find_ocaml_result EQUAL 0 )
+    set(HAVE_OCAMLOPT TRUE)
+  else()
+    set(HAVE_OCAMLOPT FALSE)
+  endif()
+endif()
+
+find_package_handle_standard_args( OCaml DEFAULT_MSG
+  OCAMLFIND
+  OCAML_VERSION
+  OCAML_STDLIB_PATH)
+
+mark_as_advanced(
+  OCAMLFIND)
+
+function(find_ocamlfind_package pkg)
+  CMAKE_PARSE_ARGUMENTS(ARG "OPTIONAL" "VERSION" "" ${ARGN})
+
+  execute_process(
+    COMMAND "${OCAMLFIND}" "query" "${pkg}" "-format" "%v"
+    RESULT_VARIABLE result
+    OUTPUT_VARIABLE version
+    ERROR_VARIABLE error
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+    ERROR_STRIP_TRAILING_WHITESPACE)
+
+  if( NOT result EQUAL 0 AND NOT ARG_OPTIONAL )
+    message(FATAL_ERROR ${error})
+  endif()
+
+  if( result EQUAL 0 )
+    set(found TRUE)
+  else()
+    set(found FALSE)
+  endif()
+
+  if( found AND ARG_VERSION )
+    if( version VERSION_LESS ARG_VERSION AND ARG_OPTIONAL )
+      # If it's optional and the constraint is not satisfied, pretend
+      # it wasn't found.
+      set(found FALSE)
+    elseif( version VERSION_LESS ARG_VERSION )
+      message(FATAL_ERROR
+              "ocamlfind package ${pkg} should have version ${ARG_VERSION} or newer")
+    endif()
+  endif()
+
+  string(TOUPPER ${pkg} pkg)
+
+  set(HAVE_OCAML_${pkg} ${found}
+      PARENT_SCOPE)
+
+  set(OCAML_${pkg}_VERSION ${version}
+      PARENT_SCOPE)
+endfunction()
index d310a0a..c6986d0 100644 (file)
@@ -104,3 +104,45 @@ if (LLVM_ENABLE_SPHINX)
 
   endif()
 endif()
+
+list(FIND LLVM_BINDINGS_LIST ocaml uses_ocaml)
+if( NOT uses_ocaml LESS 0 )
+  set(doc_targets
+        ocaml_llvm
+        ocaml_llvm_all_backends
+        ocaml_llvm_analysis
+        ocaml_llvm_bitreader
+        ocaml_llvm_bitwriter
+        ocaml_llvm_executionengine
+        ocaml_llvm_irreader
+        ocaml_llvm_linker
+        ocaml_llvm_target
+        ocaml_llvm_ipo
+        ocaml_llvm_passmgr_builder
+        ocaml_llvm_scalar_opts
+        ocaml_llvm_vectorize
+      )
+
+  foreach(llvm_target ${LLVM_TARGETS_TO_BUILD})
+    list(APPEND doc_targets ocaml_llvm_${llvm_target})
+  endforeach()
+
+  set(odoc_files)
+  foreach( doc_target ${doc_targets} )
+    get_target_property(odoc_file ${doc_target} OCAML_ODOC)
+    list(APPEND odoc_files -load ${odoc_file})
+  endforeach()
+
+  add_custom_target(ocaml_doc
+    COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_CURRENT_BINARY_DIR}/ocamldoc/html
+    COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/ocamldoc/html
+    COMMAND ${OCAMLFIND} ocamldoc -d ${CMAKE_CURRENT_BINARY_DIR}/ocamldoc/html
+                                  -sort -colorize-code -html ${odoc_files})
+
+  add_dependencies(ocaml_doc ${doc_targets})
+
+  if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
+    install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ocamldoc/html
+      DESTINATION docs/ocaml/html)
+  endif()
+endif()
index bca5d39..7a83ca1 100644 (file)
@@ -3,5 +3,5 @@ config.suffixes = ['.ml']
 if not 'ocaml' in config.root.llvm_bindings:
     config.unsupported = True
 
-if config.root.have_ocaml_ounit != '1':
+if config.root.have_ocaml_ounit not in ('1', 'TRUE'):
     config.unsupported = True
index bdb5d79..69c9cf6 100644 (file)
@@ -68,6 +68,24 @@ if(TARGET llvm-go)
   set(LLVM_TEST_DEPENDS ${LLVM_TEST_DEPENDS} llvm-go)
 endif()
 
+if(TARGET ocaml_llvm)
+  set(LLVM_TEST_DEPENDS ${LLVM_TEST_DEPENDS}
+          ocaml_llvm
+          ocaml_llvm_all_backends
+          ocaml_llvm_analysis
+          ocaml_llvm_bitreader
+          ocaml_llvm_bitwriter
+          ocaml_llvm_executionengine
+          ocaml_llvm_irreader
+          ocaml_llvm_linker
+          ocaml_llvm_target
+          ocaml_llvm_ipo
+          ocaml_llvm_passmgr_builder
+          ocaml_llvm_scalar_opts
+          ocaml_llvm_vectorize
+        )
+endif()
+
 add_lit_testsuite(check-llvm "Running the LLVM regression tests"
   ${CMAKE_CURRENT_BINARY_DIR}
   PARAMS llvm_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
index 372e091..50ae60f 100644 (file)
@@ -196,7 +196,8 @@ config.substitutions.append( ('%python', config.python_executable) )
 # OCaml substitutions.
 # Support tests for both native and bytecode builds.
 config.substitutions.append( ('%ocamlc',
-    "%s ocamlc %s" % (config.ocamlfind_executable, config.ocaml_flags)) )
+    "%s ocamlc -cclib -L%s %s" %
+        (config.ocamlfind_executable, llvm_lib_dir, config.ocaml_flags)) )
 if config.have_ocamlopt in ('1', 'TRUE'):
     config.substitutions.append( ('%ocamlopt',
         "%s ocamlopt -cclib -L%s -cclib -Wl,-rpath,%s %s" %