1 # Copyright 1999-2020 Gentoo Authors
2 # Distributed under the terms of the GNU General Public License v2
6 PYTHON_COMPAT=( python{2_7,3_{6,7}} )
7 inherit cmake-multilib llvm llvm.org multiprocessing python-any-r1 \
10 DESCRIPTION="New implementation of the C++ standard library, targeting C++11"
11 HOMEPAGE="https://libcxx.llvm.org/"
12 LLVM_COMPONENTS=( libcxx )
15 LICENSE="Apache-2.0-with-LLVM-exceptions || ( UoI-NCSA MIT )"
17 KEYWORDS="~amd64 ~arm ~arm64 ~x86"
18 IUSE="elibc_glibc elibc_musl +libcxxabi libcxxrt +libunwind +static-libs test"
19 REQUIRED_USE="libunwind? ( || ( libcxxabi libcxxrt ) )
20 ?? ( libcxxabi libcxxrt )"
21 RESTRICT="!test? ( test )"
24 libcxxabi? ( ~sys-libs/libcxxabi-${PV}[libunwind=,static-libs?,${MULTILIB_USEDEP}] )
25 libcxxrt? ( sys-libs/libcxxrt[libunwind=,static-libs?,${MULTILIB_USEDEP}] )
26 !libcxxabi? ( !libcxxrt? ( >=sys-devel/gcc-4.7:=[cxx] ) )"
27 # llvm-6 for new lit options
28 # clang-3.9.0 installs necessary target symlinks unconditionally
29 # which removes the need for MULTILIB_USEDEP
33 test? ( >=sys-devel/clang-3.9.0
34 $(python_gen_any_dep 'dev-python/lit[${PYTHON_USEDEP}]') )"
39 # Add link flag "-Wl,-z,defs" to avoid underlinking; this is needed in a
41 "${FILESDIR}/${PN}-3.9-cmake-link-flags.patch"
44 # least intrusive of all
45 CMAKE_BUILD_TYPE=RelWithDebInfo
48 has_version "dev-python/lit[${PYTHON_USEDEP}]"
53 use test && python-any-r1_pkg_setup
55 if ! use libcxxabi && ! use libcxxrt && ! tc-is-gcc ; then
56 eerror "To build ${PN} against libsupc++, you have to use gcc. Other"
57 eerror "compilers are not supported. Please set CC=gcc and CXX=g++"
58 eerror "and try again."
61 if tc-is-gcc && [[ $(gcc-version) < 4.7 ]] ; then
62 eerror "${PN} needs to be built with gcc-4.7 or later (or other"
63 eerror "conformant compilers). Please use gcc-config to switch to"
64 eerror "gcc-4.7 or later version."
70 $(tc-getCXX) ${CXXFLAGS} ${LDFLAGS} "${@}" -o /dev/null -x c++ - \
71 <<<'int main() { return 0; }' &>/dev/null
75 # note: we need to do this before multilib kicks in since it will
77 local cxxabi cxxabi_incs
78 if use libcxxabi; then
80 cxxabi_incs="${EPREFIX}/usr/include/libcxxabi"
81 elif use libcxxrt; then
83 cxxabi_incs="${EPREFIX}/usr/include/libcxxrt"
85 local gcc_inc="${EPREFIX}/usr/lib/gcc/${CHOST}/$(gcc-fullversion)/include/g++-v$(gcc-major-version)"
87 cxxabi_incs="${gcc_inc};${gcc_inc}/${CHOST}"
90 multilib-minimal_src_configure
93 multilib_src_configure() {
94 # we want -lgcc_s for unwinder, and for compiler runtime when using
95 # gcc, clang with gcc runtime (or any unknown compiler)
96 local extra_libs=() want_gcc_s=ON want_compiler_rt=OFF
97 if use libunwind; then
98 # work-around missing -lunwind upstream
99 extra_libs+=( -lunwind )
100 # if we're using libunwind and clang with compiler-rt, we want
101 # to link to compiler-rt instead of -lgcc_s
103 local compiler_rt=$($(tc-getCC) ${CFLAGS} ${CPPFLAGS} \
104 ${LDFLAGS} -print-libgcc-file-name)
105 if [[ ${compiler_rt} == *libclang_rt* ]]; then
108 extra_libs+=( "${compiler_rt}" )
113 # bootstrap: cmake is unhappy if compiler can't link to stdlib
114 local nolib_flags=( -nodefaultlibs -lc )
115 if ! test_compiler; then
116 if test_compiler "${nolib_flags[@]}"; then
117 local -x LDFLAGS="${LDFLAGS} ${nolib_flags[*]}"
118 ewarn "${CXX} seems to lack runtime, trying with ${nolib_flags[*]}"
122 local libdir=$(get_libdir)
124 -DLIBCXX_LIBDIR_SUFFIX=${libdir#lib}
125 -DLIBCXX_ENABLE_SHARED=ON
126 -DLIBCXX_ENABLE_STATIC=$(usex static-libs)
127 -DLIBCXX_CXX_ABI=${cxxabi}
128 -DLIBCXX_CXX_ABI_INCLUDE_PATHS=${cxxabi_incs}
129 # we're using our own mechanism for generating linker scripts
130 -DLIBCXX_ENABLE_ABI_LINKER_SCRIPT=OFF
131 -DLIBCXX_HAS_MUSL_LIBC=$(usex elibc_musl)
132 -DLIBCXX_HAS_GCC_S_LIB=${want_gcc_s}
133 -DLIBCXX_INCLUDE_TESTS=$(usex test)
134 -DLIBCXX_USE_COMPILER_RT=${want_compiler_rt}
135 -DCMAKE_SHARED_LINKER_FLAGS="${extra_libs[*]} ${LDFLAGS}"
139 local clang_path=$(type -P "${CHOST:+${CHOST}-}clang" 2>/dev/null)
140 local jobs=${LIT_JOBS:-$(makeopts_jobs "${MAKEOPTS}" "$(get_nproc)")}
142 [[ -n ${clang_path} ]] || die "Unable to find ${CHOST}-clang for tests"
145 -DLLVM_EXTERNAL_LIT="${EPREFIX}/usr/bin/lit"
146 -DLLVM_LIT_ARGS="-vv;-j;${jobs};--param=cxx_under_test=${clang_path}"
149 cmake-utils_src_configure
152 multilib_src_test() {
153 local -x LIT_PRESERVES_TMP=1
154 cmake-utils_src_make check-libcxx
160 output_format=$($(tc-getCC) ${CFLAGS} ${LDFLAGS} -Wl,--verbose 2>&1 | sed -n 's/^OUTPUT_FORMAT("\([^"]*\)",.*/\1/p')
161 [[ -n ${output_format} ]] && output_format="OUTPUT_FORMAT ( ${output_format} )"
165 Include missing dependencies
172 gen_static_ldscript() {
173 local libdir=$(get_libdir)
174 local cxxabi_lib=$(usex libcxxabi "libc++abi.a" "$(usex libcxxrt "libcxxrt.a" "libsupc++.a")")
177 mv "${ED}/usr/${libdir}/libc++.a" "${ED}/usr/${libdir}/libc++_static.a" || die
178 # Generate libc++.a ldscript for inclusion of its dependencies so that
179 # clang++ -stdlib=libc++ -static works out of the box.
180 local deps="libc++_static.a ${cxxabi_lib} $(usex libunwind libunwind.a libgcc_eh.a)"
181 # On Linux/glibc it does not link without libpthread or libdl. It is
183 use elibc_glibc && deps+=" libpthread.a libdl.a"
185 gen_ldscript "${deps}" > "${ED}/usr/${libdir}/libc++.a" || die
188 gen_shared_ldscript() {
189 local libdir=$(get_libdir)
190 # libsupc++ doesn't have a shared version
191 local cxxabi_lib=$(usex libcxxabi "libc++abi.so" "$(usex libcxxrt "libcxxrt.so" "libsupc++.a")")
193 mv "${ED}/usr/${libdir}/libc++.so" "${ED}/usr/${libdir}/libc++_shared.so" || die
194 local deps="libc++_shared.so ${cxxabi_lib} $(usex libunwind libunwind.so libgcc_s.so)"
196 gen_ldscript "${deps}" > "${ED}/usr/${libdir}/libc++.so" || die
199 multilib_src_install() {
200 cmake-utils_src_install
202 use static-libs && gen_static_ldscript
206 elog "This package (${PN}) is mainly intended as a replacement for the C++"
207 elog "standard library when using clang."
208 elog "To use it, instead of libstdc++, use:"
209 elog " clang++ -stdlib=libc++"
210 elog "to compile your C++ programs."