#************************************************************************** #* * #* 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) := HASH := \# ifeq "$(UNIX_OR_WIN32)" "win32" DIR_SEP := \$ # There must a space following the $ CONVERT_PATH = $(subst /,$(DIR_SEP),$(strip $(1))) else DIR_SEP = / CONVERT_PATH = $(strip $(1)) endif QUOTE_SINGLE = '$(subst ','\'',$(1))' 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 ?= # Augment directories from Makefile.config / Makefile.build_config with # $(DESTDIR). i.e. each of these 5 directories may be overridden by the user, # and the compiler distribution makes no assumptions about where they are # relative to each other. INSTALL_BINDIR = $(DESTDIR)$(BINDIR) INSTALL_DOCDIR = $(DESTDIR)$(DOCDIR) INSTALL_LIBDIR = $(DESTDIR)$(LIBDIR) INSTALL_MANDIR = $(DESTDIR)$(MANDIR) INSTALL_STUBLIBDIR = $(DESTDIR)$(STUBLIBDIR) # Library subdirectories. The compiler distribution does make assumptions about # these, and they cannot be freely overridden by the user. INSTALL_LIBDIR_CAML = caml INSTALL_LIBDIR_COMPILERLIBS = compiler-libs INSTALL_LIBDIR_DYNLINK = dynlink INSTALL_LIBDIR_FLEXDLL = flexdll INSTALL_LIBDIR_OCAMLDOC = ocamldoc INSTALL_LIBDIR_PROFILING = profiling INSTALL_LIBDIR_STDLIB = stdlib INSTALL_LIBDIR_SYSTHREADS = threads INSTALL_MANDIR_PROGRAMS = man1 INSTALL_MANDIR_LIBRARIES = man3 INSTALL_MODE ?= install # INSTALL_ITEM installs a single file, possibly with a different name and # possibly creating additional symlinks/copies # $1 = source file (may include directories) # $2 = section (bin, doc, lib, libexec, man, stublibs) # $3 = directory within section (may be empty) # $4 = target basename (may be empty) # $5 = additional basenames (either symlinked or copied, depending on what the # platform supports) # The $(origin n) dance is necessary to suppress warnings about undefined # variables. INSTALL_ITEM = \ $(INSTALL_$(INSTALL_MODE)_PREFIX)$(call INSTALL_ENSURE_DIR,$\ $(strip $(2)),$(if $(filter-out undefined,$(origin 3)),$(strip $(3))))$\ $(call INSTALL_DESPATCH_$(INSTALL_MODE)_ITEM,$\ $(strip $(1)),$\ $(strip $(2)),$\ $(if $(filter-out undefined,$(origin 3)),$(strip $(3))),$\ $(if $(filter-out undefined,$(origin 4)),$(strip $(4))),$\ $(if $(filter-out undefined,$(origin 5)),$(strip $(5)))) # INSTALL_ITEMS installs a series of files to a single directory # $1 = source file(s) (may include directories and glob patterns) # $2 = section (as for INSTALL_ITEM) # $3 = directory within section (may be omitted) # INSTALL_ITEMS is sometimes an alias for INSTALL_ITEM. For simplicity with # undefined variable warnings, INSTALL_DESPATCH_foo_ITEMS is passed 5 parameters # but $4 and $5 are always empty. INSTALL_ITEMS = \ $(INSTALL_$(INSTALL_MODE)_PREFIX)$(call INSTALL_ENSURE_DIR,$\ $(strip $(2)),$(if $(filter-out undefined,$(origin 3)),$(strip $(3))))$\ $(call INSTALL_DESPATCH_$(INSTALL_MODE)_ITEMS,$\ $(strip $(1)),$\ $(strip $(2)),$\ $(if $(filter-out undefined,$(origin 3)),$(strip $(3))),,) # INSTALL_ITEMS_OPT is INSTALL_ITEMS, but does nothing if the source file(s) do # not exist INSTALL_ITEMS_OPT = \ $(if $(wildcard $(1)),$(call INSTALL_ITEMS, \ $(1), $(2), $(if $(filter-out undefined,$(origin 3)), $(3)))) INSTALL_ENSURE_DIR = \ $(if $(filter undefined,$(origin DIR_CREATED_$(subst exec,,$(1))_$(2))),$\ $(eval DIR_CREATED_$(1)_$(2):=)$\ $(call INSTALL_DESPATCH_$(INSTALL_MODE)_MKDIR,$\ $(subst exec,,$(1)),$(2))) # INSTALL_RM takes a single argument which may include glob patterns of files to # be removed when performing a physical install. INSTALL_RM = $(call INSTALL_DESPATCH_$(INSTALL_MODE)_RM,$(strip $(1))) # INSTALL_BEGIN and INSTALL_END are used in the root Makefile's install target INSTALL_BEGIN = $(INSTALL_DESPATCH_$(INSTALL_MODE)_BEGIN) INSTALL_END = $(INSTALL_DESPATCH_$(INSTALL_MODE)_END) # Normal installation INSTALL_CMD_bin = $(INSTALL_PROG) INSTALL_CMD_doc = $(INSTALL_DATA) INSTALL_CMD_lib = $(INSTALL_DATA) INSTALL_CMD_libexec = $(INSTALL_PROG) INSTALL_CMD_man = $(INSTALL_DATA) INSTALL_CMD_stublibs = $(INSTALL_PROG) INSTALL_SECTION_bin = $(INSTALL_BINDIR) INSTALL_SECTION_doc = $(INSTALL_DOCDIR) INSTALL_SECTION_lib = $(INSTALL_LIBDIR) INSTALL_SECTION_libexec = $(INSTALL_LIBDIR) INSTALL_SECTION_man = $(INSTALL_MANDIR) INSTALL_SECTION_stublibs = $(INSTALL_STUBLIBDIR) QUOTE_SINGLE = '$(subst ','\'',$(1))' define NEWLINE endef SH_AND = && \$(NEWLINE) INSTALL_install_PREFIX = INSTALL_DESPATCH_install_RM = rm -f $(1) INSTALL_DESPATCH_install_MKDIR = \ $(MKDIR) $(call QUOTE_SINGLE,$(INSTALL_SECTION_$(1))$(addprefix /,$(2))) \ $(SH_AND) MK_LINK = \ (cd "$(INSTALL_SECTION_$(2))$(addprefix /,$(3))" && \ $(LN) $(call QUOTE_SINGLE,$(1)) $(call QUOTE_SINGLE,$(4))) INSTALL_DESPATCH_install_ITEM = \ $(INSTALL_CMD_$(2)) $(1) \ $(call QUOTE_SINGLE,$\ $(INSTALL_SECTION_$(2))$(addprefix /,$(3))$(addprefix /,$(4))) \ $(foreach link, $(5),$(SH_AND)$\ $(call MK_LINK,$(if $(4),$(4),$(notdir $(1))),$(2),$(3),$(link))) INSTALL_DESPATCH_install_ITEMS = $(INSTALL_DESPATCH_install_ITEM) INSTALL_DESPATCH_install_BEGIN = @ INSTALL_DESPATCH_install_END = @ INSTALL_display_PREFIX = @ INSTALL_DESPATCH_display_RM = @ INSTALL_DESPATCH_display_MKDIR = \ echo $(call QUOTE_SINGLE,$\ -> MKDIR $(INSTALL_SECTION_$(1))$(addprefix /,$(2))) $(SH_AND) MKLINK_display = \ echo $(call QUOTE_SINGLE,-> LN \ $(abspath $(INSTALL_SECTION_$(2))$(addprefix /,$(3))/$(1)) -> \ $(if $(4),$(4),$(notdir $(1)))) INSTALL_DESPATCH_display_ITEM = \ echo $(call QUOTE_SINGLE,-> INSTALL $(1) \ $(INSTALL_SECTION_$(2))$(addprefix /,$(3))$(addprefix /,$(4))) \ $(foreach link, $(5), && \ $(call MKLINK_display,$(if $(4),$(4),$(notdir $(1))),$(2),$(3),$(link))) INSTALL_DESPATCH_display_ITEMS = $(INSTALL_DESPATCH_display_ITEM) INSTALL_DESPATCH_display_BEGIN = @ INSTALL_DESPATCH_display_END = @ INSTALL_list_PREFIX = @ INSTALL_DESPATCH_list_RM = @ INSTALL_DESPATCH_list_MKDIR = MKLINK_list = \ echo $(call QUOTE_SINGLE,-> \ $(abspath $(INSTALL_SECTION_$(2))$(addprefix /,$(3))/$\ $(if $(4),$(4),$(notdir $(1))))) INSTALL_DESPATCH_list_ITEM = \ echo $(call QUOTE_SINGLE,-> \ $(abspath $(INSTALL_SECTION_$(2))$(addprefix /,$(3))/$\ $(if $(4),$(4),$(notdir $(1))))) \ $(foreach link, $(5), && \ $(call MKLINK_list,$(if $(4),$(4),$(notdir $(1))),$(2),$(3),$(link))) INSTALL_DESPATCH_list_ITEMS = \ $(foreach file, $(wildcard $(1)), \ echo $(call QUOTE_SINGLE,-> \ $(INSTALL_SECTION_$(2))$(addprefix /,$(3))/$(notdir $(file)));) \ true INSTALL_DESPATCH_list_BEGIN = @ INSTALL_DESPATCH_list_END = @ OPAM_PACKAGE_NAME ?= ocaml-compiler # Generate $(OPAM_PACKAGE_NAME).install and $(OPAM_PACKAGE_NAME)-fixup.sh # (INSTALL_MODE=opam) # opam's .install format isn't quite rich enough at present to express the # installation of the compiler. In particular, we can't install the doc files to # doc/ocaml using a .install and we can't create symlinks. The things which # can't be handled by the .install file are dealt with by the fixup script # instead. INVOKE = $(strip $(1)) $(call QUOTE_SINGLE,$(strip $(2))) ADD_LINE = $(call INVOKE, echo, $(2)) >> $(1) # RECORD_SYMLINK_TO_INSTALL # $1 = file to install, implicitly relative to $(ROOTDIR) # $2 = section # $3 = subdirectory within $2 (may be empty) # $4 = name to install $1 (must be specified) # $5 = single name of symlink # If symlinks are supported, $1 is ignored and the three pieces of information # are recorded in create-symlinks: the directory, implicitly relative to the # prefix, in which the symlink is to be created, the source file and name of the # symlink. # These can then be munged to a cd + ln combination in the fixup script. # If symlinks are not supported, $1 is instead used to create an additional copy # of the file, using the .install file. ifeq "$(firstword $(LN))" "ln" RECORD_SYMLINK_TO_INSTALL = \ $(call ADD_LINE, $(ROOTDIR)/create-symlinks, \ $(patsubst lib%,lib,$(2))$(addprefix /,$(3)) $(4) $(5)) else # Symlinks aren't available, so copy the file again using the target name RECORD_SYMLINK_TO_INSTALL = \ $(call RECORD_$(INSTALL_MODE)_ITEM_TO_INSTALL,$(1),$(2),$(3),$(5)) endif # Process the arguments to pass to RECORD_$(INSTALL_MODE)_ITEM_TO_INSTALL: # - Items installed to the stublibs section need to be remapped to the stublibs # subdirectory of libexec (since we install to lib/ocaml/stublibs rather than # opam's default lib/stublibs) # - Source files must be given implicitly relative to $(ROOTDIR), so prefix with # $(SUBDIR_NAME) if necessary # - Items installed to the lib/libexec sections will in fact be installed to # lib_root/libexec_root, so remap the installation directory to ocaml (i.e. to # install to lib/ocaml rather than lib) # - If no target basename has been explictly given, use the source's basename RECORD_ITEM_TO_INSTALL = \ $(if $(filter stublibs,$(2)),\ $(call RECORD_ITEM_TO_INSTALL,$\ $(1),libexec,stublibs$(addprefix /,$(3)),$(4),$(5)),\ $(call RECORD_$(INSTALL_MODE)_ITEM_TO_INSTALL,$\ $(addsuffix /,$(SUBDIR_NAME))$(1),$\ $(2),$\ $(if $(filter doc lib%,$(2)),ocaml$(addprefix /,$(3)),$(3)),$\ $(if $(4),$(4),$(notdir $(1))),$\ $(5))) # All files must be explicitly installed, so evaluate the wildcards and call # INSTALL_DESPATCH_opam_ITEM for each file. INSTALL_EVALUATE_GLOBS = \ $(foreach file, $(wildcard $(1)), \ $(call INSTALL_DESPATCH_$(INSTALL_MODE)_ITEM,$(file),$(2),$(3));) \ true # RECORD_FILE_TO_INSTALL # $1 = file to install, implicitly relative to $(ROOTDIR) # $2 = bin/lib/libexec/man # $3 = subdirectory within $2 (may be empty, but otherwise must end with "/") # $4 = name to install $1 (must be specified) # Writes an opam .install line to the section file for $(2). Each line consists # of a double-quoted implicit filename relative to $(ROOTDIR) and optionally a # second double-quoted implicit filename relative to the $(2) for the name to # install the file under. # e.g. "lex/ocamllex" {"ocamllex.byte"} or "expunge" {"ocaml/expunge"} RECORD_FILE_TO_INSTALL = \ $(call ADD_LINE, $(ROOTDIR)/opam-$(2), \ "$(1)" $(if $(3)$(filter-out $(notdir $(1)),$(4)), {"$(3)$(4)"})) # RECORD_FILE_TO_CLONE # $1 = file to install, implicitly relative to $(ROOTDIR) # $2 = subdirectory (may be empty, but otherwise must end with "/") # $3 = name to install $1 (must be specified) # The compiler is installed as the ocaml package in opam, but the actual files # are installed from other packages (typically ocaml-compiler). For the the lib # directory, the lib_root and libexec_root sections allow files to be installed # to lib/ocaml, but there's no equivalent mechanism for the doc directory. These # files are recorded to be copied manually in the fixup script. RECORD_FILE_TO_CLONE = \ $(call ADD_LINE, $(ROOTDIR)/clone-$(subst /,@,$(2)), $(1) $(3)) # RECORD_opam_ITEM_TO_INSTALL despatches the processed arguments of # INSTALL_DESPATCH_opam_ITEM to the appropriate RECORD_ macro. RECORD_opam_ITEM_TO_INSTALL = \ $(if $(filter doc,$(2)),\ $(call RECORD_FILE_TO_CLONE,$(1),doc/$(3),$(4)), \ $(call RECORD_FILE_TO_INSTALL,$(1),$(2),$(addsuffix /,$(3)),$(4))) \ $(foreach link, $(5), && \ $(call RECORD_SYMLINK_TO_INSTALL,$(1),$(2),$(3),$(4),$(link))) INSTALL_DESPATCH_opam_ITEM = $(RECORD_ITEM_TO_INSTALL) INSTALL_DESPATCH_opam_ITEMS = $(INSTALL_EVALUATE_GLOBS) INSTALL_opam_PREFIX = @ INSTALL_DESPATCH_opam_RM = @ # INSTALL_MKDIR is ignored (opam creates them when executing the .install file) INSTALL_DESPATCH_opam_MKDIR = INSTALL_DESPATCH_opam_BEGIN = \ rm -f opam-bin clone-* opam-lib opam-libexec opam-man create-symlinks # Munge opam-bin, opam-lib, opam-libexec and opam-man into a .install file and # then munge clone-* and create-symlinks into the fixup script. INSTALL_DESPATCH_opam_END = \ $(OCAMLRUN) ./ocaml$(EXE) $(STDLIBFLAGS) \ tools/opam/generate.ml $(INSTALL_MODE) $(OPAM_PACKAGE_NAME) '$(LN)' # Generate $(OPAM_PACKAGE_NAME)-clone.sh (INSTALL_MODE=clone) # ld.conf is explicitly copied, rather than cloned, to allow (in principle, if # not in practice) the cloning installation to edit it. RECORD_clone_ITEM_TO_INSTALL = \ $(if $(filter runtime/ld.conf Makefile.config, $(1)), true, \ $(if $(filter libexec,$(2)), \ $(call RECORD_clone_ITEM_TO_INSTALL,$(1),lib,$(3),$(4),$(5)), \ $(call ADD_LINE, \ $(ROOTDIR)/clone-$(2)$(addprefix @,$(subst /,@,$(3))), \ $(2)$(addprefix /,$(3))/$(if $(4),$(4),$(notdir $(1)))) \ $(foreach link, $(5), && \ $(call RECORD_SYMLINK_TO_INSTALL,$(1),$(2),$(3),$(4),$(link))))) INSTALL_DESPATCH_clone_ITEM = $(RECORD_ITEM_TO_INSTALL) INSTALL_DESPATCH_clone_ITEMS = $(INSTALL_EVALUATE_GLOBS) INSTALL_clone_PREFIX = @ INSTALL_DESPATCH_clone_RM = @ # INSTALL_MKDIR is ignored - INSTALL_DESPATCH_clone_END automatically creates # directories for each cp file. INSTALL_DESPATCH_clone_MKDIR = INSTALL_DESPATCH_clone_BEGIN = rm -f clone-* create-symlinks INSTALL_DESPATCH_clone_END = $(INSTALL_DESPATCH_opam_END) 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 # Takes an implicit path and converts it to a path expression which returns to # the current directory. e.g. $(call ROOT_FROM, foo/bar/) expands to ../.. REMOVE_SLASH = $(strip $(patsubst %/,%, $(1))) ROOT_FROM = \ $(subst $(SPACE),/,$(patsubst %,..,$(subst /, ,$(call REMOVE_SLASH, $(1))))) BYTE_BUILD_TREE = byte OPT_BUILD_TREE = opt BYTE_BINDIR = $(BYTE_BUILD_TREE)/bin OPT_BINDIR = $(OPT_BUILD_TREE)/bin ifeq "$(BOOTSTRAPPING_FLEXDLL)" "true" override REAL_ROOT_DIR := $(realpath $(ROOTDIR)) ifeq "$(filter $(REAL_ROOT_DIR)/$(BYTE_BINDIR), $(subst :, ,$(PATH)))" "" export PATH := \ $(REAL_ROOT_DIR)/$(OPT_BINDIR):$(REAL_ROOT_DIR)/$(BYTE_BINDIR):$(PATH) # $(BUILD_COMPANY_SYSTEM) is the last two parts of $(BUILD_TRIPLET) BUILD_TRIPLET_FIELDS := $(subst -,$(SPACE),$(BUILD_TRIPLET)) BUILD_COMPANY_SYSTEM := $(subst $(SPACE),-,$\ $(wordlist 2, $(words $(BUILD_TRIPLET_FIELDS)), $(BUILD_TRIPLET_FIELDS))) # Use the FLEXDIR environment variable to tell flexlink where the support # objects are located. Passing this location using -I would defeat the whole # purpose of the PATH-trick (bootstrapped flexlink is indistinguishable from # an installed flexlink). flexlink also looks for the objects in the same # directory as the executable, but this is slightly irritating as it requires # copying them to both byte/bin/ and opt/bin/ but also doesn't work if # opt/bin/flexlink.exe is a symlink to flexlink.opt.exe, as flexlink can end # up looking in the directory for the target of the symlink, rather than the # symlink itself. ifeq "" "$(filter pc-msys pc-cygwin%, $(BUILD_COMPANY_SYSTEM))" export FLEXDIR := $(REAL_ROOT_DIR) else export FLEXDIR := $(shell cygpath -w "$(REAL_ROOT_DIR)") endif undefine BUILD_TRIPLET_FIELDS undefine BUILD_COMPANY_SYSTEM endif undefine REAL_ROOT_DIR endif # ifeq "$(BOOTSTRAPPING_FLEXDLL)" "true" # 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 ifeq "$(TARGET_LIBDIR_IS_RELATIVE)" "true" SRCDIR_ENCODED = $(subst =,%+,$(subst :,%.,$(subst %,%$(HASH),$(SRCDIR_ABS)))) SRCDIR_ABS_REAL := $(shell realpath $(SRCDIR_ABS) 2>/dev/null) SRCDIR_REAL_ENCODED = \ $(subst =,%+,$(subst :,%.,$(subst %,%$(HASH),$(SRCDIR_ABS_REAL)))) BUILD_PATH_PREFIX_MAP ?= export BUILD_PATH_PREFIX_MAP := \ $(BUILD_PATH_PREFIX_MAP)$\ :.=$(SRCDIR_ENCODED)$\ $(if $(SRCDIR_REAL_ENCODED),:.=$(SRCDIR_REAL_ENCODED)) endif # ifeq "$(TARGET_LIBDIR_IS_RELATIVE)" "true" # Allow Makefile.cross to override the Standard Library default for the compiler # itself. HOST_LIBDIR ?= $(TARGET_LIBDIR) OC_COMMON_LINKFLAGS += \ -set-runtime-default \ $(call QUOTE_SINGLE,standard_library_default=$(HOST_LIBDIR)) # 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) $(OC_CFLAGS) $(CFLAGS) $(OC_CPPFLAGS) $(CPPFLAGS) \ $(OUTPUTOBJ)$@ -c $< $(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) $< # 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 and libraries # The following variable is used to accumulate a list of all the CMX # files that get built. Is is then used in the root Makefile to express # the dependency on all these files on the native compiler, so that # they get rebuilt if the native compiler is updated ALL_CMX_FILES = # We use secondary expansion here so that variables like # foo_LIBRARIES and foo_SOURCES 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: # Definitions that are common to both programs and libraries define _OCAML_COMMON_BASE $(basename $(notdir $(1)))_C_FILES = \ $$(filter %.c, $$($(basename $(notdir $(1)))_SOURCES)) $(basename $(notdir $(1)))_MLI_FILES = \ $$(filter %.mli, \ $$(subst .mly,.mli,\ $$($(basename $(notdir $(1)))_SOURCES))) $(basename $(notdir $(1)))_CMI_FILES = \ $$(subst .mli,.cmi,$$($(basename $(notdir $(1)))_MLI_FILES)) $(basename $(notdir $(1)))_ML_FILES = \ $$(filter %.ml, \ $$(subst .ml.in,.ml,$$(subst .mll,.ml,$$(subst .mly,.ml,\ $$($(basename $(notdir $(1)))_SOURCES))))) $(basename $(notdir $(1)))_MLL_FILES = \ $$(filter %.mll, \ $$($(basename $(notdir $(1)))_SOURCES)) $(basename $(notdir $(1)))_MLY_FILES = \ $$(filter %.mly, \ $$($(basename $(notdir $(1)))_SOURCES)) $(basename $(notdir $(1)))_SECONDARY_FILES = \ $$(patsubst %.mll,%.ml, $$($(basename $(notdir $(1)))_MLL_FILES)) \ $$(patsubst %.mly,%.mli, $$($(basename $(notdir $(1)))_MLY_FILES)) \ $$(patsubst %.mly,%.ml, $$($(basename $(notdir $(1)))_MLY_FILES)) .SECONDARY: $$$$($(basename $(notdir $(1)))_SECONDARY_FILES) beforedepend:: $$$$($(basename $(notdir $(1)))_SECONDARY_FILES) $(basename $(notdir $(1)))_GENERATED_FILES = \ $$($(basename $(notdir $(1)))_SECONDARY_FILES) \ $$(patsubst %.mly,%.output, $$($(basename $(notdir $(1)))_MLY_FILES)) endef # _OCAML_COMMON_BASE # Macros to build OCaml programs # Each program foo is characterised by the foo_LIBRARIES and foo_SOURCES # variables. The following macros provide the infrastructure to build foo # from the object files whose names are derived from these two # variables. In particular, the following macros define several # variables whose names are prefixed with foo_ to compute the # different lists of files used to build foo. # The first macro, _OCAML_PROGRAM_BASE, is a private macro (hence the _ at the # beginning of its name) which defines foo_ variables common to both # bytecode and native programs. The next two macros, OCAML_BYTECODE_PROGRAM # and OCAML_NATIVE_PROGRAM are used to define programs that are provided # only in bytecode or native form, respectively. Programs provided # in both forms should use OCAML_PROGRAM. define _OCAML_PROGRAM_BASE $(eval $(call _OCAML_COMMON_BASE,$(1))) # To be overridden by the programs needing special link flags $(basename $(notdir $(1)))_COMMON_LINKFLAGS = endef # _OCAML_PROGRAM_BASE # $(ROOTDIR)/ocamlc needs -launch-method to be given explicitly as its default # values are those for the target (cf. --with-target-sh and TARGET_BINDIR). BYTECODE_LAUNCHER_FLAGS = \ -launch-method $(call QUOTE_SINGLE,$(LAUNCH_METHOD) $(BINDIR)) \ -runtime-search $(if $(RUNTIME_SEARCH),$(RUNTIME_SEARCH),disable) MAYBE_ADD_BYTECODE_LAUNCHER_FLAGS = \ $(if $(filter -custom, $(1)),,\ -use-prims $(ROOTDIR)/runtime/primitives $(BYTECODE_LAUNCHER_FLAGS)) LINK_BYTECODE_PROGRAM =\ $(CAMLC) $(OC_COMMON_LINKFLAGS) \ $(call MAYBE_ADD_BYTECODE_LAUNCHER_FLAGS, \ $(OC_COMMON_LINKFLAGS) $(OC_BYTECODE_LINKFLAGS)) $(OC_BYTECODE_LINKFLAGS) # The _OCAML_BYTECODE_PROGRAM macro defines a bytecode program but assuming # that _OCAML_PROGRAM_BASE has already been called. Its public counterpart # does not rely on this assumption and rather does call _OCAML_PROGRAM_BASE # itself. define _OCAML_BYTECODE_PROGRAM $(eval $(call PROGRAM_SYNONYM,$(1))) $(basename $(notdir $(1)))_CMA_FILES = \ $$(patsubst %,%.cma, $$($(basename $(notdir $(1)))_LIBRARIES)) $(basename $(notdir $(1)))_BO_FILES = \ $$(patsubst %.c,%.b.$(O), $$($(basename $(notdir $(1)))_C_FILES)) $(basename $(notdir $(1)))_CMO_FILES = \ $$(patsubst %.ml,%.cmo, $$($(basename $(notdir $(1)))_ML_FILES)) $(basename $(notdir $(1)))_BCOBJS = \ $$($(basename $(notdir $(1)))_CMA_FILES) \ $$($(basename $(notdir $(1)))_BO_FILES) \ $$($(basename $(notdir $(1)))_CMO_FILES) # To be overridden by the programs needing special bytecode link flags $(basename $(notdir $(1)))_BYTECODE_LINKFLAGS = $(basename $(notdir $(1)))_BYTECODE_LINKCMD = \ $(strip \ $$(CAMLC) $$(OC_COMMON_LINKFLAGS) \ $$(call MAYBE_ADD_BYTECODE_LAUNCHER_FLAGS, \ $$(OC_COMMON_LINKFLAGS) $$(OC_BYTECODE_LINKFLAGS) \ $$($(basename $(notdir $(1)))_COMMON_LINKFLAGS) \ $$($(basename $(notdir $(1)))_BYTECODE_LINKFLAGS)) \ $$(OC_BYTECODE_LINKFLAGS) $$($(basename $(notdir $(1)))_COMMON_LINKFLAGS) \ $$($(basename $(notdir $(1)))_BYTECODE_LINKFLAGS)) $(1)$(EXE): $$$$($(basename $(notdir $(1)))_BCOBJS) $$(V_LINKC)$$($(basename $(notdir $(1)))_BYTECODE_LINKCMD) -o $$@ \ $$($(basename $(notdir $(1)))_BCOBJS) endef # _OCAML_BYTECODE_PROGRAM define OCAML_BYTECODE_PROGRAM $(eval $(call _OCAML_PROGRAM_BASE,$(1))) $(eval $(call _OCAML_BYTECODE_PROGRAM,$(1))) endef # OCAML_BYTECODE_PROGRAM define _OCAML_NATIVE_PROGRAM $(eval $(call PROGRAM_SYNONYM,$(1))) $(basename $(notdir $(1)))_CMXA_FILES = \ $$(patsubst %,%.cmxa, $$($(basename $(notdir $(1)))_LIBRARIES)) $(basename $(notdir $(1)))_NO_FILES = \ $$(patsubst %.c,%.n.$(O), $$($(basename $(notdir $(1)))_C_FILES)) $(basename $(notdir $(1)))_CMX_FILES = \ $$(patsubst %.ml,%.cmx, $$($(basename $(notdir $(1)))_ML_FILES)) ALL_CMX_FILES += $$($(basename $(notdir $(1)))_CMX_FILES) $(basename $(notdir $(1)))_NCOBJS = \ $$($(basename $(notdir $(1)))_CMXA_FILES) \ $$($(basename $(notdir $(1)))_NO_FILES) \ $$($(basename $(notdir $(1)))_CMX_FILES) # To be overridden by the programs needing special native link flags $(basename $(notdir $(1)))_NATIVE_LINKFLAGS = $(basename $(notdir $(1)))_NATIVE_LINKCMD = \ $(strip \ $$(CAMLOPT) $$(OC_COMMON_LINKFLAGS) $$(OC_NATIVE_LINKFLAGS) \ $$($(basename $(notdir $(1)))_COMMON_LINKFLAGS) \ $$($(basename $(notdir $(1)))_NATIVE_LINKFLAGS)) $(1)$(EXE): $$$$($(basename $(notdir $(1)))_NCOBJS) $$(V_LINKOPT)$$($(basename $(notdir $(1)))_NATIVE_LINKCMD) -o $$@ \ $$($(basename $(notdir $(1)))_NCOBJS) endef # _OCAML_NATIVE_PROGRAM define OCAML_NATIVE_PROGRAM $(eval $(call _OCAML_PROGRAM_BASE,$(1))) $(eval $(call _OCAML_NATIVE_PROGRAM,$(1))) endef # OCAML_NATIVE_PROGRAM define OCAML_PROGRAM $(eval $(call _OCAML_PROGRAM_BASE,$(1))) $(eval $(call _OCAML_BYTECODE_PROGRAM,$(1))) $(eval $(call _OCAML_NATIVE_PROGRAM,$(1).opt)) endef # OCAML_PROGRAM # Macros for OCaml libraries, similar to those for OCaml programs define _OCAML_LIBRARY_BASE $(eval $(call _OCAML_COMMON_BASE,$(1))) endef # _OCAML_LIBRARY_BASE LINK_BYTECODE_LIBRARY =\ $(CAMLC) $(OC_COMMON_LINKFLAGS) $(OC_BYTECODE_LINKFLAGS) # The _OCAML_BYTECODE_LIBRARY macro defines a bytecode library but assuming # that _OCAML_LIBRARY_BASE has already been called. Its public counterpart # does not rely on this assumption and rather does call _OCAML_LIBRARY_BASE # itself. define _OCAML_BYTECODE_LIBRARY $(basename $(notdir $(1)))_BYTE_CMI_FILES = \ $$(foreach F,$$($(basename $(notdir $(1)))_CMI_FILES),\ $$(if $$(findstring /native/,$$(F)),,$$(F))) $(basename $(notdir $(1)))_BO_FILES = \ $$(patsubst %.c,%.b.$(O), $$($(basename $(notdir $(1)))_C_FILES)) $(basename $(notdir $(1)))_CMO_FILES = \ $$(patsubst %.ml,%.cmo, \ $$(foreach F,$$($(basename $(notdir $(1)))_ML_FILES),\ $$(if $$(findstring /native/,$$(F)),,$$(F)))) $(basename $(notdir $(1)))_BCOBJS = \ $$($(basename $(notdir $(1)))_BO_FILES) \ $$($(basename $(notdir $(1)))_CMO_FILES) $(1).cma: \ $$$$($(basename $(notdir $(1)))_BYTE_CMI_FILES) \ $$$$($(basename $(notdir $(1)))_BCOBJS) $$(V_LINKC)$$(LINK_BYTECODE_LIBRARY) -a -o $$@ \ $$($(basename $(notdir $(1)))_BCOBJS) endef # _OCAML_BYTECODE_LIBRARY define OCAML_BYTECODE_LIBRARY $(eval $(call _OCAML_LIBRARY_BASE,$(1))) $(eval $(call _OCAML_BYTECODE_LIBRARY,$(1))) endef # OCAML_BYTECODE_LIBRARY LINK_NATIVE_LIBRARY =\ $(CAMLOPT) $(OC_COMMON_LINKFLAGS) $(OC_NATIVE_LINKFLAGS) define _OCAML_NATIVE_LIBRARY $(basename $(notdir $(1)))_NATIVE_CMI_FILES = \ $$(foreach F,$$($(basename $(notdir $(1)))_CMI_FILES),\ $$(if $$(findstring /byte/,$$(F)),,$$(F))) $(basename $(notdir $(1)))_NO_FILES = \ $$(patsubst %.c,%.n.$(O), $$($(basename $(notdir $(1)))_C_FILES)) $(basename $(notdir $(1)))_CMX_FILES = \ $$(patsubst %.ml,%.cmx, \ $$(foreach F,$$($(basename $(notdir $(1)))_ML_FILES),\ $$(if $$(findstring /byte/,$$(F)),,$$(F)))) ALL_CMX_FILES += $$($(basename $(notdir $(1)))_CMX_FILES) $(basename $(notdir $(1)))_NCOBJS = \ $$($(basename $(notdir $(1)))_NO_FILES) \ $$($(basename $(notdir $(1)))_CMX_FILES) $(1).cmxa: \ $$$$($(basename $(notdir $(1)))_NATIVE_CMI_FILES) \ $$$$($(basename $(notdir $(1)))_NCOBJS) $$(V_LINKOPT)$$(LINK_NATIVE_LIBRARY) -a -o $$@ \ $$($(basename $(notdir $(1)))_NCOBJS) endef # _OCAML_NATIVE_LIBRARY define OCAML_NATIVE_LIBRARY $(eval $(call _OCAML_LIBRARY_BASE,$(1))) $(eval $(call _OCAML_NATIVE_LIBRARY,$(1))) endef # OCAML_NATIVE_LIBRARY define OCAML_LIBRARY $(eval $(call _OCAML_LIBRARY_BASE,$(1))) $(eval $(call _OCAML_BYTECODE_LIBRARY,$(1))) $(eval $(call _OCAML_NATIVE_LIBRARY,$(1))) endef # OCAML_LIBRARY # Strip debug information from a bytecode executable define STRIP_BYTE_PROG $(OCAMLRUN) $(ROOTDIR)/tools/stripdebug$(EXE) \ $(strip $(1)) $(strip $(1)).stripped endef # STRIP_BYTE_PROG # ocamlc has several mechanisms for linking a bytecode image to the runtime # which executes it. The exact mechanism depends on the platform and the precise # location of the runtime. The boot compiler (boot/ocamlc) therefore needs this # additional information, which comes from the stdlib build and is copied into # boot/ as part of coldstart. See read_runtime_launch_info in # bytecomp/bytelink.ml for further details. HEADER_NAME = runtime-launch-info ifeq "$(UNIX_OR_WIN32)" "win32" # Ensure that no command can create Cygwin symbolic links by ensuring that # symlink(2) will fail if native NTFS symlinks aren't available. CYGWIN ?= MSYS ?= export CYGWIN := $(strip \ $(filter-out winsymlinks winsymlinks:%, $(CYGWIN)) winsymlinks:nativestrict) export MSYS := $(strip \ $(filter-out winsymlinks winsymlinks:%, $(MSYS)) winsymlinks:nativestrict) endif