# SliTaz package receipt.

PACKED_SIZE="2.3M"
UNPACKED_SIZE="2.3M"
PACKAGE="linux"
VERSION="3.2.53"
CATEGORY="base-system"
SHORT_DESC="The Linux kernel and modules."
MAINTAINER="devel@slitaz.org"
LICENSE="GPL2"
TARBALL="$PACKAGE-$VERSION.tar.xz"
WEB_SITE="http://www.kernel.org/"
WGET_URL="ftp://ftp.kernel.org/pub/linux/kernel/v3.0/$TARBALL"
HOST_ARCH="i486 arm x86_64"

DEPENDS="kmod"
BUILD_DEPENDS="slitaz-toolchain perl git xz lzma patch kmod \
uclibc-cross-compiler-x86_64 busybox-boot"

#
# The Linux receipt handle cross compilation. For x86_64 we actually use
# the uclibc-cross-compiler-x86_64 and for ARM we use a real cross env.
# Please discuss any change and keep it simple, dont play with VERSION
# string or Kernel SUBLEVEL because depmod and Pankso dont like that!
#
# The receipt also handle some cook options for faster build: 
# --nox64    : Skip the x86_64 cross compilation
# --nonomods : Skip bzImage without modules build
#

# Aufs enable chroot
AUFS_NOT_RAMFS="uclibc-cross-compiler-x86_64 is not compatible with aufs+tmpfs 8("

# Handle multiarch compilation. Less bdeps when cross-compiling for ARM
case "$ARCH" in
	arm) BUILD_DEPENDS="xz" ;;
	x86_64) BUILD_DEPENDS="xz" ;;
esac

# Handle multiarch installation. ARM use Busybox modutils, so avoid any
# deps on kmod. SLITAZ_ARCH can have also custom post_install commands
if [ -f $root/etc/slitaz/slitaz.conf ]; then
	. $root/etc/slitaz/slitaz.conf
	case "$SLITAZ_ARCH" in
		arm) DEPENDS="" ;;
	esac
fi

# Rules to configure and make the package.
compile_rules()
{
	if [ -f "/usr/share/boot/initrd" ]; then
		cp /usr/share/boot/initrd initrd.cpio
	fi

	# Handle cross compilation
	case "$ARCH" in
		arm)
			echo "Compiling: $ARCH Kernel"
			make mrproper
			patch -Np1 < $stuff/$ARCH/linux-arm.patch || exit 1
			cp -f $stuff/$ARCH/linux-arm.config .config
			yes '' | make ARCH=$ARCH oldconfig
			make ARCH=$ARCH CROSS_COMPILE=${HOST_SYSTEM}- bzImage &&
			make ARCH=$ARCH CROSS_COMPILE=${HOST_SYSTEM}- modules &&
			make ARCH=$ARCH CROSS_COMPILE=${HOST_SYSTEM}- \
				INSTALL_MOD_PATH=$DESTDIR modules_install &&
			mkdir -p $DESTDIR/boot &&
			cp -a arch/arm/boot/zImage \
				$DESTDIR/boot/linux-$VERSION-slitaz-$ARCH
			#$stuff/gztazmod.sh $DESTDIR/lib/modules/$VERSION-slitaz
			return 0 ;;
		x86_64)
			echo "TODO: Maybe use default ? But cross compile in x86_64 chroot"
			echo "so we can remove the 64 build by uclibc-cross-compiler-x86_64"
			return 0 ;;
	esac

	# Check for Aufs and get source/patches if needed
	echo "Checking for Aufs packages..."
	AUFSVER=$(grep ^VERSION= $WOK/aufs/receipt | cut -d "=" -f2 | sed -e 's/"//g')
	AUFSDIR="$WOK/aufs/source/aufs-${AUFSVER}"
	if [ ! -d "$AUFSDIR" ]; then
		[ ! -f "$SRC/aufs-${AUFSVER}.tar.bz2" ] && cook aufs --getsrc
		mkdir -p $WOK/aufs/source/
		echo "Extracting: aufs-${AUFSVER}.tar.bz2"
		tar xjf $SRC/aufs-${AUFSVER}.tar.bz2 -C $WOK/aufs/source/
	fi
	
	echo "cook:linux" > $command

	echo "Copying Aufs files and patches..."
	cp -a $AUFSDIR/Documentation $AUFSDIR/fs $AUFSDIR/include $src
	cp -a $AUFSDIR/aufs3-*.patch $stuff

	# SliTaz db stuff
	[ -d $WOK/$PACKAGE/source/slitaz ] && rm -rf $WOK/$PACKAGE/source/slitaz
	mkdir -p $WOK/$PACKAGE/source/slitaz
	echo "$WGET_URL" > $WOK/$PACKAGE/source/slitaz/url
	cp $stuff/gztazmod.sh $stuff/list_modules.sh $WOK/$PACKAGE/source/slitaz
	cp $stuff/bootloader.sh $WOK/$PACKAGE/source/slitaz

	# Apply patches
	echo "Applying patches..."
	while read patch_file; do
		echo "$patch_file" >> $WOK/$PACKAGE/source/slitaz/patches
		cp $stuff/$patch_file $WOK/$PACKAGE/source/slitaz
		if [ -f done.$patch_file ]; then
			echo "Skipping $patch_file" && continue
		fi
		echo "Apply $patch_file"
		patch -p1 < $WOK/$PACKAGE/source/slitaz/$patch_file || return 1
		touch done.$patch_file
	done <<EOT
