#************************************************************************** #* * #* 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) DESTDIR ?= INSTALL_BINDIR := $(DESTDIR)$(BINDIR) INSTALL_LIBDIR := $(DESTDIR)$(LIBDIR) INSTALL_INCDIR=$(INSTALL_LIBDIR)/caml INSTALL_STUBLIBDIR := $(DESTDIR)$(STUBLIBDIR) 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 # The following variable defines flags to be passed to the C preprocessor # when compiling C files for the native runtime. # These flags should be passed *in addition* to those in OC_CPPFLAGS, they # should not repace them. OC_NATIVE_CPPFLAGS=\ -DNATIVE_CODE -DTARGET_$(ARCH) -DMODEL_$(MODEL) -DSYS_$(SYSTEM) # Flags to pass to the C preprocessor when preprocessing assembly files OC_ASPPFLAGS=-I $(ROOTDIR)/runtime $(OC_NATIVE_CPPFLAGS) OPTCOMPFLAGS= ifeq "$(FUNCTION_SECTIONS)" "true" OPTCOMPFLAGS += -function-sections endif # Escape special characters in the argument string. # There are four characters that need escaping: # - backslash and ampersand, which are special in the replacement text # of sed's "s" command # - exclamation mark, which is the delimiter we use for sed's "s" command # - single quote, which interferes with shell quoting. We are inside # single quotes already, so the proper escape is '\'' # (close single quotation, insert single quote character, # reopen single quotation). SED_ESCAPE=$(subst ','\'',$(subst !,\!,$(subst &,\&,$(subst \,\\,$1)))) # Escape special characters in an OCaml string literal "..." # There are two: backslash and double quote. OCAML_ESCAPE=$(subst ",\",$(subst \,\\,$1)) # SUBST generates the sed substitution for the variable *named* in $1 SUBST=-e 's!%%$1%%!$(call SED_ESCAPE,$($1))!' # SUBST_STRING does the same, for a variable that occurs between "..." # in config.mlp. Thus, backslashes and double quotes must be escaped. SUBST_STRING=-e 's!%%$1%%!$(call SED_ESCAPE,$(call OCAML_ESCAPE,$($1)))!' # 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) ifneq "$(COMPUTE_DEPS)" "false" 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) $(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) 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 $(OCAMLLEX) $(OCAMLLEXFLAGS) $< # Parser generation OCAMLYACC ?= $(ROOTDIR)/yacc/ocamlyacc$(EXE) OCAMLYACCFLAGS ?= %.ml %.mli: %.mly $(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)