
# Copyright (C) 2024 Web Server LLC
# Copyright (C) Igor Sysoev
# Copyright (C) Nginx, Inc.


dirsep()
{
    if [ "$ngx_dirsep" = "/" ]; then
        res="$@"
        return
    fi

    res=$(echo "$@" | sed -e "s/\//$ngx_regex_dirsep/g")
}


fmt_link()
{
    dirsep "$@"
    res="$ngx_long_cont$res"
}


fmt_list()
{
    first="$1"
    shift
    last=

    for i in $@; do
        last="$last$prefix$i"
    done

    dirsep "$first$last"
}


fmt_incs()
{
    prefix="$ngx_cont$ngx_include_opt" fmt_list "$@"
}


fmt_deps()
{
    prefix="$ngx_cont" fmt_list "$@"
}


fmt_objs()
{
    prefix="$ngx_long_cont" fmt_list "$@"
}


src2obj()
{
    res=
    case $1 in
        *.c)   res="${1%.c}.$ngx_objext" ;;
        *.cc)  res="${1%.cc}.$ngx_objext" ;;
        *.cpp) res="${1%.cpp}.$ngx_objext";;
        *.S)   res="${1%.S}.$ngx_objext" ;;
        *)     res="$1" ;;
    esac

    res="$NGX_OBJS$ngx_dirsep$res"
}


srcs2objs()
{
    res=

    for i in $@; do
        case $i in
            *.c)   i="${i%.c}.$ngx_objext" ;;
            *.cc)  i="${i%.cc}.$ngx_objext" ;;
            *.cpp) i="${i%.cpp}.$ngx_objext";;
            *.S)   i="${i%.S}.$ngx_objext" ;;
            *)     i="$i" ;;
        esac

        if [ -n "$res" ]; then
            res="$res $NGX_OBJS/$i"
        else
            res="$NGX_OBJS/$i"
        fi
    done
}


echo "creating $NGX_MAKEFILE"

mkdir -p $NGX_OBJS/src/core $NGX_OBJS/src/event $NGX_OBJS/src/event/modules \
         $NGX_OBJS/src/event/quic \
         $NGX_OBJS/src/os/unix $NGX_OBJS/src/os/win32 \
         $NGX_OBJS/src/http $NGX_OBJS/src/http/v2 $NGX_OBJS/src/http/v3 \
         $NGX_OBJS/src/http/modules $NGX_OBJS/src/http/modules/perl \
         $NGX_OBJS/src/mail \
         $NGX_OBJS/src/stream \
         $NGX_OBJS/src/misc


dirsep "$NGX_USE_PCH"
ngx_use_pch=$res


cat << END                                                     > $NGX_MAKEFILE

CC =	$CC
CFLAGS = $CFLAGS
CPP =	$CPP
LINK =	$LINK

END


if test -n "$NGX_PERL_CFLAGS"; then
    echo NGX_PERL_CFLAGS = $NGX_PERL_CFLAGS                   >> $NGX_MAKEFILE
    echo NGX_PM_CFLAGS = $NGX_PM_CFLAGS                       >> $NGX_MAKEFILE
    echo NGX_PM_LDFLAGS = $NGX_PM_LDFLAGS                     >> $NGX_MAKEFILE
fi


# ALL_INCS, required by the addons and by OpenWatcom C precompiled headers

fmt_incs $CORE_INCS $NGX_OBJS $HTTP_INCS $MAIL_INCS $STREAM_INCS
ngx_incs=$res

cat << END                                                    >> $NGX_MAKEFILE

ALL_INCS = $ngx_include_opt$ngx_incs

END


ngx_all_srcs="$CORE_SRCS"


# the core dependencies and include paths

fmt_deps $CORE_DEPS $NGX_AUTO_CONFIG_H $NGX_PCH
ngx_deps=$res

fmt_incs $CORE_INCS $NGX_OBJS
ngx_incs=$res

cat << END                                                    >> $NGX_MAKEFILE

CORE_DEPS = $ngx_deps


CORE_INCS = $ngx_include_opt$ngx_incs

END


# the http dependencies and include paths

if [ $HTTP = YES ]; then

    ngx_all_srcs="$ngx_all_srcs $HTTP_SRCS"

    fmt_deps $HTTP_DEPS
    ngx_deps=$res

    fmt_incs $HTTP_INCS
    ngx_incs=$res

    cat << END                                                >> $NGX_MAKEFILE

HTTP_DEPS = $ngx_deps


HTTP_INCS = $ngx_include_opt$ngx_incs

END

fi


# the mail dependencies and include paths