$PACKAGE-diff.u
$PACKAGE-header.u
$PACKAGE-freeinitrd.u
$PACKAGE-subroot.u
$PACKAGE-CVE-2013-2929.u
aufs3-base.patch
aufs3-standalone.patch
aufs3-loopback.patch
aufs3-mmap.patch
channel-negative-one-maxim.patch
mac80211.compat08082009.wl_frag+ack_v1.patch
EOT
	
	# Mrproper and lguest
	echo "Make kernel proper and then build lguest..."
	make mrproper
	cd Documentation/virtual/lguest
	make lguest || return 1
	cd $src
	
	#
	# Arch x86_64: TODO have a real cross environment
	#
	if [ ! "$nox64" ]; then
		echo "Compiling: x86_64 Kernel"
		
		# Build bzImage64 without modules first
		if [ ! "$nonomods" ]; then
			cp -f $stuff/$PACKAGE-slitaz.config64 .config
			sed -i 's/CONFIG_MODULES=y/# CONFIG_MODULES is not set/' .config
			# We can't keep every driver in staging ???
			sed -i -e 's/^CONFIG_RTL8192/#&/' \
				-e 's/^CONFIG_R8187SE/#&/' \
				-e 's/^CONFIG_RT2870/#&/' .config
			echo -e "\n* Configure bzImage64 without modules...\n"
			yes '' | make ARCH=x86_64 oldconfig
			echo -e "\n* Building bzImage64 without modules...\n"
			make -j 4 ARCH=x86_64 CROSS_COMPILE=uclibc-x86_64- bzImage || exit 1
			[ -d $DESTDIR ] || mkdir -p $DESTDIR/linux64
			mv arch/x86/boot/bzImage $DESTDIR/linux64
			mv System.map System.map-without-modules64
		fi
		
		# Build bzImage64 with modules
		cp -f $stuff/$PACKAGE-slitaz.config64 .config
		echo -e "\n* Configure bzImage64 with modules...\n"
		yes '' | make ARCH=x86_64 oldconfig
		echo -e "\n* Building bzImage64 with modules...\n"
		make -j 4 ARCH=x86_64 CROSS_COMPILE=uclibc-x86_64- bzImage &&
		make -j 4 ARCH=x86_64 CROSS_COMPILE=uclibc-x86_64- modules &&
		make ARCH=x86_64 INSTALL_MOD_PATH=$DESTDIR/linux64 modules_install &&
		make ARCH=x86_64 INSTALL_HDR_PATH=$DESTDIR/linux64/usr headers_install &&
		ln .config $WOK/$PACKAGE/source/slitaz/config64
		[ -s arch/x86/boot/bzImage ] || return 1
		mkdir -p $DESTDIR/linux64/boot 2> /dev/null
		mv arch/x86/boot/bzImage $DESTDIR/linux64/boot/vmlinuz-$VERSION-slitaz
		ln System.map System.map-modules64
		ln Module.symvers Module.symvers-modules64
	else
		echo "* Skipping: x86_64 Kernel..."
	fi
	
	#
	# Linux Arch i386 - GCC arch i486
	#
	echo "Compiling: i386 Kernel..."

	# Build bzImage without modules first
	if [ ! "$nonomods" ]; then
		cp -f $stuff/$PACKAGE-slitaz.config .config
		sed -i 's/CONFIG_MODULES=y/# CONFIG_MODULES is not set/' .config
		# We can't keep every driver in staging ???
		sed -i -e 's/^CONFIG_RTL8192/#&/' \
			-e 's/^CONFIG_R8187SE/#&/' \
			-e 's/^CONFIG_RT2870/#&/' .config
		echo -e "\n* Configure bzImage without modules...\n"
		yes '' | make ARCH=i386 oldconfig
		echo -e "\n* Building bzImage without modules...\n"
		make ARCH=i386 -j 4 bzImage || exit 1
		[ -d $DESTDIR ] || mkdir -p $DESTDIR
		mv arch/x86/boot/bzImage $DESTDIR
		mv System.map System.map-without-modules
	fi
	
	# Build bzImage with modules
	cp -f $stuff/$PACKAGE-slitaz.config .config
	echo -e "\n* Configure bzImage with modules...\n"
	yes '' | make ARCH=i386 oldconfig
	ln .config $WOK/$PACKAGE/source/slitaz/config
	echo -e "\n* Building bzImage with modules...\n"
	make ARCH=i386 -j 4 bzImage &&
	make ARCH=i386 -j 4 modules &&
	make ARCH=i386 INSTALL_MOD_PATH=$DESTDIR modules_install &&
	make ARCH=i386 INSTALL_HDR_PATH=$DESTDIR/usr headers_install &&
	[ -s arch/x86/boot/bzImage ] || return 1
	mkdir -p $DESTDIR/boot 2> /dev/null
	mv arch/x86/boot/bzImage $DESTDIR/boot/vmlinuz-$VERSION-slitaz
	
	# Compress all modules.
	if [ -d "$DESTDIR/lib/modules/$VERSION-slitaz" ]; then
		$stuff/gztazmod.sh $DESTDIR/lib/modules/$VERSION-slitaz
	else
		return 1
	fi
	if [ -d "$DESTDIR/linux64/lib/modules/$VERSION-slitaz" ]; then
		$stuff/gztazmod.sh $DESTDIR/linux64/lib/modules/$VERSION-slitaz
	fi
	ln System.map System.map-modules
	ln Module.symvers Module.symvers-modules
}

