# Template file for 'boost'
pkgname=boost
version=1.91.0
revision=1
hostmakedepends="which bzip2-devel icu-devel python3-devel pkg-config"
makedepends="zlib-devel bzip2-devel icu-devel python3-devel liblzma-devel libzstd-devel"
checkdepends="openssl-devel libpng-devel libjpeg-turbo-devel"
short_desc="Free peer-reviewed portable C++ source libraries"
maintainer="John <me@johnnynator.dev>"
license="BSL-1.0"
homepage="https://www.boost.org/"
distfiles="https://archives.boost.io/release/${version%.rc*}/source/boost_${version//./_}.tar.bz2"
checksum=de5e6b0e4913395c6bdfa90537febd9028ea4c0735d2cdb0cd9b45d5f51264f5
python_version=3
noverifyrdeps=yes

# please do NOT delete below lines,
# upgrade boost requires patching a lot of software,
# which requires months of planning
if [ "${version%beta*}" != "$version" ]; then
	_version=${version/beta/b}
	distfiles="https://archives.boost.io/beta/${version}/source/boost_${_version//./_}.tar.bz2"
fi

replaces="libboost_program_options1.80>=0 libboost_math_c99f1.80>=0
 libboost_stacktrace_basic1.80>=0 libboost_stacktrace_noop1.80>=0
 libboost_stacktrace_basic>=0 libboost_stacktrace_noop>=0
 libboost_iostreams1.80>=0 libboost_math_tr1l1.80>=0 libboost_filesystem1.80>=0
 libboost_chrono1.80>=0 libboost_math_tr1f1.80>=0 libboost_wave1.80>=0
 libboost_graph1.80>=0 libboost_locale1.80>=0 libboost_regex1.80>=0
 libboost_fiber1.80>=0 libboost_type_erasure1.80>=0 libboost_coroutine1.80>=0
 libboost_atomic1.80>=0 libboost_prg_exec_monitor1.80>=0 libboost_math_c991.80>=0
 boost-python3-1.80>=0 libboost_log_setup1.80>=0 libboost_json1.80>=0
 libboost_timer1.80>=0 libboost_system1.80>=0 libboost_system>=0
 libboost_unit_test_framework1.80>=0
 libboost_serialization1.80>=0 libboost_math_tr11.80>=0
 libboost_math_c99l1.80>=0 boost-python1.80>=0 libboost_contract1.80>=0
 libboost_date_time1.80>=0 libboost_log1.80>=0 libboost_random1.80>=0
 libboost_thread1.80>=0 libboost_container1.80>=0
 libboost_wserialization1.80>=0 libboost_context1.80>=0
 libboost_stacktrace_from_exception>=0
 libboost_stacktrace_addr2line>=0
 libboost_stacktrace_addr2line1.80>=0"

_minimal_deps=" boost-build boost-headers
 libboost_atomic libboost_chrono libboost_container libboost_charconv
 libboost_context libboost_contract libboost_coroutine libboost_date_time
 libboost_fiber libboost_filesystem libboost_graph
 libboost_iostreams libboost_locale libboost_log libboost_log_setup
 libboost_json libboost_nowide libboost_prg_exec_monitor
 libboost_process libboost_program_options
 libboost_random libboost_regex libboost_serialization
 libboost_thread libboost_timer libboost_type_erasure
 libboost_math_c99 libboost_math_c99f libboost_math_tr1 libboost_math_tr1f
 libboost_unit_test_framework libboost_url libboost_wave libboost_wserialization"

# on glibc ppc, boost.math disables long double stuff because of
# non-ieee754-conforming long double type (IBM double-double)
#
# this does not affect musl (where long double is 64-bit)
#
case "$XBPS_TARGET_MACHINE" in
	ppc64le|ppc64|ppc|ppcle) ;;
	*) _minimal_deps+=" libboost_math_c99l libboost_math_tr1l";;
esac
subpackages="${_minimal_deps}"

case "$XBPS_TARGET_MACHINE" in
	i686*|x86_64*|ppc64le)
		makedepends+=" libquadmath-devel"
		;;
esac

if [ "$XBPS_TARGET_LIBC" = musl ]; then
	makedepends+=" libucontext-devel"
	LDFLAGS+=" -lucontext"
else
	makedepends+=" libbacktrace"
fi

_bst_except=off
case "$XBPS_TARGET_MACHINE" in
	x86_64*)
		_bst_except=on
		# subpackages+=" libboost_stacktrace_from_exception"
		;;
esac

case "$XBPS_TARGET_MACHINE" in
	i686*)    _arch=x86;      _abi=sysv  ;;
	x86_64*)  _arch=x86;      _abi=sysv  ;;
	arm*)     _arch=arm;      _abi=aapcs ;;
	aarch64*) _arch=arm;      _abi=aapcs ;;
	mips*)    _arch=mips32r2; _abi=o32   ;;
	ppc*)     _arch=power;    _abi=sysv  ;;
	riscv64*) _arch=riscv;    _abi=sysv  ;;
