#
# NOTE - When using this class the user is responsible for ensuring that
# TRANSLATED_TARGET_ARCH is added into PN. This ensures that if the TARGET_ARCH
# is changed, another nativesdk xxx-canadian-cross can be installed
#


# SDK packages are built either explicitly by the user,
# or indirectly via dependency.  No need to be in 'world'.
EXCLUDE_FROM_WORLD = "1"
NATIVESDKLIBC ?= "libc-glibc"
LIBCOVERRIDE = ":${NATIVESDKLIBC}"
CLASSOVERRIDE = "class-cross-canadian"
STAGING_BINDIR_TOOLCHAIN = "${STAGING_DIR_NATIVE}${bindir_native}/${SDK_ARCH}${SDK_VENDOR}-${SDK_OS}:${STAGING_DIR_NATIVE}${bindir_native}/${TARGET_ARCH}${TARGET_VENDOR}-${TARGET_OS}"

#
# Update BASE_PACKAGE_ARCH and PACKAGE_ARCHS
#
PACKAGE_ARCH = "${SDK_ARCH}-${SDKPKGSUFFIX}"
BASECANADIANEXTRAOS ?= "linux-musl"
CANADIANEXTRAOS = "${BASECANADIANEXTRAOS}"
CANADIANEXTRAVENDOR = ""
MODIFYTOS ??= "1"
python () {
    archs = d.getVar('PACKAGE_ARCHS').split()
    sdkarchs = []
    for arch in archs:
        sdkarchs.append(arch + '-${SDKPKGSUFFIX}')
    d.setVar('PACKAGE_ARCHS', " ".join(sdkarchs))

    # Allow the following code segment to be disabled, e.g. meta-environment
    if d.getVar("MODIFYTOS") != "1":
        return

    if d.getVar("TCLIBC") in [ 'baremetal', 'newlib' ]:
        return

    tos = d.getVar("TARGET_OS")
    tos_known = ["mingw32"]
    extralibcs = [""]
    if "musl" in d.getVar("BASECANADIANEXTRAOS"):
        extralibcs.append("musl")
    if "android" in tos:
        extralibcs.append("android")
    for variant in ["", "spe", "x32", "eabi", "n32", "_ilp32"]:
        for libc in extralibcs:
            entry = "linux"
            if variant and libc:
                entry = entry + "-" + libc + variant
            elif variant:
                entry = entry + "-gnu" + variant
            elif libc:
                entry = entry + "-" + libc
            tos_known.append(entry)
    if tos not in tos_known:
        bb.fatal("Building cross-candian for an unknown TARGET_SYS (%s), please update cross-canadian.bbclass" % d.getVar("TARGET_SYS"))

    for n in ["PROVIDES", "DEPENDS"]:
        d.setVar(n, d.getVar(n))
    d.setVar("STAGING_BINDIR_TOOLCHAIN", d.getVar("STAGING_BINDIR_TOOLCHAIN"))
    for prefix in ["AR", "AS", "DLLTOOL", "CC", "CXX", "GCC", "LD", "LIPO", "NM", "OBJDUMP", "RANLIB", "STRIP", "WINDRES"]:
        n = prefix + "_FOR_TARGET"
        d.setVar(n, d.getVar(n))
    # This is a bit ugly. We need to zero LIBC/ABI extension which will change TARGET_OS
    # however we need the old value in some variables. We expand those here first.
    tarch = d.getVar("TARGET_ARCH")
    if tarch == "x86_64":
        d.setVar("LIBCEXTENSION", "")
        d.setVar("ABIEXTENSION", "")
        d.appendVar("CANADIANEXTRAOS", " linux-gnux32")
        for extraos in d.getVar("BASECANADIANEXTRAOS").split():
            d.appendVar("CANADIANEXTRAOS", " " + extraos + "x32")
    elif tarch == "powerpc":
        # PowerPC can build "linux" and "linux-gnuspe"
        d.setVar("LIBCEXTENSION", "")
        d.setVar("ABIEXTENSION", "")
        d.appendVar("CANADIANEXTRAOS", " linux-gnuspe")
        for extraos in d.getVar("BASECANADIANEXTRAOS").split():
            d.appendVar("CANADIANEXTRAOS", " " + extraos + "spe")
    elif tarch == "mips64":
        d.appendVar("CANADIANEXTRAOS", " linux-gnun32")
        for extraos in d.getVar("BASECANADIANEXTRAOS").split():
            d.appendVar("CANADIANEXTRAOS", " " + extraos + "n32")
    if tarch == "arm" or tarch == "armeb":
        d.appendVar("CANADIANEXTRAOS", " linux-gnueabi linux-musleabi")
        d.setVar("TARGET_OS", "linux-gnueabi")
    else:
        d.setVar("TARGET_OS", "linux")

    # Also need to handle multilib target vendors
    vendors = d.getVar("CANADIANEXTRAVENDOR")
    if not vendors:
        vendors = all_multilib_tune_values(d, 'TARGET_VENDOR')
    origvendor = d.getVar("TARGET_VENDOR_MULTILIB_ORIGINAL")
    if origvendor:
        d.setVar("TARGET_VENDOR", origvendor)
        if origvendor not in vendors.split():
            vendors = origvendor + " " + vendors
    d.setVar("CANADIANEXTRAVENDOR", vendors)
}
MULTIMACH_TARGET_SYS = "${PACKAGE_ARCH}${HOST_VENDOR}-${HOST_OS}"

