#!/bin/sh
#	$NetBSD: mknative,v 1.12 2003/03/05 06:17:17 mrg Exp $
#
# Shell script for generating all the constants needed for a native
# platform build of src/gnu/dist/toolchain.
#

bomb () {
	echo >&1 "ABORT: $*"
	exit 1
}

# usage: getvars MAKEFILE VARNAME [VARNAME...]
getvars () {
	_mf="$1"; shift
	$MAKE -f - _x_ <<EOF || bomb "getvars $_mf $* failed"
_x_:
.for var in $*
	@echo G_\${var}=\${\${var}:Q} | sed 's,$_VPATH,\$\${GNUHOSTDIST},g'
.endfor
.include "$_TMPDIR/$_mf"
EOF
}

# usage: write_c FILENAME
write_c () {
	echo '/* This file is automatically generated.  DO NOT EDIT! */' >$_TOP/$1.tmp || \
		bomb "cannot create $1"
	grep '$''NetBSD' $0 | sed 's,[#$],,g;s,.*,/* Generated from: & */,' >>$_TOP/$1.tmp
	echo '' >>$_TOP/$1.tmp
	writefile $1
}

# usage: write_mk FILENAME
write_mk () {
	echo '# This file is automatically generated.  DO NOT EDIT!' >$_TOP/$1.tmp || \
		bomb "cannot create $1"
	grep '$''NetBSD' $0 | sed 's,[#$],,g;s,.*,# Generated from: &,' >>$_TOP/$1.tmp
	echo '#' >>$_TOP/$1.tmp
	writefile $1
}

writefile () {
	sed -e 's,netbsd\(elf\)*1[0-9\.]*\(_\)*[A-Z]*,netbsd\1,' \
	    -e 's,^/\* #undef HAVE_MMAP \*/$,#define HAVE_MMAP 1,' >>$_TOP/$1.tmp

	# Compare new file, sans "generated from" comments and RCS Id, to
	# old file.  If they match, don't change anything.
	rm -f $_TMPDIR/.1 $_TMPDIR/.2
	grep -v 'Generated from:' $_TOP/$1 >$_TMPDIR/.1 2>/dev/null
	grep -v 'Generated from:' $_TOP/$1.tmp >$_TMPDIR/.2

	# will not overwrite a file that has the same content
	if cmp $_TMPDIR/.1 $_TMPDIR/.2 >/dev/null 2>&1; then
		rm -f $_TOP/$1.tmp
	else
		echo >&2 "$1 changed"
		mv -f $_TOP/$1.tmp $_TOP/$1
	fi
}

##### gnu/lib/libbfd #####

get_libbfd () {
	mkdir -p $_TOP/gnu/lib/libbfd/arch/$MACHINE_ARCH

	{
		getvars bfd/Makefile \
			libbfd_la_DEPENDENCIES libbfd_la_OBJECTS DEFS \
			INCLUDES TDEFAULTS
	} | write_mk gnu/lib/libbfd/arch/$MACHINE_ARCH/defs.mk

	write_c gnu/lib/libbfd/arch/$MACHINE_ARCH/bfd.h <$_TMPDIR/bfd/bfd.h

	{
		cat $_TMPDIR/bfd/config.h
	} | write_c gnu/lib/libbfd/arch/$MACHINE_ARCH/config.h
}

##### gnu/lib/libopcodes #####

get_libopcodes () {
	mkdir -p $_TOP/gnu/lib/libopcodes/arch/$MACHINE_ARCH

	{
		getvars opcodes/Makefile \
			archdefs BFD_MACHINES libopcodes_la_SOURCES
	} | write_mk gnu/lib/libopcodes/arch/$MACHINE_ARCH/defs.mk

	{
		cat $_TMPDIR/opcodes/config.h
	} | write_c gnu/lib/libopcodes/arch/$MACHINE_ARCH/config.h
}

##### gnu/lib/libg2c #####

get_libg2c () {
	mkdir -p $_TOP/gnu/lib/libg2c/arch/$MACHINE_ARCH

	write_c gnu/lib/libg2c/arch/$MACHINE_ARCH/config.h <$_TMPDIR/$_PLATFORM/libf2c/libU77/config.h
	write_c gnu/lib/libg2c/arch/$MACHINE_ARCH/g2c.h <$_TMPDIR/$_PLATFORM/libf2c/g2c.h

	{
		getvars $_PLATFORM/libf2c/Makefile \
			F2CEXT
		getvars $_PLATFORM/libf2c/libF77/Makefile \
			ALL_CFLAGS OBJS
		getvars $_PLATFORM/libf2c/libI77/Makefile \
			ALL_CFLAGS OBJ | sed 's,=,+=,'
		getvars $_PLATFORM/libf2c/libU77/Makefile \
			ALL_CFLAGS OBJS | sed 's,=,+=,'
	} | write_mk gnu/lib/libg2c/arch/$MACHINE_ARCH/defs.mk
}

