########################################################################
# Configuration.
#

###################################
# DEV MODE
# Turn it off when release
# BYTE_ENABLED=true
# NATIVE_ENABLED=false
###################################

open build/C
open build/svn_realclean
include mk/defaults
include mk/make_gen


BOOTDIR=$(dir boot)
BUILDDIR=$(dir .)
.PHONY: realclean distclean clean install all main
.PHONY: dvi html info pdf ps txt # documentation targets

#
# Location of the OCaml library
#
if $(not $(defined CAMLLIB))
    CAMLLIB = $(dir $(string $(getenv CAMLLIB, $(getenv OCAMLLIB, $(OCAMLLIB)))))
    export

#
# Architecture-specific configuration
#
if $(equal $(OSTYPE), Win32)
    #
    # Extra options for the C compiler
    #
    if $(equal $(CCOMPTYPE), msvc)
        CFLAGS += /MT /DWIN32 /W4
        export
    else
	CFLAGS += -DWIN32 -g -O2 -Wall -Wno-unused -isystem$(CAMLLIB)
        export

    #
    # Don't build man pages
    #
    MAN_ENABLED = false

    #
    # Always use threads
    #
    THREADS_ENABLED = true

    export

else
    #
    # Extra options for the C compiler
    #
    CFLAGS += -g -O2 -Wall -Wno-unused

    #
    # We never need threads on Unix
    #
    THREADS_ENABLED = false

    export

#
# General options
#
SCANNER_MODE = error

#
# OCaml options
#
OCAMLFLAGS[] = -safe-string -strict-sequence -g -w -a-40
if $(THREADS_ENABLED)
    OCAMLFLAGS += -thread
    export

compiler_config(a_compiler) =
        config = $(Map)
        foreach(key_value_line => ..., $(shella $(a_compiler) -config))
            export config
            lex($(open-in-string $(key_value_line)))
            case $'^\([^:]*\):[[:blank:]]*\(.*\)$'
                export config
                config = $(config.add $1, $2)
        return $(config)

static. =
    OCAMLOPT_CONFIG = $(compiler_config $(OCAMLOPT))
    OCAMLOPT_OPTIMIZER_FLAGS[] =
    ConfMsgChecking($'if ocamlopt was compiled with flambda')
    if $(and $(OCAMLOPT_CONFIG.mem flambda), $(equal $(OCAMLOPT_CONFIG.find flambda), true))
        ConfMsgResult($'yes')
        OCAMLOPT_OPTIMIZER_FLAGS[] = -O3
        export
    else
        ConfMsgResult($'no')

OCAMLOPTFLAGS[] = $(OCAMLFLAGS) $(OCAMLOPT_OPTIMIZER_FLAGS)


#
# Support for profiling
#
if $(not $(defined NATIVE_PROFILE))
   NATIVE_PROFILE = false
   export

if $(NATIVE_PROFILE)
   OCAMLOPTFLAGS += -p -inline 0
   CFLAGS += -pg
   if $(equal $(NATIVE_PROFILE), compact)
      OCAMLOPTFLAGS += -compact
      export
   export

#
# Libraries (without suffixes)
#
OCAML_OTHER_LIBS = unix

if $(THREADS_ENABLED)
   OCAML_OTHER_LIBS += threads
   export

#
# C options
#
INCLUDES += $(CAMLLIB) .
EXTRA_CLIBS[] =

if $(READLINE_ENABLED)
    CFLAGS += $(READLINE_CFLAGS)
    EXTRA_CLIBS += $(READLINE_CLIBS)
    export

if $(NCURSES_ENABLED)
    CFLAGS += $(NCURSES_CFLAGS)
    EXTRA_CLIBS += $(NCURSES_CLIBS)
    export

if $(FAM_ENABLED)
    CFLAGS += $(FAM_CFLAGS)
    EXTRA_CLIBS += $(FAM_CLIBS)
    export

OCAML_LINK_FLAGS = $(mapprefix -cclib, $(set $(EXTRA_CLIBS)))

#
# Name of the genmagic program
#
VERSION_TXT = $(file version.txt)
GENMAGIC = $(file src/magic/omake_gen_magic)

########################################################################
# Clean up
#
CLEAN = rm -rf *.cm* *~ .\#* *.o *.obj *.a *.lib *.exe *.omc *.install *.tmp

