
# Copyright (C) Igor Sysoev
# Copyright (C) NGINX, Inc.

. auto/deps

echo "creating $NJS_MAKEFILE"

mkdir -p $NJS_BUILD_DIR/src
mkdir -p $NJS_BUILD_DIR/external
mkdir -p $NJS_BUILD_DIR/$NJS_BUILD_DIR
mkdir -p $NJS_BUILD_DIR/test

njs_modules_c=$NJS_BUILD_DIR/njs_modules.c

NJS_LIB_SRCS="$NJS_LIB_SRCS $njs_modules_c"

cat << END                                    > $njs_modules_c

#include <njs_main.h>

END

for mod in $NJS_LIB_MODULES
do
    echo "extern njs_module_t  $mod;"         >> $njs_modules_c
done

echo                                          >> $njs_modules_c
echo 'njs_module_t *njs_modules[] = {'        >> $njs_modules_c

for mod in $NJS_LIB_MODULES
do
    echo "    &$mod,"                         >> $njs_modules_c
done

cat << END                                    >> $njs_modules_c
    NULL
};

END

qjs_modules_c=$NJS_BUILD_DIR/qjs_modules.c

QJS_LIB_SRCS="$QJS_LIB_SRCS $qjs_modules_c"

cat << END                                    > $qjs_modules_c

#include <qjs.h>

END

for mod in $QJS_LIB_MODULES
do
    echo "extern qjs_module_t  $mod;"         >> $qjs_modules_c
done

echo                                          >> $qjs_modules_c
echo 'qjs_module_t *qjs_modules[] = {'        >> $qjs_modules_c

for mod in $QJS_LIB_MODULES
do
    echo "    &$mod,"                         >> $qjs_modules_c
done

cat << END                                    >> $qjs_modules_c
    NULL
};

END

njs_incs=`echo $NJS_LIB_INCS \
        | sed -e "s# *\([^ ]*\)#$njs_regex_cont-I\1#g"`
njs_objs=`echo $NJS_LIB_SRCS \
        | sed -e "s# *\([^ ]*\.\)c#$NJS_BUILD_DIR/\1o$njs_regex_cont#g"`

qjs_objs=`echo $QJS_LIB_SRCS \
        | sed -e "s# *\([^ ]*\.\)c#$NJS_BUILD_DIR/\1o$njs_regex_cont#g"`

QJS_LIB=""
if [ $NJS_HAVE_QUICKJS = YES ]; then
    QJS_LIB="$NJS_BUILD_DIR/libqjs.a"
fi

cat << END > $NJS_MAKEFILE

# This file is auto-generated by configure

NJS_CC = ${CC}
NJS_STATIC_LINK = ${AR} -r -c
NJS_LINK = ${CC} ${NJS_LD_OPT} ${NJS_LINK}
NJS_PIC = ${NJS_PIC}
CFLAGS = ${NJS_CC_OPT} ${CFLAGS:-${NJS_CFLAGS}}
NJS_LIB_AUX_CFLAGS = ${NJS_LIB_AUX_CFLAGS}

NJS_VER = $(grep NJS_VERSION src/njs.h | sed -e 's#.*"\(.*\)".*#\1#')
NJS_TYPES_VER = \$(NJS_VER)

NPM = npm

default: njs

NJS_LIB_INCS = $njs_incs
NJS_LIB_OBJS = $njs_objs
QJS_LIB_OBJS = $qjs_objs

libnjs: $NJS_BUILD_DIR/libnjs.a pc
libqjs: $NJS_BUILD_DIR/libqjs.a

$NJS_BUILD_DIR/libnjs.a:   \\
	$NJS_BUILD_DIR/njs_auto_config.h \\
	\$(NJS_LIB_OBJS)

	\$(NJS_STATIC_LINK) $NJS_BUILD_DIR/libnjs.a \\
		\$(NJS_LIB_OBJS)

$NJS_BUILD_DIR/libqjs.a:   \\
	$NJS_BUILD_DIR/njs_auto_config.h \\
	\$(QJS_LIB_OBJS)

	\$(NJS_STATIC_LINK) $NJS_BUILD_DIR/libqjs.a \\
		\$(QJS_LIB_OBJS)
END

# object files.

