Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -530,6 +530,12 @@ 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) Index: bindings/ocaml/CMakeLists.txt =================================================================== --- /dev/null +++ bindings/ocaml/CMakeLists.txt @@ -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) Index: bindings/ocaml/all_backends/CMakeLists.txt =================================================================== --- /dev/null +++ bindings/ocaml/all_backends/CMakeLists.txt @@ -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}) Index: bindings/ocaml/analysis/CMakeLists.txt =================================================================== --- /dev/null +++ bindings/ocaml/analysis/CMakeLists.txt @@ -0,0 +1,5 @@ +add_ocaml_library(llvm_analysis + OCAML llvm_analysis + OCAMLDEP llvm + C analysis_ocaml + LLVM analysis) Index: bindings/ocaml/backends/CMakeLists.txt =================================================================== --- /dev/null +++ bindings/ocaml/backends/CMakeLists.txt @@ -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() Index: bindings/ocaml/bitreader/CMakeLists.txt =================================================================== --- /dev/null +++ bindings/ocaml/bitreader/CMakeLists.txt @@ -0,0 +1,5 @@ +add_ocaml_library(llvm_bitreader + OCAML llvm_bitreader + OCAMLDEP llvm + C bitreader_ocaml + LLVM bitreader) Index: bindings/ocaml/bitwriter/CMakeLists.txt =================================================================== --- /dev/null +++ bindings/ocaml/bitwriter/CMakeLists.txt @@ -0,0 +1,5 @@ +add_ocaml_library(llvm_bitwriter + OCAML llvm_bitwriter + OCAMLDEP llvm + C bitwriter_ocaml + LLVM bitwriter) Index: bindings/ocaml/executionengine/CMakeLists.txt =================================================================== --- /dev/null +++ bindings/ocaml/executionengine/CMakeLists.txt @@ -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) Index: bindings/ocaml/irreader/CMakeLists.txt =================================================================== --- /dev/null +++ bindings/ocaml/irreader/CMakeLists.txt @@ -0,0 +1,5 @@ +add_ocaml_library(llvm_irreader + OCAML llvm_irreader + OCAMLDEP llvm + C irreader_ocaml + LLVM irreader) Index: bindings/ocaml/linker/CMakeLists.txt =================================================================== --- /dev/null +++ bindings/ocaml/linker/CMakeLists.txt @@ -0,0 +1,5 @@ +add_ocaml_library(llvm_linker + OCAML llvm_linker + OCAMLDEP llvm + C linker_ocaml + LLVM linker) Index: bindings/ocaml/llvm/CMakeLists.txt =================================================================== --- /dev/null +++ bindings/ocaml/llvm/CMakeLists.txt @@ -0,0 +1,11 @@ +add_ocaml_library(llvm + OCAML llvm + C llvm_ocaml + LLVM core 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) Index: bindings/ocaml/llvm/META.llvm.in =================================================================== --- bindings/ocaml/llvm/META.llvm.in +++ bindings/ocaml/llvm/META.llvm.in @@ -61,6 +61,14 @@ archive(native) = "llvm_scalar_opts.cmxa" ) +package "transform_utils" ( + requires = "llvm" + version = "@PACKAGE_VERSION@" + description = "Transform utilities for LLVM" + archive(byte) = "llvm_transform_utils.cma" + archive(native) = "llvm_transform_utils.cmxa" +) + package "vectorize" ( requires = "llvm" version = "@PACKAGE_VERSION@" Index: bindings/ocaml/llvm/Makefile =================================================================== --- bindings/ocaml/llvm/Makefile +++ bindings/ocaml/llvm/Makefile @@ -13,7 +13,7 @@ LEVEL := ../../.. LIBRARYNAME := llvm -UsedComponents := core transformutils +UsedComponents := core UsedOcamlLibs := llvm ExtraLibs := -lstdc++ Index: bindings/ocaml/llvm/llvm.ml =================================================================== --- bindings/ocaml/llvm/llvm.ml +++ bindings/ocaml/llvm/llvm.ml @@ -313,7 +313,6 @@ (*===-- Modules -----------------------------------------------------------===*) external create_module : llcontext -> string -> llmodule = "llvm_create_module" external dispose_module : llmodule -> unit = "llvm_dispose_module" -external clone_module : llmodule -> llmodule = "LLVMCloneModule" external target_triple: llmodule -> string = "llvm_target_triple" external set_target_triple: string -> llmodule -> unit Index: bindings/ocaml/llvm/llvm.mli =================================================================== --- bindings/ocaml/llvm/llvm.mli +++ bindings/ocaml/llvm/llvm.mli @@ -431,9 +431,6 @@ [llvm::Module::~Module]. *) val dispose_module : llmodule -> unit -(** [clone_module m] returns an exact copy of module [m]. *) -val clone_module : llmodule -> llmodule - (** [target_triple m] is the target specifier for the module [m], something like [i686-apple-darwin8]. See the method [llvm::Module::getTargetTriple]. *) val target_triple: llmodule -> string Index: bindings/ocaml/target/CMakeLists.txt =================================================================== --- /dev/null +++ bindings/ocaml/target/CMakeLists.txt @@ -0,0 +1,5 @@ +add_ocaml_library(llvm_target + OCAML llvm_target + OCAMLDEP llvm + C target_ocaml + LLVM target) Index: bindings/ocaml/transforms/CMakeLists.txt =================================================================== --- /dev/null +++ bindings/ocaml/transforms/CMakeLists.txt @@ -0,0 +1,5 @@ +add_subdirectory(ipo) +add_subdirectory(passmgr_builder) +add_subdirectory(scalar_opts) +add_subdirectory(utils) +add_subdirectory(vectorize) Index: bindings/ocaml/transforms/Makefile =================================================================== --- bindings/ocaml/transforms/Makefile +++ bindings/ocaml/transforms/Makefile @@ -8,7 +8,7 @@ ##===----------------------------------------------------------------------===## LEVEL := ../../.. -DIRS = scalar_opts ipo vectorize passmgr_builder +DIRS = ipo passmgr_builder scalar_opts utils vectorize ocamldoc: $(Verb) for i in $(DIRS) ; do \ Index: bindings/ocaml/transforms/ipo/CMakeLists.txt =================================================================== --- /dev/null +++ bindings/ocaml/transforms/ipo/CMakeLists.txt @@ -0,0 +1,5 @@ +add_ocaml_library(llvm_ipo + OCAML llvm_ipo + OCAMLDEP llvm + C ipo_ocaml + LLVM ipo) Index: bindings/ocaml/transforms/passmgr_builder/CMakeLists.txt =================================================================== --- /dev/null +++ bindings/ocaml/transforms/passmgr_builder/CMakeLists.txt @@ -0,0 +1,5 @@ +add_ocaml_library(llvm_passmgr_builder + OCAML llvm_passmgr_builder + OCAMLDEP llvm + C passmgr_builder_ocaml + LLVM ipo) Index: bindings/ocaml/transforms/scalar_opts/CMakeLists.txt =================================================================== --- /dev/null +++ bindings/ocaml/transforms/scalar_opts/CMakeLists.txt @@ -0,0 +1,5 @@ +add_ocaml_library(llvm_scalar_opts + OCAML llvm_scalar_opts + OCAMLDEP llvm + C scalar_opts_ocaml + LLVM scalaropts) Index: bindings/ocaml/transforms/utils/CMakeLists.txt =================================================================== --- /dev/null +++ bindings/ocaml/transforms/utils/CMakeLists.txt @@ -0,0 +1,5 @@ +add_ocaml_library(llvm_transform_utils + OCAML llvm_transform_utils + OCAMLDEP llvm + C transform_utils_ocaml + LLVM transformutils) Index: bindings/ocaml/transforms/utils/Makefile =================================================================== --- /dev/null +++ bindings/ocaml/transforms/utils/Makefile @@ -0,0 +1,19 @@ +##===- bindings/ocaml/transforms/utils/Makefile ------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +# +# This is the makefile for the Objective Caml Llvm_vectorize interface. +# +##===----------------------------------------------------------------------===## + +LEVEL := ../../../.. +LIBRARYNAME := llvm_transform_utils +UsedComponents := transformutils +UsedOcamlInterfaces := llvm + +include ../../Makefile.ocaml Index: bindings/ocaml/transforms/utils/llvm_transform_utils.ml =================================================================== --- /dev/null +++ bindings/ocaml/transforms/utils/llvm_transform_utils.ml @@ -0,0 +1,10 @@ +(*===-- llvm_transform_utils.ml - LLVM OCaml Interface --------*- OCaml -*-===* + * + * The LLVM Compiler Infrastructure + * + * This file is distributed under the University of Illinois Open Source + * License. See LICENSE.TXT for details. + * + *===----------------------------------------------------------------------===*) + +external clone_module : Llvm.llmodule -> Llvm.llmodule = "llvm_clone_module" Index: bindings/ocaml/transforms/utils/llvm_transform_utils.mli =================================================================== --- /dev/null +++ bindings/ocaml/transforms/utils/llvm_transform_utils.mli @@ -0,0 +1,17 @@ +(*===-- llvm_transform_utils.mli - LLVM OCaml Interface -------*- OCaml -*-===* + * + * The LLVM Compiler Infrastructure + * + * This file is distributed under the University of Illinois Open Source + * License. See LICENSE.TXT for details. + * + *===----------------------------------------------------------------------===*) + +(** Transform Utilities. + + This interface provides an OCaml API for LLVM transform utilities, the + classes in the [LLVMTransformUtils] library. *) + +(** [clone_module m] returns an exact copy of module [m]. + See the [llvm::CloneModule] function. *) +external clone_module : Llvm.llmodule -> Llvm.llmodule = "llvm_clone_module" Index: bindings/ocaml/transforms/utils/transform_utils_ocaml.c =================================================================== --- /dev/null +++ bindings/ocaml/transforms/utils/transform_utils_ocaml.c @@ -0,0 +1,31 @@ +/*===-- vectorize_ocaml.c - LLVM OCaml Glue ---------------------*- C++ -*-===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This file glues LLVM's OCaml interface to its C interface. These functions *| +|* are by and large transparent wrappers to the corresponding C functions. *| +|* *| +|* Note that these functions intentionally take liberties with the CAMLparamX *| +|* macros, since most of the parameters are not GC heap objects. *| +|* *| +\*===----------------------------------------------------------------------===*/ + +#include "llvm-c/Core.h" +#include "caml/mlvalues.h" +#include "caml/misc.h" + +/* + * Do not move directly into external. This function is here to pull in + * -lLLVMTransformUtils, which would otherwise be not linked on static builds, + * as ld can't see the reference from OCaml code. + */ + +/* llmodule -> llmodule */ +CAMLprim LLVMModuleRef llvm_clone_module(LLVMModuleRef M) { + return LLVMCloneModule(M); +} Index: bindings/ocaml/transforms/vectorize/CMakeLists.txt =================================================================== --- /dev/null +++ bindings/ocaml/transforms/vectorize/CMakeLists.txt @@ -0,0 +1,5 @@ +add_ocaml_library(llvm_vectorize + OCAML llvm_vectorize + OCAMLDEP llvm + C vectorize_ocaml + LLVM vectorize) Index: cmake/config-ix.cmake =================================================================== --- cmake/config-ix.cmake +++ cmake/config-ix.cmake @@ -516,3 +516,25 @@ 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}") Index: cmake/modules/AddOCaml.cmake =================================================================== --- /dev/null +++ cmake/modules/AddOCaml.cmake @@ -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() Index: cmake/modules/FindOCaml.cmake =================================================================== --- /dev/null +++ cmake/modules/FindOCaml.cmake @@ -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: docs/CMakeLists.txt =================================================================== --- docs/CMakeLists.txt +++ docs/CMakeLists.txt @@ -104,3 +104,48 @@ 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_transform_utils + 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} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/_ocamldoc/style.css + ${CMAKE_CURRENT_BINARY_DIR}/ocamldoc/html) + + 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: docs/_ocamldoc/style.css =================================================================== --- /dev/null +++ docs/_ocamldoc/style.css @@ -0,0 +1,97 @@ +/* A style for ocamldoc. Daniel C. Buenzli */ + +/* Reset a few things. */ +html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre, +a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp, +small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset, +form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td +{ margin: 0; padding: 0; border: 0 none; outline: 0; font-size: 100%; + font-weight: inherit; font-style:inherit; font-family:inherit; + line-height: inherit; vertical-align: baseline; text-align:inherit; + color:inherit; background: transparent; } + +table { border-collapse: collapse; border-spacing: 0; } + +/* Basic page layout */ + +body { font: normal 10pt/1.375em helvetica, arial, sans-serif; text-align:left; + margin: 1.375em 10%; min-width: 40ex; max-width: 72ex; + color: black; background: transparent /* url(line-height-22.gif) */; } + +b { font-weight: bold } +em { font-style: italic } + +tt, code, pre { font-family: WorkAroundWebKitAndMozilla, monospace; + font-size: 1em; } +pre code { font-size : inherit; } +.codepre { margin-bottom:1.375em /* after code example we introduce space. */ } + +.superscript,.subscript +{ font-size : 0.813em; line-height:0; margin-left:0.4ex;} +.superscript { vertical-align: super; } +.subscript { vertical-align: sub; } + +/* ocamldoc markup workaround hacks */ + + + +hr, hr + br, div + br, center + br, span + br, ul + br, ol + br, pre + br +{ display: none } /* annoying */ + +div.info + br { display:block} + +.codepre br + br { display: none } +h1 + pre { margin-bottom:1.375em} /* Toplevel module description */ + +/* Sections and document divisions */ + +/* .navbar { margin-bottom: -1.375em } */ +h1 { font-weight: bold; font-size: 1.5em; /* margin-top:1.833em; */ + margin-top:0.917em; padding-top:0.875em; + border-top-style:solid; border-width:1px; border-color:#AAA; } +h2 { font-weight: bold; font-size: 1.313em; margin-top: 1.048em } +h3 { font-weight: bold; font-size: 1.125em; margin-top: 1.222em } +h3 { font-weight: bold; font-size: 1em; margin-top: 1.375em} +h4 { font-style: italic; } + +/* Used by OCaml's own library documentation. */ + h6 { font-weight: bold; font-size: 1.125em; margin-top: 1.222em } + .h7 { font-weight: bold; font-size: 1em; margin-top: 1.375em } + +p { margin-top: 1.375em } +pre { margin-top: 1.375em } +.info { margin: 0.458em 0em -0.458em 2em;}/* Description of types values etc. */ +td .info { margin:0; padding:0; margin-left: 2em;} /* Description in indexes */ + +ul, ol { margin-top:0.688em; padding-bottom:0.687em; + list-style-position:outside} +ul + p, ol + p { margin-top: 0em } +ul { list-style-type: square } + + +/* h2 + ul, h3 + ul, p + ul { } */ +ul > li { margin-left: 1.375em; } +ol > li { margin-left: 1.7em; } +/* Links */ + +a, a:link, a:visited, a:active, a:hover { color : #00B; text-decoration: none } +a:hover { text-decoration : underline } +*:target {background-color: #FFFF99;} /* anchor highlight */ + +/* Code */ + +.keyword { font-weight: bold; } +.comment { color : red } +.constructor { color : green } +.string { color : brown } +.warning { color : red ; font-weight : bold } + +/* Functors */ + +.paramstable { border-style : hidden ; padding-bottom:1.375em} +.paramstable code { margin-left: 1ex; margin-right: 1ex } +.sig_block {margin-left: 1em} + +/* Images */ + +img { margin-top: 1.375em } Index: test/Bindings/OCaml/lit.local.cfg =================================================================== --- test/Bindings/OCaml/lit.local.cfg +++ test/Bindings/OCaml/lit.local.cfg @@ -3,5 +3,5 @@ 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: test/Bindings/OCaml/transform_utils.ml =================================================================== --- /dev/null +++ test/Bindings/OCaml/transform_utils.ml @@ -0,0 +1,21 @@ +(* RUN: cp %s %T/transform_utils.ml + * RUN: %ocamlc -g -warn-error A -package llvm.transform_utils -linkpkg %T/transform_utils.ml -o %t + * RUN: %t + * RUN: %ocamlopt -g -warn-error A -package llvm.transform_utils -linkpkg %T/transform_utils.ml -o %t + * RUN: %t + * XFAIL: vg_leak + *) + +open Llvm +open Llvm_transform_utils + +let context = global_context () + +let test_clone_module () = + let m = create_module context "mod" in + let m' = clone_module m in + if m == m' then failwith "m == m'"; + if string_of_llmodule m <> string_of_llmodule m' then failwith "string_of m <> m'" + +let () = + test_clone_module () Index: test/CMakeLists.txt =================================================================== --- test/CMakeLists.txt +++ test/CMakeLists.txt @@ -68,6 +68,25 @@ 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_transform_utils + 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: test/lit.cfg =================================================================== --- test/lit.cfg +++ test/lit.cfg @@ -198,7 +198,8 @@ # 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" %