clean:
    $(CLEAN) boot .config.omc .config.local.omc .omakedb* mk/*.omc .omake omake-boot$(EXE) lib/*.default download

if $(not $(defined FORCE_REALCLEAN))
    FORCE_REALCLEAN = false
    export

realclean: clean
    svn_realclean $(if $(FORCE_REALCLEAN), -f) -i .omakedb -i .omakedb.lock -i .config -i .config.local

########################################################################
# Source code
#
.SUBDIRS: src

########################################################################
# Packaging
#
.PHONY: rpm tar zip pkg dmg osxclean publish
.PHONY: package

VERSION=$(string $(cat version.txt))
BASENAME = omake-$(VERSION)

PUBFILES[] =
    README.md
    README.WIN32
    INSTALL
    LICENSE
    LICENSE.OMake
    ChangeLog
    ChangeLog_old.txt
    CONTRIBUTORS.org
    omake.spec
    omake.spec.in
    omake.aip
    version.txt
    OMakefile
    OMakeroot
    Makefile
    configure
    configure.ml
    build
    build.ml
    make
    make.ml

    src/OMakefile
    src/Makefile

    src/*/OMakefile
    src/*/*.ml
    src/*/*.mly
    src/*/*.mll
    src/*/*.mli
    src/*/*.h
    src/*/*.c
    src/env/omake_ast_parse.input

    lib/OMakefile.default
    lib/OMakeroot.default
    lib/OMakeroot.install
    lib/OMakeroot.om
    lib/Pervasives.install
    lib/Pervasives.om
    lib/boot/Default
    lib/boot/License
    lib/build/*.install
    lib/build/*.om
    lib/configure/*.install
    lib/configure/*.om
    lib/parse/C/*.install
    lib/parse/C/*.om
    lib/parse/LaTeX/*.install
    lib/parse/LaTeX/*.om
    lib/web/*.install
    lib/web/*.om

    mk/defaults
    mk/make_config
    mk/make_gen
    mk/osconfig_mingw.mk
    mk/osconfig_msvc.mk
    mk/osconfig_unix.mk

    doc/OMakefile
    doc/omake.1
    doc/html/*.html
    doc/html/*.css
    doc/images/*.ai
    doc/images/*.eps
    doc/images/*.gif
    doc/images/*.psd
    doc/info/omake-doc.info
    doc/info/omake-doc.info-*
    doc/ps/omake-doc.pdf
    doc/src/*.hva
    doc/src/*.sty
    doc/src/*.tex
    doc/txt/omake-doc.txt

    bench/OMakefile
    bench/mandel/Test1

    osx_resources/Description.plist
    osx_resources/Info.plist.in
    osx_resources/OMake.pmproj
    osx_resources/installer_files/License.txt
    osx_resources/installer_files/preflight
    osx_resources/installer_files/ReadMe.txt

    test/awk/Test2/stdout.expected
    test/awk/Test2/awk.osh
    test/awk/Test2/run.osh
    test/awk/Test3/stdout.expected
    test/awk/Test3/awk.osh
    test/awk/Test3/run.osh
    test/awk/Test1/stdout.expected
    test/awk/Test1/awk.osh
    test/awk/Test1/run.osh
    test/awk/Awk.out
    test/awk/Awk.in
    test/awk/Subst.in
    test/awk/Test4/Subst.in
    test/awk/Test4/Subst.out.expected
    test/awk/Test4/OMakeroot
    test/awk/Test4/OMakefile
    test/awk/Test4/run.osh
    test/syntax/Test2
    test/syntax/Test3
    test/syntax/Test1
    test/exec/Test1/xxx
    test/exec/Test1/OMakeroot
    test/exec/Test1/OMakefile
    test/parse/C/Test2/test.c
    test/parse/C/Test2/OMakeroot
    test/parse/C/Test2/OMakefile
    test/parse/C/Test3/test.c
    test/parse/C/Test3/OMakeroot
    test/parse/C/Test3/OMakefile
    test/parse/C/Test1/test.c
    test/parse/C/Test1/OMakeroot
    test/parse/C/Test1/OMakefile
    test/parse/C/test2.c
    test/exn/Test2
    test/exn/Test3/exn.om
    test/exn/Test3/run.osh
    test/exn/Test5
    test/exn/Test4
    test/vmount/Test1/src/foo.c
    test/vmount/Test1/src/OMakefile
    test/vmount/Test1/build/.dummy
    test/vmount/Test1/OMakeroot
    test/vmount/Test1/OMakefile
    test/simple/Test7
    test/simple/Test2/a/x/.dummy
    test/simple/Test2/a/y/.dummy
    test/simple/Test2/OMakeroot
    test/simple/Test2/OMakefile
    test/simple/Test9
    test/simple/Test10
    test/simple/Test3/OMakeroot
    test/simple/Test3/OMakefile
    test/simple/Test5
    test/simple/Test1/OMakeroot
    test/simple/Test1/OMakefile
    test/simple/Test12
    test/simple/Test8/stdout.expected
    test/simple/Test8/simple.om
    test/simple/Test8/run.osh
    test/simple/Test11
    test/simple/Test4/stdout.expected
    test/simple/Test4/simple.om
    test/simple/Test4/run.osh
    test/simple/Test6
    test/diff.om
    test/targets/Test2/OMakeroot
    test/targets/Test2/OMakefile
    test/targets/Test3/OMakeroot
    test/targets/Test3/OMakefile
    test/targets/Test3/run.osh
    test/targets/Test5/OMakeroot
    test/targets/Test5/run.osh
    test/targets/Test1/OMakeroot
    test/targets/Test1/OMakefile
    test/targets/Test4/OMakeroot
    test/curry/Test2
    test/curry/Test3
    test/curry/Test5
    test/curry/Test1
    test/curry/Test4
    test/object/Test13
    test/object/Test09
    test/object/Test10
    test/object/Test17
    test/object/Test18
    test/object/Test15
    test/object/Test16
    test/object/Test11
    test/object/Test03
    test/object/Test14
    test/object/Test05
    test/object/Test07
    test/object/Test06
    test/object/Test04
    test/object/Test08
    test/object/Test02
    test/object/Test01/stdout.expected
    test/object/Test01/OMakeroot
    test/object/Test01/OMakefile
    test/object/Test01/run.osh
    test/object/Test01/object.om
    test/regex/Test2
    test/regex/Test3
    test/regex/Test1
    test/regex/Test4
    test/memo/Test2/stdout.expected
    test/memo/Test2/OMakeroot
    test/memo/Test2/run.osh
    test/memo/Test3/stdout.expected
    test/memo/Test3/OMakeroot
    test/memo/Test3/run.osh
    test/memo/Test5/stdout.expected
    test/memo/Test5/run.osh
    test/memo/Test5/fib.om
    test/memo/Test1/stdout.expected
    test/memo/Test1/OMakeroot
    test/memo/Test1/run.osh
    test/memo/Test4/stdout.expected
    test/memo/Test4/memo.om
    test/memo/Test4/run.osh
    test/memo/Test6/test.om
    test/memo/Test6/OMakeroot
    test/OMakefile
    test/README
    test/lazy/Test1
    test/return/Test2
    test/return/Test1
    test/static/Test2/stdout.expected
    test/static/Test2/OMakeroot
    test/static/Test2/run.osh
    test/static/Test3/stdout.expected
    test/static/Test3/OMakeroot
    test/static/Test3/run.osh
    test/static/Test1/stdout.expected
    test/static/Test1/OMakeroot
    test/static/Test1/run.osh
    test/calculator/Test
    test/calculator/Test.input1
    test/calculator/Test.input2
    test/keyword/Test2
    test/keyword/Test3
    test/keyword/Test5
    test/keyword/Test1
    test/keyword/Test4
    test/keyword/Test6
    test/shell/Test7/OMakeroot
    test/shell/Test2/stdout.expected
    test/shell/Test2/OMakeroot
    test/shell/Test2/OMakefile
    test/shell/Test2/run.osh
    test/shell/Test3/run.osh
    test/shell/Test5
    test/shell/Test1/shell.om
    test/shell/Test1/run.osh
    test/shell/Test4/run.osh
    test/shell/Test6/run.osh

PUBFILES_EXCLUDE[] =
    src/env/omake_ast_parse.mly
    src/libmojave/lm_thread_core.ml
    src/libmojave/lm_thread_pool.ml
    src/magic/omake_magic.ml
    src/shell/omake_shell_sys.ml

package: packages/$(BASENAME).tar.gz

packages/$(BASENAME):
    rm -rf packages/$(BASENAME)
    mkdir -p packages/$(BASENAME)
    foreach(pat => ..., $(PUBFILES))
        files = $(glob $(pat))
        foreach(file => ..., $(files))
	     if $(test -f $(file))
	         mkdir -p packages/$(BASENAME)/$(dirname $(file))
                 cp $(file) packages/$(BASENAME)/$(file)
    foreach(file => ..., $(PUBFILES_EXCLUDE))
        rm -f packages/$(BASENAME)/$(file)

packages/$(BASENAME).tar.gz: packages/$(BASENAME)
    section
        cd packages
	rm -f $(BASENAME).tar.gz
        tar czf $(BASENAME).tar.gz $(BASENAME)

.PHONY: clean-package
    rm -rf packages/$(BASENAME)
    rm -f packages/$(BASENAME).tar.gz


rpm: version.txt make_rpm make_checkout
    ./make_rpm

dmg: version.txt
    ./make_dmg dmg

pkg: version.txt
    ./make_dmg pkg

osxclean: version.txt
    ./make_dmg clean

omake.spec: omake.spec.in
    echo $"%define index $(RELEASE)" > $@
    echo $"Version: $(VERSION)" >> $@
    cat $< >> $@

.DEFAULT: omake.spec

########################################################################
# Documentation
#
.SUBDIRS: doc

.PHONY: doc
doc: doc/txt doc/info doc/html doc/tex

########################################################################
# Standard library
#
.SUBDIRS: $(subdirs C, lib)
    %.install: %.om $(GENMAGIC)$(EXE) $(VERSION_TXT)
        $(GENMAGIC) -o $@ --version $(VERSION_TXT) --root $<

    clean:
        $(CLEAN)

STDLIBFILES  = $(find lib -name *.om)
INSTALLFILES = $(replacesuffixes .om, .install, $(STDLIBFILES))
STDLIBNAMES  = $(removesuffix .om, $(in lib, $(STDLIBFILES)))

BOOTFILES[] =
    lib/boot/License
    lib/boot/Default

DEFAULTFILES[] =
    lib/OMakeroot.default
    lib/OMakefile.default

lib/OMakeroot.default: $(BOOTFILES)
    fprint($@, $(OMakeroot))

lib/OMakefile.default: $(BOOTFILES)
    fprint($@, $(OMakefile))

########################################################################
# Installation
#
all: $(DEFAULTFILES)  $(INSTALLFILES) $(ROOT)/src/Makefile
# omaketop

omaketop: src/clib/clib.a src/libmojave/lm.cma src/front/frt.cma src/top/boot_repl.cma  src/magic/magic.cma src/ast/ast.cma src/ir/ir.cma src/env/env.cma  src/eval/eval.cma src/shell/shell.cma src/exec/exec.cma src/build/build.cma src/builtin/builtin.cma
	$(OCAMLC) -custom -verbose -I +compiler-libs -linkall ocamlcommon.cma ocamlbytecomp.cma ocamltoplevel.cma   unix.cma  src/clib/clib.a src/libmojave/lm.cma  src/front/frt.cma src/top/boot_repl.cma src/magic/magic.cma src/ast/ast.cma src/ir/ir.cma src/env/env.cma  src/eval/eval.cma src/shell/shell.cma src/exec/exec.cma src/build/build.cma src/builtin/builtin.cma -cclib -lreadline    topstart.cmo -o $@


omakeutop:src/clib/clib.a src/libmojave/lm.cma src/front/frt.cma  src/top/boot_repl.cma  src/magic/magic.cma src/ast/ast.cma src/ir/ir.cma src/env/env.cma  src/eval/eval.cma src/shell/shell.cma src/exec/exec.cma src/build/build.cma src/builtin/builtin.cma src/top/myutop.cmo
	ocamlfind ocamlc -custom -o omakeutop -thread -linkpkg -linkall -predicates create_toploop \
    -package compiler-libs.toplevel,utop src/clib/clib.a src/libmojave/lm.cma src/front/frt.cma  src/top/boot_repl.cma  src/magic/magic.cma src/ast/ast.cma src/ir/ir.cma src/env/env.cma  src/eval/eval.cma src/shell/shell.cma src/exec/exec.cma src/build/build.cma src/builtin/builtin.cma -cclib -lreadline src/top/myutop.cmo

install: $(DEFAULTFILES)  $(INSTALLFILES)
    mkdir -p $(INSTALL_LIBDIR)/omake
    cp -f -m 444 $(DEFAULTFILES) $(INSTALL_LIBDIR)/omake/
    foreach(name => ..., $(STDLIBNAMES))
        node = $(file $(INSTALL_LIBDIR)/omake/$(name).om)
        mkdir -p $(dirof $(node))
        cp -f -m 444 lib/$(name).install $(node)

########################################################################
# Testing
#
.PHONY: check bench

.SUBDIRS: test bench