for njs_src in $NJS_LIB_SRCS
do
    njs_obj="${njs_src%.c}.o"
    njs_dep="${njs_src%.c}.dep"
    njs_dep_flags=`njs_gen_dep_flags $njs_dep $njs_obj`
    njs_dep_post=`njs_gen_dep_post $njs_dep $njs_obj`
    cat << END >> $NJS_MAKEFILE

$NJS_BUILD_DIR/$njs_obj: $njs_src
	\$(NJS_CC) -c \$(NJS_LIB_INCS) \$(NJS_PIC) \$(CFLAGS) \\
		\$(NJS_LIB_AUX_CFLAGS) \\
		-o $NJS_BUILD_DIR/$njs_obj \\
		$njs_dep_flags \\
		$njs_src
		$njs_dep_post

-include $NJS_BUILD_DIR/$njs_dep

END

done

for njs_src in $QJS_LIB_SRCS
do
    njs_obj="${njs_src%.c}.o"
    njs_dep="${njs_src%.c}.dep"
    njs_dep_flags=`njs_gen_dep_flags $njs_dep $njs_obj`
    njs_dep_post=`njs_gen_dep_post $njs_dep $njs_obj`
    cat << END >> $NJS_MAKEFILE

$NJS_BUILD_DIR/$njs_obj: $njs_src
	\$(NJS_CC) -c \$(NJS_LIB_INCS) \$(NJS_PIC) \$(CFLAGS) \\
		\$(NJS_LIB_AUX_CFLAGS) \\
		-o $NJS_BUILD_DIR/$njs_obj \\
		$njs_dep_flags \\
		$njs_src
		$njs_dep_post

-include $NJS_BUILD_DIR/$njs_dep

END

done

# njs cli.

cat << END >> $NJS_MAKEFILE

$NJS_BUILD_DIR/njs: \\
	$NJS_BUILD_DIR/libnjs.a $QJS_LIB \\
	external/njs_shell.c
	\$(NJS_LINK) -o $NJS_BUILD_DIR/njs \$(NJS_LIB_INCS) \\
		\$(CFLAGS) \$(NJS_LIB_AUX_CFLAGS)\\
		external/njs_shell.c \\
		$NJS_BUILD_DIR/libnjs.a $QJS_LIB \\
		$NJS_LD_OPT -lm $NJS_LIBS $NJS_LIB_AUX_LIBS $NJS_READLINE_LIB

END

# njs fuzzer.

cat << END >> $NJS_MAKEFILE

$NJS_BUILD_DIR/njs_process_script_fuzzer.o: \\
	external/njs_shell.c
	\$(NJS_CC) -c \$(NJS_LIB_INCS) \$(CFLAGS) \\
		\$(NJS_LIB_AUX_CFLAGS) \\
		-DNJS_FUZZER_TARGET \\
		-o $NJS_BUILD_DIR/njs_process_script_fuzzer.o \\
		external/njs_shell.c

$NJS_BUILD_DIR/njs_process_script_fuzzer: \\
	$NJS_BUILD_DIR/libnjs.a \\
	$NJS_BUILD_DIR/njs_process_script_fuzzer.o
	\$(CXX) \$(CXXFLAGS) -o $NJS_BUILD_DIR/njs_process_script_fuzzer \\
		\$(NJS_LIB_AUX_CFLAGS) \\
		\$(LIB_FUZZING_ENGINE) \\
		$NJS_BUILD_DIR/njs_process_script_fuzzer.o \\
		$NJS_BUILD_DIR/libnjs.a \\
		-lm $NJS_LIBS $NJS_LIB_AUX_LIBS

END

# lib tests.

for njs_src in $NJS_LIB_TEST_SRCS
do
    fname=$(basename $njs_src)
    njs_dep="test/${fname%.c}.dep"
    njs_bin="${fname%.c}"
    njs_dep_flags=`njs_gen_dep_flags $njs_dep $fname`
    njs_dep_post=`njs_gen_dep_post $njs_dep $fname`
    cat << END >> $NJS_MAKEFILE

$NJS_BUILD_DIR/$njs_bin: $njs_src \\
	$NJS_BUILD_DIR/libnjs.a
	\$(NJS_LINK) -o $NJS_BUILD_DIR/$njs_bin \$(NJS_LIB_INCS) \\
		\$(CFLAGS) $njs_dep_flags \\
		$njs_src $NJS_BUILD_DIR/libnjs.a \\
		$njs_dep_post -lm $NJS_LD_OPT

