Commit 3e2f2006 authored by sebt3's avatar sebt3
Browse files

Initial upload

parent f6336f0f
Loading
Loading
Loading
Loading

environment-setup

0 → 100644
+68 −0
Original line number Diff line number Diff line
#!/bin/sh

# Where you store your pyra's projects
export PROJECTS_BASEDIR=${PROJECTS_BASEDIR:-"$HOME/projects/pyra"}
# Local storage for PNDs
export DBPS_TARGETDIR=${DBPS_TARGETDIR:-"$PROJECTS_BASEDIR/DBPs"}
# Build target and dbp moint point
export PYRA_BASEDIR=${PYRA_BASEDIR:-"/mnt/dbp/images"}

export TOOLCHAIN_ROOT=${TOOLCHAIN_ROOT:-"/usr/local/pyra"}
export PYRA_ROOTFS=${PYRA_ROOTFS:-"$TOOLCHAIN_ROOT/rootfs"}
export CMAKETOOLCHAINFILE="$TOOLCHAIN_ROOT/toolchain.cmake"
export TARGET_SYS=arm-linux-gnueabihf 
export CXXFLAGS="$CXX_DEFINES --sysroot=$PYRA_ROOTFS -mcpu=cortex-a15 -mfpu=neon-vfpv4 -mfloat-abi=hard -marm -mthumb-interwork -ftree-vectorize -fsigned-char $CXXFLAGS_ADD -I$PYRA_ROOTFS/usr/include"
export CPPFLAGS="$CXXFLAGS" CFLAGS="$CXXFLAGS"
export CROSSTOOL="$TARGET_SYS"
export CXX=$CROSSTOOL-g++ CC=$CROSSTOOL-gcc AR=$CROSSTOOL-ar AS=$CROSSTOOL-as RANLIB=$CROSSTOOL-ranlib STRIP=$CROSSTOOL-strip
export LDFLAGS="--sysroot=$PYRA_ROOTFS -L$PYRA_ROOTFS/usr/lib -Wl,-rpath,$PYRA_ROOTFS/usr/lib"

export LIBTOOL_SYSROOT_PATH=$PYRA_ROOTFS
export PKG_CONFIG_SYSROOT_DIR=$PYRA_ROOTFS
export PKG_CONFIG_PATH=$PYRA_ROOTFS/usr/lib/pkgconfig
export CPATH="$PYRA_ROOTFS/usr/include:$CPATH" 
export PATH="$TOOLCHAIN_ROOT/bin:$PATH"
export HOST_CC=gcc HOST_CXX=g++
addfastmath() {
	export CXXFLAGS="$CXXFLAGS -O3 -ffast-math"
	export CPPFLAGS="$CXXFLAGS" CFLAGS="$CXXFLAGS"
}

pyra_unset() {
	unset LIBTOOL_SYSROOT_PATH PKG_CONFIG_PATH CPATH CFLAGS CXXFLAGS LDFLAGS CROSSTOOL CXX CC AR AS RANLIB HOST_CC HOST_CXX PRJ
}

pyra_setprj() {
	export PRJ=$1;
	if [ ! -z "$PRJ" ];then
		export LDFLAGS="-L$PYRA_BASEDIR/$PRJ/lib -Wl,-rpath,$PYRA_BASEDIR/$PRJ/lib $LDFLAGS" CXXFLAGS="$CXXFLAGS -I$PYRA_BASEDIR/$PRJ/include" PKG_CONFIG_PATH="$PYRA_BASEDIR/$PRJ/lib/pkgconfig:$PKG_CONFIG_PATH" CPATH="$PYRA_BASEDIR/$PRJ/include:$PYRA_ROOTFS/usr/include"
		if [ -d $PROJECTS_BASEDIR/$PRJ ];then
			cd $PROJECTS_BASEDIR/$PRJ
		fi
	fi
}

# Help to configure stuff
#-------------------------

pyra_configure() {
	if [ -z "$PRJ" ];then
		echo "You should Configure your project (using the setprj <project> command)"
		./configure --host=$TARGET_SYS $@
	else
		./configure --host=$TARGET_SYS --prefix=$PYRA_BASEDIR/$PRJ $@
	fi
}

