llvm/bindings/ocaml/Makefile.ocaml
Peter Zotov 47f88b5bdf [OCaml] [autoconf] Migrate to ocamlfind.
This commit updates the OCaml bindings and tests to use ocamlfind.
The bindings are migrated in order to use ctypes, which are now
required for MCJIT-backed Llvm_executionengine.
The tests are migrated in order to use OUnit and to verify that
the distributed META.llvm allows to build working executables.

Every OCaml toolchain invocation is now chained through ocamlfind,
which (in theory) allows to cross-compile the OCaml bindings.

The configure script now checks for ctypes (>= 0.2.3) and
OUnit (>= 2). The code depending on these libraries will be added
later. The configure script does not check the package versions
in order to keep changes less invasive.

Additionally, OCaml bindings will now be automatically enabled
if ocamlfind is detected on the system, rather than ocamlc, as it
was before.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220899 91177308-0d34-0410-b5e6-96231b3b80d8
2014-10-30 08:29:45 +00:00

464 lines
14 KiB
Makefile

##===- bindings/ocaml/Makefile.ocaml -----------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
#
# An OCaml library is a unique project type in the context of LLVM, so rules are
# here rather than in Makefile.rules.
#
# Reference materials on installing OCaml libraries:
#
# https://fedoraproject.org/wiki/Packaging/OCaml
# http://pkg-ocaml-maint.alioth.debian.org/ocaml_packaging_policy.txt
#
##===----------------------------------------------------------------------===##
include $(LEVEL)/Makefile.config
# CFLAGS needs to be set before Makefile.rules is included.
CXX.Flags += -I"$(shell $(OCAMLFIND) c -where)"
C.Flags += -I"$(shell $(OCAMLFIND) c -where)"
ifeq ($(ENABLE_SHARED),1)
LINK_COMPONENTS := all
endif
include $(LEVEL)/Makefile.common
# Intentionally ignore PROJ_prefix here. We want the ocaml stdlib. However, the
# user can override this with OCAML_LIBDIR or configure --with-ocaml-libdir=.
PROJ_libocamldir := $(DESTDIR)$(OCAML_LIBDIR)
OcamlDir := $(LibDir)/ocaml
# Info from llvm-config and similar
ifndef IS_CLEANING_TARGET
ifdef UsedComponents
UsedLibs = $(shell $(LLVM_CONFIG) --libs --system-libs $(UsedComponents))
UsedLibNames = $(shell $(LLVM_CONFIG) --libnames $(UsedComponents))
endif
endif
# How do we link OCaml executables with LLVM?
# 1) If this is a --enable-shared build, build stub libraries. This also allows
# to use LLVM from toplevels.
# 2) If this is a --disable-shared build, embed ocamlc options for building
# a custom runtime and a static executable. It is not possible to use LLVM
# from toplevels.
ifneq ($(ObjectsO),)
ifeq ($(ENABLE_SHARED),1)
OCAMLSTUBS := 1
endif
endif
# Tools
OCAMLCFLAGS += -I $(OcamlDir)
ifndef IS_CLEANING_TARGET
ifneq ($(ObjectsO),)
OCAMLAFLAGS += $(patsubst %,-cclib %, \
$(filter-out -L$(LibDir),-l$(LIBRARYNAME) \
$(shell $(LLVM_CONFIG) --ldflags)) \
$(UsedLibs) $(ExtraLibs))
else
OCAMLAFLAGS += $(patsubst %,-cclib %, \
$(filter-out -L$(LibDir),$(shell $(LLVM_CONFIG) --ldflags)) \
$(UsedLibs) $(ExtraLibs))
endif
endif
ifneq ($(ENABLE_OPTIMIZED),1)
OCAMLDEBUGFLAG := -g
endif
Compile.CMI := $(strip $(OCAMLFIND) c -c $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG) -o)
Compile.CMO := $(strip $(OCAMLFIND) c -c $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG) -o)
Compile.CMX := $(strip $(OCAMLFIND) opt -c $(OCAMLCFLAGS) $(OCAMLDEBUGFLAG) -o)
ifdef OCAMLSTUBS
# Avoid the need for LD_LIBRARY_PATH
ifneq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW))
ifneq ($(HOST_OS),Darwin)
OCAMLRPATH := $(RPATH) -Wl,'$(SharedLibDir)'
endif
endif
endif
ifdef OCAMLSTUBS
Archive.CMA := $(strip $(OCAMLFIND) c -a -dllib -l$(LIBRARYNAME) $(OCAMLDEBUGFLAG) \
-o)
else
Archive.CMA := $(strip $(OCAMLFIND) c -a -custom $(OCAMLAFLAGS) $(OCAMLDEBUGFLAG) \
-o)
endif
ifdef OCAMLSTUBS
Archive.CMXA := $(strip $(OCAMLFIND) opt -a $(patsubst %,-cclib %, \
$(LLVMLibsOptions) -l$(LIBRARYNAME) \
-L$(SharedLibDir) $(OCAMLRPATH)) \
$(OCAMLDEBUGFLAG) -o)
else
Archive.CMXA := $(strip $(OCAMLFIND) opt -a $(OCAMLAFLAGS) $(OCAMLDEBUGFLAG) -o)
endif
# Source files
ifndef OcamlSources1
OcamlSources1 := $(sort $(wildcard $(PROJ_SRC_DIR)/*.ml))
endif
ifndef OcamlHeaders1
OcamlHeaders1 := $(sort $(wildcard $(PROJ_SRC_DIR)/*.mli))
endif
OcamlSources2 := $(filter-out $(ExcludeSources),$(OcamlSources1))
OcamlHeaders2 := $(filter-out $(ExcludeHeaders),$(OcamlHeaders1))
OcamlSources := $(OcamlSources2:$(PROJ_SRC_DIR)/%=$(ObjDir)/%)
OcamlHeaders := $(OcamlHeaders2:$(PROJ_SRC_DIR)/%=$(ObjDir)/%)
# Intermediate files
ObjectsCMI := $(OcamlSources:%.ml=%.cmi)
ObjectsCMO := $(OcamlSources:%.ml=%.cmo)
ObjectsCMX := $(OcamlSources:%.ml=%.cmx)
ifdef LIBRARYNAME
LibraryCMA := $(ObjDir)/$(LIBRARYNAME).cma
LibraryCMXA := $(ObjDir)/$(LIBRARYNAME).cmxa
endif
ifdef TOOLNAME
ToolEXE := $(ObjDir)/$(TOOLNAME)$(EXEEXT)
endif
# Output files
# The .cmo files are the only intermediates; all others are to be installed.
OutputsCMI := $(ObjectsCMI:$(ObjDir)/%.cmi=$(OcamlDir)/%.cmi)
OutputsCMX := $(ObjectsCMX:$(ObjDir)/%.cmx=$(OcamlDir)/%.cmx)
OutputLibs := $(UsedLibNames:%=$(OcamlDir)/%)
ifdef LIBRARYNAME
LibraryA := $(OcamlDir)/lib$(LIBRARYNAME).a
OutputCMA := $(LibraryCMA:$(ObjDir)/%.cma=$(OcamlDir)/%.cma)
OutputCMXA := $(LibraryCMXA:$(ObjDir)/%.cmxa=$(OcamlDir)/%.cmxa)
endif
ifdef OCAMLSTUBS
SharedLib := $(OcamlDir)/dll$(LIBRARYNAME)$(SHLIBEXT)
endif
ifdef TOOLNAME
ifdef EXAMPLE_TOOL
OutputEXE := $(ExmplDir)/$(strip $(TOOLNAME))$(EXEEXT)
else
OutputEXE := $(ToolDir)/$(strip $(TOOLNAME))$(EXEEXT)
endif
endif
# Installation targets
DestLibs := $(UsedLibNames:%=$(PROJ_libocamldir)/%)
ifdef LIBRARYNAME
DestA := $(PROJ_libocamldir)/lib$(LIBRARYNAME).a
DestCMA := $(PROJ_libocamldir)/$(LIBRARYNAME).cma
DestCMXA := $(PROJ_libocamldir)/$(LIBRARYNAME).cmxa
endif
ifdef OCAMLSTUBS
DestSharedLib := $(PROJ_libocamldir)/dll$(LIBRARYNAME)$(SHLIBEXT)
endif
##===- Dependencies -------------------------------------------------------===##
# Copy the sources into the intermediate directory because older ocamlc doesn't
# support -o except when linking (outputs are placed next to inputs).
$(ObjDir)/%.mli: $(PROJ_SRC_DIR)/%.mli $(ObjDir)/.dir
$(Verb) $(CP) -f $< $@
$(ObjDir)/%.ml: $(PROJ_SRC_DIR)/%.ml $(ObjDir)/.dir
$(Verb) $(CP) -f $< $@
$(ObjectsCMI): $(UsedOcamlInterfaces:%=$(OcamlDir)/%.cmi)
ifdef LIBRARYNAME
$(ObjDir)/$(LIBRARYNAME).ocamldep: $(OcamlSources) $(OcamlHeaders) \
$(OcamlDir)/.dir $(ObjDir)/.dir
$(Verb) $(OCAMLFIND) dep $(OCAMLCFLAGS) $(OcamlSources) $(OcamlHeaders) > $@
-include $(ObjDir)/$(LIBRARYNAME).ocamldep
endif
ifdef TOOLNAME
$(ObjDir)/$(TOOLNAME).ocamldep: $(OcamlSources) $(OcamlHeaders) \
$(OcamlDir)/.dir $(ObjDir)/.dir
$(Verb) $(OCAMLFIND) dep $(OCAMLCFLAGS) $(OcamlSources) $(OcamlHeaders) > $@
-include $(ObjDir)/$(TOOLNAME).ocamldep
endif
##===- Build static library from C sources --------------------------------===##
ifdef LibraryA
all-local:: $(LibraryA)
clean-local:: clean-a
install-local:: install-a
uninstall-local:: uninstall-a
$(LibraryA): $(ObjectsO) $(OcamlDir)/.dir
$(Echo) "Building $(BuildMode) $(notdir $@)"
-$(Verb) $(RM) -f $@
$(Verb) $(Archive) $@ $(ObjectsO)
$(Verb) $(Ranlib) $@
clean-a::
-$(Verb) $(RM) -f $(LibraryA)
install-a:: $(LibraryA)
$(Echo) "Installing $(BuildMode) $(DestA)"
$(Verb) $(MKDIR) $(PROJ_libocamldir)
$(Verb) $(INSTALL) $(LibraryA) $(DestA)
$(Verb)
uninstall-a::
$(Echo) "Uninstalling $(DestA)"
-$(Verb) $(RM) -f $(DestA)
endif
##===- Build stub library from C sources ----------------------------------===##
ifdef SharedLib
all-local:: $(SharedLib)
clean-local:: clean-shared
install-local:: install-shared
uninstall-local:: uninstall-shared
$(SharedLib): $(ObjectsO) $(OcamlDir)/.dir
$(Echo) "Building $(BuildMode) $(notdir $@)"
$(Verb) $(Link) $(SharedLinkOptions) $(OCAMLRPATH) $(LLVMLibsOptions) \
-o $@ $(ObjectsO)
clean-shared::
-$(Verb) $(RM) -f $(SharedLib)
install-shared:: $(SharedLib)
$(Echo) "Installing $(BuildMode) $(DestSharedLib)"
$(Verb) $(MKDIR) $(PROJ_libocamldir)
$(Verb) $(INSTALL) $(SharedLib) $(DestSharedLib)
$(Verb)
uninstall-shared::
$(Echo) "Uninstalling $(DestSharedLib)"
-$(Verb) $(RM) -f $(DestSharedLib)
endif
##===- Deposit dependent libraries adjacent to Ocaml libs -----------------===##
all-local:: build-deplibs
clean-local:: clean-deplibs
install-local:: install-deplibs
uninstall-local:: uninstall-deplibs
build-deplibs: $(OutputLibs)
$(OcamlDir)/%.a: $(LibDir)/%.a
$(Verb) ln -sf $< $@
$(OcamlDir)/%.o: $(LibDir)/%.o
$(Verb) ln -sf $< $@
clean-deplibs:
$(Verb) $(RM) -f $(OutputLibs)
install-deplibs:
$(Verb) $(MKDIR) $(PROJ_libocamldir)
$(Verb) for i in $(DestLibs:$(PROJ_libocamldir)/%=%); do \
ln -sf "$(PROJ_libdir)/$$i" "$(PROJ_libocamldir)/$$i"; \
done
uninstall-deplibs:
$(Verb) $(RM) -f $(DestLibs)
##===- Build ocaml interfaces (.mli's -> .cmi's) --------------------------===##
ifneq ($(OcamlHeaders),)
all-local:: build-cmis
clean-local:: clean-cmis
install-local:: install-cmis
uninstall-local:: uninstall-cmis
build-cmis: $(OutputsCMI)
$(OcamlDir)/%.cmi: $(ObjDir)/%.cmi $(OcamlDir)/.dir
$(Verb) $(CP) -f $< $@
$(ObjDir)/%.cmi: $(ObjDir)/%.mli $(ObjDir)/.dir
$(Echo) "Compiling $(notdir $<) for $(BuildMode) build"
$(Verb) $(Compile.CMI) $@ $<
clean-cmis::
-$(Verb) $(RM) -f $(OutputsCMI)
# Also install the .mli's (headers) as documentation.
install-cmis: $(OutputsCMI) $(OcamlHeaders)
$(Verb) $(MKDIR) $(PROJ_libocamldir)
$(Verb) for i in $(OcamlHeaders:$(ObjDir)/%=%); do \
$(EchoCmd) "Installing $(BuildMode) $(PROJ_libocamldir)/$$i"; \
$(DataInstall) $(ObjDir)/$$i "$(PROJ_libocamldir)/$$i"; \
done
$(Verb) for i in $(OutputsCMI:$(OcamlDir)/%=%); do \
$(EchoCmd) "Installing $(BuildMode) $(PROJ_libocamldir)/$$i"; \
$(DataInstall) $(OcamlDir)/$$i "$(PROJ_libocamldir)/$$i"; \
done
uninstall-cmis::
$(Verb) for i in $(OutputsCMI:$(OcamlDir)/%=%); do \
$(EchoCmd) "Uninstalling $(PROJ_libocamldir)/$$i"; \
$(RM) -f "$(PROJ_libocamldir)/$$i"; \
done
$(Verb) for i in $(OcamlHeaders:$(ObjDir)/%=%); do \
$(EchoCmd) "Uninstalling $(PROJ_libocamldir)/$$i"; \
$(RM) -f "$(PROJ_libocamldir)/$$i"; \
done
endif
##===- Build ocaml bytecode archive (.ml's -> .cmo's -> .cma) -------------===##
$(ObjDir)/%.cmo: $(ObjDir)/%.ml
$(Echo) "Compiling $(notdir $<) for $(BuildMode) build"
$(Verb) $(Compile.CMO) $@ $<
ifdef LIBRARYNAME
all-local:: $(OutputCMA)
clean-local:: clean-cma
install-local:: install-cma
uninstall-local:: uninstall-cma
$(OutputCMA): $(LibraryCMA) $(OcamlDir)/.dir
$(Verb) $(CP) -f $< $@
$(LibraryCMA): $(ObjectsCMO) $(OcamlDir)/.dir
$(Echo) "Archiving $(notdir $@) for $(BuildMode) build"
$(Verb) $(Archive.CMA) $@ $(ObjectsCMO)
clean-cma::
$(Verb) $(RM) -f $(OutputCMA) $(UsedLibNames:%=$(OcamlDir)/%)
install-cma:: $(OutputCMA)
$(Echo) "Installing $(BuildMode) $(DestCMA)"
$(Verb) $(MKDIR) $(PROJ_libocamldir)
$(Verb) $(DataInstall) $(OutputCMA) "$(DestCMA)"
uninstall-cma::
$(Echo) "Uninstalling $(DestCMA)"
-$(Verb) $(RM) -f $(DestCMA)
endif
##===- Build optimized ocaml archive (.ml's -> .cmx's -> .cmxa, .a) -------===##
# The ocamlopt compiler is supported on a set of targets disjoint from LLVM's.
# If unavailable, 'configure' will set HAVE_OCAMLOPT to 0 in Makefile.config.
ifeq ($(HAVE_OCAMLOPT),1)
$(OcamlDir)/%.cmx: $(ObjDir)/%.cmx
$(Verb) $(CP) -f $< $@
$(ObjDir)/%.cmx: $(ObjDir)/%.ml
$(Echo) "Compiling optimized $(notdir $<) for $(BuildMode) build"
$(Verb) $(Compile.CMX) $@ $<
ifdef LIBRARYNAME
all-local:: $(OutputCMXA) $(OutputsCMX)
clean-local:: clean-cmxa
install-local:: install-cmxa
uninstall-local:: uninstall-cmxa
$(OutputCMXA): $(LibraryCMXA)
$(Verb) $(CP) -f $< $@
$(Verb) $(CP) -f $(<:.cmxa=.a) $(@:.cmxa=.a)
$(LibraryCMXA): $(ObjectsCMX)
$(Echo) "Archiving $(notdir $@) for $(BuildMode) build"
$(Verb) $(Archive.CMXA) $@ $(ObjectsCMX)
$(Verb) $(RM) -f $(@:.cmxa=.o)
clean-cmxa::
$(Verb) $(RM) -f $(OutputCMXA) $(OutputCMXA:.cmxa=.a) $(OutputsCMX)
install-cmxa:: $(OutputCMXA) $(OutputsCMX)
$(Verb) $(MKDIR) $(PROJ_libocamldir)
$(Echo) "Installing $(BuildMode) $(DestCMXA)"
$(Verb) $(DataInstall) $(OutputCMXA) $(DestCMXA)
$(Echo) "Installing $(BuildMode) $(DestCMXA:.cmxa=.a)"
$(Verb) $(DataInstall) $(OutputCMXA:.cmxa=.a) $(DestCMXA:.cmxa=.a)
$(Verb) for i in $(OutputsCMX:$(OcamlDir)/%=%); do \
$(EchoCmd) "Installing $(BuildMode) $(PROJ_libocamldir)/$$i"; \
$(DataInstall) $(OcamlDir)/$$i "$(PROJ_libocamldir)/$$i"; \
done
uninstall-cmxa::
$(Echo) "Uninstalling $(DestCMXA)"
$(Verb) $(RM) -f $(DestCMXA)
$(Echo) "Uninstalling $(DestCMXA:.cmxa=.a)"
$(Verb) $(RM) -f $(DestCMXA:.cmxa=.a)
$(Verb) for i in $(OutputsCMX:$(OcamlDir)/%=%); do \
$(EchoCmd) "Uninstalling $(PROJ_libocamldir)/$$i"; \
$(RM) -f $(PROJ_libocamldir)/$$i; \
done
endif
endif
##===- Generate documentation ---------------------------------------------===##
$(ObjDir)/$(LIBRARYNAME).odoc: $(ObjectsCMI)
$(Echo) "Documenting $(notdir $@)"
$(Verb) $(OCAMLFIND) doc -I $(ObjDir) -I $(OcamlDir) -dump $@ $(OcamlHeaders)
ocamldoc: $(ObjDir)/$(LIBRARYNAME).odoc
##===- Debugging gunk -----------------------------------------------------===##
printvars:: printcamlvars
printcamlvars::
$(Echo) "LLVM_CONFIG : " '$(LLVM_CONFIG)'
$(Echo) "OCAMLCFLAGS : " '$(OCAMLCFLAGS)'
$(Echo) "OCAMLAFLAGS : " '$(OCAMLAFLAGS)'
$(Echo) "OCAMLFIND : " '$(OCAMLFIND)'
$(Echo) "Compile.CMI : " '$(Compile.CMI)'
$(Echo) "Compile.CMO : " '$(Compile.CMO)'
$(Echo) "Archive.CMA : " '$(Archive.CMA)'
$(Echo) "Compile.CMX : " '$(Compile.CMX)'
$(Echo) "Archive.CMXA : " '$(Archive.CMXA)'
$(Echo) "CAML_LIBDIR : " '$(CAML_LIBDIR)'
$(Echo) "LibraryCMA : " '$(LibraryCMA)'
$(Echo) "LibraryCMXA : " '$(LibraryCMXA)'
$(Echo) "SharedLib : " '$(SharedLib)'
$(Echo) "OcamlSources1: " '$(OcamlSources1)'
$(Echo) "OcamlSources2: " '$(OcamlSources2)'
$(Echo) "OcamlSources : " '$(OcamlSources)'
$(Echo) "OcamlHeaders1: " '$(OcamlHeaders1)'
$(Echo) "OcamlHeaders2: " '$(OcamlHeaders2)'
$(Echo) "OcamlHeaders : " '$(OcamlHeaders)'
$(Echo) "ObjectsCMI : " '$(ObjectsCMI)'
$(Echo) "ObjectsCMO : " '$(ObjectsCMO)'
$(Echo) "ObjectsCMX : " '$(ObjectsCMX)'
$(Echo) "OCAML_LIBDIR : " '$(OCAML_LIBDIR)'
$(Echo) "DestA : " '$(DestA)'
$(Echo) "DestCMA : " '$(DestCMA)'
$(Echo) "DestCMXA : " '$(DestCMXA)'
$(Echo) "DestSharedLib: " '$(DestSharedLib)'
$(Echo) "UsedLibs : " '$(UsedLibs)'
$(Echo) "UsedLibNames : " '$(UsedLibNames)'
$(Echo) "ExtraLibs : " '$(ExtraLibs)'
.PHONY: printcamlvars build-cmis \
clean-a clean-cmis clean-cma clean-cmxa \
install-a install-cmis install-cma install-cmxa \
install-exe \
uninstall-a uninstall-cmis uninstall-cma uninstall-cmxa \
uninstall-exe