# A Linux TARGET
# $Id: T_linux,v 1.68 2021/03/08 08:55:28 tlaronde Exp $
#
# Copyright 2004--2013, 2016--2017, 2019--2021 Thierry LARONDE <tlaronde@polynum.com>
# Copyright 2016 Mark van Atten, for Debian adaptations.
#
# Public Domain

# Some variables may be redefined by user conf because there is not
# one Linux system: Linux is just the kernel, and the userland varies...
#
# These idiosynchrasies are interspersed since values explicitely
# set by user shall be left alone.
#
# Everything can be, for new variations or even more strange context,
# overwritten by setting the variables in conf before calling.
#

#----- TARGET environment dependent
TARGET="linux"
TARGET_RELEASE=${TARGET_RELEASE:-$(uname -r)}
TARGET_ARCH=${TARGET_ARCH:-$(uname -p)}
TARGET_MACHINE=${TARGET_MACHINE:-$(uname -m)}
TARGET_TYPE="unix"
TARGET_SUBTYPE=${TARGET_SUBTYPE:-} # set after
TARGET_2D_TYPE="x11"
TARGET_NCPU=${TARGET_NCPU:-1}

#
# Trying to infer SUBTYPE if not set. "GENERIC" should be used if this
# smartness is not wanted. This only works with MATRIX == TARGET.
#
# Android (termux) has to be chrooted for not sys libraries (libc in
# android proper FSH). Raspbian has other pecularities.
#
if test "x$TARGET_SUBTYPE" = x; then
	# only on newer with systemd. Systemd dependent.
	if test -s /etc/os-release; then
		TARGET_SUBTYPE="$(sed -n 's/^ID=\([^ ]*\) *$/\1/p' /etc/os-release)"
	elif test -d /system/etc; then
		TARGET_SUBTYPE=android
	elif test -s /etc/slackware-version; then
		TARGET_SUBTYPE=slackware
	elif test -s /etc/fedora-release; then
		TARGET_SUBTYPE=fedora
	elif test -s /etc/gentoo-release; then
		TARGET_SUBTYPE=gentoo
	elif test -s /etc/debian_version; then
		TARGET_SUBTYPE=debian
	elif test -s /etc/alpine-release; then
		TARGET_SUBTYPE=alpine
	fi
fi

test "x$TARGET_SUBTYPE" != x || TARGET_SUBTYPE=GENERIC