-include $NJS_BUILD_DIR/$njs_dep

END

done


# njs tests.

njs_src="src/test/njs_externals_test.c"
fname=$(basename $njs_src)
njs_externals_obj="test/${fname%.c}.o"
njs_dep="test/${fname%.c}.dep"
njs_dep_flags=`njs_gen_dep_flags $njs_dep $njs_externals_obj`
njs_dep_post=`njs_gen_dep_post $njs_dep $njs_externals_obj`

cat << END >> $NJS_MAKEFILE

$NJS_BUILD_DIR/$njs_externals_obj: \\
    $njs_src
	\$(NJS_CC) -c \$(NJS_LIB_INCS) \$(CFLAGS) \\
		\$(NJS_LIB_AUX_CFLAGS) \\
		-o $NJS_BUILD_DIR/$njs_externals_obj \\
		$njs_dep_flags \\
		$njs_src
		$njs_dep_post

-include $NJS_BUILD_DIR/$njs_dep

END

for njs_src in $NJS_TEST_SRCS
do
    fname=$(basename $njs_src)
    njs_dep="test/${fname%.c}.dep"
    njs_bin="${fname%.c}"
    njs_dep_flags=`njs_gen_dep_flags $njs_dep $fname`
    njs_dep_post=`njs_gen_dep_post $njs_dep $fname`
    cat << END >> $NJS_MAKEFILE

$NJS_BUILD_DIR/$njs_bin: $njs_src \\
	$NJS_BUILD_DIR/libnjs.a \\
	$NJS_BUILD_DIR/$njs_externals_obj
	\$(NJS_LINK) -o $NJS_BUILD_DIR/$njs_bin \$(NJS_LIB_INCS) \\
		\$(CFLAGS) \$(NJS_LIB_AUX_CFLAGS) \\
		$njs_dep_flags \\
		$NJS_BUILD_DIR/$njs_externals_obj \\
		$njs_src $NJS_BUILD_DIR/libnjs.a \\
		$NJS_LD_OPT -lm $NJS_LIBS $NJS_LIB_AUX_LIBS
		$njs_dep_post

-include $NJS_BUILD_DIR/$njs_dep

END

done

# main targets.

cat << END >> $NJS_MAKEFILE

$NJS_BUILD_DIR/njs_auto_config.h:
	@echo
	@echo " Please run ./configure before make"
	@echo
	@exit 1

all: $NJS_BUILD_DIR/njs_auto_config.h \\
	njs ts test lib_test benchmark

njs: $NJS_BUILD_DIR/njs_auto_config.h $NJS_BUILD_DIR/njs
njs_fuzzer: $NJS_BUILD_DIR/njs_auto_config.h \\
	$NJS_BUILD_DIR/njs_process_script_fuzzer

lib_test: $NJS_BUILD_DIR/njs_auto_config.h \\
	$NJS_BUILD_DIR/random_unit_test \\
	$NJS_BUILD_DIR/rbtree_unit_test \\
	$NJS_BUILD_DIR/flathsh_unit_test \\
	$NJS_BUILD_DIR/unicode_unit_test

	$NJS_BUILD_DIR/random_unit_test
	$NJS_BUILD_DIR/rbtree_unit_test
	$NJS_BUILD_DIR/flathsh_unit_test
	$NJS_BUILD_DIR/unicode_unit_test

test262_njs: njs
	test/test262 --binary=$NJS_BUILD_DIR/njs

unit_test: $NJS_BUILD_DIR/njs_auto_config.h \\
	$NJS_BUILD_DIR/njs_unit_test

	$NJS_BUILD_DIR/njs_unit_test

test: shell_test unit_test test262

benchmark: $NJS_BUILD_DIR/njs_auto_config.h \\
	$NJS_BUILD_DIR/njs_benchmark

	$NJS_BUILD_DIR/njs_benchmark
END

if [ $NJS_HAVE_QUICKJS = YES ]; then
    cat << END >> $NJS_MAKEFILE

test262: njs test262_njs test262_quickjs

