Skip to content

Commit

Permalink
[OCaml] Build stub OCaml libraries for all configured targets
Browse files Browse the repository at this point in the history
This allows to only link in the needed targets, reducing binary
size and more importantly link time.

Note that this is an incomplete implementation: currently,
LLVM does not have the plumbing which would allow to conditionally
link in AsmPrinter, AsmParser and Disassembler for the targets
which support them. This should be improved in the future.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194670 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
whitequark committed Nov 14, 2013
1 parent a69773c commit 2bdf881
Show file tree
Hide file tree
Showing 6 changed files with 195 additions and 0 deletions.
8 changes: 8 additions & 0 deletions bindings/ocaml/backends/META.llvm_backend.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name = "llvm_@TARGET@"
version = "@PACKAGE_VERSION@"
description = "@TARGET@ Backend for LLVM"
requires = "llvm"
archive(byte) = "llvm_@[email protected]"
archive(native) = "llvm_@[email protected]"
directory = "."
linkopts = "-ccopt -lstdc++"
56 changes: 56 additions & 0 deletions bindings/ocaml/backends/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
##===- bindings/ocaml/backends/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 master makefile for backend-specific bindings. It works by
# creating a stub makefile for each configured target, e.g. Makefile.ARM, and
# invoking it to compile the corresponding library, e.g. Llvm_ARM.
#
# This scheme allows to keep changes to Makefile.ocaml minimal.
#
##===----------------------------------------------------------------------===##

LEVEL := ../../..
ExtraMakefiles = $(PROJ_OBJ_DIR)/Makefile.common

include $(LEVEL)/Makefile.config
include $(LEVEL)/Makefile.common

all-local:: all-backends
clean-local:: clean-backends
install-local:: install-backends
uninstall-local:: uninstall-backends

stubs:
$(Verb) for i in $(TARGETS_TO_BUILD); do \
$(ECHO) "TARGET := $$i" > Makefile.$$i; \
$(ECHO) "include Makefile.common" >> Makefile.$$i; \
done

all-backends: stubs
$(Verb) for i in $(TARGETS_TO_BUILD); do \
$(MAKE) -f Makefile.$$i all; \
done

clean-backends: stubs
$(Verb) for i in $(TARGETS_TO_BUILD); do \
$(MAKE) -f Makefile.$$i clean; \
$(RM) -f Makefile.$$i; \
done

install-backends: stubs
$(Verb) for i in $(TARGETS_TO_BUILD); do \
$(MAKE) -f Makefile.$$i install; \
done

uninstall-backends: stubs
$(Verb) for i in $(TARGETS_TO_BUILD); do \
$(MAKE) -f Makefile.$$i uninstall; \
done

.PHONY: all-backends clean-backends install-backends uninstall-backends
65 changes: 65 additions & 0 deletions bindings/ocaml/backends/Makefile.common
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
##===- bindings/ocaml/backends/Makefile.common -------------*- 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 slave makefile for backend-specific bindings. This makefile should
# be included after defining TARGET. It will then substitute @TARGET@ for
# the value of TARGET in various *.in files and build an OCaml library in
# a regular way.
#
##===----------------------------------------------------------------------===##

LEVEL := ../../..
LIBRARYNAME := llvm_$(TARGET)
UsedComponents := $(TARGET)
UsedOcamlInterfaces := llvm

include $(LEVEL)/Makefile.config

SOURCES := $(TARGET)_ocaml.c
OcamlHeaders1 := $(PROJ_SRC_DIR)/llvm_$(TARGET).mli
OcamlSources1 := $(PROJ_SRC_DIR)/llvm_$(TARGET).ml

include ../Makefile.ocaml

$(ObjDir)/llvm_$(TARGET).ml: $(PROJ_SRC_DIR)/llvm_backend.ml.in $(ObjDir)/.dir
$(Verb) $(SED) -e 's/@TARGET@/$(TARGET)/' $< > $@

$(ObjDir)/llvm_$(TARGET).mli: $(PROJ_SRC_DIR)/llvm_backend.mli.in $(ObjDir)/.dir
$(Verb) $(SED) -e 's/@TARGET@/$(TARGET)/' $< > $@

$(ObjDir)/$(TARGET)_ocaml.o: $(PROJ_SRC_DIR)/backend_ocaml.c $(ObjDir)/.dir
$(Echo) "Compiling $*.c for $(BuildMode) build" $(PIC_FLAG)
$(Verb) $(Compile.C) -DTARGET=$(TARGET) $< -o $@


##===- OCamlFind Package --------------------------------------------------===##

all-local:: copy-meta
install-local:: install-meta
uninstall-local:: uninstall-meta

DestMETA := $(PROJ_libocamldir)/META.llvm_$(TARGET)

# Easy way of generating META in the objdir
copy-meta: $(OcamlDir)/META.llvm_$(TARGET)

$(OcamlDir)/META.llvm_$(TARGET): META.llvm_backend.in
$(Verb) $(SED) -e 's/@TARGET@/$(TARGET)/' \
-e 's/@PACKAGE_VERSION@/$(LLVMVersion)/' $< > $@

install-meta:: $(OcamlDir)/META.llvm_$(TARGET)
$(Echo) "Install $(BuildMode) $(DestMETA)"
$(Verb) $(MKDIR) $(PROJ_libocamldir)
$(Verb) $(DataInstall) $< "$(DestMETA)"

uninstall-meta::
$(Echo) "Uninstalling $(DestMETA)"
-$(Verb) $(RM) -f "$(DestMETA)"

.PHONY: copy-meta install-meta uninstall-meta
37 changes: 37 additions & 0 deletions bindings/ocaml/backends/backend_ocaml.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*===-- backend_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/Target.h"
#include "caml/alloc.h"
#include "caml/memory.h"

#define INITIALIZER1(target) \
CAMLprim value llvm_initialize_ ## target(value Unit) { \
LLVMInitialize ## target ## TargetInfo(); \
LLVMInitialize ## target ## Target(); \
LLVMInitialize ## target ## TargetMC(); \
// TODO: Figure out how to call these only for targets \
// which support them. \
// LLVMInitialize ## target ## AsmPrinter(); \
// LLVMInitialize ## target ## AsmParser(); \
// LLVMInitialize ## target ## Disassembler(); \
return Val_unit; \
}

#define INITIALIZER(target) INITIALIZER1(target)

INITIALIZER(TARGET)
10 changes: 10 additions & 0 deletions bindings/ocaml/backends/llvm_backend.ml.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
(*===-- llvm_backend.ml.in - 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 initialize : unit -> unit = "llvm_initialize_@TARGET@"
19 changes: 19 additions & 0 deletions bindings/ocaml/backends/llvm_backend.mli.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
(*===-- llvm_backend.mli.in - 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.
*
*===----------------------------------------------------------------------===*)

(** @TARGET@ Initialization.
This interface provides an OCaml API for initialization of
the @TARGET@ LLVM target. By referencing this module, you will cause
OCaml to load or link in the LLVM libraries corresponding to the target.
By calling [initialize], you will register components of this target
in the target registry, which is necessary in order to emit assembly,
object files, and so on. *)

external initialize : unit -> unit = "llvm_initialize_@TARGET@"

0 comments on commit 2bdf881

Please sign in to comment.