# Copyright 1999-2026 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

EAPI=8

# BENTOO-DIVERGENCE: LICENSE - AGPL-3+ alongside Apache-2.0. Upstream
# relicensed the project in 5.00c; ::gentoo still reads Apache-2.0 alone
# because it has not left the 4.x series.
# BENTOO-DIVERGENCE: PATCHES - the same three Gentoo patches ::gentoo fetches
# as a tarball from dev.gentoo.org/~sam/, rebased onto 5.03c and kept in
# files/. That tarball stops at 4.35c and none was published for 5.x, so the
# 2nd SRC_URI would 404.
# BENTOO-DIVERGENCE: IUSE - llvm_slot_22 and python_single_target_python3_15,
# both absent from the 4.35c ebuild. Upstream declares LLVM_TOO_NEW_DEFAULT=23,
# so slot 22 is supported, and it is the slot this host builds with.
# BENTOO-DIVERGENCE: IUSE_DEFAULTS - falls out of the widened LLVM_COMPAT:
# llvm-r2 defaults to the newest listed slot, 22 here against 21 in ::gentoo.
# BENTOO-DIVERGENCE: REQUIRED_USE - generated by python-single-r1 and llvm-r2
# from the two widened ranges above; not written by hand.

LLVM_COMPAT=( {15..22} )
PYTHON_COMPAT=( python3_{11..15} )
inherit flag-o-matic toolchain-funcs llvm-r2 optfeature python-single-r1

DESCRIPTION="Fork of AFL, the popular compile-time instrumentation fuzzer"
HOMEPAGE="https://github.com/AFLplusplus/AFLplusplus"
SRC_URI="https://github.com/AFLplusplus/AFLplusplus/archive/v${PV}.tar.gz -> ${P}.tar.gz"
S="${WORKDIR}"/AFLplusplus-${PV}

# Relicensed in 5.00c: the project as a whole is AGPL-3+, while files that
# could not be switched (and everything compiled into a fuzzing harness)
# stay Apache-2.0.  ::gentoo still carries Apache-2.0 alone because it has
# not left the 4.x series.
LICENSE="AGPL-3+ Apache-2.0"
SLOT="0"
KEYWORDS="~amd64 ~arm64 ~ppc64"
IUSE="test"
REQUIRED_USE="${PYTHON_REQUIRED_USE}"
# Tests involve heavy use of LD_PRELOAD in some cases
# This isn't compatible with sandbox
RESTRICT="test"

RDEPEND="
	${PYTHON_DEPS}
	$(llvm_gen_dep '
		llvm-core/clang:${LLVM_SLOT}=
		llvm-core/llvm:${LLVM_SLOT}=
	')
	!app-forensics/afl
"
DEPEND="
	${RDEPEND}
	test? ( dev-util/cmocka )
"

QA_FLAGS_IGNORED="
	usr/lib.*/afl/afl-gcc-cmplog-pass.so
	usr/lib.*/afl/afl-gcc-cmptrs-pass.so
"
QA_PREBUILT="usr/share/afl/testcases/others/elf/small_exec.elf"

# ::gentoo ships these three as a patchset tarball hosted on
# dev.gentoo.org/~sam/, which stops at 4.35c -- there is none for the 5.x
# series.  They are rebased here and kept in ${FILESDIR} so the package does
# not depend on a distfile nobody regenerates.  Rebase them on every bump.
PATCHES=(
	"${FILESDIR}"/${P}-respect-flags.patch
	"${FILESDIR}"/${P}-makefile-errors.patch
	"${FILESDIR}"/${P}-test-instr-flags.patch
)

pkg_setup() {
	llvm-r2_pkg_setup
	python-single-r1_pkg_setup
}

mymake() {
	# afl-fuzz spews garbage to stdout if the environment contains any
	# variables whose name beginning with USE_ (including the underscore),
	# regardless of their value (even if empty!).  The ebuild environment
	# contains several such variables and the garbage that gets printed
	# ends up in the generated man page.
	#
	# We can work around the problem by unsetting all these variables when
	# running make.
	local badvars=("${!USE_@}")

	env "${badvars[@]/#/-u}" emake -Onone \
		CC="$(tc-getCC)" \
		CXX="$(tc-getCXX)" \
		CFLAGS_FLTO="" \
		PREFIX="${EPREFIX}/usr" \
		HELPER_PATH="${EPREFIX}/usr/$(get_libdir)/afl" \
		DOC_PATH="${EPREFIX}/usr/share/doc/${PF}" \
		MAN_PATH="${EPREFIX}/usr/share/man/man8" \
		"$@"
}

src_compile() {
	# bug #945258
	append-cflags -std=gnu17

	strip-unsupported-flags
	CC=clang CXX=clang++ strip-unsupported-flags

	mymake
}

src_test() {
	mymake test
}

src_install() {
	mymake DESTDIR="${D}" install
	dostrip -x /usr/share/afl/testcases/
}

pkg_postinst() {
	# TODO: Any others?
	optfeature "fuzzing with AFL_USE_ASAN" llvm-runtimes/compiler-rt-sanitizers[asan]
	optfeature "fuzzing with AFL_USE_MSAN" llvm-runtimes/compiler-rt-sanitizers[msan]
}