# -*- Mode: makefile -*-
# vim: ft=make
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla Communicator client code, released
# March 31, 1998.
#
# The Initial Developer of the Original Code is
# Netscape Communications Corporation.
# Portions created by the Initial Developer are Copyright (C) 1998
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#   Michael Ang <mang@subcarrier.org>
#   Kevin Buhr <buhr@stat.wisc.edu>
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****

#
# JSRef GNUmake makefile.
#
# Note: dependency rules are missing for some files (some
#       .h, all .msg, etc.)  Re-make clean if in doubt.
#


DEPTH = .

include config.mk

#NS_USE_NATIVE = 1

ifndef NANOJIT_ARCH
$(warning NANOJIT_ARCH not defined in config/$(OS_CONFIG).mk, JIT disabled)
else
ifdef DISABLE_JIT
$(warning disabling JIT per build specification)
else
ENABLE_JIT=1
endif
endif

ifdef ENABLE_JIT
DEFINES += -DJS_TRACER
DEFINES += -DFEATURE_NANOJIT
INCLUDES += -Inanojit
endif

#ifndef BUILD_OPT
#DEFINES += -Ivprof
#endif

ifdef NARCISSUS
DEFINES += -DNARCISSUS
endif

# Look in OBJDIR to find jsautocfg.h, jsautokw.h, and js-config.h
INCLUDES   += -I. -I$(OBJDIR)

ifdef JS_THREADSAFE
DEFINES += -DJS_THREADSAFE
INCLUDES += -I$(DIST)/include/nspr
ifdef USE_MSVC
OTHER_LIBS += $(DIST)/lib/libnspr$(NSPR_LIBSUFFIX).lib
else
OTHER_LIBS += -L$(DIST)/lib -lnspr$(NSPR_LIBSUFFIX)
endif
endif

ifdef JS_NO_THIN_LOCKS
DEFINES += -DJS_USE_ONLY_NSPR_LOCKS
endif

ifdef JS_HAS_FILE_OBJECT
DEFINES += -DJS_HAS_FILE_OBJECT
endif

ifdef JS_GC_ZEAL
DEFINES += -DJS_GC_ZEAL
endif

#
# XCFLAGS may be set in the environment or on the gmake command line
#
#CFLAGS += -DDEBUG -DDEBUG_brendan -DJS_ARENAMETER -DJS_HASHMETER -DJS_DUMP_PROPTREE_STATS -DJS_DUMP_SCOPE_METERS -DJS_SCOPE_DEPTH_METER -DJS_BASIC_STATS
CFLAGS          += $(OS_CFLAGS) $(DEFINES) $(INCLUDES) $(XCFLAGS)

LDFLAGS		= $(XLDFLAGS)
LDFLAGS += $(OS_LDFLAGS)

ifdef MOZ_SHARK
DEFINES += -DMOZ_SHARK
CFLAGS += -F/System/Library/PrivateFrameworks
LDFLAGS += -F/System/Library/PrivateFrameworks -framework CHUD
endif
ifdef MOZ_CALLGRIND
DEFINES += -DMOZ_CALLGRIND
endif
ifdef MOZ_VTUNE
DEFINES += -DMOZ_VTUNE
CXXFLAGS += -IC:/Program\ Files/Intel/VTune/Analyzer/Include
OTHER_LIBS += C:/Program\ Files/Intel/VTune/Analyzer/Lib/VtuneApi.lib
endif

ifndef NO_LIBM
LDFLAGS += -lm
endif

# Prevent floating point errors caused by VC++ optimizations
ifeq ($(OS_ARCH),WINNT)
_MSC_VER = $(shell $(CXX) 2>&1 | sed -n 's/.*Compiler Version \([0-9]*\)\.\([0-9]*\).*/\1\2/p')
ifeq (,$(filter-out 1200 1300 1310,$(_MSC_VER)))
CFLAGS += -Op
else
CFLAGS += -fp:precise
endif
endif # WINNT