pyra_cmake() {
	if [ -z "$PRJ" ];then
		echo "You should Configure your project (using the setprj <project> command)"
		SDLDIR="${PYRA_ROOTFS}/usr" cmake -DCMAKE_TOOLCHAIN_FILE=$CMAKETOOLCHAINFILE $@
	else
		SDLDIR="${PYRA_ROOTFS}/usr" cmake -DCMAKE_TOOLCHAIN_FILE=$CMAKETOOLCHAINFILE -DPRJ_PREFIX=$PYRA_BASEDIR/$PRJ -DCMAKE_INSTALL_PREFIX=$PYRA_BASEDIR/$PRJ $@
	fi
}

#pndqmake() {
#	qmake-qt4 -spec $TOOLCHAIN_ROOT/arm/share/qt4/mkspecs/linux-pandora-g++ $@
#}

install.sh

0 → 100755
+444 −0
Original line number Diff line number Diff line
#!/bin/bash

################################################################################
###
##	Utils
#

SCRIPT_file=${0##*/}
SCRIPT_name=${SCRIPT_file%.sh}
SCRIPT_path=$(dirname "$(readlink -f "$0")")
is.set() { 	[ ! -z ${!1+x} ]; }
is.array() { 	is.set $1 && [[ "$(declare -p $1)" =~ "declare -a" ]]; }

OUT_levels=(NONE FAIL ERROR OK TASK WARNING NOTICE CMD INFO OUTPUT DETAIL ALL)
OUT_level=${OUT_level:-OUTPUT}
out.levelID() {
	local i=0
	for l in ${OUT_levels[*]};do
		i=$(( $i + 1 ))
		if [[ "$1" = "$l" ]];then
			echo $i
			return
		fi
	done
}
OUT_color=()
OUT_color[$(out.levelID NONE)]="${OUT_color[$(out.levelID NONE)]:-$(tput sgr0)}"
OUT_color[$(out.levelID FAIL)]="${OUT_color[$(out.levelID FAIL)]:-$(tput setb 4;tput setab 1)}"
OUT_color[$(out.levelID ERROR)]="${OUT_color[$(out.levelID ERROR)]:-$(tput setf 4;tput setaf 1)}"
OUT_color[$(out.levelID OK)]="${OUT_color[$(out.levelID OK)]:-$(tput setf 2;tput setaf 2)}"
OUT_color[$(out.levelID WARNING)]="${OUT_color[$(out.levelID WARNING)]:-$(tput setf 6;tput setaf 3)}"
OUT_color[$(out.levelID INFO)]="${OUT_color[$(out.levelID INFO)]:-$(tput setf 3;tput setaf 4)}"
OUT_color[$(out.levelID NOTICE)]="${OUT_color[$(out.levelID NOTICE)]:-$(tput setf 5;tput setaf 13)}"
OUT_color[$(out.levelID CMD)]="${OUT_color[$(out.levelID CMD)]:-$(tput setf 6;tput setaf 4)}"
OUT_cmd=()
out.init() {
	eval $(resize)
	local space="\033[$((${COLUMNS} - 11))G"
	OUT_fd=1
	for lvl in ${OUT_levels[*]};do
		if [[ $lvl = "NONE" || $lvl = "ALL" ]];then continue;fi
		OUT_id=$(out.levelID $lvl)
		case "$lvl" in
		TASK)	OUT_cmd[$OUT_id]="${OUT_cmd[$OUT_id]:-"printf '\\r[ %7s ] %s' \"\" \"\$*\""}";;
		OUTPUT)	OUT_cmd[$OUT_id]="${OUT_cmd[$OUT_id]:-"printf '\\r%s\\n' \"\$*\""}";;
		CMD)	OUT_cmd[$OUT_id]="${OUT_cmd[$OUT_id]:-"printf '\\r${OUT_color[$OUT_id]}%s>${OUT_color[$(out.levelID NONE)]} %s\\n' $lvl \"\$*\""}";;
		*)	OUT_cmd[$OUT_id]="${OUT_cmd[$OUT_id]:-"printf '\\r[ ${OUT_color[$OUT_id]}%7s${OUT_color[$(out.levelID NONE)]} ] %s\\n' $lvl \"\$*\""}";;
		esac
	done
	OUT_levelID=$(out.levelID $OUT_level)
}
out.lvl() {
	local lvl=$1;shift
	local id=$(out.levelID $lvl)
	[ ${id:-10} -le ${OUT_levelID:-13} ] && eval "${OUT_cmd[$id]}  >&$OUT_fd"
	log.lvl "$lvl" "$*"
	return 0
}
out.put() {	while read line;do out.lvl OUTPUT "$line";done; }
out.error() {	out.lvl ERROR "$*"; }
out.ok() {	out.lvl OK "$*"; }
out.warn() {	out.lvl WARNING "$*"; }
out.info() {	out.lvl INFO "$*"; }
out.notice() {	out.lvl NOTICE "$*"; }
out.task() {	out.lvl TASK "$*"; }
out.fail() {	out.lvl FAIL "$*";exit 1; }
out.cmd() {	out.lvl CMD "$*";eval "$*" 2>&1|out.put; test ${PIPESTATUS[0]} -eq 0; }