esac

case "$XBPS_TARGET_MACHINE" in
	x86_64*|aarch64*|ppc64*|riscv64*)
		hostmakedepends+=" openmpi"
		makedepends+=" openmpi-devel"
		subpackages+=" libboost_mpi"
		subpackages+=" libboost_mpi-python3"
		subpackages+=" libboost_graph_parallel"
		;;
esac

# Must be last subpackages
_boost_devel_depends="${subpackages/ libboost_mpi-python3 / }"
_boost_devel_depends+=" boost-devel-minimal"
subpackages+=" boost-python3 boost-devel-minimal boost-devel"

pre_patch() {
	mkdir include
	ln -sf ../boost include
}

do_configure() {
	# bootstrap.sh will reset CXX and CXXFLAGS (L229)
	./bootstrap.sh --with-toolset=gcc \
		--prefix=${DESTDIR}/usr --with-python=/usr/bin/python3 \
		--with-python-root=${XBPS_CROSS_BASE}/usr
	cat > user-config.jam <<-EOF
	using gcc : : ${CXX} : <cxxflags>"${CXXFLAGS}" <linkflags>"${LDFLAGS}" <warnings-as-errors>"off" ;
	using mpi ;
	using python : ${py3_ver} : /usr/bin/python3 : ${XBPS_CROSS_BASE}/${py3_inc} : ${XBPS_CROSS_BASE}/${py3_lib} ;

	EOF
}

do_build() {
	# Rebuild bjam for target
	# toolset gcc will force gcc -x c++ -O2 -s
	# toolset cxx will use CXX and CXXFLAGS
	cd tools/build/src/engine
	CXXFLAGS="$CXXFLAGS -fdebug-prefix-map=$PWD=. $LDFLAGS" \
	CXX_VERSION_OPT=--version ./build.sh cxx

	cd $wrksrc
	./b2 ${makejobs} \
		--user-config=${wrksrc}/user-config.jam \
		--toolset=gcc abi=${_abi} architecture=${_arch} \
		python=${py3_ver} release \
		boost.stacktrace.from_exception=${_bst_except} \
		cxxflags="${CXXFLAGS}" linkflags="${LDFLAGS}" \
		threading=multi runtime-link=shared link=shared,static
}

