# Description: The Rust language with Cargo included.
# URL: https://www.rust-lang.org/
# Maintainer: Danny Rawlins, crux at romster dot me
# Depends on: llvm
# Optional: sccache

name=rust
version=1.48.0
_date=2020-10-08
_rustc=1.47.0
_cargo=0.48.0
_llvm=10.0.1
release=1
source=(
	https://static.rust-lang.org/dist/${name}c-$version-src.tar.xz
	https://static.rust-lang.org/dist/$_date/rust-std-$_rustc-x86_64-unknown-linux-gnu.tar.xz
	https://static.rust-lang.org/dist/$_date/rustc-$_rustc-x86_64-unknown-linux-gnu.tar.xz
	https://static.rust-lang.org/dist/$_date/cargo-$_cargo-x86_64-unknown-linux-gnu.tar.xz
	https://github.com/llvm/llvm-project/releases/download/llvmorg-$_llvm/compiler-rt-$_llvm.src.tar.xz
)

unpack_source() {
	for file in ${source[@]}; do
		case ${file##*/} in
			rustc-${version}-src.tar.xz|compiler-rt-${_llvm}.src.tar.xz)
			echo "Unpacking $(get_filename $file)";
			bsdtar -p -o -C ${SRC} -xf $(get_filename $file) ;;
		*.tar.xz)
			echo "Copying $(get_filename $file)";
			mkdir -p ${SRC}/${name}c-$version-src/build/cache/${_date} || true
			cp $(get_filename $file) ${SRC}/${name}c-$version-src/build/cache/${_date} ;;
		*)
			cp $(get_filename $file) ${SRC} ;;
		esac
	done
}

build() {
	cd "${name}c-$version-src"

	local ERROR
	local DATE="$(awk '/^date: / { print $2 }' src/stage0.txt)"
	local RUSTC="$(awk '/^rustc: / { print $2 }' src/stage0.txt)"
	local CARGO="$(awk '/^cargo: / { print $2 }' src/stage0.txt)"
	if [ "$DATE" != "$_date" ]; then
		printf "\e[031mError: _date $_date != $DATE\033[0m\n"
		ERROR=1
	fi
	if [ "$RUSTC" != "$_rustc" ]; then
		printf "\e[031mError: _rustc $_rustc != $RUSTC\033[0m\n"
		ERROR=1
	fi
	if [ "$CARGO" != "$_cargo" ]; then
		printf "\e[031mError: _cargo $_cargo != $CARGO\033[0m\n"
		ERROR=1
	fi
	[ $ERROR ] && exit 1
	unset DATE RUSTC CARGO ERROR

cat <<- EOF > $SRC/config.toml
	[llvm]
	ninja = true
	link-shared = true

	[install]
	prefix = "/usr"

	[rust]
	channel = "stable"
	rpath = false
	codegen-units-std = 1
	debuginfo-level-std = 2

	[build]
	target = ["x86_64-unknown-linux-gnu", "i686-unknown-linux-gnu"]
	tools = ["cargo", "rls", "clippy", "miri", "rustfmt", "analysis", "src"]
	docs = false
	extended = true
	sanitizers = false
	profiler = true
	vendor = true
	python = "/usr/bin/python3"
	@CARGO@
	@RUST@

	[target.x86_64-unknown-linux-gnu]
	llvm-config = "/usr/bin/llvm-config"
EOF

	if [ -e '/usr/bin/rustc' ]; then
		if [ -z "$(/usr/bin/ldd /usr/bin/rustc | egrep '.*libLLVM.*.so => not found')" ]; then
			sed	-e 's|@CARGO@|cargo = "/usr/bin/cargo"|' \
				-e 's|@RUST@|rustc = "/usr/bin/rustc"|' \
				-i $SRC/config.toml
		else
			sed -e 's|@CARGO@||' -e 's|@RUST@||' -i $SRC/config.toml
			printf "\e[031mllvm broken symlink detected, not using system rust to bootstrap\033[0m\n"
		fi
	else
		sed -e 's|@CARGO@||' -e 's|@RUST@||' -i $SRC/config.toml
	fi

	cat $SRC/config.toml

	mkdir "$PKGMK_SOURCE_DIR/rust" || true
	export CARGO_HOME="$PKGMK_SOURCE_DIR/rust"

        if [ -e '/usr/bin/sccache' ]; then
                export RUSTC_WRAPPER='/usr/bin/sccache'
                export SCCACHE_IDLE_TIMEOUT='1500'
        fi

	export RUST_BACKTRACE=1
	export RUST_COMPILER_RT_ROOT="$SRC/compiler-rt-$_llvm.src"
	/usr/bin/python3 ./x.py build --config="${SRC}"/config.toml -j $(nproc)
	DESTDIR=$PKG /usr/bin/python3 ./x.py --config="${SRC}"/config.toml install

	[ -e '/usr/bin/zsh' ] || rm -r $PKG/usr/share/zsh

	# cleanup
	rm -r $PKG/usr/share/doc
	rm -r $PKG/etc
	rm $PKG/usr/lib/rustlib/{components,manifest-rustc,rust-installer-version,uninstall.sh}

	# Remove analysis data for libs that weren't installed
	local file lib
	while read -rd '' file; do
		lib="${file%.json}.rlib"
		lib="${lib/\/analysis\///lib/}"
		if [[ ! -e $lib ]]; then
			echo "missing '$lib'"
			rm -v "$file"
		fi
	done < <(find "$PKG/usr/lib/rustlib"  -path '*/analysis/*.json' -print0)

	install -d $PKG/etc/revdep.d
	echo "/usr/lib/rustlib/i686-unknown-linux-gnu/lib" > $PKG/etc/revdep.d/rust
}