if [ $MAIL != NO ]; then

    if [ $MAIL = YES ]; then
        ngx_all_srcs="$ngx_all_srcs $MAIL_SRCS"
    fi

    fmt_deps $MAIL_DEPS
    ngx_deps=$res

    fmt_incs $MAIL_INCS
    ngx_incs=$res

    cat << END                                                >> $NGX_MAKEFILE

MAIL_DEPS = $ngx_deps


MAIL_INCS = $ngx_include_opt$ngx_incs

END

fi


# the stream dependencies and include paths

if [ $STREAM != NO ]; then

    if [ $STREAM = YES ]; then
        ngx_all_srcs="$ngx_all_srcs $STREAM_SRCS"
    fi

    fmt_deps $STREAM_DEPS
    ngx_deps=$res

    fmt_incs $STREAM_INCS
    ngx_incs=$res

    cat << END                                                >> $NGX_MAKEFILE

STREAM_DEPS = $ngx_deps


STREAM_INCS = $ngx_include_opt$ngx_incs

END

fi


ngx_all_srcs="$ngx_all_srcs $MISC_SRCS"


if test -n "$NGX_ADDON_SRCS$DYNAMIC_MODULES"; then

cat << END                                                >> $NGX_MAKEFILE

ADDON_DEPS = \$(CORE_DEPS) $NGX_ADDON_DEPS

END

fi


# angie

dirsep $ngx_all_srcs
ngx_all_srcs=$res

for ngx_src in $NGX_ADDON_SRCS
do
    ngx_obj="addon/`basename \`dirname $ngx_src\``"

    test -d $NGX_OBJS/$ngx_obj || mkdir -p $NGX_OBJS/$ngx_obj

    dirsep $ngx_obj/`basename $ngx_src`; ngx_obj=$res

    ngx_all_srcs="$ngx_all_srcs $ngx_obj"
done

srcs2objs $ngx_all_srcs
ngx_all_objs=$res

dirsep $NGX_MODULES_C
ngx_modules_c=$res

ngx_modules_obj=${ngx_modules_c%.c}.$ngx_objext


if test -n "$NGX_RES"; then
   ngx_res=$NGX_RES
else
   ngx_res="$NGX_RC $NGX_ICONS"
   dirsep $NGX_RCC
   ngx_rcc=$res
fi

fmt_deps $ngx_all_objs $ngx_modules_obj $ngx_res $LINK_DEPS
ngx_deps=$res

fmt_objs $ngx_all_objs $ngx_modules_obj
ngx_objs=$res

ngx_libs=
if test -n "$NGX_LD_OPT$CORE_LIBS"; then
    fmt_link $NGX_LD_OPT $CORE_LIBS
    ngx_libs=$res
fi

fmt_link $CORE_LINK
ngx_link=${CORE_LINK:+$res}

fmt_link $MAIN_LINK
ngx_main_link=${MAIN_LINK:+$res}


cat << END                                                    >> $NGX_MAKEFILE

build:	binary modules manpage

binary:	$NGX_OBJS${ngx_dirsep}angie$ngx_binext

$NGX_OBJS${ngx_dirsep}angie$ngx_binext:	$ngx_deps$ngx_spacer
	\$(LINK) $ngx_long_start$ngx_binout$NGX_OBJS${ngx_dirsep}angie$ngx_binext$ngx_long_cont$ngx_objs$ngx_libs$ngx_link$ngx_main_link
	$ngx_rcc
$ngx_long_end

modules:
END


# ngx_modules.c

if test -n "$NGX_PCH"; then
    ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)"
else
    ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) \$(CORE_INCS)"
fi

cat << END                                                    >> $NGX_MAKEFILE

$ngx_modules_obj:	\$(CORE_DEPS)$ngx_cont$ngx_modules_c
	$ngx_cc$ngx_tab$ngx_objout$ngx_modules_obj$ngx_tab$ngx_modules_c$NGX_AUX

END


# the core sources

for ngx_src in $CORE_SRCS
do
    dirsep $ngx_src; ngx_src=$res
    src2obj $ngx_src; ngx_obj=$res

    cat << END                                                >> $NGX_MAKEFILE

$ngx_obj:	\$(CORE_DEPS)$ngx_cont$ngx_src
	$ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX

END

done


# the http sources

if [ $HTTP = YES ]; then

    if test -n "$NGX_PCH"; then
        ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)"
    else
        ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) \$(CORE_INCS) \$(HTTP_INCS)"
        ngx_perl_cc="\$(CC) $ngx_compile_opt \$(NGX_PERL_CFLAGS)"
        ngx_perl_cc="$ngx_perl_cc \$(CORE_INCS) \$(HTTP_INCS)"
    fi

    for ngx_source in $HTTP_SRCS
    do
        dirsep $ngx_source; ngx_src=$res
        src2obj $ngx_src; ngx_obj=$res

        if [ $ngx_source = src/http/modules/perl/ngx_http_perl_module.c ]; then

            cat << END                                        >> $NGX_MAKEFILE