# Rules to gen a SliTaz package suitable for Tazpkg.
genpkg_rules()
{
	case "$ARCH" in
		arm)
			echo "Packing: ARM Kernel"
			cp -a $install/* $fs
			rm -f $fs/lib/modules/*/build $fs/lib/modules/*/source
			return 0 ;;
		x86_64)
			echo "TODO: use default or custom x86_64 packing"
			return 0 ;;
	esac

    export PACKAGE VERSION
    local path
    cp -a $install/boot $fs
    
    # Compress all modules.
    path=$fs/lib/modules/$VERSION-slitaz/kernel
    mkdir -p $path
	
    # Get the base modules
    export src install
    mkdir -p $WOK/$PACKAGE/source/tmp
    # Warning stuff/list_modules.sh must find the generated modules.list
    $stuff/list_modules.sh \
		$(cat $stuff/modules.list) > $WOK/$PACKAGE/source/tmp/modules.list
    while read module; do
    	dir=$(dirname $module)
    	[ -d $path/$dir ] || mkdir -p $path/$dir
        cp -a $install/lib/modules/$VERSION-slitaz/kernel/$module $path/$dir
    done < $WOK/$PACKAGE/source/tmp/modules.list
    
    # Remove unresolved links
    rm -f $fs/lib/modules/$VERSION-slitaz/build
    rm -f $fs/lib/modules/$VERSION-slitaz/source
    
    # We only need module.{order,builtin} because other map files are 
    # generated by depmod in post_install
    cp -a $install/lib/modules/$VERSION-slitaz/modules.order \
		$install/lib/modules/$VERSION-slitaz/modules.builtin \
		$fs/lib/modules/$VERSION-slitaz
    
    # Pack all packages with a kernel module
    for i in $(cd $WOK; grep -l '^WANTED="linux"' */receipt)
    do
		[ ! -d "$install/lib/modules/$VERSION-slitaz" ] && return 1
		cook ${i%/receipt}
    done
	
	# Check any module in kernel .config that's not added to a linux-* pkgs
	# and remove aufs patches: we dont need them in HG wok.
	$stuff/check_modules.sh
	rm -f $stuff/aufs3-*
}

# Pre and post install commands for Tazpkg.
post_install()
{
    echo "Processing post-install commands..."
    chroot "$root/" depmod -a $VERSION-slitaz
    
    # Handle multiarch installation
    case "$SLITAZ_ARCH" in
		arm)
			echo "Kernel : /boot/linux-$VERSION-slitaz-$ARCH"
			echo "Modules: /lib/modules/$VERSION-slitaz"
			return 0 ;;
	esac
	
	# GRUB stuff.
	if [ -f "$1/boot/grub/menu.lst" ]; then
		# Current root device
		root_dev="/dev/$(lsblk | grep '/$'| grep -o '[a-z]d[a-z][0-9]*')"
		grub_part="$(( $(echo $root_dev | grep -o '[0-9]*$')-1 ))"
		# Use device.map to find grub device number
		grub_dev="$(grep $(echo $root_dev | grep -o  '^/dev/.d.' ) \
			$1/boot/grub/device.map | cut -f1 | sed "s/)$/.$grub_part)/g")" 
    	
		# Add and clean kernel entries in case of upgrade for installed system.
		if ! grep -q vmlinuz-$VERSION-slitaz $1/boot/grub/menu.lst; then
		
			# Clean the old entry
			# TODO: old vmlinuz file is removed but the entry is still there.
			# So grub error:15 when selected: http://bugs.slitaz.org/?id=74

			# Add the new entry
			cat >> $1/boot/grub/menu.lst << EOT

title SliTaz GNU/Linux (Kernel $VERSION-slitaz)
$grub_dev 
kernel /boot/vmlinuz-$VERSION-slitaz root=$root_dev quiet
EOT
			# Make it the default entry
			last_entry=$(( $(grep -c '^title' $1/boot/grub/menu.lst)-1 ))
			sed -e "s/^default.*/default $last_entry/g" -i $1/boot/grub/menu.lst
		fi
		
		# Display information message.
		cat <<EOT
----
GRUB is installed, these tree lines must be in your /boot/grub/menu.lst:

title  SliTaz GNU/Linux (Kernel $VERSION-slitaz)
$grub_dev
kernel /boot/vmlinuz-$VERSION-slitaz root=$root_dev
----
EOT
	fi
}
