Bug 15920 - <bfd.h> not suitable as a general-purpose header
Summary: <bfd.h> not suitable as a general-purpose header
Status: RESOLVED DUPLICATE of bug 14243
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.24
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2013-09-02 09:38 UTC by Raphael Manfredi
Modified: 2013-09-03 20:57 UTC (History)
3 users (show)

See Also:
Last reconfirmed:


Note You need to log in before you can comment on or make changes to this bug.
Description Raphael Manfredi 2013-09-02 09:38:52 UTC
As included in MinGW and coming directly from binutils 2-23.1 it would seem, the <bfd.h> header starts with:

/* PR 14072: Ensure that config.h is included first.  */
#if !defined PACKAGE && !defined PACKAGE_VERSION
#error config.h must be included before this header

This is not suitable for a genral-purpose header, intended to be used by standalone applications that do not need to include any "config.h" -- supposedly coming from the binutils compilation environment.

The "bfd.h" file seems to be generated automatically, and as such, it should remove any meta-configuration checks done at compile time for the platform, and deliver a file that any application linking with libbfd can include.

On my Linux machine, I'm still using binutils-dev 2.22, but I also see checks like "defined (HAVE_STRINGIZE)" in /usr/include/bfd.h, which have no meaning for me since I am not using autoconf for instance.  And again, such a check should have been done at meta-configuration time, and the "bfd.h" delivered on my linux platform should be tailored for features available on that platform.

This is a sensible thing to do for a library.  You cannot make assumptions on the compilation environment the application including the file will use. "autoconf" is not the only meta-configuration tool available, even if it is widely used.

The "PR 14072" change breaks things in the current MinGW release because it makes it impossible to include <bfd.h> in an application without getting an error.

Sure, I can define "PACKAGE" and "PACKAGE_VERSION" to meaningless values, but this will only work for my application.  It will still break others, and also defeats meta-configuration packages which attempt to probe for the presence of libbfd: they cannot define PACKAGE before including <bfd.h> in their check, because they do not know whether the package they meta-configure for will do that in their code.  So they end-up not detecting BFD, despite it being present on the system.

I am certain the BFD library can provide a proper interface-definition file for the platform it is being compiled on, and generate the right <bfd.h> header that will be publicly visible to interface with the library.

For instance, you know whether HAVE_STRINGSIZE is true of false when you compile on Linux, so why perform the check in the header?  Since one will only install the generated "bfd.h" file on a Linux machine, there is no problem at all.  The same logic should apply to any other OS.

My application relies heavily on the BFD library to perform symbolic stack traces.  Not being able to compile with BFD means I get hexadecimal stack traces which make debugging impossible, especially on platform like Windows which do not dump core on crashes.
Comment 1 Andreas Schwab 2013-09-02 13:43:59 UTC
libbfd is not a general-purpose library, but intented to be embedded into the sources of the consuming applications (like GDB and binutils).
Comment 2 Earnie Boyd 2013-09-02 14:13:11 UTC
I agree with Andreas.  I think the bug is that MinGW is providing the header and library as general purpose.  However, another issue is that at least in binutils there is a --enable-install-libbfd configure option which installs the library as general purpose.  Perhaps this issue needs to look at removing that option to prevent a general purpose install.
Comment 3 Raphael Manfredi 2013-09-02 15:33:34 UTC
Why limit the audience of the library?  I fail to see the point of requiring people to go through contorsions to be able to use it when all you need to do is generate a "bfd.h" header clean of any dependency?

Since that file is generated, it's not so much a hassle to do, and it is done ONCE instead of having all the customers painfully work around all the safety you are putting in place.

I am developing a general-purpose library for which BFD is a much-needed piece.  I do not use "autoconf" for configuring my library, I am using "metaconfig".  Therefore, my compiling environment is not that of an auto-configured package.

The point is not that MinGW should or should not include BFD, the point is to make sure BFD remains a library that can be used by other packages. It will always require some care, but that is true of all non-trivial libraries.  However, my main argument is that it should not be artificially made a pain to work with.

I fail to see the rationale of making BFD hard to reuse in other packages.
Comment 4 Andreas Schwab 2013-09-02 16:05:33 UTC
BFD has no ABI nor API stability.
Comment 5 Earnie Boyd 2013-09-02 16:19:32 UTC
Gdb also installs libbfd, libiberty and libopcodes all three are private libraries.  Only libbfd adds a guard to protect against not having an autoconf config.h included before it.  Why are these private development libraries being installed into publicly used space?  Should they not remain private to the package and require being configured and compiled?  It isn't like the package will check to see if the library exists in public, on the contrary it will always use the in-source versions without an option to do otherwise.

So the bug with the packages is the installation of the private libraries into public space.
Comment 6 Raphael Manfredi 2013-09-02 16:43:33 UTC
On my Debian machine, "dpkg -L binutils-dev" yields the following files:


If there's no ABI stability, don't provide a .so, just the .a as we don't want to dynamically link against it.

If there is no API stability, then why not define one?  The BFD "component" (since you insist it's not a library) seems stable enough to get a general-purpose API.  Clearly draw the line between features that are sufficiently high-level to require an API, and those that must rather stay confidential.

The documentation in https://sourceware.org/binutils/docs/bfd/ seems to be a good start for a public API...

Capitalizing on the effort required to come-up with BFD in the first place is not only a tribute to the team, it's also saving engineering cycles for other projects because these projects have a way to access program symbols easily, meaning easier debugging during development, better code quality.  Everybody wins.

I understand committing a public API is a responsibility, meaning harder work because then you have to think about backward compatibility, etc...  It's also something that I see worth doing.  If you don't want to make everything visible, choose a subset that's been stable for the last 10 years.  I'm sure most of the application-level features could be made available via a stable API.
Comment 7 Mike Frysinger 2013-09-03 02:10:03 UTC

*** This bug has been marked as a duplicate of bug 14243 ***
Comment 8 Raphael Manfredi 2013-09-03 08:23:27 UTC
As a side note, all this started with the "config.h" protection because of the HAVE_STRSIZE check in the "bfd.h" header, to conditionally redefine the CONCAT4() macro...

Macro which is never used in "bfd.h", and that file is not including any other file either after the CONCAT4 redefinition.

Therefore, this leads me to think that the redefinition of CONCAT4 should be moved elsewhere, because this is a portability issue, probably in some auto-configuration file.  That is the real root cause that needs fixing.

That would make "bfd.h" clean again, and would remove the need to enforce that "config.h" be included before it.
Comment 9 Ian Lance Taylor 2013-09-03 20:02:09 UTC
For what it's worth the libbacktrace library in the GCC sources can be used as a standalone library to do symbolic stack traces of the running process.  It currently only supports DWARF but it would be nice to add support for other debug info types.
Comment 10 Earnie Boyd 2013-09-03 20:57:32 UTC
What about my comment that the bug is the private libraries install into public space?  If the private libraries are supposed to remain private why do they have an install target?  If you install into public space then you need to allow the header to be used publicly.  The issue isn't resolved because of the installation of supposed private library into public space.  Please relabel this issue and consider the fact that installing a private library into public space is a bug that needs resolution.