INHIBIT_DEFAULT_DEPS = "1"

STAGING_DIR_HOST = "${RECIPE_SYSROOT}"

TOOLCHAIN_OPTIONS = " --sysroot=${RECIPE_SYSROOT}"

PATH:append = ":${TMPDIR}/sysroots/${HOST_ARCH}/${bindir_cross}"
PKGHIST_DIR = "${TMPDIR}/pkghistory/${HOST_ARCH}-${SDKPKGSUFFIX}${HOST_VENDOR}-${HOST_OS}/"

HOST_ARCH = "${SDK_ARCH}"
HOST_VENDOR = "${SDK_VENDOR}"
HOST_OS = "${SDK_OS}"
HOST_PREFIX = "${SDK_PREFIX}"
HOST_CC_ARCH = "${SDK_CC_ARCH}"
HOST_LD_ARCH = "${SDK_LD_ARCH}"
HOST_AS_ARCH = "${SDK_AS_ARCH}"

#assign DPKG_ARCH
DPKG_ARCH = "${@debian_arch_map(d.getVar('SDK_ARCH'), '')}"

CPPFLAGS = "${BUILDSDK_CPPFLAGS}"
CFLAGS = "${BUILDSDK_CFLAGS}"
CXXFLAGS = "${BUILDSDK_CFLAGS}"
LDFLAGS = "${BUILDSDK_LDFLAGS} \
           -Wl,-rpath-link,${STAGING_LIBDIR}/.. \
           -Wl,-rpath,${libdir}/.. "

#
# We need chrpath >= 0.14 to ensure we can deal with 32 and 64 bit
# binaries
#
DEPENDS:append = " chrpath-replacement-native"
EXTRANATIVEPATH += "chrpath-native"

# Path mangling needed by the cross packaging
# Note that we use := here to ensure that libdir and includedir are
# target paths.
target_base_prefix := "${base_prefix}"
target_prefix := "${prefix}"
target_exec_prefix := "${exec_prefix}"
target_base_libdir = "${target_base_prefix}/${baselib}"
target_libdir = "${target_exec_prefix}/${baselib}"
target_includedir := "${includedir}"

# Change to place files in SDKPATH
base_prefix = "${SDKPATHNATIVE}"
prefix = "${SDKPATHNATIVE}${prefix_nativesdk}"
exec_prefix = "${SDKPATHNATIVE}${prefix_nativesdk}"
bindir = "${exec_prefix}/bin/${TARGET_ARCH}${TARGET_VENDOR}-${TARGET_OS}"
sbindir = "${bindir}"
base_bindir = "${bindir}"
base_sbindir = "${bindir}"
libdir = "${exec_prefix}/lib/${TARGET_ARCH}${TARGET_VENDOR}-${TARGET_OS}"
libexecdir = "${exec_prefix}/libexec/${TARGET_ARCH}${TARGET_VENDOR}-${TARGET_OS}"

FILES:${PN} = "${prefix}"

export PKG_CONFIG_DIR = "${STAGING_DIR_HOST}${exec_prefix}/lib/pkgconfig"
export PKG_CONFIG_SYSROOT_DIR = "${STAGING_DIR_HOST}"

do_populate_sysroot[stamp-extra-info] = ""
do_packagedata[stamp-extra-info] = ""

USE_NLS = "${SDKUSE_NLS}"

# We have to us TARGET_ARCH but we care about the absolute value
# and not any particular tune that is enabled.
TARGET_ARCH[vardepsexclude] = "TUNE_ARCH"

PKGDATA_DIR = "${PKGDATA_DIR_SDK}"
# If MLPREFIX is set by multilib code, shlibs
# points to the wrong place so force it
SHLIBSDIRS = "${PKGDATA_DIR}/nativesdk-shlibs2"
SHLIBSWORKDIR = "${PKGDATA_DIR}/nativesdk-shlibs2"

cross_canadian_bindirlinks () {
	for i in linux ${CANADIANEXTRAOS}
	do
		for v in ${CANADIANEXTRAVENDOR}
		do
			d=${D}${bindir}/../${TARGET_ARCH}$v-$i
			if [ -d $d ];
			then
			    continue
			fi
			install -d $d
			for j in `ls ${D}${bindir}`
			do
				p=${TARGET_ARCH}$v-$i-`echo $j | sed -e s,${TARGET_PREFIX},,`
				ln -s ../${TARGET_SYS}/$j $d/$p
			done
		done
       done
}