##### gnu/lib/libgcc #####

get_libgcc () {
	mkdir -p $_TOP/gnu/usr.bin/gcc/arch/$MACHINE_ARCH $_TOP/gnu/lib/libgcc

	# DPBIT, FPBIT only used on mn10[23]00, we don't need them.
	getvars gcc/Makefile \
		CXX_EXTRA_HEADERS CXX_LIB2FUNCS CXX_LIB2SRCS \
		INCLUDES LIB2ADD LIB2FUNCS LIB2FUNCS_EH \
		LIBGCC2_CFLAGS MAYBE_USE_COLLECT2 \
		| write_mk gnu/lib/libgcc/$MACHINE_ARCH.mk

	for f in tconfig tm; do
		write_c gnu/usr.bin/gcc/arch/$MACHINE_ARCH/$f.h <$_TMPDIR/gcc/$f.h
	done
}

##### gnu/lib/libiberty #####

get_libiberty () {
	mkdir -p $_TOP/gnu/lib/libiberty

	getvars libiberty/Makefile \
		ALLOCA EXTRA_OFILES LIBOBJS REQUIRED_OFILES \
		| write_mk gnu/lib/libiberty/defs.mk

	write_c gnu/lib/libiberty/config.h \
		<$_TMPDIR/libiberty/config.h
}

##### gnu/lib/libobjc #####

get_libobjc () {
	mkdir -p $_TOP/gnu/lib/libobjc

	getvars $_PLATFORM/libobjc/Makefile \
		ALL_CFLAGS INCLUDES OBJS OBJC_H \
		| write_mk gnu/lib/libobjc/defs.mk
}

##### gnu/lib/libstdc++ #####

get_libstdcxx () {
	mkdir -p $_TOP/gnu/lib/libstdc++/arch/$MACHINE_ARCH

	write_c gnu/lib/libstdc++/arch/$MACHINE_ARCH/_G_config.h \
		<$_TMPDIR/$_PLATFORM/libio/_G_config.h

	{
		getvars $_PLATFORM/libio/Makefile \
			CINCLUDES LIBIOSTREAM_USE MT_CFLAGS XCFLAGS XCXXFLAGS

		# Ugly hack for backticks:
		(cd $_TMPDIR/$_PLATFORM/libstdc++ && \
			printf 'x:\n\t@echo G_LIBIBERTY_OBJS=${LIBIBERTY_OBJS}\n.include "Makefile"' | $MAKE -f - x)

		getvars $_PLATFORM/libstdc++/Makefile \
			COMFUNCS COMIO CXXINCLUDES HEADERS OBJS STRFUNCS STRIO

		(cd $_TOP/gnu/dist/toolchain/libstdc++ && echo 'STD_HEADERS=' \
			`/bin/ls -1 *.h std/*.h std/*.cc std/*.tcc | sort -f`)
		(cd $_TOP/gnu/dist/toolchain/libstdc++/stl && echo 'STL_HEADERS=' \
			`/bin/ls -1 *.h | sort -f`)
		(cd $_TOP/gnu/dist/toolchain/libio && echo 'LIBIO_HEADERS=' \
			`/bin/ls -1 *.h | sort -f`)
	} | write_mk gnu/lib/libstdc++/arch/$MACHINE_ARCH/defs.mk
}

##### gnu/usr.bin/binutils #####

get_binutils () {
	### common

	mkdir -p $_TOP/gnu/usr.bin/binutils/common/arch/$MACHINE_ARCH

	{
		getvars binutils/Makefile \
			VERSION DEFS INCLUDES PROGRAMS
		getvars binutils/doc/Makefile \
			man_MANS TEXINFOS

		for f in `getvars binutils/Makefile PROGRAMS | sed 'y,-,_,;s,^[^=]*=,,'`; do
			getvars binutils/Makefile ${f}_OBJECTS ${f}_DEPENDENCIES
		done
	} | write_mk gnu/usr.bin/binutils/common/arch/$MACHINE_ARCH/defs.mk

	write_c gnu/usr.bin/binutils/common/arch/$MACHINE_ARCH/config.h \
		<$_TMPDIR/binutils/config.h

	### gas

	mkdir -p $_TOP/gnu/usr.bin/binutils/gas/arch/$MACHINE_ARCH

	getvars gas/Makefile \
		DEFS INCLUDES OBJS \
		| write_mk gnu/usr.bin/binutils/gas/arch/$MACHINE_ARCH/defs.mk

	for f in config itbl-cpu obj-format targ-cpu targ-env; do
		write_c gnu/usr.bin/binutils/gas/arch/$MACHINE_ARCH/$f.h <$_TMPDIR/gas/$f.h
	done

	### gprof

	mkdir -p $_TOP/gnu/usr.bin/binutils/gprof/arch/$MACHINE_ARCH

	getvars gprof/Makefile \
		DEFS gprof_OBJECTS INCLUDES TEXINFOS \
		| write_mk gnu/usr.bin/binutils/gprof/arch/$MACHINE_ARCH/defs.mk

	write_c gnu/usr.bin/binutils/gprof/arch/$MACHINE_ARCH/gconfig.h <$_TMPDIR/gprof/gconfig.h

	### ld

	mkdir -p $_TOP/gnu/usr.bin/binutils/ld/arch/$MACHINE_ARCH

	{
		getvars ld/Makefile \
			DEFS EMUL EMULATION_OFILES INCLUDES OFILES STRINGIFY TEXINFOS
		getvars ld/Makefile \
			target_alias | sed 's,[\._0-9A-Z]*$,,'
	} | write_mk gnu/usr.bin/binutils/ld/arch/$MACHINE_ARCH/defs.mk

	for f in config ldemul-list; do
		write_c gnu/usr.bin/binutils/ld/arch/$MACHINE_ARCH/$f.h <$_TMPDIR/ld/$f.h
	done
}

