sys-libs/uclibc-ng: 1.0.32 stable on arm
[gentoo.git] / sys-libs / uclibc-ng / uclibc-ng-1.0.32.ebuild
1 # Copyright 1999-2020 Gentoo Authors
2 # Distributed under the terms of the GNU General Public License v2
3
4 EAPI="7"
5
6 inherit flag-o-matic multilib savedconfig toolchain-funcs
7
8 if [[ ${PV} == "9999" ]] ; then
9         EGIT_REPO_URI="git://uclibc-ng.org/git/uclibc-ng"
10         inherit git-r3
11         MY_P=uclibc-ng-${PV}
12 else
13         MY_P=uClibc-ng-${PV}
14 fi
15
16 DESCRIPTION="C library for developing embedded Linux systems"
17 HOMEPAGE="https://uclibc-ng.org/"
18 if [[ ${PV} != "9999" ]] ; then
19         PATCH_VER=""
20         SRC_URI="https://downloads.uclibc-ng.org/releases/${PV}/${MY_P}.tar.bz2"
21         KEYWORDS="-* amd64 arm ~mips ppc x86"
22 fi
23
24 LICENSE="LGPL-2"
25 SLOT="0"
26 IUSE="debug hardened iconv ipv6 symlink-compat headers-only"
27 # tests fail due to unusual makefile
28 RESTRICT="strip test"
29
30 # 1) We can't upgrade from uclibc to uclibc-ng via a soft blocker since portage
31 #    will delete the ld.so sym link prematurely and break the system. So we
32 #    will hard block and give manual migration instructions.
33 # 2) Currently uclibc and uclibc-ng's iconv are in bad shape.  We've been using
34 #    the breakout library.  The disadvantage here is that we have to sprinkle
35 #    LDFAGS=-liconv on build systems that need to link against libiconv.
36 RDEPEND="
37         !!sys-libs/uclibc
38         iconv? ( dev-libs/libiconv )"
39
40 S=${WORKDIR}/${MY_P}
41
42 export CBUILD=${CBUILD:-${CHOST}}
43 export CTARGET=${CTARGET:-${CHOST}}
44 if [[ ${CHOST} == ${CTARGET} ]] ; then
45         if [[ ${CATEGORY} == cross-* ]] ; then
46                 export CTARGET=${CATEGORY#cross-}
47         fi
48 fi
49
50 is_crosscompile() {
51         [[ ${CHOST} != ${CTARGET} ]]
52 }
53
54 alt_build_kprefix() {
55         if [[ ${CBUILD} == ${CHOST} && ${CHOST} == ${CTARGET} ]] ; then
56                 echo /usr/include
57         else
58                 echo /usr/${CTARGET}/usr/include
59         fi
60 }
61
62 just_headers() {
63         use headers-only && is_crosscompile
64 }
65
66 uclibc_endian() {
67         # XXX: this wont work for a toolchain which is bi-endian, but we
68         #      dont have any such thing at the moment, so not a big deal
69         touch "${T}"/endian.s
70         $(tc-getAS ${CTARGET}) "${T}"/endian.s -o "${T}"/endian.o
71         case $(file "${T}"/endian.o) in
72                 *" MSB "*) echo "BIG";;
73                 *" LSB "*) echo "LITTLE";;
74                 *)         echo "NFC";;
75         esac
76         rm -f "${T}"/endian.{s,o}
77 }
78
79 kconfig_q_opt() {
80         local flag=$1; shift
81         case ${flag} in
82                 y|n) ;;
83                 *) flag=$(usex ${flag} y n) ;;
84         esac
85
86         local var="defs_${flag}"
87         eval "${var}+=( $* )"
88 }
89
90 get_opt() {
91         (
92         unset ${1}
93         . ${2:-"${S}"/.config}
94         echo ${!1}
95         )
96 }
97
98 make_oldconfig() {
99         yes "" 2>/dev/null | emake -s oldconfig >/dev/null
100 }
101
102 make_config() {
103         restore_config .config
104         if [ -f .config ]; then
105                 make_oldconfig
106                 return 0
107         else
108                 ewarn "Could not locate user configfile, so we will save a default one"
109         fi
110
111         emake ARCH=$1 defconfig >/dev/null
112
113         local defs_{y,n}
114
115         # These are forced off
116         defs_n=(
117                 DOASSERTS
118                 DODEBUG_PT
119                 HAS_NO_THREADS
120                 PROPOLICE_BLOCK_ABRT
121                 SSP_QUICK_CANARY
122                 SUPPORT_LD_DEBUG_EARLY
123                 UCLIBC_HAS_CTYPE_UNSAFE
124                 UCLIBC_HAS_LOCALE
125                 LDSO_SAFE_RUNPATH
126         )
127
128         # These are forced on
129         defs_y=(
130                 DO_C99_MATH
131                 DO_XSI_MATH
132                 FORCE_SHAREABLE_TEXT_SEGMENTS
133                 LDSO_GNU_HASH_SUPPORT
134                 LDSO_PRELOAD_FILE_SUPPORT
135                 LDSO_RUNPATH
136                 LDSO_RUNPATH_OF_EXECUTABLE
137                 LDSO_STANDALONE_SUPPORT
138                 PROPOLICE_BLOCK_SEGV
139                 PTHREADS_DEBUG_SUPPORT
140                 UCLIBC_HAS_ARC4RANDOM
141                 UCLIBC_HAS_BACKTRACE
142                 UCLIBC_HAS_BSD_RES_CLOSE
143                 UCLIBC_HAS_CONTEXT_FUNCS
144                 UCLIBC_HAS_CTYPE_CHECKED
145                 UCLIBC_HAS_EXTRA_COMPAT_RES_STATE
146                 UCLIBC_HAS_FENV
147                 UCLIBC_HAS_FOPEN_CLOSEEXEC_MODE
148                 UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE
149                 UCLIBC_HAS_FOPEN_LARGEFILE_MODE
150                 UCLIBC_HAS_FTS
151                 UCLIBC_HAS_FTW
152                 UCLIBC_HAS_GETPT
153                 UCLIBC_HAS_GLIBC_CUSTOM_PRINTF
154                 UCLIBC_HAS_GLIBC_CUSTOM_STREAMS
155                 UCLIBC_HAS_GNU_GLOB
156                 UCLIBC_HAS_HEXADECIMAL_FLOATS
157                 UCLIBC_HAS_LIBUTIL
158                 UCLIBC_HAS_NFTW
159                 UCLIBC_HAS_OBSOLETE_BSD_SIGNAL
160                 UCLIBC_HAS_PRINTF_M_SPEC
161                 UCLIBC_HAS_PROGRAM_INVOCATION_NAME
162                 UCLIBC_HAS_RESOLVER_SUPPORT
163                 UCLIBC_HAS_SHA256_CRYPT_IMPL
164                 UCLIBC_HAS_SHA512_CRYPT_IMPL
165                 UCLIBC_HAS_SSP
166                 UCLIBC_HAS_STUBS
167                 UCLIBC_HAS_SYS_ERRLIST
168                 UCLIBC_HAS_SYS_SIGLIST
169                 UCLIBC_HAS_THREADS_NATIVE
170                 UCLIBC_HAS_TZ_FILE_READ_MANY
171                 UCLIBC_HAS_UTMP
172                 UCLIBC_HAS_UTMPX
173                 UCLIBC_HAS_WCHAR
174                 UCLIBC_HAS_WORDEXP
175                 UCLIBC_NTP_LEGACY
176                 UCLIBC_SUPPORT_AI_ADDRCONFIG
177                 UCLIBC_SUSV2_LEGACY
178                 UCLIBC_SUSV3_LEGACY
179                 UCLIBC_SUSV3_LEGACY_MACROS
180                 UCLIBC_SUSV4_LEGACY
181                 UCLIBC_USE_NETLINK
182         )
183
184         sed -i -e '/ARCH_.*_ENDIAN/d' .config
185         kconfig_q_opt y "ARCH_WANTS_$(uclibc_endian)_ENDIAN"
186
187         kconfig_q_opt debug DODEBUG
188         kconfig_q_opt debug SUPPORT_LD_DEBUG
189         kconfig_q_opt debug UCLIBC_HAS_PROFILING
190
191         kconfig_q_opt ipv6 UCLIBC_HAS_IPV6
192
193         kconfig_q_opt hardened UCLIBC_BUILD_NOEXECSTACK
194         kconfig_q_opt hardened UCLIBC_BUILD_NOW
195         kconfig_q_opt hardened UCLIBC_BUILD_PIE
196         kconfig_q_opt hardened UCLIBC_BUILD_RELRO
197         kconfig_q_opt hardened UCLIBC_BUILD_SSP
198
199         local count def
200         for count in 1 2 ; do
201                 # Run twice as some config opts depend on others being enabled first.
202                 for def in ${defs_y[@]} ; do
203                         sed -i -e "s|.*\<${def}\>.*set|${def}=y|g" .config
204                 done
205                 for def in ${defs_n[@]} ; do
206                         sed -i -e "s|${def}=y|# ${def} is not set|g" .config
207                 done
208                 make_oldconfig
209         done
210
211         einfo "Enabled options:"
212         for def in ${defs_y[@]} ; do
213                 einfo " " $(grep "^${def}=y" .config || echo "could not find ${def}")
214         done
215         einfo "Disabled options:"
216         for def in ${defs_n[@]} ; do
217                 einfo " " $(grep "^# ${def} is not set" .config || echo "could not find ${def}")
218         done
219
220         # setup build and run paths
221         sed -i \
222                 -e "/^CROSS_COMPILER_PREFIX/s|=.*|=\"${CTARGET}-\"|" \
223                 -e "/^KERNEL_HEADERS/s|=.*|=\"$(alt_build_kprefix)\"|" \
224                 -e "/^SHARED_LIB_LOADER_PREFIX/s|=.*|=\"/$(get_libdir)\"|" \
225                 -e "/^DEVEL_PREFIX/s|=.*|=\"/usr\"|" \
226                 -e "/^RUNTIME_PREFIX/s|=.*|=\"/\"|" \
227                 -e "/^UCLIBC_EXTRA_CFLAGS/s|=.*|=\"${UCLIBC_EXTRA_CFLAGS}\"|" \
228                 .config || die
229
230         make_oldconfig
231 }
232
233 pkg_setup() {
234         # Make sure our CHOST is a uclibc toolchain for native compiling
235         if [[ ${CHOST} == ${CTARGET} ]]; then
236                 case ${CHOST} in
237                         *-uclinux*|*-uclibc*) ;;
238                         *) die "Use sys-devel/crossdev to build a uclibc toolchain" ;;
239                 esac
240         fi
241
242         # uClibc-ng doesn't carry old Linux threads, and since we force
243         # threading our only choice is NPTL which requires i486 and later.
244         [[ ${CTARGET} == i386* ]] && die "i386 can't support Native Posix Threads (NPTL)."
245 }
246
247 src_prepare() {
248         local version subversion extraversion
249
250         # uclibc-ng tries to create a two sym link with ld.so,
251         # ld-uClibc.so.{0,MAJOR_VERSION} -> ld-uClibc-<version>.so
252         # where MAJOR_VERSION != 0 indicates the ABI verison.
253         # We want to get rid of this and just have ABI = 0.
254         eapply "${FILESDIR}"/uclibc-compat-r1.patch
255
256         # We need to change the major.minor.sublevel of uclibc-ng.
257         # Upstream sets MAJOR_VERSION = 1 which breaks runtime linking.
258         # If we really want the ABI bump, we'll have to hack the gcc
259         # spec file and change the '*link:' rule.
260         version_0=$(ver_cut 1)
261         version_1=$(ver_cut 2)
262         version_2=$(ver_cut 3)
263         if [[ -z ${version_1} ]]; then
264                 subversion=0
265                 extraversion=0
266         else
267                 subversion=${version_1}
268                 if [[ -z ${version_2} ]]; then
269                         extraversion=0
270                 else
271                         extraversion=.${version_2}
272                 fi
273         fi
274
275         sed -i \
276                 -e "/^MAJOR_VERSION/s|:=.*|:= 0|" \
277                 -e "/^MINOR_VERSION/s|:=.*|:= ${version_0}|" \
278                 -e "/^SUBLEVEL/s|:=.*|:= ${subversion}|" \
279                 -e "/^EXTRAVERSION/s|:=.*|:= ${extraversion}|" \
280                 Rules.mak || die
281
282         eapply_user
283 }
284
285 src_configure() {
286         # Map our toolchain arch name to the name expected by uClibc-ng.
287         local target=$(tc-arch)
288         case ${target} in
289                 amd64) target="x86_64";;
290                 arm)   target="arm";;
291                 mips)  target="mips";;
292                 ppc)   target="powerpc";;
293                 x86)   target="i386";;
294         esac
295
296         # Do arch specific configuration by changing the defaults in
297         # extra/Configs/Config.<arch>.  If these are not overridden
298         # by an save .config, they will be selected by default.
299
300         # For i386, i486, i586 and i686
301         local cpu
302         if [[ ${target} == "i386" ]]; then
303                 [[ ${CTARGET} == i[456]86* ]] && cpu="${CTARGET:1:1}86"
304                 sed -i -e "s|default CONFIG_686|default CONFIG_${cpu:-486}|" \
305                         extra/Configs/Config.i386 || die
306         fi
307
308         # For arm
309         if [[ ${target} == "arm" ]]; then
310                 sed -i -e '/Build for EABI/a \\tdefault y' extra/Configs/Config.arm
311         fi
312
313         # We set HOSTCC to the proper tuple rather than just 'gcc'
314         sed -i -e "s|^HOSTCC.*=.*|HOSTCC=$(tc-getBUILD_CC)|" Rules.mak
315
316         make_config ${target}
317
318         einfo
319         einfo "Runtime Prefix: /"
320         einfo "Devel Prefix:   /usr"
321         einfo "Kernel Prefix:  $(alt_build_kprefix)"
322         einfo "CBUILD:         ${CBUILD}"
323         einfo "CHOST:          ${CHOST}"
324         einfo "CTARGET:        ${CTARGET}"
325         einfo "ABI:            ${ABI}"
326         einfo "ENDIAN:         $(uclibc_endian)"
327         einfo
328 }
329
330 src_compile() {
331         emake headers
332         just_headers && return 0
333
334         emake
335         if is_crosscompile ; then
336                 emake -C utils hostutils
337         else
338                 emake utils
339         fi
340 }
341
342 src_test() {
343         is_crosscompile && return 0
344
345         # assert test fails on pax/grsec enabled kernels
346         # normal vfork test fails in sandbox (both glibc/uclibc)
347         emake UCLIBC_ONLY=1 check
348 }
349
350 src_install() {
351         local sysroot=${D}
352         is_crosscompile && sysroot+="/usr/${CTARGET}"
353
354         local target="install"
355         just_headers && target="install_headers"
356         emake DESTDIR="${sysroot}" ${target}
357
358         save_config .config
359
360         # remove files coming from kernel-headers
361         rm -rf "${sysroot}"/usr/include/{linux,asm*}
362
363         # Make sure we install the sys-include symlink so that when
364         # we build a 2nd stage cross-compiler, gcc finds the target
365         # system headers correctly.  See gcc/doc/gccinstall.info
366         if is_crosscompile ; then
367                 dosym usr/include /usr/${CTARGET}/sys-include
368                 if ! just_headers && [[ -n $(get_opt HAVE_SHARED) ]] ; then
369                         newbin utils/ldconfig.host ${CTARGET}-ldconfig
370                         newbin utils/ldd.host ${CTARGET}-ldd
371                 fi
372                 return 0
373         fi
374
375         if use symlink-compat; then
376                 dosym libc.so.0 "${DESTDIR}"/lib/libcrypt.so.0
377                 dosym libc.so.0 "${DESTDIR}"/lib/libdl.so.0
378                 dosym libc.so.0 "${DESTDIR}"/lib/libm.so.0
379                 dosym libc.so.0 "${DESTDIR}"/lib/libpthread.so.0
380                 dosym libc.so.0 "${DESTDIR}"/lib/librt.so.0
381                 dosym libc.so.0 "${DESTDIR}"/lib/libresolv.so.0
382                 dosym libc.so.0 "${DESTDIR}"/lib/libubacktrace.so.0
383                 dosym libc.so.0 "${DESTDIR}"/lib/libutil.so.0
384         fi
385
386         emake DESTDIR="${D}" install_utils
387         dobin extra/scripts/getent
388         dodoc README docs/*.txt
389 }
390
391 pkg_postinst() {
392         is_crosscompile && return 0
393
394         if [ ! -e "${ROOT}"/etc/TZ ] ; then
395                 ewarn "Please remember to set your timezone in /etc/TZ"
396                 mkdir -p "${ROOT}"/etc
397                 echo "UTC" > "${ROOT}"/etc/TZ
398         fi
399         [ "${ROOT}" != "/" ] && return 0
400         # update cache before reloading init
401         ldconfig
402         # reload init ...
403         /sbin/telinit U 2>/dev/null
404 }