################################################################################
#
# cross.cygclass - for building cross-compiled packages
#
# Part of cygport - Cygwin packaging application
# Copyright (C) 2006-2015 Yaakov Selkowitz
# Provided by the Cygwin Ports project <http://sourceware.org/cygwinports/>
#
# cygport 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 3 of the License, or
# (at your option) any later version.
#
# cygport 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 cygport.  If not, see <http://www.gnu.org/licenses/>.
#
################################################################################

#****h* Cygclasses/cross.cygclass
#  SYNOPSIS
#  CROSS_HOST="..."
#  inherit cross
#  DESCRIPTION
#  This cygclass assists in building libraries to be used by "cross-compilers",
#  which generate code to be run on a different platform (the "host" system)
#  then the one on which it was built (and, in most cases, NOT on the build
#  system), but can be used on the build system to cross-compile other software
#  which depends on it.
#
#  Supported build systems for cross-compiling are autotools, cmake, qmake, and
#  custom Makefiles.  When using cross.cygclass, cygconf, cygcmake, and cygqmake4
#  automatically use the necessary arguments for cross-compiling, and cyginstall
#  and most of the do* and new* installation functions install into the sysroot
#  instead of the native root.  Note that those installation functions which
#  accept an absolute path (dodir, exeinto, insinto, dosym) make no assumptions
#  about the sysroot.
#****

#****v* cross.cygclass/CROSS_HOST
#  DESCRIPTION
#  The CPU-VENDOR-OS[-TOOLCHAIN] triplet, or customary abbreviation thereof,
#  describing the system for which you are cross-compiling; for example:
#  * i686-linux [i686-pc-linux-gnu]: i686 GNU/Linux
#  * x86_64-w64-mingw32: Win64
#  * arm-eabi [arm-unknown-eabi]: Embedded ARM ELF system (e.g. with Newlib)
#  * avr [avr-unknown-none]: Atmel AVR bare metal (e.g. Arduino)
#  Note that while 'unknown' vendor tags are often omitted, particularly in
#  conjunction with a 'none' OS tag, as above, this does not apply to e.g.
#  'armv7hl-unknown-linux-gnueabi' and other systems.
#  NOTES
#  * CROSS_HOST must be defined before inherit()ing cross.cygclass.
#  * CROSS_HOST must match the prefix of the toolchain being used (in other
#    words, the TOOLCHAIN_TARGET used for building said toolchain).
#****
if ! defined CROSS_HOST
then
	error "CROSS_HOST must be defined before 'inherit cross'"
fi

__check_triplet ${CROSS_HOST}
CHOST=${CROSS_HOST}
CTARGET=${CHOST}
ARCH=noarch
unset ARCH_i686 ARCH_x86_64


#****d* cross.cygclass/CROSS_SYSROOT
#  DESCRIPTION
#  GCC cross-compilers provide the concept of a sysroot: a directory which
#  acts as the virtual root of the target filesystem, resulting in
#  CROSS_SYSROOT/$prefix/include and CROSS_SYSROOT/$prefix/lib being in the
#  default search paths without requiring -I or -L flags.
#
#  This means that software natively compiled for the host system can be
#  unpacked into the sysroot and used for cross-compiling.  This is
#  especially useful when bootstrapping a new toolchain; e.g. for Linux, one
#  can just download glibc and kernel headers packages from a Linux distro,
#  unpack them into the CROSS_SYSROOT, and use those to build a cross-GCC
#  for the first time.
#
#  If you do use natively-compiled host packages under the sysroot, you must
#  fix paths in all *-config scripts, .la libtool libraries, and .pc
#  pkg-config files so they do not erroneously point to Cygwin-native
#  headers and libraries.
#****
CROSS_SYSROOT="/usr/${CHOST}/sys-root"

#****d* cross.cygclass/CROSS_PREFIX
#  DESCRIPTION
#  The $prefix directory under the sysroot.  This definition is meant to
#  be used in configure or cmake arguments to avoid dealing with different
#  prefixes on various systems.
#****
CROSS_PREFIX="$(__host_prefix)"

#****d* cross.cygclass/CROSS_BINDIR
#  DESCRIPTION
#  The $prefix/bin directory under the sysroot.  This definition is meant to
#  be used in configure or cmake arguments to avoid dealing with different
#  prefixes on various systems.
#****
CROSS_BINDIR="$(__host_prefix)/bin"

#****d* cross.cygclass/CROSS_INCLUDEDIR
#  DESCRIPTION
#  The $prefix/include directory under the sysroot.  This definition is
#  meant to be used in configure or cmake arguments to avoid dealing with
#  different prefixes on various systems.
#****
CROSS_INCLUDEDIR="$(__host_prefix)/include"

#****d* cross.cygclass/CROSS_LIBDIR
#  DESCRIPTION
#  The $prefix/lib directory under the sysroot.  This definition is meant to
#  be used in configure or cmake arguments to avoid dealing with different
#  prefixes on various systems.
#****
CROSS_LIBDIR="$(__host_prefix)/lib"