log.stamp() { date '+%Y%m%d_%H%M%S'; }
log.separator() { local c=${1:-"="};awk -v "V=$c" 'BEGIN{while (c++<80) printf V;printf "\n"}';}
LOG_dir=${LOG_dir:-'/tmp'}
LOG_file=${LOG_file:-"${SCRIPT_name}.log.$(log.stamp)"}
LOG_cmd=${LOG_cmd:-'printf "[$(log.stamp) - %-7s ] %s\n" "$lvl" "$text"'}
LOG_level=${LOG_level:-ALL}
LOG_head=(ARGS_cmd USER PWD)
log.lvl() {
	local lvl=$1;shift
	local text="$*"
	local id=$(out.levelID $lvl)
	if [ ${id:-10} -le ${LOG_levelID:-0} ];then
		if [[ "$lvl" = "TASK" ]];then
			[ $OUT_fd -eq 1 ] && log.separator >> $LOG_dir/$LOG_file
			[ $OUT_fd -ne 1 ] && log.separator
		fi
		[ $OUT_fd -eq 1 ] && eval "$LOG_cmd" >> $LOG_dir/$LOG_file
		[ $OUT_fd -ne 1 ] && eval "$LOG_cmd"
	fi
}
log.start() {
	local i=0
	out.init
	LOG_levelID=$(out.levelID $LOG_level)
	exec 4>&1
	exec 1>>$LOG_dir/$LOG_file 2>&1
	OUT_fd=4
	log.separator "#"
	for i in ${LOG_head[*]};do
		printf "%-15s : %s\n" "$i" "$(eval echo "\$$i")"
	done
	log.separator "#"
}
log.end() {
	log.separator "#"
	exec >&- >&4
	OUT_fd=1
}