test262_quickjs: njs
	NJS_SKIP_LIST="test/js/promise_rejection_tracker_recursive.t.js \\
test/js/async_exception_in_await.t.js" \\
	test/test262 --binary='$NJS_BUILD_DIR/njs -n QuickJS -m'
END

else
    cat << END >> $NJS_MAKEFILE

test262: njs test262_njs
END

fi


njs_ts_deps=`echo $NJS_TS_SRCS \
        | sed -e "s# *\([^ ][^ ]*\)#\1$njs_regex_cont#g"`

njs_test_ts_deps=`echo $NJS_TEST_TS_SRCS \
        | sed -e "s# *\([^ ][^ ]*\)#\1$njs_regex_cont#g"`

cat << END >> $NJS_MAKEFILE

$NJS_BUILD_DIR/ts/package.json: $njs_ts_deps
	cp -fr ts $NJS_BUILD_DIR/
	cp LICENSE $NJS_BUILD_DIR/ts/
	sed 's#__VERSION__#"\$(NJS_TYPES_VER)"#' \\
		ts/package.json > $NJS_BUILD_DIR/ts/package.json

$NJS_BUILD_DIR/ts/node_modules: $NJS_BUILD_DIR/ts/package.json
	cd $NJS_BUILD_DIR/ts && \$(NPM) install
	touch $NJS_BUILD_DIR/ts/node_modules

$NJS_BUILD_DIR/njs-types-\$(NJS_TYPES_VER).tgz: $NJS_BUILD_DIR/ts/package.json
	git ls-files --error-unmatch ts/package.json > /dev/null 2>&1 \\
		&& git rev-parse --short HEAD > $NJS_BUILD_DIR/ts/COMMITHASH \\
		|| true
	cd $NJS_BUILD_DIR && \$(NPM) pack ./ts

.PHONY: ts
ts: $NJS_BUILD_DIR/ts/package.json

ts_lint: $NJS_BUILD_DIR/ts/node_modules
	cd $NJS_BUILD_DIR/ts && \$(NPM) run lint

$NJS_BUILD_DIR/test/ts/package.json: $njs_test_ts_deps
	mkdir -p $NJS_BUILD_DIR/test
	cp -fr test/ts $NJS_BUILD_DIR/test/

$NJS_BUILD_DIR/test/ts/node_modules: \\
	$NJS_BUILD_DIR/njs-types-\$(NJS_TYPES_VER).tgz \\
	$NJS_BUILD_DIR/test/ts/package.json
	cd $NJS_BUILD_DIR/test/ts && \$(NPM) install \\
		--save-dev file:../../njs-types-\$(NJS_TYPES_VER).tgz
	cd $NJS_BUILD_DIR/test/ts && \$(NPM) install
	touch $NJS_BUILD_DIR/test/ts/node_modules

ts_test: $NJS_BUILD_DIR/test/ts/node_modules
	cd $NJS_BUILD_DIR/test/ts && \$(NPM) test

ts_publish: ts_clean $NJS_BUILD_DIR/njs-types-\$(NJS_TYPES_VER).tgz
	cd $NJS_BUILD_DIR/ && \$(NPM) publish njs-types-\$(NJS_TYPES_VER).tgz

ts_clean:
	rm -rf $NJS_BUILD_DIR/ts
END

# pkg-config file
cat << END >> $NJS_MAKEFILE

pc: $NJS_BUILD_DIR/njs.pc

$NJS_BUILD_DIR/njs.pc: $NJS_BUILD_DIR/njs_auto_config.h
	sed -e "s#@PREFIX@#$(pwd)/$NJS_BUILD_DIR#" \\
		-e "s#@LIBDIR@#$(pwd)/$NJS_BUILD_DIR#" \\
		-e "s#@CFLAGS@#-I$(pwd)/$NJS_BUILD_DIR -I$(pwd)/src#" \\
		-e "s#@VERSION@#\$(NJS_VER)#" \\
		-e "s#@EXTRA_LIBS@#-lm $NJS_LIBS $NJS_LIB_AUX_LIBS#" \\
		src/njs.pc.in > \$@
END

# Makefile.

cat << END > Makefile

# This file is auto-generated by configure

include $NJS_MAKEFILE

.PHONY: clean
clean:
	rm -rf $NJS_BUILD_DIR Makefile

END
