I have an issue with the OCaml build system and the ExecutionEngine.
PR2128 has a patch to change the Interpreter to use libffi. This breaks test/Bindings/Ocaml/executionengine.ml because OCaml doesn't try to link with libffi, even though llvm-config knows that we should:
$ Debug/bin/llvm-config --ldflags interpreter
-L/home/nicholas/llvm-commit/Debug/lib -lpthread -lffi -ldl -lm -lelf
If I run 'ocamlc' by hand and pass it '-cclib -lffi', the test succeeds, so this is the only remaining problem. Is anyone familiar with how Ocaml knows what libraries to link against? We can't just pass `llvm-config --ldflags interpreter` to ocamlc because it doesn't support the -L argument.
Does anyone have any ideas how this ought to work?
Nick
PS. why is it Bindings/Ocaml and not Bindings/OCaml?
I have an issue with the OCaml build system and the ExecutionEngine.
PR2128 has a patch to change the Interpreter to use libffi. This breaks test/Bindings/Ocaml/executionengine.ml because OCaml doesn’t try to link with libffi, even though llvm-config knows that we should:
$ Debug/bin/llvm-config --ldflags interpreter
-L/home/nicholas/llvm-commit/Debug/lib -lpthread -lffi -ldl -lm -lelf
If I run ‘ocamlc’ by hand and pass it ‘-cclib -lffi’, the test succeeds, so this is the only remaining problem. Is anyone familiar with how Ocaml knows what libraries to link against? We can’t just pass llvm-config --ldflags interpreter
to ocamlc because it doesn’t support the -L argument.
Does anyone have any ideas how this ought to work?
The linker flags for each .cma (ocaml library) are baked in by ocaml. Here’s the relevant section from Makefile.ocaml:
Info from llvm-config and similar
ifdef UsedComponents
UsedLibs = $(shell $(LLVM_CONFIG) --libs $(UsedComponents))
UsedLibNames = $(shell $(LLVM_CONFIG) --libnames $(UsedComponents))
endif
Tools
OCAMLCFLAGS += -I $(OcamlDir) -I $(ObjDir)
ifneq ($(ObjectsO),)
OCAMLAFLAGS += $(patsubst %,-cclib %,
$(filter-out -L$(LibDir),-l$(LIBRARYNAME)
$(shell $(LLVM_CONFIG) --ldflags))
$(UsedLibs))
else
OCAMLAFLAGS += $(patsubst %,-cclib %,
$(filter-out -L$(LibDir),$(shell $(LLVM_CONFIG) --ldflags))
$(UsedLibs))
endif
This transforms “x y z” from llvm-config into “-cclib x -cclib y -cclib z”, which instructs ocaml to pass “x y z” down to the linker when creating an executable. The UsedComponents variable originates in this case from bindings/ocaml/executionengine/Makefile:
LEVEL := …/…/…
LIBRARYNAME := llvm_executionengine
DONT_BUILD_RELINKED := 1
UsedComponents := executionengine jit interpreter native
UsedOcamlInterfaces := llvm llvm_target
include …/Makefile.ocaml
I don’t see anything obviously wrong here; it seems that llvm-config -ldflags executionengine jit interpreter native should be invoked, which should give you the -cclib -lffi you seek. make VERBOSE=1 and/or TOO_VERBOSE=1 should show you the full ocaml command lines; maybe that’ll show where -lffi is getting dropped on the floor.
— Gordon
Gordon Henriksen wrote:
I have an issue with the OCaml build system and the ExecutionEngine.
PR2128 has a patch to change the Interpreter to use libffi. This breaks test/Bindings/Ocaml/executionengine.ml because OCaml doesn't try to link with libffi, even though llvm-config knows that we should:
$ Debug/bin/llvm-config --ldflags interpreter
-L/home/nicholas/llvm-commit/Debug/lib -lpthread -lffi -ldl -lm -lelf
If I run 'ocamlc' by hand and pass it '-cclib -lffi', the test succeeds, so this is the only remaining problem. Is anyone familiar with how Ocaml knows what libraries to link against? We can't just pass `llvm-config --ldflags interpreter` to ocamlc because it doesn't support the -L argument.
Does anyone have any ideas how this ought to work?
The linker flags for each .cma (ocaml library) are baked in by ocaml. Here's the relevant section from Makefile.ocaml:
# Info from llvm-config and similar
ifdef UsedComponents
UsedLibs = $(shell $(LLVM_CONFIG) --libs $(UsedComponents))
UsedLibNames = $(shell $(LLVM_CONFIG) --libnames $(UsedComponents))
endif
# Tools
OCAMLCFLAGS += -I $(OcamlDir) -I $(ObjDir)
ifneq ($(ObjectsO),)
OCAMLAFLAGS += $(patsubst %,-cclib %, \
$(filter-out -L$(LibDir),-l$(LIBRARYNAME) \
$(shell $(LLVM_CONFIG)
--ldflags)) \
$(UsedLibs))
else
OCAMLAFLAGS += $(patsubst %,-cclib %, \
$(filter-out -L$(LibDir),$(shell $(LLVM_CONFIG)
--ldflags)) \
$(UsedLibs))
endif
This transforms "x y z" from llvm-config into "-cclib x -cclib y -cclib z", which instructs ocaml to pass "x y z" down to the linker when creating an executable. The UsedComponents variable originates in this case from bindings/ocaml/executionengine/Makefile:
LEVEL := ../../..
LIBRARYNAME := llvm_executionengine
DONT_BUILD_RELINKED := 1
* UsedComponents := executionengine jit interpreter native *
UsedOcamlInterfaces := llvm llvm_target
include ../Makefile.ocaml
I don't see anything obviously wrong here; it seems that llvm-config -ldflags executionengine jit interpreter native should be invoked, which should give you the -cclib -lffi you seek. make VERBOSE=1 and/or TOO_VERBOSE=1 should show you the full ocaml command lines; maybe that'll show where -lffi is getting dropped on the floor.
Thanks for the explanation. It looks like what really happened is that the .cma files weren't regenerated when llvm-config changed. After refreshing bindings/ocaml and rebuilding LLVM, the test passes.
Nick