#
#	Server-related changes :
#
ifdef NES40
DEFINES += -DNES40
endif

#
# Line editing support.
# Define JS_READLINE or JS_EDITLINE to enable line editing in the
# js command-line interpreter.
#
ifdef JS_READLINE
# For those platforms with the readline library installed.
DEFINES += -DEDITLINE
PROG_LIBS += -lreadline -ltermcap
else
ifdef JS_EDITLINE
# Use the editline library, built locally.
PREDIRS += editline
DEFINES += -DEDITLINE
PROG_LIBS += $(OBJDIR)/editline/libedit.a
endif
endif

# For purify
PURE_CFLAGS     = -DXP_UNIX $(OPTIMIZER) $(PURE_OS_CFLAGS) $(DEFINES) \
                  $(INCLUDES) $(XCFLAGS)

#
# JS file lists
#
JS_HFILES =		\
	jsarray.h	\
	jsatom.h	\
	jsbool.h	\
	jscntxt.h	\
	jsdate.h	\
	jsemit.h	\
	jsexn.h		\
	jsfun.h		\
	jsgc.h		\
	jsinterp.h	\
	jsiter.h	\
	jslibmath.h	\
	jslock.h	\
	jsmath.h	\
	jsnum.h		\
	jsobj.h		\
	json.h		\
	jsopcode.h	\
	jsparse.h	\
	jsarena.h	\
	jsclist.h	\
	jsdhash.h	\
	jsdtoa.h	\
	jshash.h	\
	jslong.h	\
	jstypes.h	\
	jsprvtd.h	\
	jspubtd.h	\
	jsregexp.h	\
	jsscan.h	\
	jsscope.h	\
	jsscript.h	\
	jsstr.h		\
	jsversion.h	\
	jsxdrapi.h	\
	jsxml.h		\
	$(NULL)

ifdef ENABLE_JIT
JS_HFILES +=			\
	jstracer.h		\
	nanojit/Assembler.h     \
	nanojit/LIR.h		\
	nanojit/Native$(NANOJIT_ARCH).h	\
	nanojit/avmplus.h	\
	nanojit/vm_fops.h	\
	nanojit/Fragmento.h	\
	nanojit/Native.h	\
	nanojit/RegAlloc.h	\
	nanojit/nanojit.h	\
	$(NULL)
endif

ifndef BUILD_OPT
#JS_HFILES +=            \
#        vprof/vprof.h   \
#        $(NULL)
endif

API_HFILES =		\
	jsapi.h		\
	jsdbgapi.h	\
	$(NULL)

OTHER_HFILES =		\
	jsbit.h		\
	jscompat.h	\
	jscpucfg.h	\
	jsotypes.h	\
	prmjtime.h	\
	resource.h	\
	jsopcode.tbl	\
	jsproto.tbl     \
	js.msg		\
	jsshell.msg	\
	jskeyword.tbl	\
	$(NULL)

ifndef PREBUILT_CPUCFG
OTHER_HFILES += $(OBJDIR)/jsautocfg.h
endif
OTHER_HFILES += $(OBJDIR)/jsautokw.h $(OBJDIR)/js-config.h

HFILES = $(JS_HFILES) $(API_HFILES) $(OTHER_HFILES)

JS_CPPFILES =		\
	jsapi.cpp	\
	jsarena.cpp	\
	jsarray.cpp	\
	jsatom.cpp	\
	jsbool.cpp	\
	jscntxt.cpp	\
	jsdate.cpp	\
	jsdbgapi.cpp	\
	jsdhash.cpp	\
	jsdtoa.cpp	\
	jsemit.cpp	\
	jsexn.cpp	\
	jsfun.cpp	\
	jsgc.cpp	\
	jshash.cpp	\
	jsinterp.cpp	\
	jsinvoke.cpp    \
	jsiter.cpp	\
	jslock.cpp	\
	jslog2.cpp	\
	jslong.cpp	\
	jsmath.cpp	\
	jsnum.cpp	\
	jsobj.cpp	\
	json.cpp	\
	jsopcode.cpp	\
	jsparse.cpp	\
	jsprf.cpp	\
	jsregexp.cpp	\
	jsscan.cpp	\
	jsscope.cpp	\
	jsscript.cpp	\
	jsstr.cpp	\
	jsutil.cpp	\
	jsxdrapi.cpp	\
	jsxml.cpp	\
	prmjtime.cpp	\
	$(NULL)

