# DIET-PC Makefile

# Copyright (C) 2003-2005 Paul A. Whittaker <whitpa@users.sourceforge.net>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

# Name of your kernel package.  "kernel" must appear somewhere in the name.
KERNEL=kernel_generic586plus

# Whether or not any non-volatile filesystems that your DIET-PC may use should
# be included in the build process.  This is only relevant if one of your
# packages adds an /etc/fstab entry for a non-root persistent filesystem (eg.
# an external /opt), and you have one or more packages that contain files in
# that subtree (eg. /opt/xine).
#
# - If this is the case and you do not enable this option, then files in the
#   relevant subtree(s) will not be included in initrd.img, and you will be
#   expected to install them on the non-volatile filesystem(s) manually.
#
# - If this is the case and you do enable this option, then the build process
#   will attempt to mount these filesystems and write package contents to them
#   where applicable.  This will only work if the filesystem can be mounted
#   read-write on the build host.  The build process will *NOT* create or
#   consistency-check the filesystem.  Typically you would only enable this if
#   your non-volatile filesystems are NFS or SMB shares writable by the build
#   host, or when using the assembler-installer package (ie. the build host is
#   the same as the run host). As a special case, the script also understands
#   how to position the files so that they will be included in an ISO image
#   build ("iso" Makefile target) for burning onto CD.  This will happen if
#   your non-volatile filesystem is of type iso9660, regardless of the device
#   name.
#
# This option is only intended to save you some time and effort where
# circumstances permit.  The build automation is not particularly safe or
# robust if this option is enabled and anything unexpected happens.  If in
# doubt, say no.
BUILD_NON_VOLATILE=no

# Preferred format for the final root filesystem image (subject to target
# and/or build host feature availability). One of: cpio.gz, e2compr, ext2.gz,
# squashfs, tar.gz.  If unspecified, the build process will try for squashfs
# first, then e2compr, then initramfs (cpio.gz) or inittar, and finally
# traditional ext2 initrd (ext2.gz).  If the preferred format is unachievable,
# earlier formats in this sequence will be forfeited.
PREF_FS_FORMAT=

# Whether or not to use UPX to compress executables when constructing an
# initramfs (compressed CPIO archive).  This may save you some RAM, but you
# can't use ldd on UPX-packed executables (to diagnose shared library problems).
USE_UPX=no

# Root directory of the TFTP hierarchy (as per tftpd directory argument).
TFTPROOT=/var/lib/tftpboot

# CD/DVD recorder device.  My CDROM test unit can read CD-RWs, so I like to
# test ISO boot images on CDRWs first (hence the "blank=fast" option).
#CDR_DEV=/dev/hdc
CDR_DEV=/dev/scd0
CDR_SPEED=16
CDR_EXTRAOPTS=blank=fast driveropts=burnproof

# Disk device to install to.  This must be a block device containing an
# uncompressed FAT12 or FAT16 filesystem, or an ext2 or ext3 filesystem.
# Typically you would specify the pathname to a removable media writer device
# here, rather than a local fixed disk.
#
# This Makefile will not partition the disk, set the active partition, create
# the filesystem, or make you coffee.  Do all of this separately prior to
# running "make install-{fat,ext2}[grub|lilo]" (you can skip the coffee if you
# wish :-).
DISK_DEV=/dev/hda1

# Whether or not to install a boot loader in the Master Boot Record of the
# disk.  This option is only relevant when using FAT or ext2 boot loaders.
# MBR installation is preferable if the disk in question will only ever be used
# for DIET-PC purposes (ie. it does not contain any other operating system).
# Otherwise say no, unless you're sure that you understand the consequences.
USE_MBR=yes

# Expert-only modification beyond this point.

BUILD_OPTS=
ifeq ($(BUILD_NON_VOLATILE), yes)
    BUILD_OPTS += -nv
endif
ifeq ($(USE_UPX), no)
    BUILD_OPTS += -noupx
endif
ifneq ($(PREF_FS_FORMAT),)
    BUILD_OPTS += -f $(PREF_FS_FORMAT)
endif

WHOLEDISK_DEV=$(shell echo $(DISK_DEV) | tr -d '[0-9]')
ifeq ($(DISK_DEV), $(WHOLEDISK_DEV))
    GRUB_ROOT=(hd7)
else
    GRUB_ROOT=(hd7,`(echo $(DISK_DEV) | tr -cd '[0-9]\n'; echo '1 - p') | dc`)
