#************************************************************************** #* * #* OCaml * #* * #* Gabriel Scherer, projet Parsifal, INRIA Saclay * #* * #* Copyright 2018 Institut National de Recherche en Informatique et * #* en Automatique. * #* * #* All rights reserved. This file is distributed under the terms of * #* the GNU Lesser General Public License version 2.1, with the * #* special exception on linking described in the file LICENSE. * #* * #************************************************************************** # This makefile contains common definitions and rules shared by # other Makefiles include $(ROOTDIR)/Makefile.config_if_required # %(DEPDIR) must be kept in sync with entries in .gitignore DEPDIR=.dep D=d MKDIR=mkdir -p # $(EMPTY) is defined in Makefile.config, but may not have been loaded EMPTY := # $(SPACE) contains a single space SPACE := $(EMPTY) $(EMPTY) # $( ) suppresses warning from the alignments in the V_ macros below $(SPACE) := V ?= 0 ifeq "$(V)" "0" V_CC = @$(info $ CC $@) V_CCDEPS = @$(info $ CCDEPS $@) V_OCAMLC = @$(info $ OCAMLC $@) V_OCAMLOPT = @$(info $ OCAMLOPT $@) V_GEN = @$(info $ GEN $@) V_LINKC = @$(info $ LINKC $@) V_LINKOPT = @$(info $ LINKOPT $@) V_MKEXE = @$(info $ MKEXE $@) V_MKLIB = @$(info $ MKLIB $@) V_MKDLL = @$(info $ MKDLL $@) V_OCAMLLEX = @$(info $ OCAMLLEX $@) V_OCAMLYACC = @$(info $ OCAMLYACC $@) V_OCAMLDEP = @$(info $ OCAMLDEP $@) V_ASM = @$(info $ ASM $@) V_OCAMLMKLIB = @$(info $ OCAMLMKLIB $@) V_OCAMLDOC = @$(info $ OCAMLDOC $@) V_ODOC = @$(info $ ODOC $@) else V_CC = V_CCDEPS = V_OCAMLC = V_OCAMLOPT = V_GEN = V_LINKC = V_LINKOPT = V_MKEXE = V_MKLIB = V_MKDLL = V_OCAMLLEX = V_OCAMLYACC = V_OCAMLDEP = V_ASM = V_OCAMLMKLIB = V_OCAMLDOC = V_ODOC = endif DESTDIR ?= INSTALL_BINDIR := $(DESTDIR)$(BINDIR) INSTALL_LIBDIR := $(DESTDIR)$(LIBDIR) INSTALL_INCDIR=$(INSTALL_LIBDIR)/caml INSTALL_STUBLIBDIR := $(DESTDIR)$(STUBLIBDIR) INSTALL_LIBDIR_PROFILING = $(INSTALL_LIBDIR)/profiling INSTALL_MANDIR := $(DESTDIR)$(MANDIR) INSTALL_PROGRAMS_MAN_DIR := $(DESTDIR)$(PROGRAMS_MAN_DIR) INSTALL_LIBRARIES_MAN_DIR := $(DESTDIR)$(LIBRARIES_MAN_DIR) INSTALL_DOCDIR := $(DESTDIR)$(DOCDIR) FLEXDLL_SUBMODULE_PRESENT := $(wildcard $(ROOTDIR)/flexdll/Makefile) IN_COREBOOT_CYCLE ?= false # Variables used to represent the OCaml runtime system # Most of the time, boot/ocamlrun and runtime/ocamlrun are the same. # However, under some circumstances it is important to be able to # distinguish one from the other, hence these two variables. # Boot/ocamlrun is the most frequently used in the build system, so # we use OCAMLRUN to designate it and keep NEW_OCAMLRUN to refer # to runtime/ocamlrun, because it's less frequently used. OCAMLRUN ?= $(ROOTDIR)/boot/ocamlrun$(EXE) NEW_OCAMLRUN ?= $(ROOTDIR)/runtime/ocamlrun$(EXE) # Standard library flags STDLIBFLAGS ?= -nostdlib -I $(ROOTDIR)/stdlib BOOT_STDLIBFLAGS ?= -nostdlib -I $(ROOTDIR)/boot TEST_BOOT_OCAMLC_OPT = $(shell \ test $(ROOTDIR)/boot/ocamlc.opt -nt $(ROOTDIR)/boot/ocamlc; \ echo $$?) # Use boot/ocamlc.opt if available ifeq "$(TEST_BOOT_OCAMLC_OPT)" "0" BOOT_OCAMLC = $(ROOTDIR)/boot/ocamlc.opt else BOOT_OCAMLC = $(OCAMLRUN) $(ROOTDIR)/boot/ocamlc endif BOOT_OCAMLDEP = $(BOOT_OCAMLC) -depend ifeq "$(BOOTSTRAPPING_FLEXDLL)" "false" FLEXLINK_ENV = CAMLOPT_CMD = $(CAMLOPT) OCAMLOPT_CMD = $(OCAMLOPT) MKLIB_CMD = $(MKLIB) ocamlc_cmd = $(ocamlc) ocamlopt_cmd = $(ocamlopt) else ifeq "$(wildcard $(ROOTDIR)/flexlink.opt$(EXE))" "" FLEXLINK_ENV = \ OCAML_FLEXLINK="$(ROOTDIR)/boot/ocamlrun$(EXE) \ $(ROOTDIR)/boot/flexlink.byte$(EXE)" else FLEXLINK_ENV = \ OCAML_FLEXLINK="$(ROOTDIR)/flexlink.opt$(EXE) -I $(ROOTDIR)/stdlib/flexdll" endif # ifeq "$(wildcard $(ROOTDIR)/flexlink.opt$(EXE))" "" CAMLOPT_CMD = $(FLEXLINK_ENV) $(CAMLOPT) OCAMLOPT_CMD = $(FLEXLINK_ENV) $(OCAMLOPT) MKLIB_CMD = $(FLEXLINK_ENV) $(MKLIB) ocamlc_cmd = $(FLEXLINK_ENV) $(ocamlc) ocamlopt_cmd = $(FLEXLINK_ENV) $(ocamlopt) endif # ifeq "$(BOOTSTRAPPING_FLEXDLL)" "false" # List of other libraries ALL_OTHERLIBS = dynlink str systhreads unix runtime_events # Flags to pass to the C preprocessor when preprocessing assembly files OC_ASPPFLAGS=$(OC_CPPFLAGS) $(OC_NATIVE_CPPFLAGS) OPTCOMPFLAGS= ifeq "$(FUNCTION_SECTIONS)" "true" OPTCOMPFLAGS += -function-sections endif # The rule to compile C files # This rule is similar to GNU make's implicit rule, except that it is more # general (it supports both .o and .obj) ifeq "$(COMPUTE_DEPS)" "true" RUNTIME_HEADERS := REQUIRED_HEADERS := else RUNTIME_HEADERS := $(wildcard $(ROOTDIR)/runtime/caml/*.tbl) \ $(wildcard $(ROOTDIR)/runtime/caml/*.h) REQUIRED_HEADERS := $(RUNTIME_HEADERS) $(wildcard *.h) endif %.$(O): %.c $(REQUIRED_HEADERS) $(V_CC)$(CC) -c $(OC_CFLAGS) $(CFLAGS) $(OC_CPPFLAGS) $(CPPFLAGS) \ $(OUTPUTOBJ)$@ $< $(DEPDIR): $(MKDIR) $@ # When executable files have an extension (e.g. ".exe"), # provide phony synonyms define PROGRAM_SYNONYM ifneq ($(EXE),) .PHONY: $(1) $(1): $(1)$(EXE) endif endef # PROGRAM_SYNONYM # Definitions related to ocamldep # Default value for OCAMLDEP # In those directories where this needs to be overridden, the overriding # should take place *before* Makefile.common is included. OCAMLDEP ?= $(BEST_OCAMLDEP) OCAMLDEPFLAGS ?= OC_OCAMLDEPFLAGS = -slash OC_OCAMLDEPDIRS = OCAMLDEP_CMD = $(OCAMLDEP) $(OC_OCAMLDEPFLAGS) \ $(addprefix -I ,$(OC_OCAMLDEPDIRS)) $(OCAMLDEPFLAGS) # Lexer generation BOOT_OCAMLLEX ?= $(OCAMLRUN) $(ROOTDIR)/boot/ocamllex # Default value for OCAMLLEX # In those directories where this needs to be overridden, the overriding # should take place *before* Makefile.common is included. OCAMLLEX ?= $(BEST_OCAMLLEX) OCAMLLEXFLAGS ?= -q %.ml: %.mll $(V_OCAMLLEX)$(OCAMLLEX) $(OCAMLLEXFLAGS) $< # Parser generation OCAMLYACC ?= $(ROOTDIR)/yacc/ocamlyacc$(EXE) OCAMLYACCFLAGS ?= --strict -v %.ml %.mli: %.mly $(V_OCAMLYACC)$(OCAMLYACC) $(OCAMLYACCFLAGS) $< SAK = $(ROOTDIR)/runtime/sak$(EXE) # stdlib/StdlibModules cannot be include'd unless $(SAK) has been built. These # two rules add that dependency. They have to be pattern rules since # Makefile.common is included before default targets. $(ROOTDIR)/%/sak$(EXE): $(MAKE) -C $(ROOTDIR)/$* sak$(EXE) ifneq "$(REQUIRES_CONFIGURATION)" "" ifneq "$(wildcard $(ROOTDIR)/Makefile.config)" "" $(ROOTDIR)/%/StdlibModules: $(SAK) ; endif endif # Used with the Microsoft toolchain to merge generated manifest files into # executables if_file_exists = ( test ! -f $(1) || $(2) && rm -f $(1) ) MERGEMANIFESTEXE = $(call if_file_exists, $(1).manifest, \ mt -nologo -outputresource:$(1) -manifest $(1).manifest) # Macros and rules to compile OCaml programs # We use secondary expansion here so that variables like # foo_LIBRARIES and foo_MODULES can be defined after the calls # to the macros below. Without secondary expansion, those variables # would have to be defined before the calls to OCAML_BYTECODE_PROGRAM etc. .SECONDEXPANSION: LINK_BYTECODE_PROGRAM =\ $(CAMLC) $(OC_COMMON_LINKFLAGS) $(OC_BYTECODE_LINKFLAGS) define OCAML_BYTECODE_PROGRAM $(eval $(call PROGRAM_SYNONYM,$(1))) $(1)$(EXE): \ $$$$(patsubst %,%.cma, $$$$($(basename $(notdir $(1)))_LIBRARIES)) \ $$$$(patsubst %,%.cmo, $$$$($(basename $(notdir $(1)))_MODULES)) $$(V_LINKC)$$(LINK_BYTECODE_PROGRAM) -o $$@ $$^ endef # OCAML_BYTECODE_PROGRAM LINK_NATIVE_PROGRAM =\ $(CAMLOPT_CMD) $(OC_COMMON_LINKFLAGS) $(OC_NATIVE_LINKFLAGS) define OCAML_NATIVE_PROGRAM $(eval $(call PROGRAM_SYNONYM,$(1))) $(1)$(EXE): \ $$$$(patsubst %,%.cmxa, $$$$($(basename $(notdir $(1)))_LIBRARIES)) \ $$$$(patsubst %,%.cmx, $$$$($(basename $(notdir $(1)))_MODULES)) $$(V_LINKOPT)$$(LINK_NATIVE_PROGRAM) -o $$@ $$^ endef # OCAML_NATIVE_PROGRAM define OCAML_PROGRAM $(eval $(call OCAML_BYTECODE_PROGRAM,$(1))) $(eval $(call OCAML_NATIVE_PROGRAM,$(1).opt)) endef # OCAML_PROGRAM # Installing a bytecode executable, with debug information removed define INSTALL_STRIPPED_BYTE_PROG $(OCAMLRUN) $(ROOTDIR)/tools/stripdebug $(1) $(1).tmp \ && $(INSTALL_PROG) $(1).tmp $(2) \ && rm $(1).tmp endef # INSTALL_STRIPPED_BYTE_PROG