$ngx_obj:	\$(CORE_DEPS) \$(HTTP_DEPS)$ngx_cont$ngx_src
	$ngx_perl_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX

END
        else

            cat << END                                        >> $NGX_MAKEFILE

$ngx_obj:	\$(CORE_DEPS) \$(HTTP_DEPS)$ngx_cont$ngx_src
	$ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX

END

        fi
    done

fi


# the mail sources

if [ $MAIL = YES ]; then

    if test -n "$NGX_PCH"; then
        ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)"
    else
        ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) \$(CORE_INCS) \$(MAIL_INCS)"
    fi

    for ngx_src in $MAIL_SRCS
    do
        dirsep $ngx_src; ngx_src=$res
        src2obj $ngx_src; ngx_obj=$res

        cat << END                                            >> $NGX_MAKEFILE

$ngx_obj:	\$(CORE_DEPS) \$(MAIL_DEPS)$ngx_cont$ngx_src
	$ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX

END
    done

fi


# the stream sources

if [ $STREAM = YES ]; then

    if test -n "$NGX_PCH"; then
        ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)"
    else
        ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) \$(CORE_INCS) \$(STREAM_INCS)"
    fi

    for ngx_src in $STREAM_SRCS
    do
        dirsep $ngx_src; ngx_src=$res
        src2obj $ngx_src; ngx_obj=$res

        cat << END                                            >> $NGX_MAKEFILE

$ngx_obj:	\$(CORE_DEPS) \$(STREAM_DEPS)$ngx_cont$ngx_src
	$ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX

END
    done

fi


# the misc sources

if test -n "$MISC_SRCS"; then

    ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)"

    for ngx_src in $MISC_SRCS
    do
        dirsep $ngx_src; ngx_src=$res
        src2obj $ngx_src; ngx_obj=$res

        cat << END                                            >> $NGX_MAKEFILE

$ngx_obj:	\$(CORE_DEPS) $ngx_cont$ngx_src
	$ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX

END
    done

fi


# the addons sources

if test -n "$NGX_ADDON_SRCS"; then

    ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)"

    for ngx_src in $NGX_ADDON_SRCS
    do
        ngx_obj="addon/`basename \`dirname $ngx_src\``"

        dirsep $ngx_obj/`basename $ngx_src`; ngx_obj=$res
        src2obj $ngx_obj; ngx_obj=$res
        dirsep $ngx_src; ngx_src=$res

        cat << END                                            >> $NGX_MAKEFILE

$ngx_obj:	\$(ADDON_DEPS)$ngx_cont$ngx_src
	$ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX

END
    done

fi


# the addons config.make

if test -n "$NGX_ADDONS$DYNAMIC_ADDONS"; then

    for ngx_addon_dir in $NGX_ADDONS $DYNAMIC_ADDONS
    do
        if test -f $ngx_addon_dir/config.make; then
            . $ngx_addon_dir/config.make
        fi
    done
fi


# Win32 resource file

if test -n "$NGX_RES"; then

    dirsep "$NGX_RES:	$NGX_RC $NGX_ICONS"; ngx_res=$res
    dirsep $NGX_RCC; ngx_rcc=$res

    cat << END                                                >> $NGX_MAKEFILE

$ngx_res
	$ngx_rcc

END

fi


# the precompiled headers

if test -n "$NGX_PCH"; then
    echo "#include <ngx_config.h>" > $NGX_OBJS/ngx_pch.c

    ngx_pch="src/core/ngx_config.h $OS_CONFIG $NGX_OBJS/ngx_auto_config.h"
    dirsep "$NGX_PCH:	$ngx_pch"
    ngx_pch=$res

    ngx_src="\$(CC) \$(CFLAGS) $NGX_BUILD_PCH $ngx_compile_opt \$(ALL_INCS)"
    ngx_src="$ngx_src $ngx_objout$NGX_OBJS/ngx_pch.obj $NGX_OBJS/ngx_pch.c"
    dirsep $ngx_src; ngx_src=$res

    cat << END                                                >> $NGX_MAKEFILE

$ngx_pch
	$ngx_src

END

fi


# dynamic modules

if test -n "$NGX_PCH"; then
    ngx_cc="\$(CC) $ngx_compile_opt $ngx_pic_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)"
else
    ngx_cc="\$(CC) $ngx_compile_opt $ngx_pic_opt \$(CFLAGS) \$(ALL_INCS)"
    ngx_perl_cc="\$(CC) $ngx_compile_opt $ngx_pic_opt \$(NGX_PERL_CFLAGS)"
    ngx_perl_cc="$ngx_perl_cc \$(ALL_INCS)"
fi