ifdef ENABLE_JIT
JS_CPPFILES +=		       \
	jsbuiltins.cpp         \
	jstracer.cpp	       \
	nanojit/Assembler.cpp  \
	nanojit/Fragmento.cpp  \
	nanojit/LIR.cpp        \
	nanojit/Native$(NANOJIT_ARCH).cpp \
	nanojit/RegAlloc.cpp   \
	nanojit/avmplus.cpp    \
	$(NULL)

endif

ifndef BUILD_OPT
#JS_CPPFILES +=                 \
#        vprof/vprof.cpp        \
#        $(NULL)
endif

ifdef JS_HAS_FILE_OBJECT
JS_CPPFILES += jsfile.cpp
JS_HFILES += jsfile.h
endif

LIB_CPPFILES  = $(JS_CPPFILES)
LIB_ASFILES := $(wildcard *_$(OS_ARCH).s)
PROG_CPPFILES = js.cpp

ifdef USE_MSVC
LIBRARY = $(OBJDIR)/js32.lib
SHARED_LIBRARY = $(OBJDIR)/js32.dll
PROGRAM = $(OBJDIR)/js.exe
else
LIBRARY = $(OBJDIR)/libjs.a
SHARED_LIBRARY = $(OBJDIR)/libjs.$(SO_SUFFIX)
PROGRAM = $(OBJDIR)/js
endif

include rules.mk

MOZ_DEPTH = ../..
include jsconfig.mk

nsinstall-target:
	cd ../../config; $(MAKE) OBJDIR=$(OBJDIR) OBJDIR_NAME=$(OBJDIR)

#
# Automatic header generation
#

AUTO_HEADERS =					\
	$(OBJDIR)/jsautokw.h			\
	$(OBJDIR)/jsautooplen.h			\
	$(NULL)

$(OBJDIR)/jsautokw.h: jskeyword.tbl

$(OBJDIR)/jsautooplen.h: jsopcode.tbl

GARBAGE += $(AUTO_HEADERS)
GARBAGE	+= $(AUTO_HEADERS:$(OBJDIR)/jsauto%.h=$(OBJDIR)/js%gen$(HOST_BIN_SUFFIX))

ifdef USE_MSVC

GARBAGE	+= $(AUTO_HEADERS:$(OBJDIR)/jsauto%.h=$(OBJDIR)/js%gen.obj)

$(AUTO_HEADERS): $(OBJDIR)/jsauto%.h: js%gen.cpp
	@$(MAKE_OBJDIR)
	$(CXX) -Fo$(OBJDIR)/ -c $(CFLAGS) $(OPTIMIZER) $<
	link.exe -out:"$(OBJDIR)/js$*gen$(HOST_BIN_SUFFIX)" $(EXE_LINK_FLAGS) $(OBJDIR)/js$*gen.obj
	$(OBJDIR)/js$*gen$(HOST_BIN_SUFFIX) $@
else

GARBAGE	+= $(AUTO_HEADERS:$(OBJDIR)/jsauto%.h=$(OBJDIR)/js%gen.d)
$(AUTO_HEADERS): $(OBJDIR)/jsauto%.h: js%gen.cpp
	@$(MAKE_OBJDIR)
	$(CXX) -o $(OBJDIR)/js$*gen$(HOST_BIN_SUFFIX) $(CFLAGS) $(OPTIMIZER) $(LDFLAGS) $<
	$(OBJDIR)/js$*gen$(HOST_BIN_SUFFIX) $@