# Multi-arch problem: mixing 64 and 32 bits. This is not the
# cross-compilation case and the "native" arch is not mandatorily in
# /lib: x86_64 is in lib64/ for example, with a special Debian case.
# We indeed adjust for all the subtypes.
#
case $TARGET_SUBTYPE in
	raspbian)
		# The libc needs supplement bits that are set in a ld script,
		# this script being in /usr/lib/arm-linux-gnueabifh, the real
		# library being in /lib/arm-linux-gnueabihf. So we put 
		# /usr/lib before /lib...
		#
		SYS_LIB_PATH=${SYS_LIB_PATH:-"/usr/lib/arm-linux-gnueabihf:/lib/arm-linux-gnueabihf"}
		LIB_SEARCH_PATH="SYS:/usr/local/lib:/usr/local/lib/arm-linux-gnueabihf:/opt/lib:/opt/lib/arm-linux-gnueabihf"
		TARGET_2D_TYPE=dumb2D # static calls dynamic X11
		;;
	android)
		SYS_LIB_PATH=${SYS_LIB_PATH:-"/system/lib64:/system/lib:$PREFIX/lib64:$PREFIX/lib:$PREFIX/usr/lib64:$PREFIX/usr/lib"}
		LIB_SEARCH_PATH="SYS:$PREFIX/usr/local/lib64:$PREFIX/usr/local/lib:$PREFIX/opt/lib64:$PREFIX/opt/lib"
		: ${TMPDIR:=$PREFIX/tmp} # to avoid having to set in calling scripts.
		TARGET_2D_TYPE=dumb2D # static calls dynamic X11
		;;
	*) case $TARGET_MACHINE in
		amd64|x86_64|armv8?|aarch64) # Debian special ${ARCH}-linux-gnu FSH.
			#
			SYS_LIB_PATH=${SYS_LIB_PATH:-"/usr/lib64:/usr/lib/${TARGET_MACHINE}-linux-gnu:/usr/lib/arm-linux-gnueabihf:/usr/lib:/lib64:/lib"}
			LIB_SEARCH_PATH="SYS:/usr/local/lib64:/usr/local/lib/${TARGET_MACHINE}-linux-gnu:/usr/local/lib/arm-linux-gnueabihf:/opt/lib64:/opt/lib/${TARGET_MACHINE}-linux-gnu:/opt/lib/arm-linux-gnueabihf"
			;;
		i?86|x86|x86_32|armv7?) SYS_LIB_PATH=${SYS_LIB_PATH:-"/lib:/lib32:/usr/lib:/usr/lib32:/lib/${TARGET_MACHINE}-linux-gnu:/usr/lib/${TARGET_MACHINE}-linux-gnu"}
			LIB_SEARCH_PATH="SYS:/usr/local/lib:/usr/local/lib32:/opt/lib:/opt/lib32:/usr/local/lib/${TARGET_MACHINE}-linux-gnu:/opt/lib/${TARGET_MACHINE}-linux-gnu"
			;;
		*) SYS_LIB_PATH=${SYS_LIB_PATH:-"/lib:/lib/${TARGET_MACHINE}-linux-gnu:/usr/lib:/usr/lib/${TARGET_MACHINE}-linux-gnu"}
			LIB_SEARCH_PATH="SYS:/usr/local/lib:/usr/local/lib/${TARGET_MACHINE}-linux-gnu:/opt/lib:/opt/lib/${TARGET_MACHINE}-linux-gnu"
			;;
		esac
		;;
esac

# HEADER will be searched in directories deduced from SYS_LIB_PATH too.
#
	HEADER_SEARCH_PATH="SYS"

OBJECT_FORMAT="ELF"

# What kind of libraries are supported? static, sshared (static shared),
# dshared (dynamic shared), or unset if use default.
LIB_TYPES="static dshared"

# The substitution expression for translating rkcomp
# fixed library naming scheme in the host supported one. 
# static lib
LIB_A_TR='-e s!\(lib[^/][^/]*\)__\([0-9.][0-9.]*\)!\1.a.\2!'
LIB_A_TR="$LIB_A_TR "'-e s!\(lib[^/][^/]*\)__$!\1.a!'
LIB_A_TR="$LIB_A_TR "'-e s!\(lib[^/][^/]*\)__\([^0-9.]\)!\1.a\2!'

# The dynamic shared lib name.
# We take into account the fact that a lib can be not versionned.
# So we keep all the :<version> and removed the `:` if it exists.
LIB_DSH_TR='-e s!\(lib[^/][^/]*\)__\([0-9.][0-9.]*\)!\1.so.\2!'
LIB_DSH_TR="$LIB_DSH_TR "'-e s!\(lib[^/][^/]*\)__$!\1.so!'
LIB_DSH_TR="$LIB_DSH_TR "'-e s!\(lib[^/][^/]*\)__\([^0-9.]\)!\1.so\2!'

# Standard libes shall be mapped
CLIB=${CLIB:-"libc__ stdio.h"}
MATHLIB=${MATHLIB:-"libm__ math.h"}
YACCLIB=${YACCLIB:-"liby__ NULL"}
LEXLIB=${LEXLIB:-"libl__ NULL"}

# POSIX XSI extensions
ICONVLIB="NULL iconv.h" # CLIB
RK_PTY_TYPE=PTY_UNIX98

# Some libraries may need to be linked in a dynamically linked program
# since they call functions only in a dynamically linked CLIB.
#
DO_NOT_MAKE_STATIC=

