416 lines
13 KiB
Makefile
416 lines
13 KiB
Makefile
#**************************************************************************
|
|
#* *
|
|
#* OCaml *
|
|
#* *
|
|
#* Xavier Leroy, projet Cristal, INRIA Rocquencourt *
|
|
#* *
|
|
#* Copyright 1999 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. *
|
|
#* *
|
|
#**************************************************************************
|
|
|
|
ROOTDIR = ..
|
|
|
|
include $(ROOTDIR)/Makefile.common
|
|
|
|
# Lists of source files
|
|
|
|
BYTECODE_C_SOURCES := $(addsuffix .c, \
|
|
interp misc stacks fix_code startup_aux startup_byt freelist major_gc \
|
|
minor_gc memory alloc roots_byt globroots fail_byt signals \
|
|
signals_byt printexc backtrace_byt backtrace compare ints eventlog \
|
|
floats str array io extern intern hash sys meta parsing gc_ctrl md5 obj \
|
|
lexing callback debugger weak compact finalise custom dynlink \
|
|
afl $(UNIX_OR_WIN32) bigarray main memprof domain \
|
|
skiplist codefrag)
|
|
|
|
NATIVE_C_SOURCES := $(addsuffix .c, \
|
|
startup_aux startup_nat main fail_nat roots_nat signals \
|
|
signals_nat misc freelist major_gc minor_gc memory alloc compare ints \
|
|
floats str array io extern intern hash sys parsing gc_ctrl eventlog md5 obj \
|
|
lexing $(UNIX_OR_WIN32) printexc callback weak compact finalise custom \
|
|
globroots backtrace_nat backtrace dynlink_nat debugger meta \
|
|
dynlink clambda_checks afl bigarray \
|
|
memprof domain skiplist codefrag)
|
|
|
|
GENERATED_HEADERS := caml/opnames.h caml/version.h caml/jumptbl.h
|
|
CONFIG_HEADERS := caml/m.h caml/s.h
|
|
|
|
ifeq "$(TOOLCHAIN)" "msvc"
|
|
ASM_EXT := asm
|
|
ASM_SOURCES := $(ARCH)nt.$(ASM_EXT)
|
|
else
|
|
ASM_EXT := S
|
|
ASM_SOURCES := $(ARCH).$(ASM_EXT)
|
|
endif
|
|
|
|
# Targets to build and install
|
|
|
|
PROGRAMS := ocamlrun$(EXE)
|
|
BYTECODE_STATIC_LIBRARIES := ld.conf libcamlrun.$(A)
|
|
BYTECODE_SHARED_LIBRARIES :=
|
|
NATIVE_STATIC_LIBRARIES := libasmrun.$(A)
|
|
NATIVE_SHARED_LIBRARIES :=
|
|
|
|
ifeq "$(RUNTIMED)" "true"
|
|
PROGRAMS += ocamlrund$(EXE)
|
|
BYTECODE_STATIC_LIBRARIES += libcamlrund.$(A)
|
|
NATIVE_STATIC_LIBRARIES += libasmrund.$(A)
|
|
endif
|
|
|
|
ifeq "$(RUNTIMEI)" "true"
|
|
PROGRAMS += ocamlruni$(EXE)
|
|
BYTECODE_STATIC_LIBRARIES += libcamlruni.$(A)
|
|
NATIVE_STATIC_LIBRARIES += libasmruni.$(A)
|
|
endif
|
|
|
|
ifeq "$(UNIX_OR_WIN32)" "unix"
|
|
ifeq "$(SUPPORTS_SHARED_LIBRARIES)" "true"
|
|
BYTECODE_STATIC_LIBRARIES += libcamlrun_pic.$(A)
|
|
BYTECODE_SHARED_LIBRARIES += libcamlrun_shared.$(SO)
|
|
NATIVE_STATIC_LIBRARIES += libasmrun_pic.$(A)
|
|
NATIVE_SHARED_LIBRARIES += libasmrun_shared.$(SO)
|
|
endif
|
|
endif
|
|
|
|
# List of object files for each target
|
|
|
|
ASM_OBJECTS := $(ASM_SOURCES:.$(ASM_EXT)=.$(O))
|
|
|
|
libcamlrun_OBJECTS := $(BYTECODE_C_SOURCES:.c=.b.$(O))
|
|
|
|
libcamlrund_OBJECTS := $(BYTECODE_C_SOURCES:.c=.bd.$(O)) \
|
|
instrtrace.bd.$(O)
|
|
|
|
libcamlruni_OBJECTS := $(BYTECODE_C_SOURCES:.c=.bi.$(O))
|
|
|
|
libcamlrunpic_OBJECTS := $(BYTECODE_C_SOURCES:.c=.bpic.$(O))
|
|
|
|
libasmrun_OBJECTS := $(NATIVE_C_SOURCES:.c=.n.$(O)) $(ASM_OBJECTS)
|
|
|
|
libasmrund_OBJECTS := $(NATIVE_C_SOURCES:.c=.nd.$(O)) $(ASM_OBJECTS)
|
|
|
|
libasmruni_OBJECTS := $(NATIVE_C_SOURCES:.c=.ni.$(O)) $(ASM_OBJECTS)
|
|
|
|
libasmrunpic_OBJECTS := $(NATIVE_C_SOURCES:.c=.npic.$(O)) \
|
|
$(ASM_OBJECTS:.$(O)=_libasmrunpic.$(O))
|
|
|
|
# General (non target-specific) assembler and compiler flags
|
|
|
|
ifdef BOOTSTRAPPING_FLEXLINK
|
|
OC_CPPFLAGS += -DBOOTSTRAPPING_FLEXLINK
|
|
endif
|
|
|
|
# On Windows, OCAML_STDLIB_DIR needs to be defined dynamically
|
|
|
|
ifeq "$(UNIX_OR_WIN32)" "win32"
|
|
# OCAML_STDLIB_DIR needs to arrive in dynlink.c as a string which both gcc and
|
|
# msvc are willing parse without warning. This means we can't pass UTF-8
|
|
# directly since, as far as I can tell, cl can cope, but the pre-processor
|
|
# can't. So the string needs to be directly translated to L"" form. To do this,
|
|
# we take advantage of the fact that Cygwin uses GNU libiconv which includes a
|
|
# Java pseudo-encoding which translates any UTF-8 sequences to \uXXXX (and,
|
|
# unlike the C99 pseudo-encoding, emits two surrogate values when needed, rather
|
|
# than \UXXXXXXXX). The \u is then translated to \x in order to accommodate
|
|
# pre-Visual Studio 2013 compilers where \x is a non-standard alias for \u.
|
|
OCAML_STDLIB_DIR = $(shell echo $(LIBDIR)| iconv -t JAVA | sed -e 's/\\u/\\x/g')
|
|
STDLIB_CPP_FLAG = -DOCAML_STDLIB_DIR='L"$(OCAML_STDLIB_DIR)"'
|
|
else # Unix
|
|
OCAML_STDLIB_DIR = $(LIBDIR)
|
|
STDLIB_CPP_FLAG = -DOCAML_STDLIB_DIR='"$(OCAML_STDLIB_DIR)"'
|
|
endif
|
|
|
|
OC_CPPFLAGS += $(IFLEXDIR)
|
|
|
|
ifneq "$(CCOMPTYPE)" "msvc"
|
|
OC_CFLAGS += -g
|
|
endif
|
|
|
|
OC_CPPFLAGS += -DCAMLDLLIMPORT=
|
|
|
|
OC_NATIVE_CPPFLAGS = -DNATIVE_CODE -DTARGET_$(ARCH)
|
|
|
|
ifeq "$(UNIX_OR_WIN32)" "unix"
|
|
OC_NATIVE_CPPFLAGS += -DMODEL_$(MODEL)
|
|
endif
|
|
|
|
OC_NATIVE_CPPFLAGS += -DSYS_$(SYSTEM) $(IFLEXDIR)
|
|
|
|
OC_DEBUG_CPPFLAGS=-DDEBUG
|
|
OC_INSTR_CPPFLAGS=-DCAML_INSTR
|
|
|
|
ifeq "$(TOOLCHAIN)" "msvc"
|
|
ASMFLAGS=
|
|
endif
|
|
|
|
ASPPFLAGS = -DSYS_$(SYSTEM) -I$(ROOTDIR)/runtime
|
|
ifeq "$(UNIX_OR_WIN32)" "unix"
|
|
ASPPFLAGS += -DMODEL_$(MODEL)
|
|
endif
|
|
|
|
# Commands used to build native libraries
|
|
|
|
ifeq "$(UNIX_OR_WIN32)" "win32"
|
|
LIBS = $(BYTECCLIBS) $(EXTRALIBS)
|
|
ifdef BOOTSTRAPPING_FLEXLINK
|
|
MAKE_OCAMLRUN=$(MKEXE_BOOT)
|
|
else
|
|
MAKE_OCAMLRUN = $(MKEXE) -o $(1) $(2)
|
|
endif
|
|
else
|
|
LIBS = $(BYTECCLIBS)
|
|
MAKE_OCAMLRUN = $(MKEXE) -o $(1) $(2)
|
|
endif
|
|
|
|
# Build, install and clean targets
|
|
|
|
.PHONY: all
|
|
all: $(BYTECODE_STATIC_LIBRARIES) $(BYTECODE_SHARED_LIBRARIES) $(PROGRAMS)
|
|
|
|
.PHONY: allopt
|
|
ifneq "$(NATIVE_COMPILER)" "false"
|
|
allopt: $(NATIVE_STATIC_LIBRARIES) $(NATIVE_SHARED_LIBRARIES)
|
|
else
|
|
allopt:
|
|
$(error The build has been configured with --disable-native-compiler)
|
|
endif
|
|
|
|
INSTALL_INCDIR=$(INSTALL_LIBDIR)/caml
|
|
.PHONY: install
|
|
install:
|
|
$(INSTALL_PROG) $(PROGRAMS) "$(INSTALL_BINDIR)"
|
|
$(INSTALL_DATA) $(BYTECODE_STATIC_LIBRARIES) "$(INSTALL_LIBDIR)"
|
|
ifneq "$(BYTECODE_SHARED_LIBRARIES)" ""
|
|
$(INSTALL_PROG) $(BYTECODE_SHARED_LIBRARIES) "$(INSTALL_LIBDIR)"
|
|
endif
|
|
mkdir -p "$(INSTALL_INCDIR)"
|
|
$(INSTALL_DATA) caml/domain_state.tbl caml/*.h "$(INSTALL_INCDIR)"
|
|
|
|
.PHONY: installopt
|
|
installopt:
|
|
$(INSTALL_DATA) $(NATIVE_STATIC_LIBRARIES) "$(INSTALL_LIBDIR)"
|
|
ifneq "$(NATIVE_SHARED_LIBRARIES)" ""
|
|
$(INSTALL_PROG) $(NATIVE_SHARED_LIBRARIES) "$(INSTALL_LIBDIR)"
|
|
endif
|
|
|
|
.PHONY: clean
|
|
clean:
|
|
rm -f *.o *.obj *.a *.lib *.so *.dll ld.conf
|
|
rm -f ocamlrun ocamlrund ocamlruni
|
|
rm -f ocamlrun.exe ocamlrund.exe ocamlruni.exe
|
|
rm -f primitives primitives.new prims.c $(GENERATED_HEADERS)
|
|
rm -f domain_state*.inc
|
|
rm -rf $(DEPDIR)
|
|
|
|
.PHONY: distclean
|
|
distclean: clean
|
|
|
|
# Generated non-object files
|
|
|
|
ld.conf: $(ROOTDIR)/Makefile.config
|
|
echo "$(STUBLIBDIR)" > $@
|
|
echo "$(LIBDIR)" >> $@
|
|
|
|
# If primitives contain duplicated lines (e.g. because the code is defined
|
|
# like
|
|
# #ifdef X
|
|
# CAMLprim value caml_foo() ...
|
|
# #else
|
|
# CAMLprim value caml_foo() ...
|
|
# end), horrible things will happen (duplicated entries in Runtimedef ->
|
|
# double registration in Symtable -> empty entry in the PRIM table ->
|
|
# the bytecode interpreter is confused).
|
|
# We sort the primitive file and remove duplicates to avoid this problem.
|
|
|
|
# Warning: we use "sort | uniq" instead of "sort -u" because in the MSVC
|
|
# port, the "sort" program in the path is Microsoft's and not cygwin's
|
|
|
|
# Warning: POSIX sort is locale dependent, that's why we set LC_ALL explicitly.
|
|
# Sort is unstable for "is_directory" and "isatty"
|
|
# see http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sort.html:
|
|
# "using sort to process pathnames, it is recommended that LC_ALL .. set to C"
|
|
|
|
# To speed up builds, we avoid changing "primitives" when files
|
|
# containing primitives change but the primitives table does not
|
|
primitives: $(shell ./gen_primitives.sh > primitives.new; \
|
|
cmp -s primitives primitives.new || echo primitives.new)
|
|
cp $^ $@
|
|
|
|
prims.c : primitives
|
|
(echo '#define CAML_INTERNALS'; \
|
|
echo '#include "caml/mlvalues.h"'; \
|
|
echo '#include "caml/prims.h"'; \
|
|
sed -e 's/.*/extern value &();/' primitives; \
|
|
echo 'c_primitive caml_builtin_cprim[] = {'; \
|
|
sed -e 's/.*/ &,/' primitives; \
|
|
echo ' 0 };'; \
|
|
echo 'char * caml_names_of_builtin_cprim[] = {'; \
|
|
sed -e 's/.*/ "&",/' primitives; \
|
|
echo ' 0 };') > prims.c
|
|
|
|
caml/opnames.h : caml/instruct.h
|
|
tr -d '\r' < $< | \
|
|
sed -e '/\/\*/d' \
|
|
-e '/^#/d' \
|
|
-e 's/enum /static char * names_of_/' \
|
|
-e 's/{$$/[] = {/' \
|
|
-e 's/\([[:upper:]][[:upper:]_0-9]*\)/"\1"/g' > $@
|
|
|
|
# caml/jumptbl.h is required only if you have GCC 2.0 or later
|
|
caml/jumptbl.h : caml/instruct.h
|
|
tr -d '\r' < $< | \
|
|
sed -n -e '/^ /s/ \([A-Z]\)/ \&\&lbl_\1/gp' \
|
|
-e '/^}/q' > $@
|
|
|
|
caml/version.h : $(ROOTDIR)/tools/make-version-header.sh $(ROOTDIR)/VERSION
|
|
$^ > $@
|
|
|
|
# Libraries and programs
|
|
|
|
ocamlrun$(EXE): prims.$(O) libcamlrun.$(A)
|
|
$(call MAKE_OCAMLRUN,$@,$^ $(LIBS))
|
|
|
|
libcamlrun.$(A): $(libcamlrun_OBJECTS)
|
|
$(call MKLIB,$@, $^)
|
|
|
|
ocamlrund$(EXE): prims.$(O) libcamlrund.$(A)
|
|
$(MKEXE) $(MKEXEDEBUGFLAG) -o $@ $^ $(LIBS)
|
|
|
|
libcamlrund.$(A): $(libcamlrund_OBJECTS)
|
|
$(call MKLIB,$@, $^)
|
|
|
|
ocamlruni$(EXE): prims.$(O) libcamlruni.$(A)
|
|
$(MKEXE) -o $@ $^ $(LIBS)
|
|
|
|
libcamlruni.$(A): $(libcamlruni_OBJECTS)
|
|
$(call MKLIB,$@, $^)
|
|
|
|
libcamlrun_pic.$(A): $(libcamlrunpic_OBJECTS)
|
|
$(call MKLIB,$@, $^)
|
|
|
|
libcamlrun_shared.$(SO): $(libcamlrunpic_OBJECTS)
|
|
$(MKDLL) -o $@ $^ $(BYTECCLIBS)
|
|
|
|
libasmrun.$(A): $(libasmrun_OBJECTS)
|
|
$(call MKLIB,$@, $^)
|
|
|
|
libasmrund.$(A): $(libasmrund_OBJECTS)
|
|
$(call MKLIB,$@, $^)
|
|
|
|
libasmruni.$(A): $(libasmruni_OBJECTS)
|
|
$(call MKLIB,$@, $^)
|
|
|
|
libasmrun_pic.$(A): $(libasmrunpic_OBJECTS)
|
|
$(call MKLIB,$@, $^)
|
|
|
|
libasmrun_shared.$(SO): $(libasmrunpic_OBJECTS)
|
|
$(MKDLL) -o $@ $^ $(NATIVECCLIBS)
|
|
|
|
# Target-specific preprocessor and compiler flags
|
|
|
|
%.bd.$(O): OC_CPPFLAGS += $(OC_DEBUG_CPPFLAGS)
|
|
%.bd.$(D): OC_CPPFLAGS += $(OC_DEBUG_CPPFLAGS)
|
|
|
|
%.bi.$(O): OC_CPPFLAGS += $(OC_INSTR_CPPFLAGS)
|
|
%.bi.$(D): OC_CPPFLAGS += $(OC_INSTR_CPPFLAGS)
|
|
|
|
%.bpic.$(O): OC_CFLAGS += $(SHAREDLIB_CFLAGS)
|
|
|
|
%.n.$(O): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS)
|
|
%.n.$(D): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS)
|
|
|
|
%.nd.$(O): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS) $(OC_DEBUG_CPPFLAGS)
|
|
%.nd.$(D): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS) $(OC_DEBUG_CPPFLAGS)
|
|
|
|
%.ni.$(O): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS) $(OC_INSTR_CPPFLAGS)
|
|
%.ni.$(D): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS) $(OC_INSTR_CPPFLAGS)
|
|
|
|
%.npic.$(O): OC_CFLAGS += $(SHAREDLIB_CFLAGS)
|
|
%.npic.$(O): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS)
|
|
%.npic.$(D): OC_CPPFLAGS += $(OC_NATIVE_CPPFLAGS)
|
|
|
|
# Compilation of C files
|
|
|
|
# The COMPILE_C_FILE macro below receives as argument the pattern
|
|
# that corresponds to the name of the generated object file
|
|
# (without the extension, which is added by the macro)
|
|
define COMPILE_C_FILE
|
|
ifneq "$(COMPUTE_DEPS)" "false"
|
|
ifneq "$(1)" "%"
|
|
# -MG would ensure that the dependencies are generated even if the files listed
|
|
# in $$(GENERATED_HEADERS) haven't been assembled yet. However, this goes subtly
|
|
# wrong if the user has the headers installed, as gcc will pick up a dependency
|
|
# on those instead and the local ones will not be generated. For this reason, we
|
|
# don't use -MG and instead include $(GENERATED_HEADERS) in the order only
|
|
# dependencies to ensure that they exist before dependencies are computed.
|
|
$(DEPDIR)/$(1).$(D): %.c | $(DEPDIR) $(GENERATED_HEADERS)
|
|
$$(DEP_CC) $$(OC_CPPFLAGS) $$(CPPFLAGS) $$< -MT \
|
|
'$$*$(subst %,,$(1)).$(O)' -MF $$@
|
|
endif
|
|
$(1).$(O): %.c
|
|
else
|
|
$(1).$(O): %.c $(CONFIG_HEADERS) $(GENERATED_HEADERS) $(RUNTIME_HEADERS)
|
|
endif
|
|
$$(CC) -c $$(OC_CFLAGS) $$(CFLAGS) $$(OC_CPPFLAGS) $$(CPPFLAGS) \
|
|
$$(OUTPUTOBJ)$$@ $$<
|
|
endef
|
|
|
|
object_types := % %.b %.bd %.bi %.bpic
|
|
ifneq "$(NATIVE_COMPILER)" "false"
|
|
object_types += %.n %.nd %.ni %.np %.npic
|
|
endif
|
|
|
|
$(foreach object_type, $(object_types), \
|
|
$(eval $(call COMPILE_C_FILE,$(object_type))))
|
|
|
|
dynlink.%.$(O): OC_CPPFLAGS += $(STDLIB_CPP_FLAG)
|
|
|
|
$(foreach object_type,$(subst %,,$(object_types)), \
|
|
$(eval dynlink$(object_type).$(O): $(ROOTDIR)/Makefile.config))
|
|
|
|
# Compilation of assembly files
|
|
|
|
%.o: %.S
|
|
$(ASPP) $(ASPPFLAGS) -o $@ $< || \
|
|
{ echo "If your assembler produced syntax errors, it is probably";\
|
|
echo "unhappy with the preprocessor. Check your assembler, or";\
|
|
echo "try producing $*.o by hand.";\
|
|
exit 2; }
|
|
|
|
%_libasmrunpic.o: %.S
|
|
$(ASPP) $(ASPPFLAGS) $(SHAREDLIB_CFLAGS) -o $@ $<
|
|
|
|
domain_state64.inc: caml/domain_state.tbl gen_domain_state64_inc.awk
|
|
$(AWK) -f ./gen_domain_state64_inc.awk $< > $@
|
|
|
|
domain_state32.inc: caml/domain_state.tbl gen_domain_state32_inc.awk
|
|
$(AWK) -f ./gen_domain_state32_inc.awk $< > $@
|
|
|
|
amd64nt.obj: amd64nt.asm domain_state64.inc
|
|
$(ASM)$@ $(ASMFLAGS) $<
|
|
|
|
i386nt.obj: i386nt.asm domain_state32.inc
|
|
$(ASM)$@ $(ASMFLAGS) $<
|
|
|
|
%_libasmrunpic.obj: %.asm
|
|
$(ASM)$@ $(ASMFLAGS) $<
|
|
|
|
# Dependencies
|
|
|
|
DEP_FILES := $(addsuffix .b, $(basename $(BYTECODE_C_SOURCES) instrtrace))
|
|
ifneq "$(NATIVE_COMPILER)" "false"
|
|
DEP_FILES += $(addsuffix .n, $(basename $(NATIVE_C_SOURCES)))
|
|
endif
|
|
DEP_FILES += $(addsuffix d, $(DEP_FILES)) \
|
|
$(addsuffix i, $(DEP_FILES)) \
|
|
$(addsuffix pic, $(DEP_FILES))
|
|
DEP_FILES := $(addsuffix .$(D), $(DEP_FILES))
|
|
|
|
ifeq "$(COMPUTE_DEPS)" "true"
|
|
include $(addprefix $(DEPDIR)/, $(DEP_FILES))
|
|
endif
|