for ngx_module in $DYNAMIC_MODULES
do
    eval ngx_module_srcs="\$${ngx_module}_SRCS"
    eval ngx_module_shrd="\$${ngx_module}_SHRD"
    eval eval ngx_module_libs="\\\"\$${ngx_module}_LIBS\\\""

    eval ngx_module_modules="\$${ngx_module}_MODULES"
    eval ngx_module_order="\$${ngx_module}_ORDER"

    ngx_modules_c=$NGX_OBJS/${ngx_module}_modules.c

    cat << END                                    > $ngx_modules_c

#include <ngx_config.h>
#include <ngx_core.h>

END

    for mod in $ngx_module_modules
    do
        echo "extern ngx_module_t  $mod;"         >> $ngx_modules_c
    done

    echo                                          >> $ngx_modules_c
    echo 'ngx_module_t *ngx_modules[] = {'        >> $ngx_modules_c

    for mod in $ngx_module_modules
    do
        echo "    &$mod,"                         >> $ngx_modules_c
    done

    cat << END                                    >> $ngx_modules_c
    NULL
};

END

    echo 'char *ngx_module_names[] = {'           >> $ngx_modules_c

    for mod in $ngx_module_modules
    do
        echo "    \"$mod\","                      >> $ngx_modules_c
    done

    cat << END                                    >> $ngx_modules_c
    NULL
};

END

    echo 'char *ngx_module_order[] = {'           >> $ngx_modules_c

    for mod in $ngx_module_order
    do
        echo "    \"$mod\","                      >> $ngx_modules_c
    done

    cat << END                                    >> $ngx_modules_c
    NULL
};

END

    dirsep $ngx_modules_c; ngx_modules_c=$res

    ngx_modules_obj=${ngx_modules_c%.c}.$ngx_objext

    ngx_module_objs=
    for ngx_src in $ngx_module_srcs $ngx_module_shrd
    do
        case "$ngx_src" in
            src/*)
                ngx_obj=$ngx_src
                ;;
            *)
                ngx_obj="addon/`basename \`dirname $ngx_src\``"
                mkdir -p $NGX_OBJS/$ngx_obj
                ngx_obj="$ngx_obj/`basename $ngx_src`"
                ;;
        esac

        ngx_module_objs="$ngx_module_objs $ngx_obj"
    done

    srcs2objs $ngx_module_objs
    ngx_module_objs=$res

    fmt_deps $ngx_module_objs $ngx_modules_obj $LINK_DEPS
    ngx_deps=$res

    fmt_objs $ngx_module_objs $ngx_modules_obj
    ngx_objs=$res

    ngx_obj=$NGX_OBJS$ngx_dirsep$ngx_module$ngx_modext

    if [ "$NGX_PLATFORM" = win32 ]; then
        ngx_module_libs="$CORE_LIBS $ngx_module_libs"
    fi

    ngx_libs=
    if test -n "$NGX_LD_OPT$ngx_module_libs"; then
        fmt_link $NGX_LD_OPT $ngx_module_libs
        ngx_libs=$res
    fi

    fmt_link $CORE_LINK
    ngx_link=${CORE_LINK:+$res}

    fmt_link $MODULE_LINK
    ngx_module_link=${MODULE_LINK:+$res}


    cat << END                                            >> $NGX_MAKEFILE

modules:	$ngx_obj

$ngx_obj:	$ngx_deps$ngx_spacer
	\$(LINK) $ngx_long_start$ngx_binout$ngx_obj$ngx_long_cont$ngx_objs$ngx_libs$ngx_link$ngx_module_link
$ngx_long_end

$ngx_modules_obj:	\$(CORE_DEPS)$ngx_cont$ngx_modules_c
	$ngx_cc$ngx_tab$ngx_objout$ngx_modules_obj$ngx_tab$ngx_modules_c$NGX_AUX

END

    for ngx_source in $ngx_module_srcs
    do
        case "$ngx_source" in
            src/*)
                dirsep $ngx_source; ngx_obj=$res
                ;;
            *)
                ngx_obj="addon/`basename \`dirname $ngx_source\``"
                dirsep $ngx_obj/`basename $ngx_source`; ngx_obj=$res
                ;;
        esac

        src2obj $ngx_obj; ngx_obj=$res
        dirsep $ngx_source; ngx_src=$res

        if [ $ngx_source = src/http/modules/perl/ngx_http_perl_module.c ]; then

            cat << END                                        >> $NGX_MAKEFILE

$ngx_obj:	\$(ADDON_DEPS)$ngx_cont$ngx_src
	$ngx_perl_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX

END
        else

            cat << END                                        >> $NGX_MAKEFILE

$ngx_obj:	\$(ADDON_DEPS)$ngx_cont$ngx_src
	$ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX

END

        fi
    done
done
