summaryrefslogtreecommitdiff
blob: bb00a9d93c613d925319c487835decd7b55c3926 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# Copyright 1999-2017 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

EAPI=6

: ${CMAKE_MAKEFILE_GENERATOR:=ninja}
# (needed due to CMAKE_BUILD_TYPE != Gentoo)
CMAKE_MIN_VERSION=3.7.0-r1
PYTHON_COMPAT=( python2_7 )

# TODO: fix unnecessary dep on Python upstream
inherit cmake-utils flag-o-matic llvm python-any-r1 toolchain-funcs

DESCRIPTION="Compiler runtime library for clang (built-in part)"
HOMEPAGE="https://llvm.org/"
SRC_URI="https://releases.llvm.org/${PV/_//}/${P/_/}.src.tar.xz"

LICENSE="|| ( UoI-NCSA MIT )"
SLOT="${PV%_*}"
KEYWORDS="amd64 ~arm64 x86"
IUSE="+clang test"

CLANG_SLOT=${SLOT%%.*}
RDEPEND="!=sys-libs/compiler-rt-${SLOT}*:0"
# llvm-4 needed for --cmakedir
DEPEND="
	>=sys-devel/llvm-4
	clang? ( sys-devel/clang )
	test? ( =sys-devel/clang-${PV%_*}*:${CLANG_SLOT} )
	${PYTHON_DEPS}"

S=${WORKDIR}/${P/_/}.src

# least intrusive of all
CMAKE_BUILD_TYPE=RelWithDebInfo

pkg_pretend() {
	if ! use clang && ! tc-is-clang; then
		ewarn "Building using a compiler other than clang may result in broken atomics"
		ewarn "library. Enable USE=clang unless you have a very good reason not to."
	fi
}

pkg_setup() {
	llvm_pkg_setup
	python-any-r1_pkg_setup
}

test_compiler() {
	$(tc-getCC) ${CFLAGS} ${LDFLAGS} "${@}" -o /dev/null -x c - \
		<<<'int main() { return 0; }' &>/dev/null
}

src_configure() {
	# pre-set since we need to pass it to cmake
	BUILD_DIR=${WORKDIR}/${P}_build

	local nolib_flags=( -nodefaultlibs -lc )
	if use clang; then
		local -x CC=${CHOST}-clang
		local -x CXX=${CHOST}-clang++
		# ensure we can use clang before installing compiler-rt
		local -x LDFLAGS="${LDFLAGS} ${nolib_flags[*]}"
		strip-unsupported-flags
	elif ! test_compiler; then
		if test_compiler "${nolib_flags[@]}"; then
			local -x LDFLAGS="${LDFLAGS} ${nolib_flags[*]}"
			ewarn "${CC} seems to lack runtime, trying with ${nolib_flags[*]}"
		fi
	fi

	local mycmakeargs=(
		-DCOMPILER_RT_INSTALL_PATH="${EPREFIX}/usr/lib/clang/${SLOT}"
		# use a build dir structure consistent with install
		# this makes it possible to easily deploy test-friendly clang
		-DCOMPILER_RT_OUTPUT_DIR="${BUILD_DIR}/lib/clang/${SLOT}"

		# currently lit covers only sanitizer tests
		-DCOMPILER_RT_INCLUDE_TESTS=OFF
		-DCOMPILER_RT_BUILD_SANITIZERS=OFF
		-DCOMPILER_RT_BUILD_XRAY=OFF
	)

	cmake-utils_src_configure
}

src_test() {
	# prepare a test compiler
	# copy clang over since resource_dir is located relatively to binary
	# therefore, we can put our new libraries in it
	mkdir -p "${BUILD_DIR}"/lib/{llvm/${CLANG_SLOT}{/bin,$(get_libdir)},clang/${SLOT}/include} || die
	cp "${EPREFIX}"/usr/lib/llvm/${CLANG_SLOT}/bin/clang{,++} \
		"${BUILD_DIR}"/lib/llvm/${CLANG_SLOT}/bin/ || die
	cp "${EPREFIX}/usr/lib/clang/${SLOT}/include"/*.h \
		"${BUILD_DIR}/lib/clang/${SLOT}/include/" || die

	# builtins are not converted to lit yet, so run them manually
	local tests=() f
	cd "${S}"/test/builtins/Unit || die
	while read -r -d '' f; do
		# ppc subdir is unmaintained and lacks proper guards
		# (and ppc builtins do not seem to be used anyway)
		[[ ${f} == ./ppc/* ]] && continue
		# these are special
		[[ ${f} == ./cpu_model_test.c ]] && continue
		[[ ${f} == ./gcc_personality_test.c ]] && continue
		# unsupported
		[[ ${f} == ./trampoline_setup_test.c ]] && continue
		tests+=( "${f%.c}" )
	done < <(find -name '*.c' -print0)

	{
		echo "check: ${tests[*]/#/check-}" &&
		echo ".PHONY: check ${tests[*]/#/check-}" &&
		for f in "${tests[@]}"; do
			echo "check-${f}: ${f}" &&
			echo "	${f}"
		done
	} > Makefile || die

	local ABI
	for ABI in $(get_all_abis); do
		# not supported at all at the moment
		[[ ${ABI} == x32 ]] && continue

		rm -f "${tests[@]}" || die

		einfo "Running tests for ABI=${ABI}"
		# use -k to run all tests even if some fail
		emake -k \
			CC="${BUILD_DIR}/lib/llvm/${CLANG_SLOT}/bin/clang" \
			CFLAGS="$(get_abi_CFLAGS)" \
			CPPFLAGS='-I../../../lib/builtins' \
			LDFLAGS='-rtlib=compiler-rt' \
			LDLIBS='-lm'
	done
}

src_install() {
	cmake-utils_src_install

	# includes are mistakenly installed for all sanitizers and xray
	rm -rf "${ED}"usr/lib/clang/*/include || die
}