endif

SUDO=
ifneq ($(shell id -u), 0)
    SUDO = sudo
endif

# The initrd.img target ought to have proper dependencies, but it is very
# difficult to detect whether or not anything relevant to the final state of
# the initrd image has changed, so unless building a specific target, we'll
# just assume the worst and rebuild from scratch each time.
all: clean initrd.img

clean:
	rm -rf diet-pc.nbi diet-pc.iso initrd.img cdimage/boot

distclean: clean
	rm -rf kbuild metadata

ipks:
	@sh -c 'for PKG in ipkg-tree/*; do \
		ARCH=`grep -s "^Architecture: " $$PKG/CONTROL/control | cut \
				-f2 -d" "`;\
		[ ! "$$ARCH" ] && continue;\
		mkdir -p $$ARCH;\
		$(SUDO) ./tools/ipkg-build -o root -g root $$PKG $$PWD/$$ARCH;\
	done'

fetch-ipks:
	@sh -c 'for ARCH in `./tools/ipkg -f ipkg.conf -V 0 print_architecture \
				| cut -f2 -d" "`; do \
		echo -e "Synchronizing \"$$ARCH\" feed ... \c";\
		rsync -aqc rsync://dietpc.org/feeds/3/$$ARCH/ $$ARCH/;\
		echo "done.";\
	done'

ipkg-tree:
	mkdir -p ipkg-tree
	@sh -c 'cd ipkg-tree; for ARCH in `../tools/ipkg -f ../ipkg.conf -V 0 \
				print_architecture | cut -f2 -d" "`; do \
		for IPK in ../$$ARCH/*.ipk; do \
			[ "$$IPK" = "../$$ARCH/*.ipk" ] && break;\
			../tools/ipkg-unbuild $$IPK;\
		done;\
	done'

metadata:
	./tools/extract_metadata

kbuild/Kconfig: metadata
	./tools/ipkg2kconfig

config: kbuild/Kconfig
	./tools/mconf kbuild/Kconfig

menuconfig: config

initrd.img: config
	$(SUDO) ./tools/build_initrdimg $(BUILD_OPTS) $(KERNEL)/System.map

iso: diet-pc.iso

diet-pc.iso: initrd.img
	tar -C templates/isolinux -cf - . | tar -C cdimage -xf -
	cp $(KERNEL)/bzImage cdimage/boot
	cp initrd.img cdimage/boot
	mkisofs -o diet-pc.iso -b boot/isolinux/isolinux.bin -c \
		boot/isolinux/boot.cat -J -hide-joliet-trans-tbl -r \
		-hide-rr-moved -no-emul-boot -boot-load-size 4 \
		-boot-info-table -A "DIET-PC (C) 2002-2008 Paul A. Whittaker \
		<whitpa@users.sourceforge.net>" -V 'DIET-PC 3' cdimage

nbi: diet-pc.nbi

diet-pc.nbi: initrd.img
	@echo
	./tools/mknbi-linux -L /tmp -a 'rw root=/dev/ram0 console=tty1' -i \
		rom -r initrd.img -k $(KERNEL)/bzImage -o diet-pc.nbi
	@echo
	@printf '\t%s\n' "`ls -sh diet-pc.nbi`"

install:
	@echo 'make install-(extlinux|grub|iso|lilo|nbi|netgrub|pxelinux|syslinux)'

install-extlinux:
ifeq ($(USE_MBR), yes)
	$(SUDO) dd if=templates/mbr/mbr.bin of=$(WHOLEDISK_DEV) bs=446 \
		count=1 2>/dev/null
endif
	$(SUDO) mount -t ext2 $(DISK_DEV) initrd
	$(SUDO) sh -c "tar -C templates/extlinux -cf - . | tar -C initrd \
		--no-same-owner -xf -"
	$(SUDO) ./tools/chattr -cR initrd/boot
	$(SUDO) cp $(KERNEL)/bzImage initrd/boot
	$(SUDO) cp initrd.img initrd/boot
	sync
	$(SUDO) ./tools/extlinux -i initrd/boot/extlinux
	$(SUDO) umount initrd

