* [Buildroot] [pull request] Pull request for branch perf-elfutils
@ 2013-01-06 15:22 Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 01/15] package: support multiple patches Thomas Petazzoni
` (15 more replies)
0 siblings, 16 replies; 19+ messages in thread
From: Thomas Petazzoni @ 2013-01-06 15:22 UTC (permalink / raw)
To: buildroot
Hello,
Here is a set of patches that add the elfutils and perf packages in
Buildroot, based on previous efforts from Stefan Fr?berg and Kaiwan
Billimoria (thanks !).
These packages are not trivial because:
1) perf is part of the kernel sources
2) elfutils is a nightmare to build against uClibc
I've been working on this for about two days, trying different
solutions, the one proposed here appeared to be the most reasonable
one in terms of patch size, and maintenability.
Here is a short description of the patches, and the logic behind the
order of the patches:
* Patches 1 and 2 make it possible to list several patches in the
<pkg>_PATCH variable of a package .mk file. This is used by the
elfutils package to apply two big patches that are provided along
with elfutils tarball. Compared to the previous proposal from
Stefan Fr?berg, it avoids the need from merging in Buildroot two
fairly large patches (57K and 62K).
* Patch 3 adds elfutils as a glibc-only package, to keep things
simple.
* Patch 4 allows to disable the installation of elfutils. Instead of
doing it by removing executable after their installation, I've
added a configuration option inside elfutils. This will be useful
to support uClibc, as the elfutils tools are causing issues to
build with uClibc, and we don't need them to just build the
elfutils libraries.
* Patch 5 adds a perf package, with no support for libelf.
* Patch 6 improves the perf package to use libelf when available
(thanks to the elfutils package).
* Patch 7 adds error checking to the perf package to catch kernel
version problems.
* Patch 8 builds argp-standalone as position-independent code. This
is needed as it will be used by the elfutils package in some shared
library.
* Patch 9 to 14 are here to progressively make elfutils buildable on
uClibc. Notice that at this point, it is *NOT* possible to select
elfutils with a uClibc toolchain. Only the final commit makes that
possible. So this split of patches is here only to make things
easier to review (but this split also doesn't break the build, as
uClibc build of elfutils is not possible until we reach patch 15).
Most of the patches are relatively simple. The most annoying one is
the one regarding the fts_*() family of functions. I had basically
three choices here:
(1) Enable fts_*() functions in our default uClibc
configuration. But elfutils is apparently the only package to
make use of these functions, since even the uClibc help text
for those functions mention elfutils as the primary reason
for having support for those functions in uClibc. The help
text also encourages migrating to the nftw() function
instead. So, changing our default uClibc configuration didn't
seem like the right choice.
(2) Use gnulib to provide fts. This is what Stefan Fr?berg
initially did. It required a very large (1.5 MB) patch. I
improved that by creating a host-gnulib package, and then
call gnulib-tool at build time in the elfutils package so
that the needed functions are added. But it still required
changes to the configure.ac file, Makefile.am and so on. So,
a lot better than the 1.5 MB patch, but still not really
nice, especially just to get the 'fts' feature.
(3) Copy the fts_*() functions from uClibc. This is what I've
decided to implement in this proposal.
* Patch 15 finally makes elfutils available on uClibc (but only the
libraries, not the utilities themselves).
The result has been tested on a x86 glibc toolchain, x86 uClibc
toolchain and ARM uClibc toolchain.
Best regards,
Thomas
The following changes since commit 66bfe1d4fe2de50aef6ac3fc836a710fa577cdef:
xdriver_xf86-video-sunffb: remove package (2013-01-05 14:34:48 +0100)
are available in the git repository at:
git://git.free-electrons.com/users/thomas-petazzoni/buildroot.git perf-elfutils
for you to fetch changes up to 3e9f9e1a1d4de1c948dcf64dffd1a9e6e653d7bd:
elfutils: make available on uClibc toolchains (2013-01-06 16:08:29 +0100)
----------------------------------------------------------------
Stefan Fr?berg (1):
elfutils: new package
Thomas Petazzoni (14):
package: support multiple patches
docs/manual: update to mention the multiple patches support
elfutils: make it possible to only install the libraries
perf: new package
perf: allow build against libelf when available
perf: add kernel version checks
argp-standlone: build position independent code
elfutils: towards uClibc support: argp-standalone usage
elfutils: towards uClibc support: solve memcpy problem
elfutils: towards uClibc support: requires largefile
elfutils: towards uClibc support: gettext
elfutils: towards uClibc support: FTS functions
elfutils: towards uClibc support: disable po build
elfutils: make available on uClibc toolchains
docs/manual/adding-packages-generic.txt | 17 +-
package/Config.in | 2 +
package/argp-standalone/argp-standalone.mk | 3 +
package/elfutils/Config.in | 29 +
package/elfutils/elfutils-01-disable-progs.patch | 47 +
package/elfutils/elfutils-02-argp-support.patch | 92 ++
package/elfutils/elfutils-03-memcpy-def.patch | 24 +
package/elfutils/elfutils-04-fts.patch | 1307 ++++++++++++++++++++++
package/elfutils/elfutils-05-disable-po.patch | 22 +
package/elfutils/elfutils.mk | 70 ++
package/perf/Config.in | 22 +
package/perf/perf.mk | 55 +
package/pkg-generic.mk | 17 +-
13 files changed, 1695 insertions(+), 12 deletions(-)
create mode 100644 package/elfutils/Config.in
create mode 100644 package/elfutils/elfutils-01-disable-progs.patch
create mode 100644 package/elfutils/elfutils-02-argp-support.patch
create mode 100644 package/elfutils/elfutils-03-memcpy-def.patch
create mode 100644 package/elfutils/elfutils-04-fts.patch
create mode 100644 package/elfutils/elfutils-05-disable-po.patch
create mode 100644 package/elfutils/elfutils.mk
create mode 100644 package/perf/Config.in
create mode 100644 package/perf/perf.mk
Thanks,
--
Thomas Petazzoni
^ permalink raw reply [flat|nested] 19+ messages in thread
* [Buildroot] [PATCH 01/15] package: support multiple patches
2013-01-06 15:22 [Buildroot] [pull request] Pull request for branch perf-elfutils Thomas Petazzoni
@ 2013-01-06 15:22 ` Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 02/15] docs/manual: update to mention the multiple patches support Thomas Petazzoni
` (14 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Thomas Petazzoni @ 2013-01-06 15:22 UTC (permalink / raw)
To: buildroot
With this commit, we extend the behaviour of the <pkg>_PATCH variable
so that it now allows to list several patches to be downloaded and
applied, and no longer just one patch.
This will be useful for the elfutils package, and should anyway not
break the existing behaviour for packages using just one patch.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
package/pkg-generic.mk | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/package/pkg-generic.mk b/package/pkg-generic.mk
index a570ad7..59de0f0 100644
--- a/package/pkg-generic.mk
+++ b/package/pkg-generic.mk
@@ -28,12 +28,19 @@
$(BUILD_DIR)/%/.stamp_downloaded:
ifeq ($(DL_MODE),DOWNLOAD)
# Only show the download message if it isn't already downloaded
- $(Q)(test -e $(DL_DIR)/$($(PKG)_SOURCE) && \
- (test -z $($(PKG)_PATCH) || test -e $(DL_DIR)$($(PKG)_PATCH))) || \
- $(call MESSAGE,"Downloading")
+ $(Q)if test ! -e $(DL_DIR)/$($(PKG)_SOURCE); then \
+ $(call MESSAGE,"Downloading") ; \
+ else \
+ for p in $($(PKG)_PATCH) ; do \
+ if test ! -e $(DL_DIR)/$$p ; then \
+ $(call MESSAGE,"Downloading") ; \
+ break ; \
+ fi ; \
+ done ; \
+ fi
endif
$(if $($(PKG)_SOURCE),$(call DOWNLOAD,$($(PKG)_SITE)/$($(PKG)_SOURCE)))
- $(if $($(PKG)_PATCH),$(call DOWNLOAD,$($(PKG)_SITE)/$($(PKG)_PATCH)))
+ $(foreach p,$($(PKG)_PATCH),$(call DOWNLOAD,$($(PKG)_SITE)/$(p))$(sep))
$(foreach hook,$($(PKG)_POST_DOWNLOAD_HOOKS),$(call $(hook))$(sep))
ifeq ($(DL_MODE),DOWNLOAD)
$(Q)mkdir -p $(@D)
@@ -78,7 +85,7 @@ $(BUILD_DIR)/%/.stamp_patched: NAMEVER = $(RAWNAME)-$($(PKG)_VERSION)
$(BUILD_DIR)/%/.stamp_patched:
@$(call MESSAGE,"Patching $($(PKG)_DIR_PREFIX)/$(RAWNAME)")
$(foreach hook,$($(PKG)_PRE_PATCH_HOOKS),$(call $(hook))$(sep))
- $(if $($(PKG)_PATCH),support/scripts/apply-patches.sh $(@D) $(DL_DIR) $($(PKG)_PATCH))
+ $(foreach p,$($(PKG)_PATCH),support/scripts/apply-patches.sh $(@D) $(DL_DIR) $(p)$(sep))
$(Q)( \
if test -d $($(PKG)_DIR_PREFIX)/$(RAWNAME); then \
if test "$(wildcard $($(PKG)_DIR_PREFIX)/$(RAWNAME)/$(NAMEVER)*.patch*)"; then \
--
1.7.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Buildroot] [PATCH 02/15] docs/manual: update to mention the multiple patches support
2013-01-06 15:22 [Buildroot] [pull request] Pull request for branch perf-elfutils Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 01/15] package: support multiple patches Thomas Petazzoni
@ 2013-01-06 15:22 ` Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 03/15] elfutils: new package Thomas Petazzoni
` (13 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Thomas Petazzoni @ 2013-01-06 15:22 UTC (permalink / raw)
To: buildroot
After the modification of the <pkg>_PATCH semantic, let's update the
documentation accordingly.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
docs/manual/adding-packages-generic.txt | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/docs/manual/adding-packages-generic.txt b/docs/manual/adding-packages-generic.txt
index 0759d4f..7b8561a 100644
--- a/docs/manual/adding-packages-generic.txt
+++ b/docs/manual/adding-packages-generic.txt
@@ -156,14 +156,17 @@ information is (assuming the package name is +libfoo+) :
+packagename-$(LIBFOO_VERSION).tar.gz+. +
Example: +LIBFOO_SOURCE = foobar-$(LIBFOO_VERSION).tar.bz2+
-* +LIBFOO_PATCH+ may contain the name of a patch, that will be
- downloaded from the same location as the tarball indicated in
- +LIBFOO_SOURCE+. If +HOST_LIBFOO_PATCH+ is not specified, it
- defaults to +LIBFOO_PATCH+. Note that patches that are included
- in Buildroot itself use a different mechanism: all files of the
- form +<packagename>-*.patch+ present in the package directory inside
+* +LIBFOO_PATCH+ may contain a space-separated list of patch file
+ names, that will be downloaded from the same location as the tarball
+ indicated in +LIBFOO_SOURCE+, and then applied to the package source
+ code. If +HOST_LIBFOO_PATCH+ is not specified, it defaults to
+ +LIBFOO_PATCH+. Note that patches that are included in Buildroot
+ itself use a different mechanism: all files of the form
+ +<packagename>-*.patch+ present in the package directory inside
Buildroot will be applied to the package after extraction (see
- xref:patch-policy[patching a package]).
+ xref:patch-policy[patching a package]). Finally, patches listed in
+ the +LIBFOO_PATCH+ variable are applied _before_ the patches stored
+ in the Buildroot package directory.
* +LIBFOO_SITE+ provides the location of the package, which can be a
URL or a local filesystem path. HTTP, FTP and SCP are supported URL
--
1.7.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Buildroot] [PATCH 03/15] elfutils: new package
2013-01-06 15:22 [Buildroot] [pull request] Pull request for branch perf-elfutils Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 01/15] package: support multiple patches Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 02/15] docs/manual: update to mention the multiple patches support Thomas Petazzoni
@ 2013-01-06 15:22 ` Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 04/15] elfutils: make it possible to only install the libraries Thomas Petazzoni
` (12 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Thomas Petazzoni @ 2013-01-06 15:22 UTC (permalink / raw)
To: buildroot
From: Stefan Fr?berg <stefan.froberg@petroprogram.com>
This patch adds a a package for elfutils. For now, the package is
glibc specific, as adding uClibc support for this package is quite
tedious, and will therefore be done through followup patches.
Heavily based from work done by Stefan Fr?berg, but with many further
modifications by Thomas Petazzoni.
Signed-off-by: Stefan Fr?berg <stefan.froberg@petroprogram.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
package/Config.in | 1 +
package/elfutils/Config.in | 15 +++++++++++++
package/elfutils/elfutils.mk | 49 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 65 insertions(+)
create mode 100644 package/elfutils/Config.in
create mode 100644 package/elfutils/elfutils.mk
diff --git a/package/Config.in b/package/Config.in
index 11ff82d..0cf0a2b 100644
--- a/package/Config.in
+++ b/package/Config.in
@@ -512,6 +512,7 @@ menu "Other"
source "package/apr/Config.in"
source "package/apr-util/Config.in"
source "package/classpath/Config.in"
+source "package/elfutils/Config.in"
source "package/fftw/Config.in"
source "package/libargtable2/Config.in"
source "package/argp-standalone/Config.in"
diff --git a/package/elfutils/Config.in b/package/elfutils/Config.in
new file mode 100644
index 0000000..836ce4c
--- /dev/null
+++ b/package/elfutils/Config.in
@@ -0,0 +1,15 @@
+comment "elfutils requires a glibc toolchain"
+ depends on !(BR2_TOOLCHAIN_EXTERNAL_GLIBC || \
+ BR2_TOOLCHAIN_CTNG_glibc || \
+ BR2_TOOLCHAIN_CTNG_eglibc)
+
+config BR2_PACKAGE_ELFUTILS
+ bool "elfutils"
+ depends on BR2_TOOLCHAIN_EXTERNAL_GLIBC || \
+ BR2_TOOLCHAIN_CTNG_glibc || \
+ BR2_TOOLCHAIN_CTNG_eglibc
+ help
+ Libraries/utilities to handle ELF objects (drop in
+ replacement for libelf).
+
+ https://fedorahosted.org/elfutils
diff --git a/package/elfutils/elfutils.mk b/package/elfutils/elfutils.mk
new file mode 100644
index 0000000..2750060
--- /dev/null
+++ b/package/elfutils/elfutils.mk
@@ -0,0 +1,49 @@
+#############################################################
+#
+# elfutils
+#
+#############################################################
+ELFUTILS_VERSION = 0.155
+ELFUTILS_SOURCE = elfutils-$(ELFUTILS_VERSION).tar.bz2
+ELFUTILS_SITE = https://fedorahosted.org/releases/e/l/elfutils/$(ELFUTILS_VERSION)
+ELFUTILS_LICENSE = GPLv3 GPLv2 LGPLv3
+ELFUTILS_LICENSE_FILES = COPYING COPYING-GPLV2 COPYING-LGPLV3
+
+# The tarball does not have a generated configure script
+ELFUTILS_AUTORECONF = YES
+ELFUTILS_CONF_OPT += --disable-werror
+ELFUTILS_PATCH = \
+ elfutils-portability.patch \
+ elfutils-robustify.patch
+
+ELFUTILS_INSTALL_STAGING = YES
+
+ifeq ($(BR2_LARGEFILE),y)
+# elfutils gets confused when lfs mode is forced, so don't
+ELFUTILS_CONF_ENV += \
+ CFLAGS="$(filter-out -D_FILE_OFFSET_BITS=64,$(TARGET_CFLAGS))" \
+ CPPFLAGS="$(filter-out -D_FILE_OFFSET_BITS=64,$(TARGET_CPPFLAGS))"
+endif
+
+ifeq ($(BR2_PACKAGE_ZLIB),y)
+ ELFUTILS_DEPENDENCIES += zlib
+ ELFUTILS_CONF_OPT += --with-zlib
+else
+ ELFUTILS_CONF_OPT += --without-zlib
+endif
+
+ifeq ($(BR2_PACKAGE_BZIP2),y)
+ ELFUTILS_DEPENDENCIES += bzip2
+ ELFUTILS_CONF_OPT += --with-bzlib
+else
+ ELFUTILS_CONF_OPT += --without-bzlib
+endif
+
+ifeq ($(BR2_PACKAGE_XZ),y)
+ ELFUTILS_DEPENDENCIES += xz
+ ELFUTILS_CONF_OPT += --with-lzma
+else
+ ELFUTILS_CONF_OPT += --without-lzma
+endif
+
+$(eval $(autotools-package))
--
1.7.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Buildroot] [PATCH 04/15] elfutils: make it possible to only install the libraries
2013-01-06 15:22 [Buildroot] [pull request] Pull request for branch perf-elfutils Thomas Petazzoni
` (2 preceding siblings ...)
2013-01-06 15:22 ` [Buildroot] [PATCH 03/15] elfutils: new package Thomas Petazzoni
@ 2013-01-06 15:22 ` Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 05/15] perf: new package Thomas Petazzoni
` (11 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Thomas Petazzoni @ 2013-01-06 15:22 UTC (permalink / raw)
To: buildroot
Add and use a --{enable,disable}-progs configuration option to
selectively enable or disable the elfutils programs. Generally, on an
embedded system, the libraries are more useful than the programs, and
being able to not build the programs will make it easier to build the
elfutils libraries on uClibc.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
package/elfutils/Config.in | 13 ++++++
package/elfutils/elfutils-01-disable-progs.patch | 47 ++++++++++++++++++++++
package/elfutils/elfutils.mk | 6 +++
3 files changed, 66 insertions(+)
create mode 100644 package/elfutils/elfutils-01-disable-progs.patch
diff --git a/package/elfutils/Config.in b/package/elfutils/Config.in
index 836ce4c..87744b5 100644
--- a/package/elfutils/Config.in
+++ b/package/elfutils/Config.in
@@ -12,4 +12,17 @@ config BR2_PACKAGE_ELFUTILS
Libraries/utilities to handle ELF objects (drop in
replacement for libelf).
+ Note that this option only installs the libraries, and not
+ the programs.
+
https://fedorahosted.org/elfutils
+
+if BR2_PACKAGE_ELFUTILS
+
+config BR2_PACKAGE_ELFUTILS_PROGS
+ bool "Install programs"
+ help
+ This option tells elfutils to not only install the libelf
+ libraries, but also the elfutils programs.
+
+endif
diff --git a/package/elfutils/elfutils-01-disable-progs.patch b/package/elfutils/elfutils-01-disable-progs.patch
new file mode 100644
index 0000000..462de89
--- /dev/null
+++ b/package/elfutils/elfutils-01-disable-progs.patch
@@ -0,0 +1,47 @@
+Add a --{enable,disable}-progs configure option
+
+Add a --{enable,disable}-progs configuration option to elfutils. This
+allows to selectively disable the compilation of the elfutils programs
+(in which case only the libraries are built and installed). This is
+useful because the programs are often not needed, and also because
+building the programs against uClibc causes several issues (lack of
+obstack_printf() in uClibc for example).
+
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+
+Index: b/Makefile.am
+===================================================================
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -22,9 +22,13 @@
+
+ pkginclude_HEADERS = version.h
+
++if ENABLE_PROGS
++PROGS_SUBDIR = src
++endif
++
+ # Add doc back when we have some real content.
+ SUBDIRS = config m4 lib libelf libebl libdwfl libdw libcpu libasm backends \
+- src po tests
++ $(PROGS_SUBDIR) po tests
+
+ EXTRA_DIST = elfutils.spec GPG-KEY NOTES CONTRIBUTING \
+ COPYING COPYING-GPLV2 COPYING-LGPLV3
+Index: b/configure.ac
+===================================================================
+--- a/configure.ac
++++ b/configure.ac
+@@ -263,6 +263,12 @@
+ AC_DEFINE_UNQUOTED(LIBEBL_SUBDIR, "$LIBEBL_SUBDIR")
+ AH_TEMPLATE([LIBEBL_SUBDIR], [$libdir subdirectory containing libebl modules.])
+
++AC_ARG_ENABLE([progs],
++ AS_HELP_STRING([--enable-progs], [enable progs]),
++ enable_progs=$enableval,
++ enable_progs=yes)
++AM_CONDITIONAL(ENABLE_PROGS, test "$enable_progs" = yes)
++
+ dnl Test for zlib and bzlib, gives ZLIB/BZLIB .am
+ dnl conditional and config.h USE_ZLIB/USE_BZLIB #define.
+ save_LIBS="$LIBS"
diff --git a/package/elfutils/elfutils.mk b/package/elfutils/elfutils.mk
index 2750060..f8a4e85 100644
--- a/package/elfutils/elfutils.mk
+++ b/package/elfutils/elfutils.mk
@@ -46,4 +46,10 @@ else
ELFUTILS_CONF_OPT += --without-lzma
endif
+ifeq ($(BR2_PACKAGE_ELFUTILS_PROGS),y)
+ ELFUTILS_CONF_OPT += --enable-progs
+else
+ ELFUTILS_CONF_OPT += --disable-progs
+endif
+
$(eval $(autotools-package))
--
1.7.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Buildroot] [PATCH 05/15] perf: new package
2013-01-06 15:22 [Buildroot] [pull request] Pull request for branch perf-elfutils Thomas Petazzoni
` (3 preceding siblings ...)
2013-01-06 15:22 ` [Buildroot] [PATCH 04/15] elfutils: make it possible to only install the libraries Thomas Petazzoni
@ 2013-01-06 15:22 ` Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 06/15] perf: allow build against libelf when available Thomas Petazzoni
` (10 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Thomas Petazzoni @ 2013-01-06 15:22 UTC (permalink / raw)
To: buildroot
This patch adds a new package that allows to build the 'perf'
userspace tool that comes in the tools/perf directory of the kernel
sources.
It is an alternative proposal to the one done by Kaiwan Billimoria
<kaiwan.billimoria@gmail.com>, in that it creates the package in
package/perf/. It therefore properly integrates with the Buildroot
package infrastructure.
Of course, the package depends on the Linux kernel to be built by
Buildroot, in order to get Perf sources matching the version of the
kernel that will be executed.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
package/Config.in | 1 +
package/perf/Config.in | 22 ++++++++++++++++++++++
package/perf/perf.mk | 39 +++++++++++++++++++++++++++++++++++++++
3 files changed, 62 insertions(+)
create mode 100644 package/perf/Config.in
create mode 100644 package/perf/perf.mk
diff --git a/package/Config.in b/package/Config.in
index 0cf0a2b..0584462 100644
--- a/package/Config.in
+++ b/package/Config.in
@@ -35,6 +35,7 @@ source "package/ltrace/Config.in"
source "package/memstat/Config.in"
source "package/netperf/Config.in"
source "package/oprofile/Config.in"
+source "package/perf/Config.in"
source "package/ramspeed/Config.in"
source "package/rt-tests/Config.in"
source "package/strace/Config.in"
diff --git a/package/perf/Config.in b/package/perf/Config.in
new file mode 100644
index 0000000..54b24fe
--- /dev/null
+++ b/package/perf/Config.in
@@ -0,0 +1,22 @@
+config BR2_PACKAGE_PERF
+ bool "perf"
+ depends on BR2_LINUX_KERNEL
+ depends on BR2_LARGEFILE
+ help
+ perf (sometimes "Perf Events" or perf tools, originally
+ "Performance Counters for Linux") - is a performance
+ analyzing tool in Linux, available from kernel version
+ 2.6.31. User-space controlling utility, called 'perf' has
+ git-like interface with subcommands. It is capable of
+ statistical profiling of entire system (both kernel and user
+ code), single CPU or severals threads.
+
+ This package builds and install the userspace 'perf'
+ command. It is up to the user to ensure that the kernel
+ configuration has all suitable options enable to allow a
+ proper operation of 'perf'.
+
+ https://perf.wiki.kernel.org/
+
+comment "perf only available if Linux kernel is enabled, and requires largefile support"
+ depends on !BR2_LINUX_KERNEL || !BR2_LARGEFILE
diff --git a/package/perf/perf.mk b/package/perf/perf.mk
new file mode 100644
index 0000000..2aef900
--- /dev/null
+++ b/package/perf/perf.mk
@@ -0,0 +1,39 @@
+#############################################################
+#
+# perf
+#
+#############################################################
+
+# Source taken from the Linux kernel tree
+PERF_SOURCE =
+PERF_VERSION = $(call qstrip,$(BR2_LINUX_KERNEL_VERSION))
+
+PERF_DEPENDENCIES = linux
+
+PERF_MAKE_FLAGS = \
+ $(LINUX_MAKE_FLAGS) \
+ NO_LIBELF=1 \
+ NO_DWARF=1 \
+ NO_LIBAUDIT=1 \
+ NO_NEWT=1 \
+ NO_GTK2=1 \
+ NO_LIBPERL=1 \
+ NO_LIBPYTHON=1 \
+ DESTDIR=$(TARGET_DIR) \
+ prefix=/usr \
+ WERROR=0
+
+define PERF_BUILD_CMDS
+ $(MAKE) -C $(LINUX_DIR)/tools/perf \
+ $(PERF_MAKE_FLAGS) O=$(@D)
+endef
+
+# After installation, we remove the Perl and Python scripts from the
+# target.
+define PERF_INSTALL_TARGET_CMDS
+ $(MAKE) -C $(LINUX_DIR)/tools/perf \
+ $(PERF_MAKE_FLAGS) O=$(@D) install
+ $(RM) -rf $(TARGET_DIR)/usr/libexec/perf-core/scripts/
+endef
+
+$(eval $(generic-package))
--
1.7.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Buildroot] [PATCH 06/15] perf: allow build against libelf when available
2013-01-06 15:22 [Buildroot] [pull request] Pull request for branch perf-elfutils Thomas Petazzoni
` (4 preceding siblings ...)
2013-01-06 15:22 ` [Buildroot] [PATCH 05/15] perf: new package Thomas Petazzoni
@ 2013-01-06 15:22 ` Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 07/15] perf: add kernel version checks Thomas Petazzoni
` (9 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Thomas Petazzoni @ 2013-01-06 15:22 UTC (permalink / raw)
To: buildroot
Now that libelf is available thanks to elfutils (for glibc only),
allow to build perf against it if available.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
package/perf/perf.mk | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/package/perf/perf.mk b/package/perf/perf.mk
index 2aef900..eed30a2 100644
--- a/package/perf/perf.mk
+++ b/package/perf/perf.mk
@@ -12,8 +12,6 @@ PERF_DEPENDENCIES = linux
PERF_MAKE_FLAGS = \
$(LINUX_MAKE_FLAGS) \
- NO_LIBELF=1 \
- NO_DWARF=1 \
NO_LIBAUDIT=1 \
NO_NEWT=1 \
NO_GTK2=1 \
@@ -23,6 +21,12 @@ PERF_MAKE_FLAGS = \
prefix=/usr \
WERROR=0
+ifeq ($(BR2_PACKAGE_ELFUTILS),y)
+ PERF_DEPENDENCIES += elfutils
+else
+ PERF_MAKE_FLAGS += NO_LIBELF=1 NO_DWARF=1
+endif
+
define PERF_BUILD_CMDS
$(MAKE) -C $(LINUX_DIR)/tools/perf \
$(PERF_MAKE_FLAGS) O=$(@D)
--
1.7.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Buildroot] [PATCH 07/15] perf: add kernel version checks
2013-01-06 15:22 [Buildroot] [pull request] Pull request for branch perf-elfutils Thomas Petazzoni
` (5 preceding siblings ...)
2013-01-06 15:22 ` [Buildroot] [PATCH 06/15] perf: allow build against libelf when available Thomas Petazzoni
@ 2013-01-06 15:22 ` Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 08/15] argp-standlone: build position independent code Thomas Petazzoni
` (8 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Thomas Petazzoni @ 2013-01-06 15:22 UTC (permalink / raw)
To: buildroot
perf is only available since kernel 2.6.31, so if we can't find
tools/perf/Makefile, error out and tell the user about this.
perf without libelf can only be built since kernel 3.7, so error out
and tell the user about this if he's trying to build perf from a < 3.7
kernel without libelf.
Unfortunately, those tests can only be build-time checks as we either
need to know the real kernel version (i.e, using LINUX_VERSION would
not be correct as it can be a Git commit ID, or Git tag), or have
access to the kernel sources themselves. So we can't prevent those
invalid situations at the configuration, we can only nicely tell the
user at build time.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
package/perf/perf.mk | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/package/perf/perf.mk b/package/perf/perf.mk
index eed30a2..4356f5d 100644
--- a/package/perf/perf.mk
+++ b/package/perf/perf.mk
@@ -28,6 +28,18 @@ else
endif
define PERF_BUILD_CMDS
+ $(Q)if test ! -f $(LINUX_DIR)/tools/perf/Makefile ; then \
+ echo "Your kernel version is too old and does not have the perf tool." ; \
+ echo "At least kernel 2.6.31 must be used." ; \
+ exit 1 ; \
+ fi
+ $(Q)if test "$(BR2_PACKAGE_ELFUTILS)" = "" ; then \
+ if ! grep -q NO_LIBELF $(LINUX_DIR)/tools/perf/Makefile ; then \
+ echo "The perf tool in your kernel cannot be built without libelf." ; \
+ echo "Either upgrade your kernel to >= 3.7, or enable the elfutils package." ; \
+ exit 1 ; \
+ fi \
+ fi
$(MAKE) -C $(LINUX_DIR)/tools/perf \
$(PERF_MAKE_FLAGS) O=$(@D)
endef
--
1.7.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Buildroot] [PATCH 08/15] argp-standlone: build position independent code
2013-01-06 15:22 [Buildroot] [pull request] Pull request for branch perf-elfutils Thomas Petazzoni
` (6 preceding siblings ...)
2013-01-06 15:22 ` [Buildroot] [PATCH 07/15] perf: add kernel version checks Thomas Petazzoni
@ 2013-01-06 15:22 ` Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 09/15] elfutils: towards uClibc support: argp-standalone usage Thomas Petazzoni
` (7 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Thomas Petazzoni @ 2013-01-06 15:22 UTC (permalink / raw)
To: buildroot
Even though argp-standalone is built as a static library, it might get
linked in a shared library, so we must built it as
position-independent code.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
package/argp-standalone/argp-standalone.mk | 3 +++
1 file changed, 3 insertions(+)
diff --git a/package/argp-standalone/argp-standalone.mk b/package/argp-standalone/argp-standalone.mk
index 47c09b2..ba7f757 100644
--- a/package/argp-standalone/argp-standalone.mk
+++ b/package/argp-standalone/argp-standalone.mk
@@ -8,6 +8,9 @@ ARGP_STANDALONE_VERSION = 1.3
ARGP_STANDALONE_SITE = http://www.lysator.liu.se/~nisse/archive
ARGP_STANDALONE_INSTALL_STAGING = YES
+ARGP_STANDALONE_CONF_ENV = \
+ CFLAGS="$(TARGET_CFLAGS) -fPIC"
+
define ARGP_STANDALONE_INSTALL_STAGING_CMDS
$(INSTALL) -D $(@D)/libargp.a $(STAGING_DIR)/usr/lib/libargp.a
$(INSTALL) -D $(@D)/argp.h $(STAGING_DIR)/usr/include/argp.h
--
1.7.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Buildroot] [PATCH 09/15] elfutils: towards uClibc support: argp-standalone usage
2013-01-06 15:22 [Buildroot] [pull request] Pull request for branch perf-elfutils Thomas Petazzoni
` (7 preceding siblings ...)
2013-01-06 15:22 ` [Buildroot] [PATCH 08/15] argp-standlone: build position independent code Thomas Petazzoni
@ 2013-01-06 15:22 ` Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 10/15] elfutils: towards uClibc support: solve memcpy problem Thomas Petazzoni
` (6 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Thomas Petazzoni @ 2013-01-06 15:22 UTC (permalink / raw)
To: buildroot
elfutils uses the argp family of functions, that isn't available in
uClibc. So, we add a dependency on argp-standalone if building with
uClibc, and modify elfutils source code to link against argp if
needed.
Heavily based from work done by Stefan Fr?berg, but with many further
modifications by Thomas Petazzoni.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
package/elfutils/Config.in | 4 +
package/elfutils/elfutils-02-argp-support.patch | 92 +++++++++++++++++++++++
package/elfutils/elfutils.mk | 4 +
3 files changed, 100 insertions(+)
create mode 100644 package/elfutils/elfutils-02-argp-support.patch
diff --git a/package/elfutils/Config.in b/package/elfutils/Config.in
index 87744b5..ee1e4ab 100644
--- a/package/elfutils/Config.in
+++ b/package/elfutils/Config.in
@@ -8,6 +8,10 @@ config BR2_PACKAGE_ELFUTILS
depends on BR2_TOOLCHAIN_EXTERNAL_GLIBC || \
BR2_TOOLCHAIN_CTNG_glibc || \
BR2_TOOLCHAIN_CTNG_eglibc
+ select BR2_PACKAGE_ARGP_STANDALONE if \
+ BR2_TOOLCHAIN_BUILDROOT || \
+ BR2_TOOLCHAIN_CTNG_uClibc || \
+ BR2_TOOLCHAIN_EXTERNAL_UCLIBC
help
Libraries/utilities to handle ELF objects (drop in
replacement for libelf).
diff --git a/package/elfutils/elfutils-02-argp-support.patch b/package/elfutils/elfutils-02-argp-support.patch
new file mode 100644
index 0000000..f81ac8f
--- /dev/null
+++ b/package/elfutils/elfutils-02-argp-support.patch
@@ -0,0 +1,92 @@
+Allow the usage of an external implementation of the argp functions
+
+uClibc lack the argp family of functions that glibc has. Therefore, we
+add a check in the configure script to see if argp_parse is available
+in the C library. If not, we look if it is available in the additional
+'argp' library. If so, we link against that library. If not, we error
+out.
+
+This allows to build elfutils against uClibc with an external argp
+library.
+
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+
+Index: b/configure.ac
+===================================================================
+--- a/configure.ac
++++ b/configure.ac
+@@ -269,6 +269,13 @@
+ enable_progs=yes)
+ AM_CONDITIONAL(ENABLE_PROGS, test "$enable_progs" = yes)
+
++AC_CHECK_FUNC([argp_parse])
++if test "$ac_cv_func_argp_parse" != yes; then
++ AC_CHECK_LIB([argp],[argp_parse],ARGP_LIBS=-largp,
++ AC_MSG_ERROR([No argp_parse function available.]))
++fi
++AC_SUBST(ARGP_LIBS)
++
+ dnl Test for zlib and bzlib, gives ZLIB/BZLIB .am
+ dnl conditional and config.h USE_ZLIB/USE_BZLIB #define.
+ save_LIBS="$LIBS"
+Index: b/src/Makefile.am
+===================================================================
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -98,26 +98,29 @@
+ # Buggy old compilers.
+ readelf_no_Werror = yes
+
+-readelf_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl
++readelf_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl \
++ $(ARGP_LIBS)
+ nm_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl \
+- $(demanglelib)
+-size_LDADD = $(libelf) $(libeu) $(libmudflap)
+-strip_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl
+-ld_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl
++ $(demanglelib) $(ARGP_LIBS)
++size_LDADD = $(libelf) $(libeu) $(libmudflap) $(ARGP_LIBS)
++strip_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl $(ARGP_LIBS)
++ld_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl $(ARGP_LIBS)
+ if NATIVE_LD
+ # -ldl is always needed for libebl.
+ ld_LDADD += libld_elf.a
+ endif
+ ld_LDFLAGS = -rdynamic
+-elflint_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl
+-findtextrel_LDADD = $(libdw) $(libelf) $(libmudflap)
+-addr2line_LDADD = $(libdw) $(libelf) $(libmudflap)
+-elfcmp_LDADD = $(libebl) $(libelf) $(libmudflap) -ldl
+-objdump_LDADD = $(libasm) $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl
+-ranlib_LDADD = libar.a $(libelf) $(libeu) $(libmudflap)
+-strings_LDADD = $(libelf) $(libeu) $(libmudflap)
+-ar_LDADD = libar.a $(libelf) $(libeu) $(libmudflap)
+-unstrip_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(libmudflap) -ldl
++elflint_LDADD = $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl $(ARGP_LIBS)
++findtextrel_LDADD = $(libdw) $(libelf) $(libmudflap) $(ARGP_LIBS)
++addr2line_LDADD = $(libdw) $(libelf) $(libmudflap) $(ARGP_LIBS)
++elfcmp_LDADD = $(libebl) $(libelf) $(libmudflap) -ldl $(ARGP_LIBS)
++objdump_LDADD = $(libasm) $(libebl) $(libelf) $(libeu) $(libmudflap) -ldl \
++ $(ARGP_LIBS)
++ranlib_LDADD = libar.a $(libelf) $(libeu) $(libmudflap) $(ARGP_LIBS)
++strings_LDADD = $(libelf) $(libeu) $(libmudflap) $(ARGP_LIBS)
++ar_LDADD = libar.a $(libelf) $(libeu) $(libmudflap) $(ARGP_LIBS)
++unstrip_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(libmudflap) -ldl \
++ $(ARGP_LIBS)
+
+ ldlex.o: ldscript.c
+ ldlex_no_Werror = yes
+Index: b/libdw/Makefile.am
+===================================================================
+--- a/libdw/Makefile.am
++++ b/libdw/Makefile.am
+@@ -111,7 +111,7 @@
+ -Wl,--enable-new-dtags,-rpath,$(pkglibdir) \
+ -Wl,--version-script,$<,--no-undefined \
+ -Wl,--whole-archive $(filter-out $<,$^) -Wl,--no-whole-archive\
+- -ldl $(zip_LIBS)
++ -ldl $(zip_LIBS) $(ARGP_LIBS)
+ if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi
+ ln -fs $@ $@.$(VERSION)
+
diff --git a/package/elfutils/elfutils.mk b/package/elfutils/elfutils.mk
index f8a4e85..9f9de52 100644
--- a/package/elfutils/elfutils.mk
+++ b/package/elfutils/elfutils.mk
@@ -25,6 +25,10 @@ ELFUTILS_CONF_ENV += \
CPPFLAGS="$(filter-out -D_FILE_OFFSET_BITS=64,$(TARGET_CPPFLAGS))"
endif
+ifeq ($(BR2_TOOLCHAIN_BUILDROOT)$(BR2_TOOLCHAIN_EXTERNAL_UCLIBC)$(BR2_TOOLCHAIN_CTNG_uClibc),y)
+ ELFUTILS_DEPENDENCIES += argp-standalone
+endif
+
ifeq ($(BR2_PACKAGE_ZLIB),y)
ELFUTILS_DEPENDENCIES += zlib
ELFUTILS_CONF_OPT += --with-zlib
--
1.7.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Buildroot] [PATCH 10/15] elfutils: towards uClibc support: solve memcpy problem
2013-01-06 15:22 [Buildroot] [pull request] Pull request for branch perf-elfutils Thomas Petazzoni
` (8 preceding siblings ...)
2013-01-06 15:22 ` [Buildroot] [PATCH 09/15] elfutils: towards uClibc support: argp-standalone usage Thomas Petazzoni
@ 2013-01-06 15:22 ` Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 11/15] elfutils: towards uClibc support: requires largefile Thomas Petazzoni
` (5 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Thomas Petazzoni @ 2013-01-06 15:22 UTC (permalink / raw)
To: buildroot
elfutils uses some strange internal alias of memcpy in glibc, so
workaround this when building with uClibc.
Heavily based from work done by Stefan Fr?berg, but with many further
modifications by Thomas Petazzoni.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
package/elfutils/elfutils-03-memcpy-def.patch | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
create mode 100644 package/elfutils/elfutils-03-memcpy-def.patch
diff --git a/package/elfutils/elfutils-03-memcpy-def.patch b/package/elfutils/elfutils-03-memcpy-def.patch
new file mode 100644
index 0000000..eb50cf6
--- /dev/null
+++ b/package/elfutils/elfutils-03-memcpy-def.patch
@@ -0,0 +1,24 @@
+Provide a compatibility alias __memcpy
+
+For some reason, libelf uses the internal glibc alias __memcpy, which
+doesn't exist in uClibc. Add a manual alias so that the build can
+proceed with uClibc.
+
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+
+Index: b/libelf/libelf.h
+===================================================================
+--- a/libelf/libelf.h
++++ b/libelf/libelf.h
+@@ -34,6 +34,11 @@
+ /* Get the ELF types. */
+ #include <elf.h>
+
++#ifndef _LIBC
++#ifndef __mempcpy
++#define __mempcpy mempcpy
++#endif
++#endif
+
+ /* Known translation types. */
+ typedef enum
--
1.7.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Buildroot] [PATCH 11/15] elfutils: towards uClibc support: requires largefile
2013-01-06 15:22 [Buildroot] [pull request] Pull request for branch perf-elfutils Thomas Petazzoni
` (9 preceding siblings ...)
2013-01-06 15:22 ` [Buildroot] [PATCH 10/15] elfutils: towards uClibc support: solve memcpy problem Thomas Petazzoni
@ 2013-01-06 15:22 ` Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 12/15] elfutils: towards uClibc support: gettext Thomas Petazzoni
` (4 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Thomas Petazzoni @ 2013-01-06 15:22 UTC (permalink / raw)
To: buildroot
elfutils unconditionally uses off64_t for example, so largefile is
needed.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
package/elfutils/Config.in | 1 +
1 file changed, 1 insertion(+)
diff --git a/package/elfutils/Config.in b/package/elfutils/Config.in
index ee1e4ab..5ec4ca9 100644
--- a/package/elfutils/Config.in
+++ b/package/elfutils/Config.in
@@ -12,6 +12,7 @@ config BR2_PACKAGE_ELFUTILS
BR2_TOOLCHAIN_BUILDROOT || \
BR2_TOOLCHAIN_CTNG_uClibc || \
BR2_TOOLCHAIN_EXTERNAL_UCLIBC
+ depends on BR2_LARGEFILE
help
Libraries/utilities to handle ELF objects (drop in
replacement for libelf).
--
1.7.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Buildroot] [PATCH 12/15] elfutils: towards uClibc support: gettext
2013-01-06 15:22 [Buildroot] [pull request] Pull request for branch perf-elfutils Thomas Petazzoni
` (10 preceding siblings ...)
2013-01-06 15:22 ` [Buildroot] [PATCH 11/15] elfutils: towards uClibc support: requires largefile Thomas Petazzoni
@ 2013-01-06 15:22 ` Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 13/15] elfutils: towards uClibc support: FTS functions Thomas Petazzoni
` (3 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Thomas Petazzoni @ 2013-01-06 15:22 UTC (permalink / raw)
To: buildroot
elfutils is annoying: it needs gettext even if locale support is
disabled...
Heavily based from work done by Stefan Fr?berg, but with many further
modifications by Thomas Petazzoni.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
package/elfutils/Config.in | 1 +
package/elfutils/elfutils.mk | 11 +++++++++++
2 files changed, 12 insertions(+)
diff --git a/package/elfutils/Config.in b/package/elfutils/Config.in
index 5ec4ca9..78d02a5 100644
--- a/package/elfutils/Config.in
+++ b/package/elfutils/Config.in
@@ -12,6 +12,7 @@ config BR2_PACKAGE_ELFUTILS
BR2_TOOLCHAIN_BUILDROOT || \
BR2_TOOLCHAIN_CTNG_uClibc || \
BR2_TOOLCHAIN_EXTERNAL_UCLIBC
+ select BR2_PACKAGE_GETTEXT if BR2_NEEDS_GETTEXT
depends on BR2_LARGEFILE
help
Libraries/utilities to handle ELF objects (drop in
diff --git a/package/elfutils/elfutils.mk b/package/elfutils/elfutils.mk
index 9f9de52..39407db 100644
--- a/package/elfutils/elfutils.mk
+++ b/package/elfutils/elfutils.mk
@@ -25,6 +25,17 @@ ELFUTILS_CONF_ENV += \
CPPFLAGS="$(filter-out -D_FILE_OFFSET_BITS=64,$(TARGET_CPPFLAGS))"
endif
+ELFUTILS_LDFLAGS = $(TARGET_LDFLAGS)
+
+# Unconditionnally requires gettext.
+ifeq ($(BR2_NEEDS_GETTEXT),y)
+ELFUTILS_DEPENDENCIES += gettext
+ELFUTILS_LDFLAGS += -lintl
+endif
+
+ELFUTILS_CONF_ENV += \
+ LDFLAGS="$(ELFUTILS_LDFLAGS)"
+
ifeq ($(BR2_TOOLCHAIN_BUILDROOT)$(BR2_TOOLCHAIN_EXTERNAL_UCLIBC)$(BR2_TOOLCHAIN_CTNG_uClibc),y)
ELFUTILS_DEPENDENCIES += argp-standalone
endif
--
1.7.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Buildroot] [PATCH 13/15] elfutils: towards uClibc support: FTS functions
2013-01-06 15:22 [Buildroot] [pull request] Pull request for branch perf-elfutils Thomas Petazzoni
` (11 preceding siblings ...)
2013-01-06 15:22 ` [Buildroot] [PATCH 12/15] elfutils: towards uClibc support: gettext Thomas Petazzoni
@ 2013-01-06 15:22 ` Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 14/15] elfutils: towards uClibc support: disable po build Thomas Petazzoni
` (2 subsequent siblings)
15 siblings, 0 replies; 19+ messages in thread
From: Thomas Petazzoni @ 2013-01-06 15:22 UTC (permalink / raw)
To: buildroot
The fts_*() functions are optional in uClibc, and not compiled in our
default configuration. The best option would be to migrate this
elfutils code to the nftw family of functions, but it requires quite
some work.
So we have several options here:
*) Enable fts_*() functions in our default uClibc configuration. Not
nice since only one package needs them (the help text of uClibc
for fts_*() functions explicitly mention that they have been added
to be able to build elfutils).
*) Use gnulib, but it is quite heavy to setup, requires modifications
to configure.ac, and other things.
*) Copy the fts function from uClibc into elfutils source code. This
is the solution used below. uClibc is LGPL, and elfutils is
LGPL/GPL, so there should not be any licensing issue.
Of course, the fts_*() functions are only built if they are not
already provided by the C library.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
package/elfutils/elfutils-04-fts.patch | 1307 ++++++++++++++++++++++++++++++++
1 file changed, 1307 insertions(+)
create mode 100644 package/elfutils/elfutils-04-fts.patch
diff --git a/package/elfutils/elfutils-04-fts.patch b/package/elfutils/elfutils-04-fts.patch
new file mode 100644
index 0000000..7318236
--- /dev/null
+++ b/package/elfutils/elfutils-04-fts.patch
@@ -0,0 +1,1307 @@
+Add an implementation of the fts_*() functions
+
+The fts_*() functions are optional in uClibc, and not compiled in our
+default configuration. The best option would be to migrate this
+elfutils code to the nftw family of functions, but it requires quite
+some work.
+
+So we have several options here:
+
+ *) Enable fts_*() functions in our default uClibc configuration. Not
+ nice since only one package needs them (the help text of uClibc
+ for fts_*() functions explicitly mention that they have been added
+ to be able to build elfutils).
+
+ *) Use gnulib, but it is quite heavy to setup, requires modifications
+ to configure.ac, and other things.
+
+ *) Copy the fts function from uClibc into elfutils source code. This
+ is the solution used below. uClibc is LGPL, and elfutils is
+ LGPL/GPL, so there should not be any licensing issue.
+
+Of course, the fts_*() functions are only built if they are not
+already provided by the C library.
+
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+
+Index: b/configure.ac
+===================================================================
+--- a/configure.ac
++++ b/configure.ac
+@@ -276,6 +276,10 @@
+ fi
+ AC_SUBST(ARGP_LIBS)
+
++AC_CHECK_HEADER([fts.h],
++ AC_DEFINE([HAVE_FTS_H], [], [Define if <fts.h> is available in C library]))
++AM_CONDITIONAL(HAVE_FTS, test "$ac_cv_header_fts_h" = yes)
++
+ dnl Test for zlib and bzlib, gives ZLIB/BZLIB .am
+ dnl conditional and config.h USE_ZLIB/USE_BZLIB #define.
+ save_LIBS="$LIBS"
+Index: b/libdwfl/Makefile.am
+===================================================================
+--- a/libdwfl/Makefile.am
++++ b/libdwfl/Makefile.am
+@@ -79,6 +79,9 @@
+ if LZMA
+ libdwfl_a_SOURCES += lzma.c
+ endif
++if !HAVE_FTS
++libdwfl_a_SOURCES += fts.c
++endif
+
+ if MUDFLAP
+ libdwfl = libdwfl.a $(libdw) $(libebl) $(libelf) $(libeu)
+Index: b/libdwfl/fts.c
+===================================================================
+--- /dev/null
++++ b/libdwfl/fts.c
+@@ -0,0 +1,1095 @@
++/*-
++ * Copyright (c) 1990, 1993, 1994
++ * The Regents of the University of California. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 4. Neither the name of the University nor the names of its contributors
++ * may be used to endorse or promote products derived from this software
++ * without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++#include <sys/param.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <dirent.h>
++#include <errno.h>
++#include "fts_.h"
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++
++/* Largest alignment size needed, minus one.
++ Usually long double is the worst case. */
++#ifndef ALIGNBYTES
++#define ALIGNBYTES (__alignof__ (long double) - 1)
++#endif
++/* Align P to that size. */
++#ifndef ALIGN
++#define ALIGN(p) (((unsigned long int) (p) + ALIGNBYTES) & ~ALIGNBYTES)
++#endif
++
++
++static FTSENT *fts_alloc (FTS *, const char *, size_t);
++static FTSENT *fts_build (FTS *, int);
++static void fts_lfree (FTSENT *);
++static void fts_load (FTS *, FTSENT *);
++static size_t fts_maxarglen (char * const *);
++static void fts_padjust (FTS *, FTSENT *);
++static int fts_palloc (FTS *, size_t);
++static FTSENT *fts_sort (FTS *, FTSENT *, int);
++static u_short fts_stat (FTS *, FTSENT *, int);
++static int fts_safe_changedir (FTS *, FTSENT *, int, const char *);
++
++#ifndef MAX
++#define MAX(a, b) ({ __typeof__ (a) _a = (a); \
++ __typeof__ (b) _b = (b); \
++ _a > _b ? _a : _b; })
++#endif
++
++#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
++
++#define CLR(opt) (sp->fts_options &= ~(opt))
++#define ISSET(opt) (sp->fts_options & (opt))
++#define SET(opt) (sp->fts_options |= (opt))
++
++#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
++
++/* fts_build flags */
++#define BCHILD 1 /* fts_children */
++#define BNAMES 2 /* fts_children, names only */
++#define BREAD 3 /* fts_read */
++
++FTS *
++fts_open( char * const *argv, register int options,
++ int (*compar) (const FTSENT **, const FTSENT **))
++{
++ register FTS *sp;
++ register FTSENT *p, *root;
++ register int nitems;
++ FTSENT *parent = NULL;
++ FTSENT *tmp = NULL;
++
++ /* Options check. */
++ if (options & ~FTS_OPTIONMASK) {
++ errno = EINVAL;
++ return (NULL);
++ }
++
++ /* Allocate/initialize the stream */
++ if ((sp = malloc((u_int)sizeof(FTS))) == NULL)
++ return (NULL);
++ memset(sp, 0, sizeof(FTS));
++ sp->fts_compar = (int (*) (const void *, const void *)) compar;
++ sp->fts_options = options;
++
++ /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
++ if (ISSET(FTS_LOGICAL))
++ SET(FTS_NOCHDIR);
++
++ /*
++ * Start out with 1K of path space, and enough, in any case,
++ * to hold the user's paths.
++ */
++#ifndef MAXPATHLEN
++#define MAXPATHLEN 1024
++#endif
++ size_t maxarglen = fts_maxarglen(argv);
++ if (fts_palloc(sp, MAX(maxarglen, MAXPATHLEN)))
++ goto mem1;
++
++ /* Allocate/initialize root's parent. */
++ if (*argv != NULL) {
++ if ((parent = fts_alloc(sp, "", 0)) == NULL)
++ goto mem2;
++ parent->fts_level = FTS_ROOTPARENTLEVEL;
++ }
++
++ /* Allocate/initialize root(s). */
++ for (root = NULL, nitems = 0; *argv != NULL; ++argv, ++nitems) {
++ /* Don't allow zero-length paths. */
++ size_t len = strlen(*argv);
++ if (len == 0) {
++ errno = ENOENT;
++ goto mem3;
++ }
++
++ p = fts_alloc(sp, *argv, len);
++ p->fts_level = FTS_ROOTLEVEL;
++ p->fts_parent = parent;
++ p->fts_accpath = p->fts_name;
++ p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW));
++
++ /* Command-line "." and ".." are real directories. */
++ if (p->fts_info == FTS_DOT)
++ p->fts_info = FTS_D;
++
++ /*
++ * If comparison routine supplied, traverse in sorted
++ * order; otherwise traverse in the order specified.
++ */
++ if (compar) {
++ p->fts_link = root;
++ root = p;
++ } else {
++ p->fts_link = NULL;
++ if (root == NULL)
++ tmp = root = p;
++ else {
++ tmp->fts_link = p;
++ tmp = p;
++ }
++ }
++ }
++ if (compar && nitems > 1)
++ root = fts_sort(sp, root, nitems);
++
++ /*
++ * Allocate a dummy pointer and make fts_read think that we've just
++ * finished the node before the root(s); set p->fts_info to FTS_INIT
++ * so that everything about the "current" node is ignored.
++ */
++ if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
++ goto mem3;
++ sp->fts_cur->fts_link = root;
++ sp->fts_cur->fts_info = FTS_INIT;
++
++ /*
++ * If using chdir(2), grab a file descriptor pointing to dot to ensure
++ * that we can get back here; this could be avoided for some paths,
++ * but almost certainly not worth the effort. Slashes, symbolic links,
++ * and ".." are all fairly nasty problems. Note, if we can't get the
++ * descriptor we run anyway, just more slowly.
++ */
++ if (!ISSET(FTS_NOCHDIR)
++ && (sp->fts_rfd = open(".", O_RDONLY, 0)) < 0)
++ SET(FTS_NOCHDIR);
++
++ return (sp);
++
++mem3: fts_lfree(root);
++ free(parent);
++mem2: free(sp->fts_path);
++mem1: free(sp);
++ return (NULL);
++}
++
++static void
++fts_load(FTS *sp, register FTSENT *p)
++{
++ register int len;
++ register char *cp;
++
++ /*
++ * Load the stream structure for the next traversal. Since we don't
++ * actually enter the directory until after the preorder visit, set
++ * the fts_accpath field specially so the chdir gets done to the right
++ * place and the user can access the first node. From fts_open it's
++ * known that the path will fit.
++ */
++ len = p->fts_pathlen = p->fts_namelen;
++ memmove(sp->fts_path, p->fts_name, len + 1);
++ if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) {
++ len = strlen(++cp);
++ memmove(p->fts_name, cp, len + 1);
++ p->fts_namelen = len;
++ }
++ p->fts_accpath = p->fts_path = sp->fts_path;
++ sp->fts_dev = p->fts_dev;
++}
++
++int
++fts_close(FTS *sp)
++{
++ register FTSENT *freep, *p;
++ int saved_errno;
++
++ /*
++ * This still works if we haven't read anything -- the dummy structure
++ * points to the root list, so we step through to the end of the root
++ * list which has a valid parent pointer.
++ */
++ if (sp->fts_cur) {
++ for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
++ freep = p;
++ p = p->fts_link != NULL ? p->fts_link : p->fts_parent;
++ free(freep);
++ }
++ free(p);
++ }
++
++ /* Free up child linked list, sort array, path buffer. */
++ if (sp->fts_child)
++ fts_lfree(sp->fts_child);
++ free(sp->fts_array);
++ free(sp->fts_path);
++
++ /* Return to original directory, save errno if necessary. */
++ if (!ISSET(FTS_NOCHDIR)) {
++ saved_errno = fchdir(sp->fts_rfd) ? errno : 0;
++ (void)close(sp->fts_rfd);
++
++ /* Set errno and return. */
++ if (saved_errno != 0) {
++ /* Free up the stream pointer. */
++ free(sp);
++ errno = saved_errno;
++ return (-1);
++ }
++ }
++
++ /* Free up the stream pointer. */
++ free(sp);
++ return (0);
++}
++
++/*
++ * Special case of "/" at the end of the path so that slashes aren't
++ * appended which would cause paths to be written as "....//foo".
++ */
++#define NAPPEND(p) \
++ (p->fts_path[p->fts_pathlen - 1] == '/' \
++ ? p->fts_pathlen - 1 : p->fts_pathlen)
++
++FTSENT *
++fts_read(register FTS *sp)
++{
++ register FTSENT *p, *tmp;
++ register int instr;
++ register char *t;
++ int saved_errno;
++
++ /* If finished or unrecoverable error, return NULL. */
++ if (sp->fts_cur == NULL || ISSET(FTS_STOP))
++ return (NULL);
++
++ /* Set current node pointer. */
++ p = sp->fts_cur;
++
++ /* Save and zero out user instructions. */
++ instr = p->fts_instr;
++ p->fts_instr = FTS_NOINSTR;
++
++ /* Any type of file may be re-visited; re-stat and re-turn. */
++ if (instr == FTS_AGAIN) {
++ p->fts_info = fts_stat(sp, p, 0);
++ return (p);
++ }
++
++ /*
++ * Following a symlink -- SLNONE test allows application to see
++ * SLNONE and recover. If indirecting through a symlink, have
++ * keep a pointer to current location. If unable to get that
++ * pointer, follow fails.
++ */
++ if (instr == FTS_FOLLOW &&
++ (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
++ p->fts_info = fts_stat(sp, p, 1);
++ if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
++ if ((p->fts_symfd = open(".", O_RDONLY, 0)) < 0) {
++ p->fts_errno = errno;
++ p->fts_info = FTS_ERR;
++ } else
++ p->fts_flags |= FTS_SYMFOLLOW;
++ }
++ return (p);
++ }
++
++ /* Directory in pre-order. */
++ if (p->fts_info == FTS_D) {
++ /* If skipped or crossed mount point, do post-order visit. */
++ if (instr == FTS_SKIP ||
++ (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) {
++ if (p->fts_flags & FTS_SYMFOLLOW)
++ (void)close(p->fts_symfd);
++ if (sp->fts_child) {
++ fts_lfree(sp->fts_child);
++ sp->fts_child = NULL;
++ }
++ p->fts_info = FTS_DP;
++ return (p);
++ }
++
++ /* Rebuild if only read the names and now traversing. */
++ if (sp->fts_child != NULL && ISSET(FTS_NAMEONLY)) {
++ CLR(FTS_NAMEONLY);
++ fts_lfree(sp->fts_child);
++ sp->fts_child = NULL;
++ }
++
++ /*
++ * Cd to the subdirectory.
++ *
++ * If have already read and now fail to chdir, whack the list
++ * to make the names come out right, and set the parent errno
++ * so the application will eventually get an error condition.
++ * Set the FTS_DONTCHDIR flag so that when we logically change
++ * directories back to the parent we don't do a chdir.
++ *
++ * If haven't read do so. If the read fails, fts_build sets
++ * FTS_STOP or the fts_info field of the node.
++ */
++ if (sp->fts_child != NULL) {
++ if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
++ p->fts_errno = errno;
++ p->fts_flags |= FTS_DONTCHDIR;
++ for (p = sp->fts_child; p != NULL;
++ p = p->fts_link)
++ p->fts_accpath =
++ p->fts_parent->fts_accpath;
++ }
++ } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) {
++ if (ISSET(FTS_STOP))
++ return (NULL);
++ return (p);
++ }
++ p = sp->fts_child;
++ sp->fts_child = NULL;
++ sp->fts_cur = p;
++ goto name;
++ }
++
++ /* Move to the next node on this level. */
++next: tmp = p;
++ if ((p = p->fts_link) != NULL) {
++ sp->fts_cur = p;
++ free(tmp);
++
++ /*
++ * If reached the top, return to the original directory (or
++ * the root of the tree), and load the paths for the next root.
++ */
++ if (p->fts_level == FTS_ROOTLEVEL) {
++ if (FCHDIR(sp, sp->fts_rfd)) {
++ SET(FTS_STOP);
++ return (NULL);
++ }
++ fts_load(sp, p);
++ return p;
++ }
++
++ /*
++ * User may have called fts_set on the node. If skipped,
++ * ignore. If followed, get a file descriptor so we can
++ * get back if necessary.
++ */
++ if (p->fts_instr == FTS_SKIP)
++ goto next;
++ if (p->fts_instr == FTS_FOLLOW) {
++ p->fts_info = fts_stat(sp, p, 1);
++ if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
++ if ((p->fts_symfd =
++ open(".", O_RDONLY, 0)) < 0) {
++ p->fts_errno = errno;
++ p->fts_info = FTS_ERR;
++ } else
++ p->fts_flags |= FTS_SYMFOLLOW;
++ }
++ p->fts_instr = FTS_NOINSTR;
++ }
++
++name: t = sp->fts_path + NAPPEND(p->fts_parent);
++ *t++ = '/';
++ memmove(t, p->fts_name, p->fts_namelen + 1);
++ return p;
++ }
++
++ /* Move up to the parent node. */
++ p = tmp->fts_parent;
++ sp->fts_cur = p;
++ free(tmp);
++
++ if (p->fts_level == FTS_ROOTPARENTLEVEL) {
++ /*
++ * Done; free everything up and set errno to 0 so the user
++ * can distinguish between error and EOF.
++ */
++ free(p);
++ errno = 0;
++ return (sp->fts_cur = NULL);
++ }
++
++ /* NUL terminate the pathname. */
++ sp->fts_path[p->fts_pathlen] = '\0';
++
++ /*
++ * Return to the parent directory. If at a root node or came through
++ * a symlink, go back through the file descriptor. Otherwise, cd up
++ * one directory.
++ */
++ if (p->fts_level == FTS_ROOTLEVEL) {
++ if (FCHDIR(sp, sp->fts_rfd)) {
++ SET(FTS_STOP);
++ return (NULL);
++ }
++ } else if (p->fts_flags & FTS_SYMFOLLOW) {
++ if (FCHDIR(sp, p->fts_symfd)) {
++ saved_errno = errno;
++ (void)close(p->fts_symfd);
++ errno = saved_errno;
++ SET(FTS_STOP);
++ return (NULL);
++ }
++ (void)close(p->fts_symfd);
++ } else if (!(p->fts_flags & FTS_DONTCHDIR) &&
++ fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
++ SET(FTS_STOP);
++ return (NULL);
++ }
++ p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
++ return p;
++}
++
++/*
++ * Fts_set takes the stream as an argument although it's not used in this
++ * implementation; it would be necessary if anyone wanted to add global
++ * semantics to fts using fts_set. An error return is allowed for similar
++ * reasons.
++ */
++/* ARGSUSED */
++int
++fts_set(FTS *sp, FTSENT *p, int instr)
++{
++ if (instr != 0 && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
++ instr != FTS_NOINSTR && instr != FTS_SKIP) {
++ errno = EINVAL;
++ return (1);
++ }
++ p->fts_instr = instr;
++ return (0);
++}
++
++FTSENT *
++fts_children(register FTS *sp, int instr)
++{
++ register FTSENT *p;
++ int fd;
++
++ if (instr != 0 && instr != FTS_NAMEONLY) {
++ errno = EINVAL;
++ return (NULL);
++ }
++
++ /* Set current node pointer. */
++ p = sp->fts_cur;
++
++ /*
++ * Errno set to 0 so user can distinguish empty directory from
++ * an error.
++ */
++ errno = 0;
++
++ /* Fatal errors stop here. */
++ if (ISSET(FTS_STOP))
++ return (NULL);
++
++ /* Return logical hierarchy of user's arguments. */
++ if (p->fts_info == FTS_INIT)
++ return (p->fts_link);
++
++ /*
++ * If not a directory being visited in pre-order, stop here. Could
++ * allow FTS_DNR, assuming the user has fixed the problem, but the
++ * same effect is available with FTS_AGAIN.
++ */
++ if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */)
++ return (NULL);
++
++ /* Free up any previous child list. */
++ if (sp->fts_child != NULL)
++ fts_lfree(sp->fts_child);
++
++ if (instr == FTS_NAMEONLY) {
++ SET(FTS_NAMEONLY);
++ instr = BNAMES;
++ } else
++ instr = BCHILD;
++
++ /*
++ * If using chdir on a relative path and called BEFORE fts_read does
++ * its chdir to the root of a traversal, we can lose -- we need to
++ * chdir into the subdirectory, and we don't know where the current
++ * directory is, so we can't get back so that the upcoming chdir by
++ * fts_read will work.
++ */
++ if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' ||
++ ISSET(FTS_NOCHDIR))
++ return (sp->fts_child = fts_build(sp, instr));
++
++ if ((fd = open(".", O_RDONLY, 0)) < 0)
++ return (NULL);
++ sp->fts_child = fts_build(sp, instr);
++ if (fchdir(fd))
++ return (NULL);
++ (void)close(fd);
++ return (sp->fts_child);
++}
++
++/*
++ * This is the tricky part -- do not casually change *anything* in here. The
++ * idea is to build the linked list of entries that are used by fts_children
++ * and fts_read. There are lots of special cases.
++ *
++ * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is
++ * set and it's a physical walk (so that symbolic links can't be directories),
++ * we can do things quickly. First, if it's a 4.4BSD file system, the type
++ * of the file is in the directory entry. Otherwise, we assume that the number
++ * of subdirectories in a node is equal to the number of links to the parent.
++ * The former skips all stat calls. The latter skips stat calls in any leaf
++ * directories and for any files after the subdirectories in the directory have
++ * been found, cutting the stat calls by about 2/3.
++ */
++static FTSENT *
++fts_build(register FTS *sp, int type)
++{
++ register struct dirent *dp;
++ register FTSENT *p, *head;
++ register int nitems;
++ FTSENT *cur, *tail;
++ DIR *dirp;
++ void *oldaddr;
++ int cderrno, descend, len, level, nlinks, saved_errno,
++ nostat, doadjust;
++ size_t maxlen;
++ char *cp;
++
++ /* Set current node pointer. */
++ cur = sp->fts_cur;
++
++ /*
++ * Open the directory for reading. If this fails, we're done.
++ * If being called from fts_read, set the fts_info field.
++ */
++#if defined FTS_WHITEOUT && 0
++ if (ISSET(FTS_WHITEOUT))
++ oflag = DTF_NODUP|DTF_REWIND;
++ else
++ oflag = DTF_HIDEW|DTF_NODUP|DTF_REWIND;
++#else
++# define opendir2(path, flag) opendir(path)
++#endif
++ if ((dirp = opendir2(cur->fts_accpath, oflag)) == NULL) {
++ if (type == BREAD) {
++ cur->fts_info = FTS_DNR;
++ cur->fts_errno = errno;
++ }
++ return (NULL);
++ }
++
++ /*
++ * Nlinks is the number of possible entries of type directory in the
++ * directory if we're cheating on stat calls, 0 if we're not doing
++ * any stat calls at all, -1 if we're doing stats on everything.
++ */
++ if (type == BNAMES) {
++ nlinks = 0;
++ /* Be quiet about nostat, GCC. */
++ nostat = 0;
++ } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
++ nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2);
++ nostat = 1;
++ } else {
++ nlinks = -1;
++ nostat = 0;
++ }
++
++#ifdef notdef
++ (void)printf("nlinks == %d (cur: %d)\n", nlinks, cur->fts_nlink);
++ (void)printf("NOSTAT %d PHYSICAL %d SEEDOT %d\n",
++ ISSET(FTS_NOSTAT), ISSET(FTS_PHYSICAL), ISSET(FTS_SEEDOT));
++#endif
++ /*
++ * If we're going to need to stat anything or we want to descend
++ * and stay in the directory, chdir. If this fails we keep going,
++ * but set a flag so we don't chdir after the post-order visit.
++ * We won't be able to stat anything, but we can still return the
++ * names themselves. Note, that since fts_read won't be able to
++ * chdir into the directory, it will have to return different path
++ * names than before, i.e. "a/b" instead of "b". Since the node
++ * has already been visited in pre-order, have to wait until the
++ * post-order visit to return the error. There is a special case
++ * here, if there was nothing to stat then it's not an error to
++ * not be able to stat. This is all fairly nasty. If a program
++ * needed sorted entries or stat information, they had better be
++ * checking FTS_NS on the returned nodes.
++ */
++ cderrno = 0;
++ if (nlinks || type == BREAD) {
++ if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
++ if (nlinks && type == BREAD)
++ cur->fts_errno = errno;
++ cur->fts_flags |= FTS_DONTCHDIR;
++ descend = 0;
++ cderrno = errno;
++ (void)closedir(dirp);
++ dirp = NULL;
++ } else
++ descend = 1;
++ } else
++ descend = 0;
++
++ /*
++ * Figure out the max file name length that can be stored in the
++ * current path -- the inner loop allocates more path as necessary.
++ * We really wouldn't have to do the maxlen calculations here, we
++ * could do them in fts_read before returning the path, but it's a
++ * lot easier here since the length is part of the dirent structure.
++ *
++ * If not changing directories set a pointer so that can just append
++ * each new name into the path.
++ */
++ len = NAPPEND(cur);
++ if (ISSET(FTS_NOCHDIR)) {
++ cp = sp->fts_path + len;
++ *cp++ = '/';
++ } else {
++ /* GCC, you're too verbose. */
++ cp = NULL;
++ }
++ len++;
++ maxlen = sp->fts_pathlen - len;
++
++ level = cur->fts_level + 1;
++
++ /* Read the directory, attaching each entry to the `link' pointer. */
++ doadjust = 0;
++ for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) {
++ if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
++ continue;
++
++ if ((p = fts_alloc(sp, dp->d_name, _D_EXACT_NAMLEN (dp))) == NULL)
++ goto mem1;
++ if (_D_EXACT_NAMLEN (dp) >= maxlen) {/* include space for NUL */
++ oldaddr = sp->fts_path;
++ if (fts_palloc(sp, _D_EXACT_NAMLEN (dp) + len + 1)) {
++ /*
++ * No more memory for path or structures. Save
++ * errno, free up the current structure and the
++ * structures already allocated.
++ */
++mem1: saved_errno = errno;
++ free(p);
++ fts_lfree(head);
++ (void)closedir(dirp);
++ cur->fts_info = FTS_ERR;
++ SET(FTS_STOP);
++ errno = saved_errno;
++ return (NULL);
++ }
++ /* Did realloc() change the pointer? */
++ if (oldaddr != sp->fts_path) {
++ doadjust = 1;
++ if (ISSET(FTS_NOCHDIR))
++ cp = sp->fts_path + len;
++ }
++ maxlen = sp->fts_pathlen - len;
++ }
++
++ if (len + _D_EXACT_NAMLEN (dp) >= USHRT_MAX) {
++ /*
++ * In an FTSENT, fts_pathlen is a u_short so it is
++ * possible to wraparound here. If we do, free up
++ * the current structure and the structures already
++ * allocated, then error out with ENAMETOOLONG.
++ */
++ free(p);
++ fts_lfree(head);
++ (void)closedir(dirp);
++ cur->fts_info = FTS_ERR;
++ SET(FTS_STOP);
++ errno = ENAMETOOLONG;
++ return (NULL);
++ }
++ p->fts_level = level;
++ p->fts_parent = sp->fts_cur;
++ p->fts_pathlen = len + _D_EXACT_NAMLEN (dp);
++
++#if defined FTS_WHITEOUT && 0
++ if (dp->d_type == DT_WHT)
++ p->fts_flags |= FTS_ISW;
++#endif
++
++#if 0
++ /* Unreachable code. cderrno is only ever set to a nonnull
++ value if dirp is closed at the same time. But then we
++ cannot enter this loop. */
++ if (cderrno) {
++ if (nlinks) {
++ p->fts_info = FTS_NS;
++ p->fts_errno = cderrno;
++ } else
++ p->fts_info = FTS_NSOK;
++ p->fts_accpath = cur->fts_accpath;
++ } else
++#endif
++ if (nlinks == 0
++#if defined DT_DIR && defined _DIRENT_HAVE_D_TYPE
++ || (nostat &&
++ dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)
++#endif
++ ) {
++ p->fts_accpath =
++ ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;
++ p->fts_info = FTS_NSOK;
++ } else {
++ /* Build a file name for fts_stat to stat. */
++ if (ISSET(FTS_NOCHDIR)) {
++ p->fts_accpath = p->fts_path;
++ memmove(cp, p->fts_name, p->fts_namelen + 1);
++ } else
++ p->fts_accpath = p->fts_name;
++ /* Stat it. */
++ p->fts_info = fts_stat(sp, p, 0);
++
++ /* Decrement link count if applicable. */
++ if (nlinks > 0 && (p->fts_info == FTS_D ||
++ p->fts_info == FTS_DC || p->fts_info == FTS_DOT))
++ --nlinks;
++ }
++
++ /* We walk in directory order so "ls -f" doesn't get upset. */
++ p->fts_link = NULL;
++ if (head == NULL)
++ head = tail = p;
++ else {
++ tail->fts_link = p;
++ tail = p;
++ }
++ ++nitems;
++ }
++ if (dirp)
++ (void)closedir(dirp);
++
++ /*
++ * If realloc() changed the address of the path, adjust the
++ * addresses for the rest of the tree and the dir list.
++ */
++ if (doadjust)
++ fts_padjust(sp, head);
++
++ /*
++ * If not changing directories, reset the path back to original
++ * state.
++ */
++ if (ISSET(FTS_NOCHDIR)) {
++ if (len == sp->fts_pathlen || nitems == 0)
++ --cp;
++ *cp = '\0';
++ }
++
++ /*
++ * If descended after called from fts_children or after called from
++ * fts_read and nothing found, get back. At the root level we use
++ * the saved fd; if one of fts_open()'s arguments is a relative path
++ * to an empty directory, we wind up here with no other way back. If
++ * can't get back, we're done.
++ */
++ if (descend && (type == BCHILD || !nitems) &&
++ (cur->fts_level == FTS_ROOTLEVEL ?
++ FCHDIR(sp, sp->fts_rfd) :
++ fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
++ cur->fts_info = FTS_ERR;
++ SET(FTS_STOP);
++ fts_lfree(head);
++ return (NULL);
++ }
++
++ /* If didn't find anything, return NULL. */
++ if (!nitems) {
++ if (type == BREAD)
++ cur->fts_info = FTS_DP;
++ fts_lfree(head);
++ return (NULL);
++ }
++
++ /* Sort the entries. */
++ if (sp->fts_compar && nitems > 1)
++ head = fts_sort(sp, head, nitems);
++ return (head);
++}
++
++static u_short
++fts_stat(FTS *sp, register FTSENT *p, int follow)
++{
++ register FTSENT *t;
++ register dev_t dev;
++ register ino_t ino;
++ struct stat *sbp, sb;
++ int saved_errno;
++
++ /* If user needs stat info, stat buffer already allocated. */
++ sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp;
++
++#if defined FTS_WHITEOUT && 0
++ /* check for whiteout */
++ if (p->fts_flags & FTS_ISW) {
++ if (sbp != &sb) {
++ memset(sbp, '\0', sizeof (*sbp));
++ sbp->st_mode = S_IFWHT;
++ }
++ return (FTS_W);
++ }
++#endif
++
++ /*
++ * If doing a logical walk, or application requested FTS_FOLLOW, do
++ * a stat(2). If that fails, check for a non-existent symlink. If
++ * fail, set the errno from the stat call.
++ */
++ if (ISSET(FTS_LOGICAL) || follow) {
++ if (stat(p->fts_accpath, sbp)) {
++ saved_errno = errno;
++ if (!lstat(p->fts_accpath, sbp)) {
++ errno = 0;
++ return (FTS_SLNONE);
++ }
++ p->fts_errno = saved_errno;
++ goto err;
++ }
++ } else if (lstat(p->fts_accpath, sbp)) {
++ p->fts_errno = errno;
++err: memset(sbp, 0, sizeof(struct stat));
++ return (FTS_NS);
++ }
++
++ if (S_ISDIR(sbp->st_mode)) {
++ /*
++ * Set the device/inode. Used to find cycles and check for
++ * crossing mount points. Also remember the link count, used
++ * in fts_build to limit the number of stat calls. It is
++ * understood that these fields are only referenced if fts_info
++ * is set to FTS_D.
++ */
++ dev = p->fts_dev = sbp->st_dev;
++ ino = p->fts_ino = sbp->st_ino;
++ p->fts_nlink = sbp->st_nlink;
++
++ if (ISDOT(p->fts_name))
++ return (FTS_DOT);
++
++ /*
++ * Cycle detection is done by brute force when the directory
++ * is first encountered. If the tree gets deep enough or the
++ * number of symbolic links to directories is high enough,
++ * something faster might be worthwhile.
++ */
++ for (t = p->fts_parent;
++ t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
++ if (ino == t->fts_ino && dev == t->fts_dev) {
++ p->fts_cycle = t;
++ return (FTS_DC);
++ }
++ return (FTS_D);
++ }
++ if (S_ISLNK(sbp->st_mode))
++ return (FTS_SL);
++ if (S_ISREG(sbp->st_mode))
++ return (FTS_F);
++ return (FTS_DEFAULT);
++}
++
++static FTSENT *
++fts_sort(FTS *sp, FTSENT *head, register int nitems)
++{
++ register FTSENT **ap, *p;
++
++ /*
++ * Construct an array of pointers to the structures and call qsort(3).
++ * Reassemble the array in the order returned by qsort. If unable to
++ * sort for memory reasons, return the directory entries in their
++ * current order. Allocate enough space for the current needs plus
++ * 40 so don't realloc one entry at a time.
++ */
++ if (nitems > sp->fts_nitems) {
++ struct _ftsent **a;
++
++ sp->fts_nitems = nitems + 40;
++ if ((a = realloc(sp->fts_array,
++ (size_t)(sp->fts_nitems * sizeof(FTSENT *)))) == NULL) {
++ free(sp->fts_array);
++ sp->fts_array = NULL;
++ sp->fts_nitems = 0;
++ return (head);
++ }
++ sp->fts_array = a;
++ }
++ for (ap = sp->fts_array, p = head; p; p = p->fts_link)
++ *ap++ = p;
++ qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), sp->fts_compar);
++ for (head = *(ap = sp->fts_array); --nitems; ++ap)
++ ap[0]->fts_link = ap[1];
++ ap[0]->fts_link = NULL;
++ return (head);
++}
++
++static FTSENT *
++fts_alloc(FTS *sp, const char *name, size_t namelen)
++{
++ register FTSENT *p;
++ size_t len;
++
++ /*
++ * The file name is a variable length array and no stat structure is
++ * necessary if the user has set the nostat bit. Allocate the FTSENT
++ * structure, the file name and the stat structure in one chunk, but
++ * be careful that the stat structure is reasonably aligned. Since the
++ * fts_name field is declared to be of size 1, the fts_name pointer is
++ * namelen + 2 before the first possible address of the stat structure.
++ */
++ len = sizeof(FTSENT) + namelen;
++ if (!ISSET(FTS_NOSTAT))
++ len += sizeof(struct stat) + ALIGNBYTES;
++ if ((p = malloc(len)) == NULL)
++ return (NULL);
++
++ /* Copy the name and guarantee NUL termination. */
++ memmove(p->fts_name, name, namelen);
++ p->fts_name[namelen] = '\0';
++
++ if (!ISSET(FTS_NOSTAT))
++ p->fts_statp = (struct stat *)ALIGN(p->fts_name + namelen + 2);
++ p->fts_namelen = namelen;
++ p->fts_path = sp->fts_path;
++ p->fts_errno = 0;
++ p->fts_flags = 0;
++ p->fts_instr = FTS_NOINSTR;
++ p->fts_number = 0;
++ p->fts_pointer = NULL;
++ return (p);
++}
++
++static void
++fts_lfree(register FTSENT *head)
++{
++ register FTSENT *p;
++
++ /* Free a linked list of structures. */
++ while ((p = head)) {
++ head = head->fts_link;
++ free(p);
++ }
++}
++
++/*
++ * Allow essentially unlimited paths; find, rm, ls should all work on any tree.
++ * Most systems will allow creation of paths much longer than MAXPATHLEN, even
++ * though the kernel won't resolve them. Add the size (not just what's needed)
++ * plus 256 bytes so don't realloc the path 2 bytes at a time.
++ */
++static int
++fts_palloc(FTS *sp, size_t more)
++{
++ char *p;
++
++ sp->fts_pathlen += more + 256;
++ /*
++ * Check for possible wraparound. In an FTS, fts_pathlen is
++ * a signed int but in an FTSENT it is an unsigned short.
++ * We limit fts_pathlen to USHRT_MAX to be safe in both cases.
++ */
++ if (sp->fts_pathlen < 0 || sp->fts_pathlen >= USHRT_MAX) {
++ free(sp->fts_path);
++ sp->fts_path = NULL;
++ errno = ENAMETOOLONG;
++ return (1);
++ }
++ p = realloc(sp->fts_path, sp->fts_pathlen);
++ if (p == NULL) {
++ free(sp->fts_path);
++ sp->fts_path = NULL;
++ return 1;
++ }
++ sp->fts_path = p;
++ return 0;
++}
++
++/*
++ * When the path is realloc'd, have to fix all of the pointers in structures
++ * already returned.
++ */
++static void
++fts_padjust(FTS *sp, FTSENT *head)
++{
++ FTSENT *p;
++ char *addr = sp->fts_path;
++
++#define ADJUST(p) do { \
++ if ((p)->fts_accpath != (p)->fts_name) { \
++ (p)->fts_accpath = \
++ (char *)addr + ((p)->fts_accpath - (p)->fts_path); \
++ } \
++ (p)->fts_path = addr; \
++} while (0)
++ /* Adjust the current set of children. */
++ for (p = sp->fts_child; p; p = p->fts_link)
++ ADJUST(p);
++
++ /* Adjust the rest of the tree, including the current level. */
++ for (p = head; p->fts_level >= FTS_ROOTLEVEL;) {
++ ADJUST(p);
++ p = p->fts_link ? p->fts_link : p->fts_parent;
++ }
++}
++
++static size_t
++fts_maxarglen(char * const *argv)
++{
++ size_t len, max;
++
++ for (max = 0; *argv; ++argv)
++ if ((len = strlen(*argv)) > max)
++ max = len;
++ return (max + 1);
++}
++
++/*
++ * Change to dir specified by fd or p->fts_accpath without getting
++ * tricked by someone changing the world out from underneath us.
++ * Assumes p->fts_dev and p->fts_ino are filled in.
++ */
++static int
++fts_safe_changedir(FTS *sp, FTSENT *p, int fd, const char *path)
++{
++ int ret, oerrno, newfd;
++ struct stat64 sb;
++
++ newfd = fd;
++ if (ISSET(FTS_NOCHDIR))
++ return (0);
++ if (fd < 0 && (newfd = open(path, O_RDONLY, 0)) < 0)
++ return (-1);
++ if (fstat64(newfd, &sb)) {
++ ret = -1;
++ goto bail;
++ }
++ if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) {
++ errno = ENOENT; /* disinformation */
++ ret = -1;
++ goto bail;
++ }
++ ret = fchdir(newfd);
++bail:
++ oerrno = errno;
++ if (fd < 0)
++ (void)close(newfd);
++ errno = oerrno;
++ return (ret);
++}
+Index: b/libdwfl/fts_.h
+===================================================================
+--- /dev/null
++++ b/libdwfl/fts_.h
+@@ -0,0 +1,131 @@
++/*
++ * Copyright (c) 1989, 1993
++ * The Regents of the University of California. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 4. Neither the name of the University nor the names of its contributors
++ * may be used to endorse or promote products derived from this software
++ * without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ *
++ * @(#)fts.h 8.3 (Berkeley) 8/14/94
++ */
++
++#ifndef _FTS_H
++#define _FTS_H 1
++
++#include <features.h>
++#include <sys/types.h>
++
++/* The fts interface is incompatible with the LFS interface which
++ transparently uses the 64-bit file access functions. */
++#ifdef __USE_FILE_OFFSET64
++# error "<fts.h> cannot be used with -D_FILE_OFFSET_BITS==64"
++#endif
++
++
++typedef struct {
++ struct _ftsent *fts_cur; /* current node */
++ struct _ftsent *fts_child; /* linked list of children */
++ struct _ftsent **fts_array; /* sort array */
++ dev_t fts_dev; /* starting device # */
++ char *fts_path; /* path for this descent */
++ int fts_rfd; /* fd for root */
++ int fts_pathlen; /* sizeof(path) */
++ int fts_nitems; /* elements in the sort array */
++ int (*fts_compar) (const void *, const void *); /* compare fn */
++
++#define FTS_COMFOLLOW 0x0001 /* follow command line symlinks */
++#define FTS_LOGICAL 0x0002 /* logical walk */
++#define FTS_NOCHDIR 0x0004 /* don't change directories */
++#define FTS_NOSTAT 0x0008 /* don't get stat info */
++#define FTS_PHYSICAL 0x0010 /* physical walk */
++#define FTS_SEEDOT 0x0020 /* return dot and dot-dot */
++#define FTS_XDEV 0x0040 /* don't cross devices */
++#define FTS_WHITEOUT 0x0080 /* return whiteout information */
++#define FTS_OPTIONMASK 0x00ff /* valid user option mask */
++
++#define FTS_NAMEONLY 0x0100 /* (private) child names only */
++#define FTS_STOP 0x0200 /* (private) unrecoverable error */
++ int fts_options; /* fts_open options, global flags */
++} FTS;
++
++typedef struct _ftsent {
++ struct _ftsent *fts_cycle; /* cycle node */
++ struct _ftsent *fts_parent; /* parent directory */
++ struct _ftsent *fts_link; /* next file in directory */
++ long fts_number; /* local numeric value */
++ void *fts_pointer; /* local address value */
++ char *fts_accpath; /* access path */
++ char *fts_path; /* root path */
++ int fts_errno; /* errno for this node */
++ int fts_symfd; /* fd for symlink */
++ u_short fts_pathlen; /* strlen(fts_path) */
++ u_short fts_namelen; /* strlen(fts_name) */
++
++ ino_t fts_ino; /* inode */
++ dev_t fts_dev; /* device */
++ nlink_t fts_nlink; /* link count */
++
++#define FTS_ROOTPARENTLEVEL -1
++#define FTS_ROOTLEVEL 0
++ short fts_level; /* depth (-1 to N) */
++
++#define FTS_D 1 /* preorder directory */
++#define FTS_DC 2 /* directory that causes cycles */
++#define FTS_DEFAULT 3 /* none of the above */
++#define FTS_DNR 4 /* unreadable directory */
++#define FTS_DOT 5 /* dot or dot-dot */
++#define FTS_DP 6 /* postorder directory */
++#define FTS_ERR 7 /* error; errno is set */
++#define FTS_F 8 /* regular file */
++#define FTS_INIT 9 /* initialized only */
++#define FTS_NS 10 /* stat(2) failed */
++#define FTS_NSOK 11 /* no stat(2) requested */
++#define FTS_SL 12 /* symbolic link */
++#define FTS_SLNONE 13 /* symbolic link without target */
++#define FTS_W 14 /* whiteout object */
++ u_short fts_info; /* user flags for FTSENT structure */
++
++#define FTS_DONTCHDIR 0x01 /* don't chdir .. to the parent */
++#define FTS_SYMFOLLOW 0x02 /* followed a symlink to get here */
++ u_short fts_flags; /* private flags for FTSENT structure */
++
++#define FTS_AGAIN 1 /* read node again */
++#define FTS_FOLLOW 2 /* follow symbolic link */
++#define FTS_NOINSTR 3 /* no instructions */
++#define FTS_SKIP 4 /* discard node */
++ u_short fts_instr; /* fts_set() instructions */
++
++ struct stat *fts_statp; /* stat(2) information */
++ char fts_name[1]; /* file name */
++} FTSENT;
++
++__BEGIN_DECLS
++FTSENT *fts_children (FTS *, int);
++int fts_close (FTS *);
++FTS *fts_open (char * const *, int,
++ int (*)(const FTSENT **, const FTSENT **));
++FTSENT *fts_read (FTS *);
++int fts_set (FTS *, FTSENT *, int) __THROW;
++__END_DECLS
++
++#endif /* fts.h */
+Index: b/libdwfl/linux-kernel-modules.c
+===================================================================
+--- a/libdwfl/linux-kernel-modules.c
++++ b/libdwfl/linux-kernel-modules.c
+@@ -29,7 +29,11 @@
+ /* We include this before config.h because it can't handle _FILE_OFFSET_BITS.
+ Everything we need here is fine if its declarations just come first. */
+
++#ifdef HAVE_FTS_H
+ #include <fts.h>
++#else
++#include "fts_.h"
++#endif
+
+ #include <config.h>
+
--
1.7.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Buildroot] [PATCH 14/15] elfutils: towards uClibc support: disable po build
2013-01-06 15:22 [Buildroot] [pull request] Pull request for branch perf-elfutils Thomas Petazzoni
` (12 preceding siblings ...)
2013-01-06 15:22 ` [Buildroot] [PATCH 13/15] elfutils: towards uClibc support: FTS functions Thomas Petazzoni
@ 2013-01-06 15:22 ` Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 15/15] elfutils: make available on uClibc toolchains Thomas Petazzoni
2013-01-07 22:32 ` [Buildroot] [pull request] Pull request for branch perf-elfutils Peter Korsgaard
15 siblings, 0 replies; 19+ messages in thread
From: Thomas Petazzoni @ 2013-01-06 15:22 UTC (permalink / raw)
To: buildroot
Building the po/ directory complains that the scripts in there have
been generated with gettext 0.17, while we use gettext 0.18 in
Buildroot. Since we don't care that much about po files anyway, just
disable the build of this directory.
Heavily based from work done by Stefan Fr?berg, but with many further
modifications by Thomas Petazzoni.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
package/elfutils/elfutils-05-disable-po.patch | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 package/elfutils/elfutils-05-disable-po.patch
diff --git a/package/elfutils/elfutils-05-disable-po.patch b/package/elfutils/elfutils-05-disable-po.patch
new file mode 100644
index 0000000..d98da0b
--- /dev/null
+++ b/package/elfutils/elfutils-05-disable-po.patch
@@ -0,0 +1,22 @@
+Disable the build of the po/ directory
+
+Building the po/ directory complains that the scripts in there have
+been generated with gettext 0.17, while we use gettext 0.18 in
+Buildroot. Since we don't care that much about po files anyway, just
+disable the build of this directory.
+
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+
+Index: b/Makefile.am
+===================================================================
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -28,7 +28,7 @@
+
+ # Add doc back when we have some real content.
+ SUBDIRS = config m4 lib libelf libebl libdwfl libdw libcpu libasm backends \
+- $(PROGS_SUBDIR) po tests
++ $(PROGS_SUBDIR) tests
+
+ EXTRA_DIST = elfutils.spec GPG-KEY NOTES CONTRIBUTING \
+ COPYING COPYING-GPLV2 COPYING-LGPLV3
--
1.7.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Buildroot] [PATCH 15/15] elfutils: make available on uClibc toolchains
2013-01-06 15:22 [Buildroot] [pull request] Pull request for branch perf-elfutils Thomas Petazzoni
` (13 preceding siblings ...)
2013-01-06 15:22 ` [Buildroot] [PATCH 14/15] elfutils: towards uClibc support: disable po build Thomas Petazzoni
@ 2013-01-06 15:22 ` Thomas Petazzoni
2013-01-07 22:32 ` [Buildroot] [pull request] Pull request for branch perf-elfutils Peter Korsgaard
15 siblings, 0 replies; 19+ messages in thread
From: Thomas Petazzoni @ 2013-01-06 15:22 UTC (permalink / raw)
To: buildroot
We finally have all the pieces needed to allow the build of elfutils
on uClibc. Only the libraries can be built, the programs remain
available only for glibc/eglibc toolchains.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
package/elfutils/Config.in | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/package/elfutils/Config.in b/package/elfutils/Config.in
index 78d02a5..b107a97 100644
--- a/package/elfutils/Config.in
+++ b/package/elfutils/Config.in
@@ -1,13 +1,5 @@
-comment "elfutils requires a glibc toolchain"
- depends on !(BR2_TOOLCHAIN_EXTERNAL_GLIBC || \
- BR2_TOOLCHAIN_CTNG_glibc || \
- BR2_TOOLCHAIN_CTNG_eglibc)
-
config BR2_PACKAGE_ELFUTILS
bool "elfutils"
- depends on BR2_TOOLCHAIN_EXTERNAL_GLIBC || \
- BR2_TOOLCHAIN_CTNG_glibc || \
- BR2_TOOLCHAIN_CTNG_eglibc
select BR2_PACKAGE_ARGP_STANDALONE if \
BR2_TOOLCHAIN_BUILDROOT || \
BR2_TOOLCHAIN_CTNG_uClibc || \
@@ -27,6 +19,9 @@ if BR2_PACKAGE_ELFUTILS
config BR2_PACKAGE_ELFUTILS_PROGS
bool "Install programs"
+ depends on BR2_TOOLCHAIN_EXTERNAL_GLIBC || \
+ BR2_TOOLCHAIN_CTNG_glibc || \
+ BR2_TOOLCHAIN_CTNG_eglibc
help
This option tells elfutils to not only install the libelf
libraries, but also the elfutils programs.
--
1.7.9.5
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [Buildroot] [pull request] Pull request for branch perf-elfutils
2013-01-06 15:22 [Buildroot] [pull request] Pull request for branch perf-elfutils Thomas Petazzoni
` (14 preceding siblings ...)
2013-01-06 15:22 ` [Buildroot] [PATCH 15/15] elfutils: make available on uClibc toolchains Thomas Petazzoni
@ 2013-01-07 22:32 ` Peter Korsgaard
2013-01-07 22:39 ` Thomas Petazzoni
15 siblings, 1 reply; 19+ messages in thread
From: Peter Korsgaard @ 2013-01-07 22:32 UTC (permalink / raw)
To: buildroot
>>>>> "Thomas" == Thomas Petazzoni <thomas.petazzoni@free-electrons.com> writes:
Thomas> Hello,
Thomas> Here is a set of patches that add the elfutils and perf packages in
Thomas> Buildroot, based on previous efforts from Stefan Fr?berg and Kaiwan
Thomas> Billimoria (thanks !).
Thomas> These packages are not trivial because:
Thomas> 1) perf is part of the kernel sources
Thomas> 2) elfutils is a nightmare to build against uClibc
Thomas> I've been working on this for about two days, trying different
Thomas> solutions, the one proposed here appeared to be the most reasonable
Thomas> one in terms of patch size, and maintenability.
Thanks everyone, committed series.
Thomas, please don't forget to (try to) send these patches upstream so
we don't have to maintain them ourselves in the future.
--
Bye, Peter Korsgaard
^ permalink raw reply [flat|nested] 19+ messages in thread
* [Buildroot] [pull request] Pull request for branch perf-elfutils
2013-01-07 22:32 ` [Buildroot] [pull request] Pull request for branch perf-elfutils Peter Korsgaard
@ 2013-01-07 22:39 ` Thomas Petazzoni
2013-01-08 7:18 ` Peter Korsgaard
0 siblings, 1 reply; 19+ messages in thread
From: Thomas Petazzoni @ 2013-01-07 22:39 UTC (permalink / raw)
To: buildroot
Dear Peter Korsgaard,
On Mon, 07 Jan 2013 23:32:56 +0100, Peter Korsgaard wrote:
> Thanks everyone, committed series.
Thanks for merging them. Hopefully, it won't make the autobuilders
explode too much.
> Thomas, please don't forget to (try to) send these patches upstream so
> we don't have to maintain them ourselves in the future.
Which ones exactly? The big fat patches we are downloading from
fedorahosted.org? Our patches?
All our patches are really specific to uClibc support, and seeing the
number of glibc-isms in elfutils, I am not sure the maintainers will be
interested in making it uClibc friendly. But it's maybe worth trying.
One nice thing that could be done is migrate the linux-kernel-module.c
thing to use nftw(), so we could drop the fts() mess.
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 19+ messages in thread
* [Buildroot] [pull request] Pull request for branch perf-elfutils
2013-01-07 22:39 ` Thomas Petazzoni
@ 2013-01-08 7:18 ` Peter Korsgaard
0 siblings, 0 replies; 19+ messages in thread
From: Peter Korsgaard @ 2013-01-08 7:18 UTC (permalink / raw)
To: buildroot
>>>>> "Thomas" == Thomas Petazzoni <thomas.petazzoni@free-electrons.com> writes:
Hi,
>> Thomas, please don't forget to (try to) send these patches upstream so
>> we don't have to maintain them ourselves in the future.
Thomas> Which ones exactly? The big fat patches we are downloading from
Thomas> fedorahosted.org? Our patches?
Thomas> All our patches are really specific to uClibc support, and
Thomas> seeing the number of glibc-isms in elfutils, I am not sure the
Thomas> maintainers will be interested in making it uClibc
Thomas> friendly. But it's maybe worth trying.
Our own. I would certainly say it's worth a try.
Thomas> One nice thing that could be done is migrate the
Thomas> linux-kernel-module.c thing to use nftw(), so we could drop the
Thomas> fts() mess.
Indeed.
--
Bye, Peter Korsgaard
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2013-01-08 7:18 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-06 15:22 [Buildroot] [pull request] Pull request for branch perf-elfutils Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 01/15] package: support multiple patches Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 02/15] docs/manual: update to mention the multiple patches support Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 03/15] elfutils: new package Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 04/15] elfutils: make it possible to only install the libraries Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 05/15] perf: new package Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 06/15] perf: allow build against libelf when available Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 07/15] perf: add kernel version checks Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 08/15] argp-standlone: build position independent code Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 09/15] elfutils: towards uClibc support: argp-standalone usage Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 10/15] elfutils: towards uClibc support: solve memcpy problem Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 11/15] elfutils: towards uClibc support: requires largefile Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 12/15] elfutils: towards uClibc support: gettext Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 13/15] elfutils: towards uClibc support: FTS functions Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 14/15] elfutils: towards uClibc support: disable po build Thomas Petazzoni
2013-01-06 15:22 ` [Buildroot] [PATCH 15/15] elfutils: make available on uClibc toolchains Thomas Petazzoni
2013-01-07 22:32 ` [Buildroot] [pull request] Pull request for branch perf-elfutils Peter Korsgaard
2013-01-07 22:39 ` Thomas Petazzoni
2013-01-08 7:18 ` Peter Korsgaard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox