2016-11-07 02:19:58 +01:00
################################################################################
# External toolchain package infrastructure
#
# This package infrastructure implements the support for external
# toolchains, i.e toolchains that are available pre-built, ready to
# use. Such toolchain may either be readily available on the Web
# (Linaro, Sourcery CodeBench, from processor vendors) or may be built
# with tools like Crosstool-NG or Buildroot itself. So far, we have
# tested this with:
#
# * Toolchains generated by Crosstool-NG
# * Toolchains generated by Buildroot
# * Toolchains provided by Linaro for the ARM and AArch64
# architectures
# * Sourcery CodeBench toolchains (from Mentor Graphics) for the ARM,
2024-03-06 22:35:58 +01:00
# MIPS, PowerPC, and x86_64 architectures. For the MIPS
2016-11-07 02:19:58 +01:00
# toolchain, the -muclibc variant isn't supported yet, only the
# default glibc-based variant is.
# * Synopsys DesignWare toolchains for ARC cores
#
# The basic principle is the following
#
# 1. If the toolchain is not pre-installed, download and extract it
# in $(TOOLCHAIN_EXTERNAL_INSTALL_DIR). Otherwise,
# $(TOOLCHAIN_EXTERNAL_INSTALL_DIR) points to were the toolchain has
# already been installed by the user.
#
# 2. For all external toolchains, perform some checks on the
# conformity between the toolchain configuration described in the
# Buildroot menuconfig system, and the real configuration of the
# external toolchain. This is for example important to make sure that
# the Buildroot configuration system knows whether the toolchain
# supports RPC, IPv6, locales, large files, etc. Unfortunately, these
# things cannot be detected automatically, since the value of these
# options (such as BR2_TOOLCHAIN_HAS_NATIVE_RPC) are needed at
# configuration time because these options are used as dependencies
# for other options. And at configuration time, we are not able to
# retrieve the external toolchain configuration.
#
# 3. Copy the libraries needed at runtime to the target directory,
# $(TARGET_DIR). Obviously, things such as the C library, the dynamic
# loader and a few other utility libraries are needed if dynamic
# applications are to be executed on the target system.
#
# 4. Copy the libraries and headers to the staging directory. This
# will allow all further calls to gcc to be made using --sysroot
# $(STAGING_DIR), which greatly simplifies the compilation of the
# packages when using external toolchains. So in the end, only the
# cross-compiler binaries remains external, all libraries and headers
# are imported into the Buildroot tree.
#
# 5. Build a toolchain wrapper which executes the external toolchain
# with a number of arguments (sysroot/march/mtune/..) hardcoded,
# so we're sure the correct configuration is always used and the
# toolchain behaves similar to an internal toolchain.
# This toolchain wrapper and symlinks are installed into
2017-07-05 13:14:19 +02:00
# $(HOST_DIR)/bin like for the internal toolchains, and the rest
2016-11-07 02:19:58 +01:00
# of Buildroot is handled identical for the 2 toolchain types.
################################################################################
#
# Definitions of where the toolchain can be found
#
TOOLCHAIN_EXTERNAL_PREFIX = $( call qstrip,$( BR2_TOOLCHAIN_EXTERNAL_PREFIX) )
TOOLCHAIN_EXTERNAL_DOWNLOAD_INSTALL_DIR = $( HOST_DIR) /opt/ext-toolchain
i f e q ( $( BR 2_TOOLCHAIN_EXTERNAL_DOWNLOAD ) , y )
TOOLCHAIN_EXTERNAL_INSTALL_DIR = $( TOOLCHAIN_EXTERNAL_DOWNLOAD_INSTALL_DIR)
e l s e
2021-05-27 16:51:18 +02:00
TOOLCHAIN_EXTERNAL_INSTALL_DIR = $( abspath $( call qstrip,$( BR2_TOOLCHAIN_EXTERNAL_PATH) ) )
2016-11-07 02:19:58 +01:00
e n d i f
i f e q ( $( TOOLCHAIN_EXTERNAL_INSTALL_DIR ) , )
i f n e q ( $( TOOLCHAIN_EXTERNAL_PREFIX ) , )
# if no path set, figure it out from path
2021-10-01 20:08:32 +02:00
TOOLCHAIN_EXTERNAL_BIN := $( dir $( shell which $( TOOLCHAIN_EXTERNAL_PREFIX) -gcc) )
2016-11-07 02:19:58 +01:00
e n d i f
e l s e
2018-03-25 12:18:55 +02:00
TOOLCHAIN_EXTERNAL_REL_BIN_PATH = $( call qstrip,$( BR2_TOOLCHAIN_EXTERNAL_REL_BIN_PATH) )
i f e q ( $( TOOLCHAIN_EXTERNAL_REL_BIN_PATH ) , )
TOOLCHAIN_EXTERNAL_REL_BIN_PATH = bin
e n d i f
TOOLCHAIN_EXTERNAL_BIN = $( TOOLCHAIN_EXTERNAL_INSTALL_DIR) /$( TOOLCHAIN_EXTERNAL_REL_BIN_PATH)
2016-11-07 02:19:58 +01:00
e n d i f
# If this is a buildroot toolchain, it already has a wrapper which we want to
# bypass. Since this is only evaluated after it has been extracted, we can use
# $(wildcard ...) here.
TOOLCHAIN_EXTERNAL_SUFFIX = \
$( if $( wildcard $( TOOLCHAIN_EXTERNAL_BIN) /*.br_real) ,.br_real)
TOOLCHAIN_EXTERNAL_CROSS = $( TOOLCHAIN_EXTERNAL_BIN) /$( TOOLCHAIN_EXTERNAL_PREFIX) -
TOOLCHAIN_EXTERNAL_CC = $( TOOLCHAIN_EXTERNAL_CROSS) gcc$( TOOLCHAIN_EXTERNAL_SUFFIX)
TOOLCHAIN_EXTERNAL_CXX = $( TOOLCHAIN_EXTERNAL_CROSS) g++$( TOOLCHAIN_EXTERNAL_SUFFIX)
2019-11-02 19:00:51 +01:00
TOOLCHAIN_EXTERNAL_GDC = $( TOOLCHAIN_EXTERNAL_CROSS) gdc$( TOOLCHAIN_EXTERNAL_SUFFIX)
2016-11-07 02:19:58 +01:00
TOOLCHAIN_EXTERNAL_FC = $( TOOLCHAIN_EXTERNAL_CROSS) gfortran$( TOOLCHAIN_EXTERNAL_SUFFIX)
2017-03-26 15:14:33 +02:00
TOOLCHAIN_EXTERNAL_READELF = $( TOOLCHAIN_EXTERNAL_CROSS) readelf
2016-11-07 02:19:58 +01:00
2016-11-07 02:19:59 +01:00
# Normal handling of downloaded toolchain tarball extraction.
i f e q ( $( BR 2_TOOLCHAIN_EXTERNAL_DOWNLOAD ) , y )
# As a regular package, the toolchain gets extracted in $(@D), but
# since it's actually a fairly special package, we need it to be moved
# into TOOLCHAIN_EXTERNAL_DOWNLOAD_INSTALL_DIR.
d e f i n e T O O L C H A I N _ E X T E R N A L _ M O V E
rm -rf $( TOOLCHAIN_EXTERNAL_DOWNLOAD_INSTALL_DIR)
mkdir -p $( TOOLCHAIN_EXTERNAL_DOWNLOAD_INSTALL_DIR)
mv $( @D) /* $( TOOLCHAIN_EXTERNAL_DOWNLOAD_INSTALL_DIR) /
e n d e f
e n d i f
2016-11-07 02:19:58 +01:00
#
# Definitions of the list of libraries that should be copied to the target.
#
toolchain-external: copy ld*.so* for all C libraries
Currently, for the dynamic loader, we're copying ld*.so* for glibc and
uClibc, except for glibc/EABIhf where we are explicitly copying
ld-linux-armhf.so.*. For musl, we're not copying the dynamic linker
because it's simply a symbolic link to libc.so. However, the name of
the musl dynamic linker changes from one architecture to the other,
and we don't handle all cases.
Since handling the musl dynamic linker symlink creation is becoming
more and more annoying to maintain, this commit makes musl use the
same mechanism as glibc/uClibc: put the dynamic linker in
TOOLCHAIN_EXTERNAL_LIBS.
In addition, the special condition on glibc/EABIhf was added in
11ec38b6950cf3337b52fb97f27c2fd7c776c5c2 ("toolchain-external: fix
Linaro ARM toolchain support") because an old Linaro toolchain had two
dynamic loaders, and we wanted to copy only one. But 1/ this is old
and 2/ having the two dynamic linkers doesn't really matter.
So this commit simply unconditionally adds "ld*.so*" to
TOOLCHAIN_EXTERNAL_LIBS, regardless of the C library being chosen. It
re-uses the musl dynamic linker symlink from the sysroot, which makes
it always correct, and allows us to remove the
TOOLCHAIN_EXTERNAL_MUSL_LD_LINK hook, and all the related logic.
This commit therefore solves two problems with the musl dynamic linker
symbolic link creation logic:
1 We support all architectures, without having to hardcode in
Buildroot the mapping between the CPU architecture and the
corresponding dynamic linker name. For example, our current logic
was not handling the mips64+n32 ABI case, where the dynamic linker
is named ld-musl-mipsn32el.so.1.
2 We support Crosstool-NG musl toolchains, where the dynamic linker
is in /lib, but libc.so is in /usr/lib.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
This commit therefore replaces:
- https://patchwork.ozlabs.org/patch/780411/ (was another solution
for solving problem 1 above)
- https://patchwork.ozlabs.org/patch/763977/ and
https://patchwork.ozlabs.org/patch/748974/ (was another solution
for solving problem 2 above)
2017-07-02 15:14:17 +02:00
toolchain/toolchain-external: restrict copying of dynamic loader to ld*.so.*
Commit 32bec8ee2fb00c6750fa842bbb0eb79b0c081fa2
("toolchain-external: copy ld*.so* for all C libraries") changed (among
other things) the glob pattern to catch the dynamic loader from
ld*.so.*
to
ld*.so*
thus now matching files like 'ld-2.20.so' in addition to files like
'ld.so.1'.
However, there is no apparent reason why that change was made. It is
not explicitly mentioned in the commit message as to why that would be
needed, nor is clear based on the rest of the changes in that
commit. But it turns out that it causes too many files to be copied
with some toolchains.
In most toolchains, the structure looks like this:
-rwxr-xr-x 1 tdescham tdescham 834364 Feb 16 21:23 output/target/lib/ld-2.16.so
lrwxrwxrwx 1 tdescham tdescham 10 Feb 16 21:23 output/target/lib/ld.so.1 -> ld-2.16.so
So, a symlink 'ld.so.1' which points to another file. Applications
would have 'ld.so.1' (the link) encoded as program interpreter
(readelf -l <program>, see INTERP entry)
The patterns like 'ld*.so*' are passed as argument to
copy_toolchain_lib_root which is defined in toolchain/helpers.mk.
This macro copy_toolchain_lib_root will find all files/links matching
the pattern. If a match is a regular file, it is simply copied. If it
is a symbolic link, the link is copied and then the logic is
recursively repeated on the link destination. That destination could
either again be a link or a regular file. In the first case we recurse
again, in the latter we stop and continue with the next match of the
pattern.
The problem this patch is solving is when a toolchain does not have
this structure with a link and a real file, but rather two actual
files:
-rwxr-xr-x 1 tdescham tdescham 170892 Feb 16 21:55 output/target/lib/ld-2.20.so
-rwxr-xr-x 1 tdescham tdescham 170892 Feb 16 21:55 output/target/lib/ld.so.1
In this case the pattern 'ld*.so*' would find two regular file matches
and copy both. On the other hand, the pattern 'ld*.so.*' would only
find the 'ld.so.1' file and copy just that. This saves about 170K in
rootfs size.
Closer inspection reveals that this particular toolchain has more such
dedoubled symbolic links, e.g. the standard pattern of
'usr/lib/libfoo.so -> libfoo.so.1 -> libfoo.so.1.0.2' is not present,
and each of these three components are real files. In any case, it is
obvious that the toolchain itself is 'broken'.
That being said, because we have the logic that recursively resolves
symbolic links, TOOLCHAIN_EXTERNAL_LIBS really only needs to contain
the "initial" name of the library to be copied.
Therefore, revert the glob pattern back to what it was.
Signed-off-by: Thomas De Schampheleire <thomas.de_schampheleire@nokia.com>
[Thomas: improve the commit log with the additional details from Thomas]
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2019-02-05 22:15:44 +01:00
TOOLCHAIN_EXTERNAL_LIBS += ld*.so.* libgcc_s.so.* libatomic.so.*
toolchain-external: copy ld*.so* for all C libraries
Currently, for the dynamic loader, we're copying ld*.so* for glibc and
uClibc, except for glibc/EABIhf where we are explicitly copying
ld-linux-armhf.so.*. For musl, we're not copying the dynamic linker
because it's simply a symbolic link to libc.so. However, the name of
the musl dynamic linker changes from one architecture to the other,
and we don't handle all cases.
Since handling the musl dynamic linker symlink creation is becoming
more and more annoying to maintain, this commit makes musl use the
same mechanism as glibc/uClibc: put the dynamic linker in
TOOLCHAIN_EXTERNAL_LIBS.
In addition, the special condition on glibc/EABIhf was added in
11ec38b6950cf3337b52fb97f27c2fd7c776c5c2 ("toolchain-external: fix
Linaro ARM toolchain support") because an old Linaro toolchain had two
dynamic loaders, and we wanted to copy only one. But 1/ this is old
and 2/ having the two dynamic linkers doesn't really matter.
So this commit simply unconditionally adds "ld*.so*" to
TOOLCHAIN_EXTERNAL_LIBS, regardless of the C library being chosen. It
re-uses the musl dynamic linker symlink from the sysroot, which makes
it always correct, and allows us to remove the
TOOLCHAIN_EXTERNAL_MUSL_LD_LINK hook, and all the related logic.
This commit therefore solves two problems with the musl dynamic linker
symbolic link creation logic:
1 We support all architectures, without having to hardcode in
Buildroot the mapping between the CPU architecture and the
corresponding dynamic linker name. For example, our current logic
was not handling the mips64+n32 ABI case, where the dynamic linker
is named ld-musl-mipsn32el.so.1.
2 We support Crosstool-NG musl toolchains, where the dynamic linker
is in /lib, but libc.so is in /usr/lib.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
This commit therefore replaces:
- https://patchwork.ozlabs.org/patch/780411/ (was another solution
for solving problem 1 above)
- https://patchwork.ozlabs.org/patch/763977/ and
https://patchwork.ozlabs.org/patch/748974/ (was another solution
for solving problem 2 above)
2017-07-02 15:14:17 +02:00
toolchain/external: copy libssp.so if SSP is enabled
In Buildroot, the internal toolchain backend uses the SSP support from
the C library, not that of gcc.
Some external toolchains come with SSP suport in gcc, which is
implemented in libssp.so, rather than in the C library.
When a toolchain even has both, it is up to the compiler to decide
whether it will link to libssp or use the support from the C library.
However, in the latter case, a (incorrectly written) package may decide
to explicitly link with libssp.so when it is available (even though the
compiler may have decided otherwise if left by itself). This is the case
for example with sox, which results in runtime failures, such as:
$ sox
sox: error while loading shared libraries: libssp.so.0: cannot open
shared object file: No such file or directory
Even if sox is wrong in doing so, the case for libssp-only toolchains is
still valid, and we must copy it as we copy other libs.
Signed-off-by: Yann Droneaud <ydroneaud@opteya.com>
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2019-10-25 15:42:41 +02:00
i f n e q ( $( BR 2_SSP_NONE ) , y )
TOOLCHAIN_EXTERNAL_LIBS += libssp.so.*
e n d i f
2016-11-07 02:19:58 +01:00
i f e q ( $( BR 2_TOOLCHAIN_EXTERNAL_GLIBC ) $( BR 2_TOOLCHAIN_EXTERNAL_UCLIBC ) , y )
toolchain/external: remove libcrypt from glibc
Note: this commit only deals with glibc and its internal libcrypt (or
lack thereof); other C libraries, musl and uClibc-NG, are not considered.
libcrypt from glibc has been deprecated for a long time, and it has now
been entirely dropped with glibc 2.39. Now, packages that need crypt(3)
features need to explicitly depend on the libxcrypt pacakge.
However, the set of files installed both by glibc and libxcrypt is not
empty:
glibc libxcrypt
/usr/include/crypt.h /usr/include/crypt.h
/usr/lib/libcrypt.a /usr/lib/libcrypt.a
/usr/lib/libcrypt.so /usr/lib/libcrypt.so
/lib/libcrypt.so.1
/lib/libcrypt-2.23.so
/usr/lib/libcrypt.so.2
The two libraries have different SO_NAME, so they do not conflict on the
library filename. However, the .so synlink is present in both, and thus
conflicts. The header and the static library also conflict.
So, the situation is that, with a glibc 2.39 or later, packages have to
use libxcrypt, which is a drop-in replacement. With glibc 2.38 or
earlier, they can use either.
Since we already bumped to glibc 2.39 for the internal toolchain, we
have already converted quite a few packages to use libxcrypt. That works
well with an internl toolchain, because glibc does not install the
conflicting files.
However, for external toolchains, we may very well end up in three
situations:
- a glibc 2.39 or later, without libcrypt
- a glibc 2.39 or later, without libcrypt, but with libxcrypt [0]
- a glibc 2.38 or earlier with libcrypt
In the first case, all is OK and we are in a situation similar to the
internal toolchain, but in the latter two cases, we end up with a
conflict.
We could introduce BR2_TOOLCHAIN_EXTERNAL_HAS_LIBCRYPT os something
along those lines, but this is going to be a bit complex on packages,
which would have to select LIBXCRYPT if GLIBC && !_HAS_LIBCRYPT.
So, to simplify things, we want to get the external toolchains into a
situation similar to the internal one, where libcrypt is not provided by
the toolchain; packages have to select libxcrypt for glibc toolchains,
without having to care whether this is an internal or external toolchain
or some more complex conditions.
So, we remove from staging whatever could be used to compile and link
with libcrypt. We however keep the SO_NAME file, if it exists, and we
also install it in target/, for those pre-built binaries that may be
linked with it [1]. The glibc SO_NAME has always been libcrypt.so.1, so
this is what we copy exactly, to avoid copying the libxcrypt one, which
is libcrypt.so.2.
[0] that could happen if a toolchain provider tried to be helpful and
suplies a toolchain with libxcrypt to be trasnparent to users, in which
case that would conflict with ours...
[1] if such a prebuilt binary (executable or library) is used with a
glibc 2.39 or later toolchain, it will obviously not work at all.
libxcrypt is supposed to be a drop-in replacement for glibc's libcrypt,
so we could look into symlinking libcrypt.so.1 to libcrypt.so.2. In a
later patch, maybe...
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Cc: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Cc: Fabrice Fontaine <fontaine.fabrice@gmail.com>
Reviewed-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2024-04-08 22:24:06 +02:00
TOOLCHAIN_EXTERNAL_LIBS += libc.so.* libdl.so.* libm.so.* libnsl.so.* libresolv.so.* librt.so.* libutil.so.*
2016-11-07 02:19:58 +01:00
i f e q ( $( BR 2_TOOLCHAIN_HAS_THREADS ) , y )
TOOLCHAIN_EXTERNAL_LIBS += libpthread.so.*
i f n e q ( $( BR 2_PACKAGE_GDB ) $( BR 2_TOOLCHAIN_EXTERNAL_GDB_SERVER_COPY ) , )
TOOLCHAIN_EXTERNAL_LIBS += libthread_db.so.*
e n d i f # gdbserver
e n d i f # ! no threads
e n d i f
toolchain/external: remove libcrypt from glibc
Note: this commit only deals with glibc and its internal libcrypt (or
lack thereof); other C libraries, musl and uClibc-NG, are not considered.
libcrypt from glibc has been deprecated for a long time, and it has now
been entirely dropped with glibc 2.39. Now, packages that need crypt(3)
features need to explicitly depend on the libxcrypt pacakge.
However, the set of files installed both by glibc and libxcrypt is not
empty:
glibc libxcrypt
/usr/include/crypt.h /usr/include/crypt.h
/usr/lib/libcrypt.a /usr/lib/libcrypt.a
/usr/lib/libcrypt.so /usr/lib/libcrypt.so
/lib/libcrypt.so.1
/lib/libcrypt-2.23.so
/usr/lib/libcrypt.so.2
The two libraries have different SO_NAME, so they do not conflict on the
library filename. However, the .so synlink is present in both, and thus
conflicts. The header and the static library also conflict.
So, the situation is that, with a glibc 2.39 or later, packages have to
use libxcrypt, which is a drop-in replacement. With glibc 2.38 or
earlier, they can use either.
Since we already bumped to glibc 2.39 for the internal toolchain, we
have already converted quite a few packages to use libxcrypt. That works
well with an internl toolchain, because glibc does not install the
conflicting files.
However, for external toolchains, we may very well end up in three
situations:
- a glibc 2.39 or later, without libcrypt
- a glibc 2.39 or later, without libcrypt, but with libxcrypt [0]
- a glibc 2.38 or earlier with libcrypt
In the first case, all is OK and we are in a situation similar to the
internal toolchain, but in the latter two cases, we end up with a
conflict.
We could introduce BR2_TOOLCHAIN_EXTERNAL_HAS_LIBCRYPT os something
along those lines, but this is going to be a bit complex on packages,
which would have to select LIBXCRYPT if GLIBC && !_HAS_LIBCRYPT.
So, to simplify things, we want to get the external toolchains into a
situation similar to the internal one, where libcrypt is not provided by
the toolchain; packages have to select libxcrypt for glibc toolchains,
without having to care whether this is an internal or external toolchain
or some more complex conditions.
So, we remove from staging whatever could be used to compile and link
with libcrypt. We however keep the SO_NAME file, if it exists, and we
also install it in target/, for those pre-built binaries that may be
linked with it [1]. The glibc SO_NAME has always been libcrypt.so.1, so
this is what we copy exactly, to avoid copying the libxcrypt one, which
is libcrypt.so.2.
[0] that could happen if a toolchain provider tried to be helpful and
suplies a toolchain with libxcrypt to be trasnparent to users, in which
case that would conflict with ours...
[1] if such a prebuilt binary (executable or library) is used with a
glibc 2.39 or later toolchain, it will obviously not work at all.
libxcrypt is supposed to be a drop-in replacement for glibc's libcrypt,
so we could look into symlinking libcrypt.so.1 to libcrypt.so.2. In a
later patch, maybe...
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Cc: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Cc: Fabrice Fontaine <fontaine.fabrice@gmail.com>
Reviewed-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2024-04-08 22:24:06 +02:00
i f e q ( $( BR 2_TOOLCHAIN_EXTERNAL_UCLIBC ) , y )
# uClibc, though mono-lib, still has a separate libcrypt as a stub
TOOLCHAIN_EXTERNAL_LIBS += libcrypt.so.*
e n d i f
2016-11-07 02:19:58 +01:00
i f e q ( $( BR 2_TOOLCHAIN_EXTERNAL_GLIBC ) , y )
2017-02-24 10:03:08 +01:00
TOOLCHAIN_EXTERNAL_LIBS += libnss_files.so.* libnss_dns.so.* libmvec.so.* libanl.so.*
toolchain/external: remove libcrypt from glibc
Note: this commit only deals with glibc and its internal libcrypt (or
lack thereof); other C libraries, musl and uClibc-NG, are not considered.
libcrypt from glibc has been deprecated for a long time, and it has now
been entirely dropped with glibc 2.39. Now, packages that need crypt(3)
features need to explicitly depend on the libxcrypt pacakge.
However, the set of files installed both by glibc and libxcrypt is not
empty:
glibc libxcrypt
/usr/include/crypt.h /usr/include/crypt.h
/usr/lib/libcrypt.a /usr/lib/libcrypt.a
/usr/lib/libcrypt.so /usr/lib/libcrypt.so
/lib/libcrypt.so.1
/lib/libcrypt-2.23.so
/usr/lib/libcrypt.so.2
The two libraries have different SO_NAME, so they do not conflict on the
library filename. However, the .so synlink is present in both, and thus
conflicts. The header and the static library also conflict.
So, the situation is that, with a glibc 2.39 or later, packages have to
use libxcrypt, which is a drop-in replacement. With glibc 2.38 or
earlier, they can use either.
Since we already bumped to glibc 2.39 for the internal toolchain, we
have already converted quite a few packages to use libxcrypt. That works
well with an internl toolchain, because glibc does not install the
conflicting files.
However, for external toolchains, we may very well end up in three
situations:
- a glibc 2.39 or later, without libcrypt
- a glibc 2.39 or later, without libcrypt, but with libxcrypt [0]
- a glibc 2.38 or earlier with libcrypt
In the first case, all is OK and we are in a situation similar to the
internal toolchain, but in the latter two cases, we end up with a
conflict.
We could introduce BR2_TOOLCHAIN_EXTERNAL_HAS_LIBCRYPT os something
along those lines, but this is going to be a bit complex on packages,
which would have to select LIBXCRYPT if GLIBC && !_HAS_LIBCRYPT.
So, to simplify things, we want to get the external toolchains into a
situation similar to the internal one, where libcrypt is not provided by
the toolchain; packages have to select libxcrypt for glibc toolchains,
without having to care whether this is an internal or external toolchain
or some more complex conditions.
So, we remove from staging whatever could be used to compile and link
with libcrypt. We however keep the SO_NAME file, if it exists, and we
also install it in target/, for those pre-built binaries that may be
linked with it [1]. The glibc SO_NAME has always been libcrypt.so.1, so
this is what we copy exactly, to avoid copying the libxcrypt one, which
is libcrypt.so.2.
[0] that could happen if a toolchain provider tried to be helpful and
suplies a toolchain with libxcrypt to be trasnparent to users, in which
case that would conflict with ours...
[1] if such a prebuilt binary (executable or library) is used with a
glibc 2.39 or later toolchain, it will obviously not work at all.
libxcrypt is supposed to be a drop-in replacement for glibc's libcrypt,
so we could look into symlinking libcrypt.so.1 to libcrypt.so.2. In a
later patch, maybe...
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Cc: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Cc: Fabrice Fontaine <fontaine.fabrice@gmail.com>
Reviewed-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2024-04-08 22:24:06 +02:00
# Note: explicitly do copy libcrypt.so.1: it is not the same SONAME as the
# one from libxcrypt, so no conflict, but some prebuilt binaries may have
# it in their DT_NEEDED. However, do remove the headers, static lib, and
# symlink to avoid conflict with libxcrypt (the prebuilt binaries do not
# need those either).
TOOLCHAIN_EXTERNAL_LIBS += libcrypt.so.1
d e f i n e T O O L C H A I N _ E X T E R N A L _ G L I B C _ N O _ L I B C R Y P T
rm -f $( STAGING_DIR) /usr/include/crypt.h \
$( STAGING_DIR) /usr/lib/libcrypt.so \
$( STAGING_DIR) /usr/lib/libcrypt.a
e n d e f
2016-11-07 02:19:58 +01:00
e n d i f
i f e q ( $( BR 2_TOOLCHAIN_EXTERNAL_MUSL ) , y )
2017-07-02 15:25:03 +02:00
TOOLCHAIN_EXTERNAL_LIBS += libc.so
2016-11-07 02:19:58 +01:00
e n d i f
i f e q ( $( BR 2_INSTALL_LIBSTDCPP ) , y )
TOOLCHAIN_EXTERNAL_LIBS += libstdc++.so.*
e n d i f
i f e q ( $( BR 2_TOOLCHAIN_HAS_FORTRAN ) , y )
TOOLCHAIN_EXTERNAL_LIBS += libgfortran.so.*
# fortran needs quadmath on x86 and x86_64
i f e q ( $( BR 2_TOOLCHAIN_HAS_LIBQUADMATH ) , y )
TOOLCHAIN_EXTERNAL_LIBS += libquadmath.so*
e n d i f
e n d i f
2019-03-26 13:30:45 +01:00
i f e q ( $( BR 2_TOOLCHAIN_HAS_OPENMP ) , y )
TOOLCHAIN_EXTERNAL_LIBS += libgomp.so.*
e n d i f
2019-10-24 20:16:21 +02:00
i f e q ( $( BR 2_TOOLCHAIN_HAS_DLANG ) , y )
TOOLCHAIN_EXTERNAL_LIBS += libgdruntime.so* libgphobos.so*
e n d i f
2019-10-27 21:59:02 +01:00
TOOLCHAIN_EXTERNAL_LIBS += $( addsuffix .so*,$( call qstrip,$( BR2_TOOLCHAIN_EXTRA_LIBS) ) )
2016-11-07 02:19:58 +01:00
#
# Definition of the CFLAGS to use with the external toolchain, as well as the
# common toolchain wrapper build arguments
#
# march/mtune/floating point mode needs to be passed to the external toolchain
# to select the right multilib variant
i f e q ( $( BR 2_x 86_ 64) , y )
TOOLCHAIN_EXTERNAL_CFLAGS += -m64
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += -DBR_64
e n d i f
2018-09-23 22:38:50 +02:00
i f n e q ( $( GCC_TARGET_ARCH ) , )
2018-10-01 17:33:59 +02:00
TOOLCHAIN_EXTERNAL_CFLAGS += -march= $( GCC_TARGET_ARCH)
2018-09-23 22:38:50 +02:00
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += -DBR_ARCH= '"$(GCC_TARGET_ARCH)"'
2016-11-07 02:19:58 +01:00
e n d i f
2018-09-23 22:38:50 +02:00
i f n e q ( $( GCC_TARGET_CPU ) , )
TOOLCHAIN_EXTERNAL_CFLAGS += -mcpu= $( GCC_TARGET_CPU)
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += -DBR_CPU= '"$(GCC_TARGET_CPU)"'
2016-11-07 02:19:58 +01:00
e n d i f
2018-09-23 22:38:50 +02:00
i f n e q ( $( GCC_TARGET_ABI ) , )
TOOLCHAIN_EXTERNAL_CFLAGS += -mabi= $( GCC_TARGET_ABI)
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += -DBR_ABI= '"$(GCC_TARGET_ABI)"'
2017-06-28 17:17:10 +02:00
e n d i f
2017-07-21 19:06:31 +02:00
i f e q ( $( BR 2_TOOLCHAIN_HAS_MNAN_OPTION ) , y )
2018-09-23 22:38:50 +02:00
i f n e q ( $( GCC_TARGET_NAN ) , )
TOOLCHAIN_EXTERNAL_CFLAGS += -mnan= $( GCC_TARGET_NAN)
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += -DBR_NAN= '"$(GCC_TARGET_NAN)"'
2017-06-28 17:17:11 +02:00
e n d i f
2017-07-21 19:06:31 +02:00
e n d i f
2018-09-23 22:38:50 +02:00
i f n e q ( $( GCC_TARGET_FP 32_MODE ) , )
TOOLCHAIN_EXTERNAL_CFLAGS += -mfp$( GCC_TARGET_FP32_MODE)
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += -DBR_FP32_MODE= '"$(GCC_TARGET_FP32_MODE)"'
2016-11-07 02:19:58 +01:00
e n d i f
2018-09-23 22:38:50 +02:00
i f n e q ( $( GCC_TARGET_FPU ) , )
TOOLCHAIN_EXTERNAL_CFLAGS += -mfpu= $( GCC_TARGET_FPU)
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += -DBR_FPU= '"$(GCC_TARGET_FPU)"'
2016-11-07 02:19:58 +01:00
e n d i f
2018-09-23 22:38:50 +02:00
i f n e q ( $( GCC_TARGET_FLOAT_ABI ) , )
TOOLCHAIN_EXTERNAL_CFLAGS += -mfloat-abi= $( GCC_TARGET_FLOAT_ABI)
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += -DBR_FLOAT_ABI= '"$(GCC_TARGET_FLOAT_ABI)"'
2016-11-07 02:19:58 +01:00
e n d i f
2018-09-23 22:38:50 +02:00
i f n e q ( $( GCC_TARGET_MODE ) , )
TOOLCHAIN_EXTERNAL_CFLAGS += -m$( GCC_TARGET_MODE)
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += -DBR_MODE= '"$(GCC_TARGET_MODE)"'
2016-11-07 02:19:58 +01:00
e n d i f
i f e q ( $( BR 2_BINFMT_FLAT ) , y )
TOOLCHAIN_EXTERNAL_CFLAGS += -Wl,-elf2flt
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += -DBR_BINFMT_FLAT
e n d i f
i f e q ( $( BR 2_mipsel ) $( BR 2_mips 64el ) , y )
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += -DBR_MIPS_TARGET_LITTLE_ENDIAN
TOOLCHAIN_EXTERNAL_CFLAGS += -EL
e n d i f
i f e q ( $( BR 2_mips ) $( BR 2_mips 64) , y )
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += -DBR_MIPS_TARGET_BIG_ENDIAN
TOOLCHAIN_EXTERNAL_CFLAGS += -EB
e n d i f
i f e q ( $( BR 2_arceb ) , y )
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += -DBR_ARC_TARGET_BIG_ENDIAN
TOOLCHAIN_EXTERNAL_CFLAGS += -EB
e n d i f
TOOLCHAIN_EXTERNAL_CFLAGS += $( call qstrip,$( BR2_TARGET_OPTIMIZATION) )
i f e q ( $( BR 2_SOFT_FLOAT ) , y )
TOOLCHAIN_EXTERNAL_CFLAGS += -msoft-float
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += -DBR_SOFTFLOAT= 1
e n d i f
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += \
-DBR_CROSS_PATH_SUFFIX= '"$(TOOLCHAIN_EXTERNAL_SUFFIX)"'
i f e q ( $( filter $ ( HOST_DIR ) /%,$ ( TOOLCHAIN_EXTERNAL_BIN ) ) , )
# TOOLCHAIN_EXTERNAL_BIN points outside HOST_DIR => absolute path
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += \
-DBR_CROSS_PATH_ABS= '"$(TOOLCHAIN_EXTERNAL_BIN)"'
e l s e
# TOOLCHAIN_EXTERNAL_BIN points inside HOST_DIR => relative path
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += \
-DBR_CROSS_PATH_REL= '"$(TOOLCHAIN_EXTERNAL_BIN:$(HOST_DIR)/%=%)"'
e n d i f
#
# The following functions creates the symbolic links needed to get the
2017-07-05 13:14:19 +02:00
# cross-compilation tools visible in $(HOST_DIR)/bin. Some of
2016-11-07 02:19:58 +01:00
# links are done directly to the corresponding tool in the external
# toolchain installation directory, while some other links are done to
# the toolchain wrapper (preprocessor, C, C++ and Fortran compiler)
#
# We skip gdb symlink when we are building our own gdb to prevent two
2017-07-05 13:14:19 +02:00
# gdb's in $(HOST_DIR)/bin.
2016-11-07 02:19:58 +01:00
#
# The LTO support in gcc creates wrappers for ar, ranlib and nm which load
# the lto plugin. These wrappers are called *-gcc-ar, *-gcc-ranlib, and
# *-gcc-nm and should be used instead of the real programs when -flto is
# used. However, we should not add the toolchain wrapper for them, and they
# match the *cc-* pattern. Therefore, an additional case is added for *-ar,
# *-ranlib and *-nm.
d e f i n e T O O L C H A I N _ E X T E R N A L _ I N S T A L L _ W R A P P E R
2017-07-05 13:14:19 +02:00
$( Q) cd $( HOST_DIR) /bin; \
2016-11-07 02:19:58 +01:00
for i in $( TOOLCHAIN_EXTERNAL_CROSS) *; do \
base = $$ { i##*/} ; \
case " $$ base " in \
*-ar| *-ranlib| *-nm) \
Eliminate $(HOST_DIR)/usr
We currently use $(HOST_DIR)/usr as the prefix for host packages. That
has a few disadvantages:
- There are some things installed in $(HOST_DIR)/etc and
$(HOST_DIR)/sbin, which is inconsistent.
- To pack a buildroot-built toolchain into a tarball for use as an
external toolchain, you have to pack output/host/usr instead of the
more obvious output/host.
- Because of the above, the internal toolchain wrapper breaks which
forces us to work around it (call the actual toolchain executable
directly). This is OK for us, but when used in another build system,
that's a problem.
- Paths are four characters longer.
To allow us to gradually eliminate $(HOST_DIR)/usr while building
packages, replace it with a symlink to .
The symlinks from $(HOST_DIR)/usr/$(GNU_TARGET_NAME) and
$(HOST_DIR)/usr/lib that were added previously are removed again.
Note that the symlink creation will break when $(HOST_DIR)/usr
already exists as a directory, i.e. when rebuilding in an existing
output directory. This is necessary: if we don't break it now, the
following commits (which remove the usr part from various variables)
_will_ break it.
At the same time as creating this symlink, we have to update the
external toolchain wrapper and the external toolchain symlinks to go
one directory less up. Indeed, $(HOST_DIR) is one level less up than
it was before.
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Reviewed-by: Romain Naour <romain.naour@smile.fr>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
2017-07-04 16:03:53 +02:00
ln -sf $$ ( echo $$ i | sed 's%^$(HOST_DIR)%..%' ) .; \
2016-11-07 02:19:58 +01:00
; ; \
2019-11-02 19:00:51 +01:00
*cc| *cc-*| *++| *++-*| *cpp| *-gfortran| *-gdc) \
2016-11-07 02:19:58 +01:00
ln -sf toolchain-wrapper $$ base; \
; ; \
*gdb| *gdbtui) \
if test " $( BR2_PACKAGE_HOST_GDB) " != "y" ; then \
Eliminate $(HOST_DIR)/usr
We currently use $(HOST_DIR)/usr as the prefix for host packages. That
has a few disadvantages:
- There are some things installed in $(HOST_DIR)/etc and
$(HOST_DIR)/sbin, which is inconsistent.
- To pack a buildroot-built toolchain into a tarball for use as an
external toolchain, you have to pack output/host/usr instead of the
more obvious output/host.
- Because of the above, the internal toolchain wrapper breaks which
forces us to work around it (call the actual toolchain executable
directly). This is OK for us, but when used in another build system,
that's a problem.
- Paths are four characters longer.
To allow us to gradually eliminate $(HOST_DIR)/usr while building
packages, replace it with a symlink to .
The symlinks from $(HOST_DIR)/usr/$(GNU_TARGET_NAME) and
$(HOST_DIR)/usr/lib that were added previously are removed again.
Note that the symlink creation will break when $(HOST_DIR)/usr
already exists as a directory, i.e. when rebuilding in an existing
output directory. This is necessary: if we don't break it now, the
following commits (which remove the usr part from various variables)
_will_ break it.
At the same time as creating this symlink, we have to update the
external toolchain wrapper and the external toolchain symlinks to go
one directory less up. Indeed, $(HOST_DIR) is one level less up than
it was before.
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Reviewed-by: Romain Naour <romain.naour@smile.fr>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
2017-07-04 16:03:53 +02:00
ln -sf $$ ( echo $$ i | sed 's%^$(HOST_DIR)%..%' ) .; \
2016-11-07 02:19:58 +01:00
fi \
; ; \
*) \
Eliminate $(HOST_DIR)/usr
We currently use $(HOST_DIR)/usr as the prefix for host packages. That
has a few disadvantages:
- There are some things installed in $(HOST_DIR)/etc and
$(HOST_DIR)/sbin, which is inconsistent.
- To pack a buildroot-built toolchain into a tarball for use as an
external toolchain, you have to pack output/host/usr instead of the
more obvious output/host.
- Because of the above, the internal toolchain wrapper breaks which
forces us to work around it (call the actual toolchain executable
directly). This is OK for us, but when used in another build system,
that's a problem.
- Paths are four characters longer.
To allow us to gradually eliminate $(HOST_DIR)/usr while building
packages, replace it with a symlink to .
The symlinks from $(HOST_DIR)/usr/$(GNU_TARGET_NAME) and
$(HOST_DIR)/usr/lib that were added previously are removed again.
Note that the symlink creation will break when $(HOST_DIR)/usr
already exists as a directory, i.e. when rebuilding in an existing
output directory. This is necessary: if we don't break it now, the
following commits (which remove the usr part from various variables)
_will_ break it.
At the same time as creating this symlink, we have to update the
external toolchain wrapper and the external toolchain symlinks to go
one directory less up. Indeed, $(HOST_DIR) is one level less up than
it was before.
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Reviewed-by: Romain Naour <romain.naour@smile.fr>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
2017-07-04 16:03:53 +02:00
ln -sf $$ ( echo $$ i | sed 's%^$(HOST_DIR)%..%' ) .; \
2016-11-07 02:19:58 +01:00
; ; \
esac ; \
done
e n d e f
# Various utility functions used by the external toolchain package
# infrastructure. Those functions are mainly responsible for:
#
# - installation the toolchain libraries to $(TARGET_DIR)
# - copying the toolchain sysroot to $(STAGING_DIR)
# - installing a gdbinit file
#
# Details about sysroot directory selection.
#
# To find the sysroot directory, we use the trick of looking for the
# 'libc.a' file with the -print-file-name gcc option, and then
# mangling the path to find the base directory of the sysroot.
#
# Note that we do not use the -print-sysroot option, because it is
# only available since gcc 4.4.x, and we only recently dropped support
# for 4.2.x and 4.3.x.
#
# When doing this, we don't pass any option to gcc that could select a
# multilib variant (such as -march) as we want the "main" sysroot,
# which contains all variants of the C library in the case of multilib
# toolchains. We use the TARGET_CC_NO_SYSROOT variable, which is the
# path of the cross-compiler, without the --sysroot=$(STAGING_DIR),
# since what we want to find is the location of the original toolchain
# sysroot. This "main" sysroot directory is stored in SYSROOT_DIR.
#
# Then, multilib toolchains are a little bit more complicated, since
# they in fact have multiple sysroots, one for each variant supported
# by the toolchain. So we need to find the particular sysroot we're
# interested in.
#
# To do so, we ask the compiler where its sysroot is by passing all
# flags (including -march and al.), except the --sysroot flag since we
# want to the compiler to tell us where its original sysroot
# is. ARCH_SUBDIR will contain the subdirectory, in the main
# SYSROOT_DIR, that corresponds to the selected architecture
# variant. ARCH_SYSROOT_DIR will contain the full path to this
# location.
#
# One might wonder why we don't just bother with ARCH_SYSROOT_DIR. The
# fact is that in multilib toolchains, the header files are often only
# present in the main sysroot, and only the libraries are available in
# each variant-specific sysroot directory.
# toolchain_find_sysroot returns the sysroot location for the given
# compiler + flags. We need to handle cases where libc.a is in:
#
# - lib/
# - usr/lib/
# - lib32/
# - lib64/
# - lib32-fp/ (Cavium toolchain)
# - lib64-fp/ (Cavium toolchain)
# - usr/lib/<tuple>/ (Linaro toolchain)
#
# And variations on these.
d e f i n e t o o l c h a i n _ f i n d _ s y s r o o t
2019-08-01 16:53:36 +02:00
$$ (printf $(call toolchain_find_libc_a,$(1)) | sed -r -e 's : /(usr /)?lib (32| 64)?([^/]*)?/([^/]*/)?libc \.a :/:')
2016-11-07 02:19:58 +01:00
e n d e f
# Returns the lib subdirectory for the given compiler + flags (i.e
# typically lib32 or lib64 for some toolchains)
d e f i n e t o o l c h a i n _ f i n d _ l i b d i r
2017-02-07 22:56:43 +01:00
$$ (printf $(call toolchain_find_libc_a,$(1)) | sed -r -e 's : .*/(usr /)?(lib (32| 64)?([^/]*)?(/[^/]*)?)/libc .a :\2:')
2016-11-07 02:19:58 +01:00
e n d e f
# Returns the location of the libc.a file for the given compiler + flags
d e f i n e t o o l c h a i n _ f i n d _ l i b c _ a
$$ ( r e a d l i n k - f $$ (LANG = C $( 1) -print-file-name= libc.a) )
e n d e f
# Integration of the toolchain into Buildroot: find the main sysroot
# and the variant-specific sysroot, then copy the needed libraries to
# the $(TARGET_DIR) and copy the whole sysroot (libraries and headers)
# to $(STAGING_DIR).
#
# Variables are defined as follows:
#
2017-01-31 17:03:38 +01:00
# SYSROOT_DIR: the main sysroot directory, deduced from the location of
# the libc.a file in the default multilib variant, by
# removing the usr/lib[32|64]/libc.a part of the path.
2016-11-07 02:19:58 +01:00
# Ex: /x-tools/mips-2011.03/mips-linux-gnu/libc/
#
# ARCH_SYSROOT_DIR: the sysroot of the selected multilib variant,
2017-01-31 17:03:38 +01:00
# deduced from the location of the libc.a file in the
# selected multilib variant (taking into account the
# CFLAGS), by removing usr/lib[32|64]/libc.a at the end
# of the path.
2016-11-07 02:19:58 +01:00
# Ex: /x-tools/mips-2011.03/mips-linux-gnu/libc/mips16/soft-float/el/
#
# ARCH_LIB_DIR: 'lib', 'lib32' or 'lib64' depending on where libraries
2017-01-31 17:03:38 +01:00
# are stored. Deduced from the location of the libc.a file
# in the selected multilib variant, by looking at
# usr/lib??/libc.a.
2016-11-07 02:19:58 +01:00
# Ex: lib
#
# ARCH_SUBDIR: the relative location of the sysroot of the selected
# multilib variant compared to the main sysroot.
2017-01-31 17:03:38 +01:00
# Ex: mips16/soft-float/el
2016-11-07 02:19:58 +01:00
#
# SUPPORT_LIB_DIR: some toolchains, such as recent Linaro toolchains,
# store GCC support libraries (libstdc++,
# libgcc_s, etc.) outside of the sysroot. In
# this case, SUPPORT_LIB_DIR is set to a
# non-empty value, and points to the directory
# where these support libraries are
# available. Those libraries will be copied to
# our sysroot, and the directory will also be
# considered when searching libraries for copy
# to the target filesystem.
#
# Please be very careful to check the major toolchain sources:
# Buildroot, Crosstool-NG, CodeSourcery and Linaro
# before doing any modification on the below logic.
i f e q ( $( BR 2_STATIC_LIBS ) , )
d e f i n e T O O L C H A I N _ E X T E R N A L _ I N S T A L L _ T A R G E T _ L I B S
$( Q) $( call MESSAGE,"Copying external toolchain libraries to target..." )
2017-02-07 22:56:48 +01:00
$( Q) for libpattern in $( TOOLCHAIN_EXTERNAL_LIBS) ; do \
$( call copy_toolchain_lib_root,$$ libpattern) ; \
2016-11-07 02:19:58 +01:00
done
e n d e f
e n d i f
i f e q ( $( BR 2_TOOLCHAIN_EXTERNAL_GDB_SERVER_COPY ) , y )
d e f i n e T O O L C H A I N _ E X T E R N A L _ I N S T A L L _ T A R G E T _ G D B S E R V E R
$( Q) $( call MESSAGE,"Copying gdbserver" )
$( Q) ARCH_SYSROOT_DIR = " $( call toolchain_find_sysroot,$( TOOLCHAIN_EXTERNAL_CC) $( TOOLCHAIN_EXTERNAL_CFLAGS) ) " ; \
ARCH_LIB_DIR = " $( call toolchain_find_libdir,$( TOOLCHAIN_EXTERNAL_CC) $( TOOLCHAIN_EXTERNAL_CFLAGS) ) " ; \
gdbserver_found = 0 ; \
for d in $$ { ARCH_SYSROOT_DIR} /usr \
$$ { ARCH_SYSROOT_DIR} /../debug-root/usr \
$$ { ARCH_SYSROOT_DIR} /usr/$$ { ARCH_LIB_DIR} \
$( TOOLCHAIN_EXTERNAL_INSTALL_DIR) ; do \
if test -f $$ { d} /bin/gdbserver ; then \
install -m 0755 -D $$ { d} /bin/gdbserver $( TARGET_DIR) /usr/bin/gdbserver ; \
gdbserver_found = 1 ; \
break ; \
fi ; \
done ; \
if [ $$ { gdbserver_found} -eq 0 ] ; then \
echo "Could not find gdbserver in external toolchain" ; \
exit 1 ; \
fi
e n d e f
e n d i f
d e f i n e T O O L C H A I N _ E X T E R N A L _ I N S T A L L _ S Y S R O O T _ L I B S
$( Q) SYSROOT_DIR = " $( call toolchain_find_sysroot,$( TOOLCHAIN_EXTERNAL_CC) ) " ; \
ARCH_SYSROOT_DIR = " $( call toolchain_find_sysroot,$( TOOLCHAIN_EXTERNAL_CC) $( TOOLCHAIN_EXTERNAL_CFLAGS) ) " ; \
ARCH_LIB_DIR = " $( call toolchain_find_libdir,$( TOOLCHAIN_EXTERNAL_CC) $( TOOLCHAIN_EXTERNAL_CFLAGS) ) " ; \
SUPPORT_LIB_DIR = "" ; \
if test ` find $$ { ARCH_SYSROOT_DIR} -name 'libstdc++.a' | wc -l` -eq 0 ; then \
LIBSTDCPP_A_LOCATION = $$ ( LANG = C $( TOOLCHAIN_EXTERNAL_CC) $( TOOLCHAIN_EXTERNAL_CFLAGS) -print-file-name= libstdc++.a) ; \
if [ -e " $$ {LIBSTDCPP_A_LOCATION} " ] ; then \
SUPPORT_LIB_DIR = ` readlink -f $$ { LIBSTDCPP_A_LOCATION} | sed -r -e 's:libstdc\+\+\.a::' ` ; \
fi ; \
fi ; \
if [ " $$ {SYSROOT_DIR} " = = " $$ {ARCH_SYSROOT_DIR} " ] ; then \
ARCH_SUBDIR = "" ; \
elif [ " `dirname $$ {ARCH_SYSROOT_DIR}` " = " `dirname $$ {SYSROOT_DIR}` " ] ; then \
SYSROOT_DIR_DIRNAME = ` dirname $$ { SYSROOT_DIR} ` / ; \
ARCH_SUBDIR = ` echo $$ { ARCH_SYSROOT_DIR} | sed -r -e " s:^ $$ {SYSROOT_DIR_DIRNAME}(.*)/ $$ :\1: " ` ; \
else \
ARCH_SUBDIR = ` echo $$ { ARCH_SYSROOT_DIR} | sed -r -e " s:^ $$ {SYSROOT_DIR}(.*)/ $$ :\1: " ` ; \
fi ; \
$( call MESSAGE,"Copying external toolchain sysroot to staging..." ) ; \
$( call copy_toolchain_sysroot,$$ { SYSROOT_DIR} ,$$ { ARCH_SYSROOT_DIR} ,$$ { ARCH_SUBDIR} ,$$ { ARCH_LIB_DIR} ,$$ { SUPPORT_LIB_DIR} )
e n d e f
# Create a symlink from (usr/)$(ARCH_LIB_DIR) to lib.
# Note: the skeleton package additionally creates lib32->lib or lib64->lib
# (as appropriate)
#
# $1: destination directory (TARGET_DIR / STAGING_DIR)
create_lib_symlinks = \
2017-03-19 10:59:52 +01:00
$( Q) DESTDIR = " $( strip $1 ) " ; \
ARCH_LIB_DIR = " $( call toolchain_find_libdir,$( TOOLCHAIN_EXTERNAL_CC) $( TOOLCHAIN_EXTERNAL_CFLAGS) ) " ; \
if [ ! -e " $$ {DESTDIR}/ $$ {ARCH_LIB_DIR} " -a ! -e " $$ {DESTDIR}/usr/ $$ {ARCH_LIB_DIR} " ] ; then \
2017-02-07 22:56:43 +01:00
relpath = " $( call relpath_prefix,$$ { ARCH_LIB_DIR} ) " ; \
ln -snf $$ { relpath} lib " $$ {DESTDIR}/ $$ {ARCH_LIB_DIR} " ; \
ln -snf $$ { relpath} lib " $$ {DESTDIR}/usr/ $$ {ARCH_LIB_DIR} " ; \
2017-03-19 10:59:52 +01:00
fi
2016-11-07 02:19:58 +01:00
d e f i n e T O O L C H A I N _ E X T E R N A L _ C R E A T E _ S T A G I N G _ L I B _ S Y M L I N K
2017-03-19 10:59:52 +01:00
$( call create_lib_symlinks,$( STAGING_DIR) )
2016-11-07 02:19:58 +01:00
e n d e f
d e f i n e T O O L C H A I N _ E X T E R N A L _ C R E A T E _ T A R G E T _ L I B _ S Y M L I N K
2017-03-19 10:59:52 +01:00
$( call create_lib_symlinks,$( TARGET_DIR) )
2016-11-07 02:19:58 +01:00
e n d e f
#
# Generate gdbinit file for use with Buildroot
#
d e f i n e T O O L C H A I N _ E X T E R N A L _ I N S T A L L _ G D B I N I T
$( Q) if test -f $( TARGET_CROSS) gdb ; then \
$( call MESSAGE,"Installing gdbinit" ) ; \
$( gen_gdbinit_file) ; \
fi
e n d e f
2021-06-08 17:18:38 +02:00
# GCC installs a libstdcxx-...so-gdb.py file that gdb will load automatically,
# but it contains hardcoded paths referring to the location where the (external)
# toolchain was built. Fix up these paths so that the pretty printers can be
# loaded automatically.
# By default, the pretty printers are installed in
# $(datadir)/gcc-$(gcc_version)/python but this could have been overwritten with
# the gcc configure option: --with-python-dir. We thus have to search the
# correct path first.
d e f i n e T O O L C H A I N _ E X T E R N A L _ F I X U P _ P R E T T Y _ P R I N T E R _ L O A D E R
$( Q) loadfiles = $$ ( find $( STAGING_DIR) -name 'libstdc++.so*-gdb.py' 2>/dev/null) ; \
pythondir = $$ ( find $( TOOLCHAIN_EXTERNAL_DOWNLOAD_INSTALL_DIR) -path '*/libstdcxx/__init__.py' 2>/dev/null | sed 's%/libstdcxx/__init__.py%%' | head -n1) ; \
if [ -n " $$ loadfiles " ] && [ -n " $$ pythondir " ] ; then \
echo " Fixing up hardcoded paths in GDB pretty-printer auto-load file(s) for libstdcxx: $$ loadfiles " ; \
sed -ri \
-e 's%^libdir\s*=.*%libdir = "$(STAGING_DIR)/lib"%' \
-e " s%^pythondir\s*=.*%pythondir = ' $$ pythondir'% " \
$$ loadfiles; \
fi
e n d e f
2016-11-07 02:19:58 +01:00
# uClibc-ng dynamic loader is called ld-uClibc.so.1, but gcc is not
# patched specifically for uClibc-ng, so it continues to generate
# binaries that expect the dynamic loader to be named ld-uClibc.so.0,
# like with the original uClibc. Therefore, we create an additional
# symbolic link to make uClibc-ng systems work properly.
d e f i n e T O O L C H A I N _ E X T E R N A L _ F I X U P _ U C L I B C N G _ L D S O
$( Q) if test -e $( TARGET_DIR) /lib/ld-uClibc.so.1; then \
ln -sf ld-uClibc.so.1 $( TARGET_DIR) /lib/ld-uClibc.so.0 ; \
fi
$( Q) if test -e $( TARGET_DIR) /lib/ld64-uClibc.so.1; then \
ln -sf ld64-uClibc.so.1 $( TARGET_DIR) /lib/ld64-uClibc.so.0 ; \
fi
e n d e f
2016-11-07 02:19:59 +01:00
2020-04-22 17:34:42 +02:00
d e f i n e T O O L C H A I N _ E X T E R N A L _ I N S T A L L _ T A R G E T _ L D D
$( Q) if test -f $( STAGING_DIR) /usr/bin/ldd ; then \
$( INSTALL) -D $( STAGING_DIR) /usr/bin/ldd $( TARGET_DIR) /usr/bin/ldd ; \
$( SED) 's:.*/bin/bash:#!/bin/sh:' $( TARGET_DIR) /usr/bin/ldd ; \
fi
e n d e f
2016-11-07 02:19:59 +01:00
################################################################################
# inner-toolchain-external-package -- defines the generic installation rules
# for external toolchain packages
#
# argument 1 is the lowercase package name
# argument 2 is the uppercase package name, including a HOST_ prefix
# for host packages
# argument 3 is the uppercase package name, without the HOST_ prefix
# for host packages
# argument 4 is the type (target or host)
################################################################################
d e f i n e i n n e r - t o o l c h a i n - e x t e r n a l - p a c k a g e
$(2)_INSTALL_STAGING = YES
$(2)_ADD_TOOLCHAIN_DEPENDENCY = NO
# In fact, we don't need to download the toolchain, since it is already
# available on the system, so force the site and source to be empty so
# that nothing will be downloaded/extracted.
i f e q ( $$ ( B R 2 _ T O O L C H A I N _ E X T E R N A L _ P R E I N S T A L L E D ) , y )
$(2)_SITE =
$(2)_SOURCE =
e n d i f
i f e q ( $$ ( B R 2 _ T O O L C H A I N _ E X T E R N A L _ D O W N L O A D ) , y )
$(2)_EXCLUDES = usr/lib/locale/*
$(2)_POST_EXTRACT_HOOKS += \
TOOLCHAIN_EXTERNAL_MOVE
e n d i f
# Checks for an already installed toolchain: check the toolchain
# location, check that it is usable, and then verify that it
# matches the configuration provided in Buildroot: ABI, C++ support,
# kernel headers version, type of C library and all C library features.
d e f i n e $( 2) _ C O N F I G U R E _ C M D S
$$ ( Q) $$ ( call check_cross_compiler_exists,$$ ( TOOLCHAIN_EXTERNAL_CC) )
2023-02-11 19:28:38 +01:00
$$ ( Q) $$ ( call check_unusable_toolchain,$$ ( TOOLCHAIN_EXTERNAL_CC) ," $$ (TOOLCHAIN_EXTERNAL_CFLAGS) " )
2016-11-07 02:19:59 +01:00
$$ ( Q) SYSROOT_DIR = " $$ (call toolchain_find_sysroot, $$ (TOOLCHAIN_EXTERNAL_CC)) " ; \
$$ ( call check_kernel_headers_version,\
toolchain/toolchain-external: fix call to check_kernel_headers_version
The external toolchain configure step calls the
check_kernel_headers_version make function to compare the kernel
headers version declared in the configuration with the actual kernel
headers of the toolchain.
This function takes 4 arguments, but due to a missing comma what
should be the first two arguments are both passed into the first
argument. Due to this, when check_kernel_headers_version does:
if ! support/scripts/check-kernel-headers.sh $(1) $(2) $(3) \
$(if $(BR2_TOOLCHAIN_HEADERS_LATEST),$(4),strict); \
Then:
$(1) contains "$(BUILD_DIR) $$(call toolchain_find_sysroot,$$(TOOLCHAIN_EXTERNAL_CC))"
$(2) contains "$$(call qstrip,$$(BR2_TOOLCHAIN_HEADERS_AT_LEAST))"
$(3) contains "$$(if $$(BR2_TOOLCHAIN_EXTERNAL_CUSTOM),loose,strict))"
So from the point of view of check-kernel-headers.sh, it already has
four arguments, and therefore the additional argument passed by:
$(if $(BR2_TOOLCHAIN_HEADERS_LATEST),$(4),strict); \
is ignored, defeating the $(BR2_TOOLCHAIN_HEADERS_LATEST) test.
The practical consequence is that a toolchain that has 5.4 kernel
headers but declared as using 5.3 kernel headers does not abort the
build, because the check is considered "loose" while it should be
"strict".
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
2020-03-21 14:52:18 +01:00
$$ ( BUILD_DIR) ,\
2016-11-07 02:19:59 +01:00
$$ ( call toolchain_find_sysroot,$$ ( TOOLCHAIN_EXTERNAL_CC) ) ,\
toolchain: allow using custom headers newer than latest known ones
When Buildroot is released, it knows up to a certain kernel header
version, and no later. However, it is possible that an external
toolchain will be used, that uses headers newer than the latest version
Buildroot knows about.
This may also happen when testing a development, an rc-class, or a newly
released kernel, either in an external toolchain, or with an internal
toolchain with custom headers (same-as-kernel, custom version, custom
git, custom tarball).
In the current state, Buildroot would refuse to use such toolchains,
because the test is for strict equality.
We'd like to make that situation possible, but we also want the user not
to be lenient at the same time, and select the right headers version
when it is known.
So, we add a new Kconfig blind option that the latest kernel headers
version selects. This options is then used to decide whether we do a
strict or loose check of the kernel headers.
Suggested-by: Aaron Sierra <asierra@xes-inc.com>
Signed-off-by: Vincent Fazio <vfazio@xes-inc.com>
[yann.morin.1998@free.fr:
- only do a loose check for the latest version
- expand commit log
]
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Tested-by: Vincent Fazio <vfazio@xes-inc.com>
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
2020-01-15 19:29:07 +01:00
$$ ( call qstrip,$$ ( BR2_TOOLCHAIN_HEADERS_AT_LEAST) ) ,\
$$ ( if $$ ( BR2_TOOLCHAIN_EXTERNAL_CUSTOM) ,loose,strict) ) ; \
2016-11-07 02:19:59 +01:00
$$ ( call check_gcc_version,$$ ( TOOLCHAIN_EXTERNAL_CC) ,\
$$ ( call qstrip,$$ ( BR2_TOOLCHAIN_GCC_AT_LEAST) ) ) ; \
if test " $$ (BR2_arm) " = "y" ; then \
$$ ( call check_arm_abi,\
2017-03-26 15:25:52 +02:00
" $$ (TOOLCHAIN_EXTERNAL_CC) $$ (TOOLCHAIN_EXTERNAL_CFLAGS) " ) ; \
2016-11-07 02:19:59 +01:00
fi ; \
2023-07-06 19:18:34 +02:00
$$ ( call check_cplusplus,$$ ( TOOLCHAIN_EXTERNAL_CXX) ) ; \
$$ ( call check_dlang,$$ ( TOOLCHAIN_EXTERNAL_GDC) ) ; \
$$ ( call check_fortran,$$ ( TOOLCHAIN_EXTERNAL_FC) ) ; \
$$ ( call check_openmp,$$ ( TOOLCHAIN_EXTERNAL_CC) ) ; \
2016-11-07 02:19:59 +01:00
if test " $$ (BR2_TOOLCHAIN_EXTERNAL_UCLIBC) " = "y" ; then \
$$ ( call check_uclibc,$$ $$ { SYSROOT_DIR} ) ; \
elif test " $$ (BR2_TOOLCHAIN_EXTERNAL_MUSL) " = "y" ; then \
2017-03-20 06:56:10 +01:00
$$ ( call check_musl,\
2018-07-04 23:42:57 +02:00
" $$ (TOOLCHAIN_EXTERNAL_CC) $$ (TOOLCHAIN_EXTERNAL_CFLAGS) " ) ; \
2016-11-07 02:19:59 +01:00
else \
$$ ( call check_glibc,$$ $$ { SYSROOT_DIR} ) ; \
fi
toolchain: check the SSP option is known
Some toolchain vendors may have backported those options to older gcc
versions, and we have no way to know, so we have to check that the
user's selection is acceptable.
Extend the macro that currently checks for SSP in the toolchain, with
a new test that the actual SSP option is recognised and accepted.
Note that the SSP option is either totaly empty, or an already-quoted
string, so we can safely and easily assign it to a shell variable to
test and use it.
Note that we do not introduce BR2_TOOLCHAIN_HAS_SSP_STRONG, because:
- our internal toolchain infra only supports gcc >= 4.9, so it has
SSP strong;
- of the external pre-built toolchains, only the codesourcery-arm
one has a gcc-4.8 which lacks SSP strong, all the others have a
gcc >= 4.9;
- we'd still have to do the actual check for custom external
toolchains anyway.
So, we're not adding BR2_TOOLCHAIN_HAS_SSP_STRONG just for a single
case.
Signed-off-by: "Yann E. MORIN" <yann.morin@orange.com>
Cc: Matt Weber <matthew.weber@rockwellcollins.com>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Cc: Thomas De Schampheleire <thomas.de_schampheleire@nokia.com>
Cc: Arnout Vandecappelle <arnout@mind.be>
Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
2019-03-12 13:09:34 +01:00
$$ ( Q) $$ ( call check_toolchain_ssp,$$ ( TOOLCHAIN_EXTERNAL_CC) ,$( BR2_SSP_OPTION) )
2016-11-07 02:19:59 +01:00
e n d e f
$(2)_TOOLCHAIN_WRAPPER_ARGS += $$ ( TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS)
$(2)_BUILD_CMDS = $$ ( TOOLCHAIN_WRAPPER_BUILD)
d e f i n e $( 2) _ I N S T A L L _ S T A G I N G _ C M D S
$$ ( TOOLCHAIN_WRAPPER_INSTALL)
$$ ( TOOLCHAIN_EXTERNAL_CREATE_STAGING_LIB_SYMLINK)
$$ ( TOOLCHAIN_EXTERNAL_INSTALL_SYSROOT_LIBS)
toolchain/external: remove libcrypt from glibc
Note: this commit only deals with glibc and its internal libcrypt (or
lack thereof); other C libraries, musl and uClibc-NG, are not considered.
libcrypt from glibc has been deprecated for a long time, and it has now
been entirely dropped with glibc 2.39. Now, packages that need crypt(3)
features need to explicitly depend on the libxcrypt pacakge.
However, the set of files installed both by glibc and libxcrypt is not
empty:
glibc libxcrypt
/usr/include/crypt.h /usr/include/crypt.h
/usr/lib/libcrypt.a /usr/lib/libcrypt.a
/usr/lib/libcrypt.so /usr/lib/libcrypt.so
/lib/libcrypt.so.1
/lib/libcrypt-2.23.so
/usr/lib/libcrypt.so.2
The two libraries have different SO_NAME, so they do not conflict on the
library filename. However, the .so synlink is present in both, and thus
conflicts. The header and the static library also conflict.
So, the situation is that, with a glibc 2.39 or later, packages have to
use libxcrypt, which is a drop-in replacement. With glibc 2.38 or
earlier, they can use either.
Since we already bumped to glibc 2.39 for the internal toolchain, we
have already converted quite a few packages to use libxcrypt. That works
well with an internl toolchain, because glibc does not install the
conflicting files.
However, for external toolchains, we may very well end up in three
situations:
- a glibc 2.39 or later, without libcrypt
- a glibc 2.39 or later, without libcrypt, but with libxcrypt [0]
- a glibc 2.38 or earlier with libcrypt
In the first case, all is OK and we are in a situation similar to the
internal toolchain, but in the latter two cases, we end up with a
conflict.
We could introduce BR2_TOOLCHAIN_EXTERNAL_HAS_LIBCRYPT os something
along those lines, but this is going to be a bit complex on packages,
which would have to select LIBXCRYPT if GLIBC && !_HAS_LIBCRYPT.
So, to simplify things, we want to get the external toolchains into a
situation similar to the internal one, where libcrypt is not provided by
the toolchain; packages have to select libxcrypt for glibc toolchains,
without having to care whether this is an internal or external toolchain
or some more complex conditions.
So, we remove from staging whatever could be used to compile and link
with libcrypt. We however keep the SO_NAME file, if it exists, and we
also install it in target/, for those pre-built binaries that may be
linked with it [1]. The glibc SO_NAME has always been libcrypt.so.1, so
this is what we copy exactly, to avoid copying the libxcrypt one, which
is libcrypt.so.2.
[0] that could happen if a toolchain provider tried to be helpful and
suplies a toolchain with libxcrypt to be trasnparent to users, in which
case that would conflict with ours...
[1] if such a prebuilt binary (executable or library) is used with a
glibc 2.39 or later toolchain, it will obviously not work at all.
libxcrypt is supposed to be a drop-in replacement for glibc's libcrypt,
so we could look into symlinking libcrypt.so.1 to libcrypt.so.2. In a
later patch, maybe...
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Cc: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Cc: Fabrice Fontaine <fontaine.fabrice@gmail.com>
Reviewed-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
2024-04-08 22:24:06 +02:00
$$ ( TOOLCHAIN_EXTERNAL_GLIBC_NO_LIBCRYPT)
2016-11-07 02:19:59 +01:00
$$ ( TOOLCHAIN_EXTERNAL_INSTALL_WRAPPER)
$$ ( TOOLCHAIN_EXTERNAL_INSTALL_GDBINIT)
2021-06-08 17:18:38 +02:00
$$ ( TOOLCHAIN_EXTERNAL_FIXUP_PRETTY_PRINTER_LOADER)
2016-11-07 02:19:59 +01:00
e n d e f
# Even though we're installing things in both the staging, the host
# and the target directory, we do everything within the
# install-staging step, arbitrarily.
d e f i n e $( 2) _ I N S T A L L _ T A R G E T _ C M D S
$$ ( TOOLCHAIN_EXTERNAL_CREATE_TARGET_LIB_SYMLINK)
$$ ( TOOLCHAIN_EXTERNAL_INSTALL_TARGET_LIBS)
$$ ( TOOLCHAIN_EXTERNAL_INSTALL_TARGET_GDBSERVER)
$$ ( TOOLCHAIN_EXTERNAL_FIXUP_UCLIBCNG_LDSO)
2020-04-22 17:34:42 +02:00
$$ ( TOOLCHAIN_EXTERNAL_INSTALL_TARGET_LDD)
2016-11-07 02:19:59 +01:00
e n d e f
# Call the generic package infrastructure to generate the necessary
# make targets
$( call inner -generic -package ,$ ( 1) ,$ ( 2) ,$ ( 3) ,$ ( 4) )
e n d e f
toolchain-external-package = $( call inner-toolchain-external-package,$( pkgname) ,$( call UPPERCASE,$( pkgname) ) ,$( call UPPERCASE,$( pkgname) ) ,target)