# Some libraries must not be used static even if provided (libdl...).
# But this is OS dependent, not user configurable.
#
DO_NOT_USE_STATIC_LIBES=
if test $TARGET_SUBTYPE = raspbian; then
	DO_NOT_USE_STATIC_LIBES=$CLIB
fi

# C99
HAVE_VSNPRINTF=YES

# Allow unprivileged install.
#
case $TARGET_SUBTYPE in
	debian|raspbian) USER0=${USER0:-root}; GROUP0=${GROUP0:-sudo};;
	android) USER0=${USER0:-$(id -un)}; GROUP0=${GROUP0:-$(id -gn)};;
	*) USER0=${USER0:-root}; GROUP0=${GROUP0:-wheel};;
esac

case $TARGET_SUBTYPE in
	android) TARGETOPTDIR=${TARGETOPTDIR:-$PREFIX/../home}
		TARGETSHELL="$PREFIX/bin/sh";;
	*) TARGETOPTDIR=${TARGETOPTDIR:-/usr/local}
		TARGETSHELL="/bin/sh";;
esac
TARGETRMDIR="rmdir"
TARGETLIBDIR="$TARGETOPTDIR/share"
TARGETBINDIR="$TARGETOPTDIR/bin"
TARGETSBINDIR="$TARGETOPTDIR/sbin"
case $TARGET_SUBTYPE in
	alpine) TARGETDOCDIR="$TARGETOPTDIR/share";;
	*) TARGETDOCDIR="$TARGETOPTDIR/share/doc";;
esac
TARGETTMPDIR="/tmp"
SYSTEM_ENCODING=RK_ICONV_ASCII
T_DIR_SEP="/"
T_PATH_SEP=":"

# Map ftn so called with all fields and args i.e $# == 7.
# ck_status is global and shall be set to non 0 (rkconfig debugging)
# and nothing echoed.
#

# The man related functions are independant from the rootdir where the
# hierarchy of manpages is rooted.

# Tmandir() used in map for setting correct man section subdir.
#
# dst=some_dir/{0,*}
#   -> some_dir/man/ if basename == 0,
#   -> some_dir/man/man$basename if basename != 0.
#
Tmandir()
{
	if test $# -ne 7; then
		log "Incorrect Tmandir ftn call with '$*'"
		ck_status=1
		return
	fi
	 
	action="$1"; ftype="$2"; owner="$3"; mod="$4"; src="$5"; dst="$6";
	# args ignored.

  	rootdir=$(dirname $dst)
	section=$(basename $dst)
  	if test $section -eq 0; then
    	dst="$rootdir/man"
  	else
    	dst="$rootdir/man/man$section"
	fi

	echo "$action" "$ftype" "$owner" "$mod" "$src" "$dst"
}

# Qualifying the files. Add the subdir and the suffix to the file.
# Map substitution ftn (see above).
#
# dst=rootdir/section/manpage
#
Tman()
{
	if test $# -ne 7; then
		log "Incorrect Tman ftn call with '$*'"
		ck_status=1
		return
	fi
	 
	action="$1"; ftype="$2"; owner="$3"; mod="$4"; src="$5"; dst="$6";
	# args ignored.

	manpage=$(basename $dst)
	rootdir=$(dirname $dst)
	section=$(basename $rootdir)
	if test "x$section" = x; then
		log "Incorrect $0 ftn call with '$*'"
		ck_status=1
		return
	fi

	rootdir=$(dirname $rootdir)
	if test $section -eq 0; then
		dst="$rootdir/man/$manpage"
	else
		dst="$rootdir/man/man$section/$manpage.$section"
	fi

	echo "$action" "$ftype" "$owner" "$mod" "$src" "$dst"
}


# For now, the default librkcompsh version for explicating libraries map
# instructions will do.
# It is used only at rkconfig() time, not on the TARGET (but is TARGET
# dependant via the regexp).
#
Tlibexpl()
{
	rk_expl_lib "$@"
}