#****d* cross.cygclass/CROSS_DATADIR
#  DESCRIPTION
#  The $prefix/share directory under the sysroot.  This definition is meant to
#  be used in configure or cmake arguments to avoid dealing with different
#  prefixes on various systems.
#****
CROSS_DATADIR="$(__host_prefix)/share"

CC="${CHOST}-gcc"
CXX="${CHOST}-g++"
F77="${CHOST}-gfortran"
FC="${CHOST}-gfortran"
GCJ="${CHOST}-gcj"
GOC="${CHOST}-gccgo"
OBJC="${CHOST}-gcc"
OBJCXX="${CHOST}-g++"
PKG_CONFIG="${CHOST}-pkg-config"

CC_SYSROOT=$(${CC} -print-sysroot)

# native binutils do not install $host- prefixed equivalents, so we must not
# prefix them when "crossbacking" (e.g. building i686-cygwin sysroot libs on
# i686-cygwin for use on x86_64-cygwin)
if cross_compiling
then
	AR="${CHOST}-ar"
	NM="${CHOST}-nm"
	OBJDUMP="${CHOST}-objdump"
	RANLIB="${CHOST}-ranlib"
	STRIP="${CHOST}-strip"
fi

# windres is not provided for all platforms
case ${CHOST} in
*-cygwin*|*-mingw*|*-msys*|*-*-pe*|*-wince*|*-cegcc*|*-netbsdpe)
	if cross_compiling
	then
		DLLTOOL="${CHOST}-dlltool"
		RC="${CHOST}-windres"
	fi ;;
*)	DLLTOOL="false"
	RC="false"
	;;
esac

case ${CHOST} in
*-*-mingw*)
	# GCC since 4.7 uses -mms-bitfields by default
	;;
*-*-linux-gnu)
	LDFLAGS="${LDFLAGS} -Wl,--as-needed -Wl,--no-undefined"
	;;
esac

if ! check_tool gcc || ! check_tool strip
then
	error "This package requires ${CHOST} binutils and gcc"
fi

#****I* cross.cygclass/doelflib
#  SYNOPSIS
#  doelflib libfoo.so.X.Y.Z [...]
#  DESCRIPTION
#  Installs the given ELF libraries into the CROSS_SYSROOT libdir and creates
#  the symlinks for the SONAME (usually .so.X) and the link library (.so).
#  NOTE
#  Only the real library file should be passed to doelflib, not the symlinks
#  usually created in the build directory.
#****
doelflib() {
	local clibdir="$(__host_prefix)/lib"
	local i soname sonames

	dodir ${clibdir}

	for i
	do
		if [ ! -e ${i} ]
		then
			error "file ${i} does not exist"
		fi

		case ${i##*/} in
		*.so*)	;;
		*)	error "doelflib: ${i}: not an ELF shared object" ;;
		esac

		soname=$(${OBJDUMP} -p ${i} | sed -n -e 's| *SONAME *\([^ ]*\).*|\1|gp')

		# try to catch mistaken "doelflib libfoo.so*"
		if echo "${sonames}" | grep -q ${soname}
		then
			error "SONAME ${soname} has already been installed"
		else
			sonames+=" ${soname} "
		fi

		__doinstall 0755 ${i} ${clibdir} || error "doelflib ${i} failed"

		if test ${i##*/} != ${soname}
		then
			dosym ${i##*/} ${clibdir}/${soname}
		fi
		if test ${soname%.so*}.so != ${soname}
		then
			dosym ${i##*/} ${clibdir}/${soname%.so*}.so
		fi
	done
}

#****I* cross.cygclass/cross_sysrootize
#  SYNOPSIS
#  cross_sysrootize FILE [FILE] ...
#  DESCRIPTION
#  Adds CROSS_SYSROOT to all paths in given text file(s).  Paths should
#  be specified as if on the system, without a leading $D.
#****
cross_sysrootize(){
	local f
	local prefix=$(__target_prefix)

	for f in ${@}
	do
		if [ ! -e ${D}${f#${D}} ]
		then
			error "cross_sysrootize: $f: file not found"
		fi

		# the [^t] should catch paths already containing the sysroot
		sed -i -e "s|\([^t]\)${prefix}|\1${CROSS_PREFIX}|g" ${D}${f#${D}} || error "$FUNCNAME: $f: sed failed"
	done
}

#****I* cross.cygclass/cross_desysrootize
#  SYNOPSIS
#  cross_desysrootize FILE [FILE] ...
#  DESCRIPTION
#  Removes CROSS_SYSROOT from all paths in given text file(s).  Paths should
#  be specified as if on the system, without a leading $D.
#****
cross_desysrootize(){
	local f

	for f in ${@}
	do
		if [ ! -e ${D}${f#${D}} ]
		then
			error "cross_desysrootize: $f: file not found"
		fi

		sed -i -e "s|${CROSS_SYSROOT}||g" ${D}${f#${D}} || error "$FUNCNAME: $f: sed failed"
	done
}

readonly -f doelflib cross_sysrootize cross_desysrootize