##### gnu/usr.bin/gcc #####

get_gcc () {
	mkdir -p $_TOP/gnu/usr.bin/gcc/arch/$MACHINE_ARCH

	{
		getvars gcc/Makefile \
			ALL_CFLAGS ALL_CPPFLAGS C_AND_OBJC_OBJS C_OBJS CCCP_OBJS \
			GCOV_OBJS PROTO_OBJS HOST_PRINT HOST_RTL HOST_RTLANAL \
			INCLUDES md_file OBJC_OBJS OBJS out_file version
		getvars gcc/cp/Makefile \
			CXX_OBJS
		getvars gcc/f/Makefile \
			F77_OBJS
	} | write_mk gnu/usr.bin/gcc/arch/$MACHINE_ARCH/defs.mk

	for f in auto-host config gencheck options specs; do
		write_c gnu/usr.bin/gcc/arch/$MACHINE_ARCH/$f.h <$_TMPDIR/gcc/$f.h
	done
}

##### gnu/usr.bin/gdb #####

get_gdb () {
	(cd $_TMPDIR/gdb && $MAKE init.c version.c)

	mkdir -p $_TOP/gnu/usr.bin/gdb/arch/$MACHINE_ARCH

	{
		getvars gdb/Makefile \
			INTERNAL_CFLAGS LIBGDB_OBS SIM_OBJS
		getvars readline/Makefile \
			CCFLAGS OBJECTS
	} | write_mk gnu/usr.bin/gdb/arch/$MACHINE_ARCH/defs.mk

#	getvars gdb/gdbserver/Makefile \
#		INTERNAL_CFLAGS OBS \
#		| write_mk gnu/usr.bin/gdb/arch/$MACHINE_ARCH/gdbserver.mk

	cat $_TMPDIR/gdb/config.h $_TMPDIR/readline/config.h \
		| write_c gnu/usr.bin/gdb/arch/$MACHINE_ARCH/config.h

	for f in init version; do
		write_c gnu/usr.bin/gdb/arch/$MACHINE_ARCH/$f.c <$_TMPDIR/gdb/$f.c
	done

	for f in nm tm xm; do
		ls -l $_TMPDIR/gdb/$f.h | sed 's,^.*->.*/gdb/config/,,;s,^,#include <,;s,$,>,' \
			| write_c gnu/usr.bin/gdb/arch/$MACHINE_ARCH/$f.h
	done

	case $MACHINE_ARCH in
	powerpc*)
		mkdir -p $_TOP/gnu/usr.bin/sim/arch/$MACHINE_ARCH
		write_c gnu/usr.bin/sim/arch/$MACHINE_ARCH/config.h \
			<$_TMPDIR/sim/ppc/config.h
		;;
	*)
		;;
	esac
}

##### main #####

_TMPDIR=$2
_TOP=$3
_PLATFORM=$4
_VPATH=`grep VPATH ${_TMPDIR}/Makefile | sed 's,^.*= ,,'`

case $1 in
libgcc)	# .mk and .h files for libgcc bootstrap (from host build)
	get_libgcc
	exit 0
	;;

all)	# everything (uses "canadian cross" temp environment)
	get_binutils
	get_gcc
	[ -f $_TMPDIR/gdb/config.h ] && get_gdb
	get_libbfd
	get_libopcodes
	get_libg2c
	get_libgcc
	get_libiberty
	get_libobjc
	get_libstdcxx
	exit 0
	;;

binutils)
	get_binutils
	get_libbfd
	get_libopcodes
	exit 0
	;;

gcc)
	get_gcc
	get_libg2c
	get_libgcc
	get_libiberty
	get_libobjc
	get_libstdcxx
	exit 0
	;;

gdb)
	[ -f $_TMPDIR/gdb/config.h ] && get_gdb && get_libbfd && get_libopcodes
	exit 0
	;;

*)	echo invalid arguments; exit 1;;
esac