do_check() {
	local _testcase _component
	local _ignore="contract graph"
	# Too heavy
	_ignore+=" math"
	_ignore+=" multiprecision"
	_ignore+=" mpi"
	_ignore+=" geometry"
	# requires clang
	rm -f libs/hana/test/experimental/type_name.cpp
	# https://github.com/open-mpi/ompi/issues/7330
	export OMPI_MCA_plm_rsh_agent=
	# Seems to fail on everything but x86_64,
	# because of floating point comparision
	if [ "$XBPS_TARGET_MACHINE" != x86_64 ]; then
		_ignore+=" geometry"
	fi
	if [ "$XBPS_TARGET_LIBC" = musl ]; then
		# locale things
		_ignore+=" locale serialization"
	fi

	# No idea what is wrong
	_ignore+=" python"
	# Wanna find main in stacktrace,
	_ignore+=" stacktrace"

	# required by boost::math
	mkdir -p .temps
	local _skip=
	local _last=
	for _testcase in libs/*/test/; do
		_testcase=${_testcase%/test/}
		_component=${_testcase#libs/}
		if [ -z "$_last$_skip" ]; then
			:
		elif [ "$_component" = "$_last" ]; then
			unset _last
		else
			continue
		fi
		case " $_ignore " in
		*" $_component "*)
			continue ;;
		esac
		_component="boost::$_component"
		msg_normal "Testing: $_component\n"
		./b2 ${makejobs} $_testcase/test \
			--user-config=${wrksrc}/user-config.jam \
			--toolset=gcc abi=${_abi} architecture=${_arch} \
			boost.stacktrace.from_exception=${_bst_except} \
			python=${py3_ver} release warnings-as-errors=off \
			cxxflags="${CXXFLAGS}" linkflags="${LDFLAGS}" \
			threading=multi ||
		msg_error "do_check: ${_component}: failure\n"
	done
}

do_install() {
	# Install headers/libs
	# - disable boost.stacktrace because everyone is using headers only
	#   those libraries are only for decoration
	./b2 --prefix=${DESTDIR}/usr abi=${_abi} architecture=${_arch} \
		--user-config=${wrksrc}/user-config.jam \
		cxxflags="${CXXFLAGS}" linkflags="${LDFLAGS}" \
		python=${py3_ver} release \
		boost.stacktrace.noop=off \
		boost.stacktrace.backtrace=off \
		boost.stacktrace.addr2line=off \
		boost.stacktrace.basic=off \
		boost.stacktrace.from_exception=off \
		threading=multi runtime-link=shared link=shared,static \
		install

	# Install Boost.Build stuff.
	# XXX: make bjam a compat symlink to b2
	vbin tools/build/src/engine/b2
	ln -sf b2 "$DESTDIR/usr/bin/bjam"
	vmkdir usr/share
	rm -rf ${DESTDIR}/usr/share/b2
	cp -a ${wrksrc}/tools/build ${DESTDIR}/usr/share/b2
	find ${DESTDIR}/usr/share/b2 \
		-type f -name \*.orig -exec rm -f {} \;
	rm -rf ${DESTDIR}/usr/share/b2/src/engine/bootstrap
	rm -rf ${DESTDIR}/usr/share/b2/src/engine/{b2,bjam}
	cat <<-'EOF' >${wrksrc}/site-config.jam
	# System wide configuration file for Boost.Build.'
	#
	using gcc ;
	EOF
	cd $wrksrc
	vconf site-config.jam

	# license, not required for binary distribution
	# but required for source distribution
	vlicense LICENSE_1_0.txt
}

boost-python3_package() {
	depends="python3"
	shlib_requires="libpython${py3_ver}${py3_abiver}.so.1.0"
	short_desc+=" - Python3 bindings"
	pkg_install() {
		vmove "usr/lib/libboost_python3*.so.*"
	}
}

boost-build_package() {
	depends="boost"
	conf_files="/etc/site-config.jam"
	short_desc+=" - Boost.Build utility and framework"
	provides="boost-jam-${version}_${revision}"
	replaces="boost-jam<${version}_${revision}"
	pkg_install() {
		vmove usr/bin/b2
		vmove usr/bin/bjam
		vmove usr/share/b2
		# vmove usr/share/boost_predef
		vmove etc/site-config.jam
	}
}

boost-headers_package() {
	noverifyrdeps=yes
	nostrip=yes
	short_desc+=" header only"
	pkg_install() {
		vmove usr/include
		vmove "usr/lib/cmake/Boost*"
		vmove "usr/lib/cmake/boost_headers-*"
	}
}


boost-devel-minimal_package() {
	depends="boost ${_minimal_deps}"
	noverifyrdeps=yes
	nostrip=yes
	short_desc+=" - development files"
	pkg_install() {
		vmove usr/lib/cmake
		vmove "usr/lib/*.so"
		vmove "usr/lib/libboost_test_exec_monitor.a"
	}
}

boost-devel_package() {
	short_desc+=" - development files - full"
	depends="${_boost_devel_depends}"
	pkg_install() {
		vmove "usr/lib/*.a"
	}
}

libboost_atomic_package() {
	short_desc+=" - libboost_atomic"
	pkg_install() {
		vmove "usr/lib/libboost_atomic.so.*"
	}
}

libboost_charconv_package() {
	short_desc+=" - libboost_charconv"
	pkg_install() {
		vmove "usr/lib/libboost_charconv.so.*"
	}
}

libboost_chrono_package() {
	short_desc+=" - libboost_chrono"
	pkg_install() {
		vmove "usr/lib/libboost_chrono.so.*"
	}
}

libboost_container_package() {
	short_desc+=" - libboost_container"
	pkg_install() {
		vmove "usr/lib/libboost_container.so.*"
	}
}

libboost_context_package() {
	short_desc+=" - libboost_context"
	pkg_install() {
		vmove "usr/lib/libboost_context.so.*"
	}
}

libboost_contract_package() {
	short_desc+=" - libboost_contract"
	pkg_install() {
		vmove "usr/lib/libboost_contract.so.*"
	}
}

libboost_coroutine_package() {
	short_desc+=" - libboost_coroutine"
	pkg_install() {
		vmove "usr/lib/libboost_coroutine.so.*"
	}
}

libboost_date_time_package() {
	short_desc+=" - libboost_date_time"
	pkg_install() {
		vmove "usr/lib/libboost_date_time.so.*"
	}
}

libboost_fiber_package() {
	short_desc+=" - libboost_fiber"
	pkg_install() {
		vmove "usr/lib/libboost_fiber.so.*"
	}
}

libboost_filesystem_package() {
	short_desc+=" - libboost_filesystem"
	pkg_install() {
		vmove "usr/lib/libboost_filesystem.so.*"
	}
}

libboost_graph_package() {
	short_desc+=" - libboost_graph"
	pkg_install() {
		vmove "usr/lib/libboost_graph.so.*"
	}
}

libboost_graph_parallel_package() {
	short_desc+=" - libboost_graph_parallel"
	pkg_install() {
		vmove "usr/lib/libboost_graph_parallel.so.*"
	}
}

libboost_iostreams_package() {
	short_desc+=" - libboost_iostreams"
	pkg_install() {
		vmove "usr/lib/libboost_iostreams.so.*"
	}
}

libboost_json_package() {
	short_desc+=" - libboost_json"
	pkg_install() {
		vmove "usr/lib/libboost_json.so.*"
	}
}

libboost_locale_package() {
	short_desc+=" - libboost_locale"
	pkg_install() {
		vmove "usr/lib/libboost_locale.so.*"
	}
}

libboost_log_package() {
	short_desc+=" - libboost_log"
	pkg_install() {
		vmove "usr/lib/libboost_log.so.*"
	}
}

libboost_log_setup_package() {
	short_desc+=" - libboost_log_setup"
	pkg_install() {
		vmove "usr/lib/libboost_log_setup.so.*"
	}
}

libboost_math_c99_package() {
	short_desc+=" - libboost_math_c99"
	pkg_install() {
		vmove "usr/lib/libboost_math_c99.so.*"
	}
}

libboost_math_c99f_package() {
	short_desc+=" - libboost_math_c99f"
	pkg_install() {
		vmove "usr/lib/libboost_math_c99f.so.*"
	}
}

libboost_math_c99l_package() {
	short_desc+=" - libboost_math_c99l"
	pkg_install() {
		vmove "usr/lib/libboost_math_c99l.so.*"
	}
}

libboost_math_tr1_package() {
	short_desc+=" - libboost_math_tr1"
	pkg_install() {
		vmove "usr/lib/libboost_math_tr1.so.*"
	}
}

libboost_math_tr1f_package() {
	short_desc+=" - libboost_math_tr1f"
	pkg_install() {
		vmove "usr/lib/libboost_math_tr1f.so.*"
	}
}

libboost_math_tr1l_package() {
	short_desc+=" - libboost_math_tr1l"
	pkg_install() {
		vmove "usr/lib/libboost_math_tr1l.so.*"
	}
}

libboost_mpi_package() {
	short_desc+=" - libboost_mpi"
	pkg_install() {
		vmove "usr/lib/libboost_mpi.so.*"
	}
}
libboost_mpi-python3_package() {
	short_desc+=" - libboost_mpi - Python 3 bindings"
	shlib_requires="libpython${py3_ver}${py3_abiver}.so.1.0"
	pkg_install() {
		vmove "usr/lib/libboost_mpi_python3*.so.*"
		vmove "usr/lib/boost-python${py3_ver}/mpi.so"
	}
}

libboost_nowide_package() {
	short_desc+=" - libboost_nowide"
	pkg_install() {
		vmove "usr/lib/libboost_nowide.so.*"
	}
}

libboost_prg_exec_monitor_package() {
	short_desc+=" - libboost_prg_exec_monitor"
	pkg_install() {
		vmove "usr/lib/libboost_prg_exec_monitor.so.*"
	}
}

libboost_process_package() {
	short_desc+=" - libboost_process"
	pkg_install() {
		vmove "usr/lib/libboost_process.so.*"
	}
}

libboost_program_options_package() {
	short_desc+=" - libboost_program_options"
	pkg_install() {
		vmove "usr/lib/libboost_program_options.so.*"
	}
}

libboost_random_package() {
	short_desc+=" - libboost_random"
	pkg_install() {
		vmove "usr/lib/libboost_random.so.*"
	}
}

libboost_regex_package() {
	short_desc+=" - libboost_regex"
	pkg_install() {
		vmove "usr/lib/libboost_regex.so.*"
	}
}

libboost_serialization_package() {
	short_desc+=" - libboost_serialization"
	pkg_install() {
		vmove "usr/lib/libboost_serialization.so.*"
	}
}

libboost_thread_package() {
	short_desc+=" - libboost_thread"
	pkg_install() {
		vmove "usr/lib/libboost_thread.so.*"
	}
}

libboost_timer_package() {
	short_desc+=" - libboost_timer"
	pkg_install() {
		vmove "usr/lib/libboost_timer.so.*"
	}
}

libboost_type_erasure_package() {
	short_desc+=" - libboost_type_erasure"
	pkg_install() {
		vmove "usr/lib/libboost_type_erasure.so.*"
	}
}

libboost_unit_test_framework_package() {
	short_desc+=" - libboost_unit_test_framework"
	pkg_install() {
		vmove "usr/lib/libboost_unit_test_framework.so.*"
	}
}

libboost_url_package() {
	short_desc+=" - libboost_url"
	pkg_install() {
		vmove "usr/lib/libboost_url.so.*"
	}
}

libboost_wave_package() {
	short_desc+=" - libboost_wave"
	pkg_install() {
		vmove "usr/lib/libboost_wave.so.*"
	}
}

libboost_wserialization_package() {
	short_desc+=" - libboost_wserialization"
	pkg_install() {
		vmove "usr/lib/libboost_wserialization.so.*"
	}
}