install-grub: initrd.img
	$(SUDO) mount -t ext2,vfat $(DISK_DEV) initrd
	$(SUDO) sh -c "tar -C templates/grub -cf - . | tar -C initrd \
		--no-same-owner -xf -"
	$(SUDO) ./tools/chattr -cR initrd/boot
	$(SUDO) cp $(KERNEL)/bzImage initrd/boot
	$(SUDO) cp initrd.img initrd/boot
	sync
	echo "device (hd7) $(WHOLEDISK_DEV)" >/tmp/grubcmds
	echo "root $(GRUB_ROOT)" >>/tmp/grubcmds
ifeq ($(USE_MBR), yes)
	echo 'setup (hd7)' >>/tmp/grubcmds
else
	echo "setup $(GRUB_ROOT)" >>/tmp/grubcmds
endif
	echo quit >>/tmp/grubcmds
	$(SUDO) ./tools/grub --batch </tmp/grubcmds
	rm /tmp/grubcmds
	$(SUDO) rm initrd/boot/grub/*stage1*
	$(SUDO) umount initrd

install-iso: diet-pc.iso
	$(SUDO) cdrecord dev=$(CDR_DEV):@ -v speed=$(CDR_SPEED) \
		$(CDR_EXTRAOPTS) diet-pc.iso

install-lilo: initrd.img
	$(SUDO) mount -t ext2,vfat $(DISK_DEV) initrd
	$(SUDO) sh -c "tar -C templates/lilo -cf - . | tar -C initrd \
		--no-same-owner -xf -"
	$(SUDO) ./tools/chattr -cR initrd/boot 2>/dev/null
	$(SUDO) cp $(KERNEL)/bzImage initrd/boot
	$(SUDO) cp initrd.img initrd/boot
	$(SUDO) mount --bind /dev initrd/dev
	sync
ifeq ($(USE_MBR), yes)
	$(SUDO) ./tools/lilo -r initrd -b $(WHOLEDISK_DEV)
else
	$(SUDO) ./tools/lilo -r initrd -b $(DISK_DEV)
endif
	$(SUDO) umount initrd/dev
	$(SUDO) rmdir initrd/dev
	$(SUDO) rm -rf initrd/tmp initrd/etc
	$(SUDO) umount initrd

install-nbi: diet-pc.nbi
	$(SUDO) mkdir -m 755 -p $(TFTPROOT)/diet-pc
	$(SUDO) cp diet-pc.nbi $(TFTPROOT)/diet-pc
	$(SUDO) chmod 644 $(TFTPROOT)/diet-pc/diet-pc.nbi

install-netgrub:
	$(SUDO) mkdir -m 755 -p $(TFTPROOT)/diet-pc
	$(SUDO) sh -c "tar -C templates/netgrub -cf - . | tar -C $(TFTPROOT) \
		--no-same-owner -xf -"
	$(SUDO) cp initrd.img $(TFTPROOT)/diet-pc/
	$(SUDO) cp $(KERNEL)/bzImage $(TFTPROOT)/diet-pc/
	$(SUDO) chmod 644 $(TFTPROOT)/diet-pc/initrd.img \
		$(TFTPROOT)/diet-pc/bzImage
	@echo 'See templates/netgrub/diet-pc/grub/README for DHCP setup info.'

install-pxelinux: initrd.img
	$(SUDO) mkdir -m 755 -p $(TFTPROOT)/diet-pc
	$(SUDO) sh -c "tar -C templates/pxelinux -cf - . | tar -C $(TFTPROOT) \
		--no-same-owner -xf -"
	$(SUDO) cp initrd.img $(TFTPROOT)/diet-pc/
	$(SUDO) cp $(KERNEL)/bzImage $(TFTPROOT)/diet-pc/
	$(SUDO) chmod 644 $(TFTPROOT)/diet-pc/initrd.img \
		$(TFTPROOT)/diet-pc/bzImage

install-syslinux: initrd.img
ifeq ($(USE_MBR), yes)
	$(SUDO) dd if=templates/mbr/mbr.bin of=$(WHOLEDISK_DEV) bs=446 \
		count=1 2>/dev/null
endif
	$(SUDO) mount -t vfat $(DISK_DEV) initrd
	$(SUDO) sh -c "tar -C templates/syslinux -cf - . | tar -C initrd \
		--no-same-owner -xf -"
	$(SUDO) cp $(KERNEL)/bzImage initrd/boot
	$(SUDO) cp initrd.img initrd/boot
	$(SUDO) umount initrd
	$(SUDO) ./tools/syslinux -d /boot/syslinux $(DISK_DEV)
