brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.0 KiB · 2d9116b Raw
235 lines · plain
1# CMake build rules for the OCaml language.2# Assumes FindOCaml is used.3# http://ocaml.org/4#5# Example usage:6#7# add_ocaml_library(pkg_a OCAML mod_a OCAMLDEP pkg_b C mod_a_stubs PKG ctypes LLVM core)8#9# Unnamed parameters:10#11#   * Library name.12#13# Named parameters:14#15# OCAML     OCaml module names. Imply presence of a corresponding .ml and .mli files.16# OCAMLDEP  Names of libraries this library depends on.17# C         C stub sources. Imply presence of a corresponding .c file.18# CFLAGS    Additional arguments passed when compiling C stubs.19# PKG       Names of ocamlfind packages this library depends on.20# LLVM      Names of LLVM libraries this library depends on.21# NOCOPY    Do not automatically copy sources (.c, .ml, .mli) from the source directory,22#           e.g. if they are generated.23#24 25function(add_ocaml_library name)26  CMAKE_PARSE_ARGUMENTS(ARG "NOCOPY" "" "OCAML;OCAMLDEP;C;CFLAGS;PKG;LLVM" ${ARGN})27 28  set(src ${CMAKE_CURRENT_SOURCE_DIR})29  set(bin ${CMAKE_CURRENT_BINARY_DIR})30 31  set(ocaml_pkgs)32  foreach( ocaml_pkg ${ARG_PKG} )33    list(APPEND ocaml_pkgs "-package" "${ocaml_pkg}")34  endforeach()35 36  set(sources)37 38  set(ocaml_inputs)39 40  set(ocaml_outputs "${bin}/${name}.cma")41  if( ARG_C )42    list(APPEND ocaml_outputs43         "${bin}/lib${name}${CMAKE_STATIC_LIBRARY_SUFFIX}")44    if ( BUILD_SHARED_LIBS )45      list(APPEND ocaml_outputs46           "${bin}/dll${name}${CMAKE_SHARED_LIBRARY_SUFFIX}")47    endif()48  endif()49  if( HAVE_OCAMLOPT )50    list(APPEND ocaml_outputs51         "${bin}/${name}.cmxa"52         "${bin}/${name}${CMAKE_STATIC_LIBRARY_SUFFIX}")53  endif()54 55  set(ocaml_flags "-lstdc++" "-ldopt" "-L${LLVM_LIBRARY_DIR}"56                  "-ccopt" "-L\\$CAMLORIGIN/../.."57                  "-ccopt" "-Wl,-rpath,\\$CAMLORIGIN/../.."58                  ${ocaml_pkgs})59 60  foreach( ocaml_dep ${ARG_OCAMLDEP} )61    get_target_property(dep_ocaml_flags "ocaml_${ocaml_dep}" OCAML_FLAGS)62    list(APPEND ocaml_flags ${dep_ocaml_flags})63  endforeach()64 65  if( NOT BUILD_SHARED_LIBS )66    list(APPEND ocaml_flags "-custom")67  endif()68 69  if(LLVM_LINK_LLVM_DYLIB)70    list(APPEND ocaml_flags "-lLLVM")71  else()72    explicit_map_components_to_libraries(llvm_libs ${ARG_LLVM})73    foreach( llvm_lib ${llvm_libs} )74      list(APPEND ocaml_flags "-l${llvm_lib}" )75    endforeach()76 77    get_property(system_libs TARGET LLVMSupport PROPERTY LLVM_SYSTEM_LIBS)78    foreach(system_lib ${system_libs})79      if (system_lib MATCHES "^-")80        # If it's an option, pass it without changes.81        list(APPEND ocaml_flags "${system_lib}" )82      else()83        # Otherwise assume it's a library name we need to link with.84        list(APPEND ocaml_flags "-l${system_lib}" )85      endif()86    endforeach()87  endif()88 89  string(REPLACE ";" " " ARG_CFLAGS "${ARG_CFLAGS}")90  set(c_flags "${ARG_CFLAGS} ${LLVM_DEFINITIONS}")91  foreach( include_dir ${LLVM_INCLUDE_DIR} ${LLVM_MAIN_INCLUDE_DIR} )92    set(c_flags "${c_flags} -I${include_dir}")93  endforeach()94  # include -D/-UNDEBUG to match dump function visibility95  # regex from HandleLLVMOptions.cmake96  string(REGEX MATCH "(^| )[/-][UD] *NDEBUG($| )" flag_matches97         "${CMAKE_C_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${CMAKE_C_FLAGS}")98  set(c_flags "${c_flags} ${flag_matches}")99 100  foreach( ocaml_file ${ARG_OCAML} )101    list(APPEND sources "${ocaml_file}.mli" "${ocaml_file}.ml")102 103    list(APPEND ocaml_inputs "${bin}/${ocaml_file}.mli" "${bin}/${ocaml_file}.ml")104 105    list(APPEND ocaml_outputs "${bin}/${ocaml_file}.cmi" "${bin}/${ocaml_file}.cmo")106 107        list(APPEND ocaml_outputs "${bin}/${ocaml_file}.cmti" "${bin}/${ocaml_file}.cmt")108 109    if( HAVE_OCAMLOPT )110      list(APPEND ocaml_outputs111           "${bin}/${ocaml_file}.cmx"112           "${bin}/${ocaml_file}${CMAKE_C_OUTPUT_EXTENSION}")113    endif()114  endforeach()115 116  foreach( c_file ${ARG_C} )117    list(APPEND sources "${c_file}.c")118 119    list(APPEND c_inputs  "${bin}/${c_file}.c")120    list(APPEND c_outputs "${bin}/${c_file}${CMAKE_C_OUTPUT_EXTENSION}")121  endforeach()122 123  if( NOT ARG_NOCOPY )124    foreach( source ${sources} )125      add_custom_command(126          OUTPUT "${bin}/${source}"127          COMMAND "${CMAKE_COMMAND}" "-E" "copy" "${src}/${source}" "${bin}"128          DEPENDS "${src}/${source}"129          COMMENT "Copying ${source} to build area")130    endforeach()131  endif()132 133  foreach( c_input ${c_inputs} )134    get_filename_component(basename "${c_input}" NAME_WE)135    add_custom_command(136      OUTPUT "${basename}${CMAKE_C_OUTPUT_EXTENSION}"137      COMMAND "${OCAMLFIND}" "ocamlc" "-c" "${c_input}" -ccopt ${c_flags}138      DEPENDS "${c_input}"139      COMMENT "Building OCaml stub object file ${basename}${CMAKE_C_OUTPUT_EXTENSION}"140      VERBATIM)141  endforeach()142 143  set(ocaml_params)144  foreach( ocaml_input ${ocaml_inputs} ${c_outputs})145    get_filename_component(filename "${ocaml_input}" NAME)146    list(APPEND ocaml_params "${filename}")147  endforeach()148 149  if( APPLE )150    set(ocaml_rpath "@executable_path/../../../lib${LLVM_LIBDIR_SUFFIX}")151  elseif( UNIX )152    set(ocaml_rpath "\\$ORIGIN/../../../lib${LLVM_LIBDIR_SUFFIX}")153  endif()154  list(APPEND ocaml_flags "-ldopt" "-Wl,-rpath,${ocaml_rpath}")155 156  add_custom_command(157    OUTPUT ${ocaml_outputs}158    COMMAND "${OCAMLFIND}" "ocamlmklib" "-ocamlcflags" "-bin-annot"159      "-o" "${name}" ${ocaml_flags} ${ocaml_params}160    DEPENDS ${ocaml_inputs} ${c_outputs}161    COMMENT "Building OCaml library ${name}"162    VERBATIM)163 164  add_custom_command(165    OUTPUT "${bin}/${name}.odoc"166    COMMAND "${OCAMLFIND}" "ocamldoc"167            "-I" "${bin}"168            "-I" "${LLVM_LIBRARY_DIR}/ocaml/llvm/"169            "-dump" "${bin}/${name}.odoc"170            ${ocaml_pkgs} ${ocaml_inputs}171    DEPENDS ${ocaml_inputs} ${ocaml_outputs}172    COMMENT "Building OCaml documentation for ${name}"173    VERBATIM)174 175  add_custom_target("ocaml_${name}" ALL DEPENDS ${ocaml_outputs} "${bin}/${name}.odoc")176  get_subproject_title(subproject_title)177  set_target_properties("ocaml_${name}" PROPERTIES FOLDER "${subproject_title}/Bindings/OCaml")178 179  set_target_properties("ocaml_${name}" PROPERTIES180    OCAML_FLAGS "-I;${bin}")181  set_target_properties("ocaml_${name}" PROPERTIES182    OCAML_ODOC "${bin}/${name}.odoc")183 184  foreach( ocaml_dep ${ARG_OCAMLDEP} )185    add_dependencies("ocaml_${name}" "ocaml_${ocaml_dep}")186  endforeach()187 188  if( NOT LLVM_OCAML_OUT_OF_TREE )189    foreach( llvm_lib ${llvm_libs} )190      add_dependencies("ocaml_${name}" "${llvm_lib}")191    endforeach()192  endif()193 194  add_dependencies("ocaml_all" "ocaml_${name}")195 196  set(install_files)197  set(install_shlibs)198  foreach( ocaml_output ${ocaml_inputs} ${ocaml_outputs} )199    get_filename_component(ext "${ocaml_output}" EXT)200 201    if( NOT (ext STREQUAL ".cmo" OR202             ext STREQUAL ".ml" OR203             ext STREQUAL CMAKE_C_OUTPUT_EXTENSION OR204             ext STREQUAL CMAKE_SHARED_LIBRARY_SUFFIX) )205      list(APPEND install_files "${ocaml_output}")206    elseif( ext STREQUAL CMAKE_SHARED_LIBRARY_SUFFIX)207      list(APPEND install_shlibs "${ocaml_output}")208    endif()209  endforeach()210 211  install(FILES ${install_files}212          DESTINATION "${LLVM_OCAML_INSTALL_PATH}/llvm")213  install(FILES ${install_shlibs}214          PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE215                      GROUP_READ GROUP_EXECUTE216                      WORLD_READ WORLD_EXECUTE217          DESTINATION "${LLVM_OCAML_INSTALL_PATH}/stublibs")218 219  foreach( install_file ${install_files} ${install_shlibs} )220    get_filename_component(filename "${install_file}" NAME)221    add_custom_command(TARGET "ocaml_${name}" POST_BUILD222      COMMAND "${CMAKE_COMMAND}" "-E" "copy" "${install_file}"223                                             "${LLVM_LIBRARY_DIR}/ocaml/llvm/"224      COMMENT "Copying OCaml library component ${filename} to intermediate area"225      VERBATIM)226    add_dependencies("ocaml_${name}" ocaml_make_directory)227  endforeach()228endfunction()229 230add_custom_target(ocaml_make_directory231  COMMAND "${CMAKE_COMMAND}" "-E" "make_directory" "${LLVM_LIBRARY_DIR}/ocaml/llvm")232add_custom_target("ocaml_all")233set_target_properties(ocaml_all PROPERTIES FOLDER "LLVM/Bindings/OCaml")234set_target_properties(ocaml_make_directory PROPERTIES FOLDER "LLVM/Bindings/OCaml")235