ARGS_vars=()
ARGS_short=()
ARGS_long=()
ARGS_haveVal=()
ARGS_mandatory=()
ARGS_option=()
ARGS_desc=()
ARGS_cnt=0
ARGS_info=${ARGS_info:-''}
ARGS_cmd="$*"
ARGS_short_cmd=()
args.declare() {
	ARGS_cnt=$(( $ARGS_cnt + 1 ))
	LOG_head+=($1)
	ARGS_vars[$ARGS_cnt]=$1;shift
	ARGS_short[$ARGS_cnt]=$1;shift
	ARGS_long[$ARGS_cnt]=$1;shift
	case $1 in
	Y*|y*|1)	ARGS_haveVal[$ARGS_cnt]='Y';shift;;
	*)		ARGS_haveVal[$ARGS_cnt]='N';eval "${ARGS_vars[$ARGS_cnt]}=N";shift;;
	esac
	case $1 in
	Y*|y*|1)	ARGS_option[$ARGS_cnt]='Y';eval "ARGS_values_${ARGS_vars[$ARGS_cnt]}=();ARGS_desc_${ARGS_vars[$ARGS_cnt]}=()";shift;;
	*)		ARGS_option[$ARGS_cnt]='N';shift;;
	esac
	case $1 in
	Y*|y*|1)	ARGS_mandatory[$ARGS_cnt]='Y';shift;;
	*)		ARGS_mandatory[$ARGS_cnt]='N';shift;;
	esac
	ARGS_desc[$ARGS_cnt]="$*";
}
args.option.declare() {
	local V=$1;shift;
	local s=$1;shift;
	local l=$1;shift;
	local m=$1;shift;
	args.declare $V $s $l Y Y $m "$*"
}
args.option() {
	local A=$1;shift;local V=$1;shift
	eval "ARGS_values_$A+=($V)"
	eval "ARGS_desc_${A}+=('$*')"
}
args.use.help() {
	args.declare ARGS_help       -h --help       N N N Show this help text
}
args.help() {
	local l="$0"
	local s="$0"
	local v=""
	local n=0
	local i=0
	if is.set ARGS_short_cmd;then
		ARGS_tmp=("${ARGS_short_cmd[@]}")
		while is.set ARGS_tmp;do 
			v=${ARGS_tmp[0]};ARGS_tmp=("${ARGS_tmp[@]:1}")
			for i in $(seq 1 $ARGS_cnt);do
				if [[ "${ARGS_vars[$i]}" == "$v" ]];then
					if [[ "${ARGS_mandatory[$i]}" = "Y" ]];then
						s="$s $v"
					else
						s="$s [$v]"
					fi
				fi
			done
		done
	fi
	for i in $(seq 1 $ARGS_cnt);do
		v="${ARGS_short[$i]}|${ARGS_long[$i]}"
		[[ "${ARGS_haveVal[$i]}" = "Y" ]] && v="$v ${ARGS_vars[$i]}"
		if [[ "${ARGS_mandatory[$i]}" = "Y" ]];then
			l="$l $v"
		else
			l="$l [$v]"
		fi
	done
	[ -n "$ARGS_info" ] && echo "$ARGS_info"
	echo $l
	is.set ARGS_short_cmd && echo $s
	for i in $(seq 1 $ARGS_cnt);do
		v="${ARGS_short[$i]}|${ARGS_long[$i]}"
		[[ "${ARGS_haveVal[$i]}" = "Y" ]] && v="$v ${ARGS_vars[$i]}"
		printf "%-25s: %s\n" "$v" "${ARGS_desc[$i]}"
	done
	for i in $(seq 1 $ARGS_cnt);do
		if [[ "${ARGS_option[$i]}" = "Y" ]];then
			echo;echo "Available values for ${ARGS_vars[$i]}:";n=0
			for j in $(eval "echo \${ARGS_values_${ARGS_vars[$i]}[*]}");do
				l=$(eval "echo \${ARGS_desc_${ARGS_vars[$i]}[$n]}")
				n=$(( $n +1 ))
				printf "%-25s: %s\n" "$j" "$l"
			done
		fi
	done
	echo
}
args.parse() {
	local f=0
	out.init
	if [ $# -gt 0 ] && [[ "$1" == -* ]];then
		while [ $# -gt 0 ];do
			f=0
			for i in $(seq 1 $ARGS_cnt);do
				case "$1" in
				${ARGS_short[$i]}|${ARGS_long[$i]})
					if [[ "${ARGS_vars[$i]}" = "ARGS_help" ]];then
						args.help
						exit 0
					elif [[ "${ARGS_haveVal[$i]}" != "Y" ]];then
						eval "${ARGS_vars[$i]}=Y"
						ARGS_mandatory[$i]='N'
						f=1
					elif [ $# -lt 2 ];then
						out.error "$1 expect a value"
						args.help
						exit 1
					elif [[ "${ARGS_option[$i]}" = "Y" ]];then
						for j in $(eval "echo \${ARGS_values_${ARGS_vars[$i]}[*]}");do
							[[ "$2" = "$j" ]] && f=1
						done
						if [ $f -eq 0 ];then
							out.error "\"$2\" is an invalid value for \"$1\""
							args.help
							exit 1
						fi
						eval "${ARGS_vars[$i]}=\"$2\"";
						ARGS_mandatory[$i]='N'
						shift
					else
						eval "${ARGS_vars[$i]}=\"$2\"";
						ARGS_mandatory[$i]='N'
						f=1
						shift
					fi;;
				esac
			done
			if [ $f -eq 0 ];then
				out.error "Unknown flag \"$1\""
				args.help
				exit 1
			fi
			shift
		done
	elif [ $# -gt 0 ] && is.set ARGS_short_cmd;then
		ARGS_tmp=("${ARGS_short_cmd[@]}")
		while is.set ARGS_tmp;do 
			v=${ARGS_tmp[0]};ARGS_tmp=("${ARGS_tmp[@]:1}")
			for i in $(seq 1 $ARGS_cnt);do
				if [[ "${ARGS_vars[$i]}" == "$v" ]];then
					ARGS_mandatory[$i]='N'
					if [[ "${ARGS_option[$i]}" = "Y" ]];then
						f=0
						for j in $(eval "echo \${ARGS_values_${ARGS_vars[$i]}[*]}");do
							[[ "$1" = "$j" ]] && f=1
						done
						if [ $f -eq 0 ];then
							out.error "\"$1\" is an invalid value for \"$v\""
							args.help
							exit 1
						fi
					fi
					if is.set ARGS_tmp;then
						eval "${ARGS_vars[$i]}=\"$1\"";
					else
						eval "${ARGS_vars[$i]}=\"$*\"";
					fi
					shift
				fi
			done
		done
	fi
	f=0
	for i in $(seq 1 $ARGS_cnt);do
		if [[ "${ARGS_mandatory[$i]}" = "Y" ]];then
			f=1
			out.error "flag ${ARGS_long[$i]} should be used"
			args.help
			exit 3
		fi
	done
}

################################################################################
###
##	install functions
#
install() {
	local j
	local n=0
	local l
	for j in ${ARGS_values_ACTION[*]};do
		[[ "$j" = "install" ]] && return 0;
		l=${ARGS_desc_ACTION[$n]}
		n=$(( $n +1 ))
		out.task "$l"
		$j
		if [ $? -eq 0 ];then
			out.ok "$l"
		else
			out.fail "$l"
			return 1
		fi
	done
}
chroot.mount() {
	if awk -v D="$DEST/rootfs$1" 'BEGIN{R=1}$2==D{R=0}END{exit R}'</etc/mtab;then
		out.info "$1 already mounted, skipping"
	else
		out.cmd mount --bind $1 $DEST/rootfs$1
	fi
}
chroot.umount() {
	if awk -v D="$DEST/rootfs$1" 'BEGIN{R=1}$2==D{R=0}END{exit R}'</etc/mtab;then
		out.cmd umount $DEST/rootfs$1
	fi
}
chroot.cmd() {
	unset LD_PRELOAD;export LANG=C;
	chroot.mount /dev
	chroot.mount /dev/pts
#	chroot.mount /proc
	out.cmd chroot $DEST/rootfs "$@"
	chroot.umount /dev/pts
	chroot.umount /dev
	chroot.umount /proc
}

apt_install() {
	export DEBIAN_FRONTEND=noninteractive
	out.cmd apt-get -y install crossbuild-essential-armhf qemu binfmt-support qemu-user-static squashfs-tools
	local RET=$?
	unset DEBIAN_FRONTEND
	return $RET
}

rootfs.get() {
	mkdir -p $DEST
	if [ -e $DEST/pyra-rootfs.tgz ];then
		out.info "$DEST/pyra-rootfs.tgz exist"
		out.notice "step skipped"
	else
		out.cmd wget -O $DEST/pyra-rootfs.tgz $SRC
	fi
}

rootfs.extract() {
	mkdir -p $DEST/rootfs
	if [ -d $DEST/rootfs/usr/share/pyra/scripts ];then
		out.info "the rootfs looks extracted, skipping"
	else
		out.cmd tar -C $DEST/rootfs -xf $DEST/pyra-rootfs.tgz
	fi
}

rootfs.prepare() {
	out.cmd cp /usr/bin/qemu-arm-static $DEST/rootfs/usr/bin/
	out.cmd cp /etc/resolv.conf $DEST/rootfs/etc/resolv.conf
	out.cmd chown root:root $DEST/rootfs/tmp
	out.cmd chmod 1777 $DEST/rootfs/tmp
}
rootfs.fix() {
	local la pc d
	for la in $(find $DEST/rootfs -type f -name '*.la');do
		sed -i "s#libdir='/usr/lib#libdir='$DEST/rootfs/usr/lib#g" $la
	done
	for d in $(find $DEST/rootfs -name pkgconfig -type d);do
		for pc in $(find $d -name '*pc');do
			sed -i "s#prefix=/usr\$#prefix=$DEST/rootfs/usr#g;s#libdir=/usr/lib#libdir=$DEST/rootfs/usr/lib#g;s#includedir=/usr/include#includedir=$DEST/rootfs/usr/include#g" $pc
		done
	done
	mkdir -p $DEST/bin
	for f in $(find $DEST/rootfs/usr/bin -type f -name "*-config");do 
		if file $f|grep -q shell;then 
			cp -f $f $DEST/bin
			sed -i "s#prefix=/usr\$#prefix=$DEST/rootfs/usr#g;s#libdir=/usr/lib#libdir=$DEST/rootfs/usr/lib#g;s#includedir=/usr/include#includedir=$DEST/rootfs/usr/include#g" "$DEST/bin/$(basename $f)"
		fi
	done
	for f in $(find $DEST/rootfs/usr/lib/arm-linux-gnueabihf -type l);do 
		[ ! -e $f ] && ln -sf "../../..$(readlink $f)" "$f"
	done
	for f in $DEST/rootfs/etc/alternatives/lib*;do
		[ ! -e $f ] && ln -sf "../..$(readlink $f)" "$f"
	done
	for f in $DEST/rootfs/usr/lib/arm-linux-gnueabihf/lib*so;do 
		if [ -h $f ] && [ ! -h $DEST/rootfs/usr/lib/$(basename $f) ] ;then 
			l=$(readlink $f)
			if [[ "$(basename $l)" == "$l" ]];then 
				ln -sf "arm-linux-gnueabihf/$l" "$DEST/rootfs/usr/lib/$(basename $f)"
			elif [[ "$l" = ../* ]];then
				ln -sf "$(echo $l|sed 's#^../##')" "$DEST/rootfs/usr/lib/$(basename $f)"
			fi
		fi
	done
}

pyra_apt() { chroot.cmd apt-get -y "$@"; }
pyra.apt() { pyra_apt $OPTS; }
pyra.update() {		pyra_apt update; }
pyra.upgrade() {	pyra_apt upgrade; }
pyra.build-dep() {	pyra_apt build-dep $OPTS; }
pyra.install() {
	local pkgs=${OPTS:-"build-essential libsdl1.2-dev libsdl-image1.2-dev libsdl-mixer1.2-dev libsdl-net1.2-dev libsdl-ttf2.0-dev libsdl-gfx1.2-dev libsdl2-dev libsdl2-gfx-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-net-dev libsdl2-ttf-dev"}
	pyra_apt install $pkgs
}



################################################################################
###
##	Main script
#

SRC=${SRC:-"http://packages.pyra-handheld.com/images/stretch/pyra-debian-stretch-mate-rootfs.tgz"}
DEST=${DEST:-"$SCRIPT_path"}
OPTS=""
ARGS_info="Pyra toolchain installer for debian"
args.use.help
args.declare DEST -d --dest Y N N "Installation destination (Default: ${DEST})"
args.declare OPTS -o --option Y N N "Optionnal argument for the given task"
args.option.declare ACTION -a --action Y "Task to do"
args.option ACTION apt_install    "Install debian dependencies"
args.option ACTION rootfs.get     "Download the pyra rootfs"
args.option ACTION rootfs.extract "Extract the downloaded file"
args.option ACTION rootfs.prepare "Setup the rootfs for chroot"
args.option ACTION rootfs.fix	  "Correct path in all .la and .pc files and broken symlinks"
args.option ACTION pyra.update	  "Update the pyra rootfs apt database"
args.option ACTION pyra.upgrade	  "Upgrade the pyra rootfs packages"
args.option ACTION pyra.install	  "Install base header files"
args.option ACTION install 	  "Do all the previous steps"
args.option ACTION pyra.apt	  "run apt-get with your OPTS in the rootfs"
args.option ACTION pyra.build-dep "Get the build dependencies for OPTS"
ARGS_short_cmd+=(ACTION OPTS)
args.parse "$@"
[[ "$ACTION" == "install" ]] && OUT_level=WARNING
log.start
$ACTION
log.end