endif

# force creation of autoheaders before compiling any source that may use them
$(LIB_OBJS) : $(AUTO_HEADERS)

#
# An installed header file describing configuration options that affect
# the API.
#

# Avoid rebuilding unless js-config.h's contents actually change.  The
# timestamp on js-config.h.stamp corresponds to the last time we
# checked that js-config.h was up to date.  If the stamp changes but
# js-config.h does not, then make concludes that targets depending on
# js-config.h don't need to be rebuilt.  The dummy '@true' rule here
# keeps make from concluding that js-config.h never changes.
$(OBJDIR)/js-config.h: $(OBJDIR)/js-config.h.stamp
	@true

js-config-switch=$(if $(value $($1)),-e 's/\#undef $1/\#define $1/')
$(OBJDIR)/js-config.h.stamp: js-config.h.in Makefile.ref
	sed < $< > $(@:.stamp=.tmp)			\
	    $(call js-config-switch,JS_THREADSAFE)	\
	    $(call js-config-switch,JS_GC_ZEAL)		\
	    -e :dummy
	if ! [ -f $(@:.stamp=) ] || ! cmp $(@:.stamp=.tmp) $(@:.stamp=); then \
	    mv $(@:.stamp=.tmp) $(@:.stamp=);				      \
	fi
	touch $@

GARBAGE += $(OBJDIR)/js-config.h $(OBJDIR)/js-config.h.stamp

# Force creation of js-config.h before compiling any source that may use it.
$(LIB_OBJS) : $(OBJDIR)/js-config.h

#
# JS shell executable
#

ifdef USE_MSVC
$(PROGRAM): $(PROG_OBJS) $(LIBRARY)
	link.exe -out:"$@" $(EXE_LINK_FLAGS) $^
else
$(PROGRAM): $(PROG_OBJS) $(LIBRARY)
	$(CXX) -o $@ $(CFLAGS) $(PROG_OBJS) $(LIBRARY) $(LDFLAGS) $(OTHER_LIBS) \
	    $(PROG_LIBS)
endif

$(PROGRAM).pure: $(PROG_OBJS) $(LIBRARY)
	purify $(PUREFLAGS) \
	    $(CXX) -o $@ $(PURE_OS_CFLAGS) $(PROG_OBJS) $(LIBRARY) $(LDFLAGS) \
		$(OTHER_LIBS) $(PROG_LIBS)

ifndef PREBUILT_CPUCFG
$(filter-out jscpucfg.h $(OBJDIR)/jsautocfg.h, $(HFILES)) $(CPPFILES): $(OBJDIR)/jsautocfg.h

$(OBJDIR)/jsautocfg.h: $(OBJDIR)/jscpucfg
	rm -f $@
	$(OBJDIR)/jscpucfg > $@

$(OBJDIR)/jscpucfg: $(OBJDIR)/jscpucfg.o
	$(CXX) $(OS_LDFLAGS) -o $@ $(OBJDIR)/jscpucfg.o

GARBAGE += $(OBJDIR)/jsautocfg.h $(OBJDIR)/jscpucfg \
	   $(OBJDIR)/jscpucfg.o $(OBJDIR)/jscpucfg.d
endif

# Automatic make dependencies files
DEPENDENCIES    = $(CPPFILES:%.cpp=$(OBJDIR)/%.d)

#
# Hardwire dependencies for some files 
#
ifdef USE_MSVC
OBJ=obj
else
OBJ=o
endif

$(OBJDIR)/jsinvoke.$(OBJ): jsinterp.h jsinterp.cpp
$(OBJDIR)/jsinvoke.obj : jsinterp.h jsinterp.cpp

-include $(DEPENDENCIES)

TARNAME = jsref.tar
TARFILES = files `cat files`

SUFFIXES: .i
%.i: %.cpp
	$(CXX) -C -E $(CFLAGS) $< > $*.i
