[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: C++ ABI transition for etch



Thanks for your feedback, on the list and irc. Appended is an updated
version, the most notable change is to drop the 'c102' suffix from
packages, if it exists. This way, we get rid off the "ugly" extension,
and we don't support direct upgrades from woody to etch anyway.

    Matthias



C++ ABI Transition

Debian already had a C++ transition in 2002. Still remember? We are
proposing the same schema for the forthcoming ABI transition. The
following text is derived from this plan.

- Why do we need one?

  Because GCC 3.4/4.0 changed the C++ ABI. You can't mix a C++ library
  compiled with GCC 3.4/4.0 and a C++ application compiled with an
  earlier version, or vice versa.

  Transitions are painful. This will be no exception. The rules here
  are designed to make it as smooth as possible, but it's still going
  to be unpleasant. We have to do it, we can't stay with GCC 3.3 for
  ever.

  Other distributions did already switch to 3.4 or 4.0, and most of
  our ports will have much better toolchains with the newer compiler.

- How is it called?

  The C++ ABI has many names (no, actually only two). G++ 3.2/3.3 have
  the Version 1, 3.4/4.0 have the version 2. To get the ABI version:

    g++ -E -dM - < /dev/null | awk '/GXX_ABI/ {print $3}'

  Compilers with ABI version 1 print '102', those with version 2 print
  1002. During the last C++ ABI transition package names were renamed
  from libfoo to libfooc102. So rename them to libfooc1002 this time?

  No,
  - if your package is called libfoo1, add the string ''c2'' to the
    package name (see below).
  - if your package is called libfoo1c102, then drop the ''c102'' from
    the package name (see below).

- So what're we going to do?

  We're going to rebuild all C++ packages with the gcc-3.4/4.0 ABI.

  * If you have workarounds to build with a specific gcc version on
    certain architectures, these should be removed. Also if there are
    specific optimization settings that have been used to workaround
    compiler bugs, these should be removed, if possible.

  * If you maintain a library written in C++

    * Wait until all of your dependencies have been uploaded in c2
      versions, and rebuilt on all architectures (check the
      update_excuses file).

    * If your package does not contain the c102 suffix, add a c2 to
      the end of the name of your .deb, eg libdb4.0++.deb
      -> libdb4.0++c2.deb. This is similar in spirit to the glibc
      transition adding g to the end of libraries.

    * If your package already has a c102 suffix, drop the suffix from
      the package name. (that works, because we don't support direct
      upgrades from woody to etch).

    * Add a Conflict with the non-c2 version of the package (the
      previous version), i.e.
        Package: libdb4.0++.deb
        Conflicts: libdb4.0++c102.deb

        Package: libdb4.2++c2.deb
        Conflicts: libdb4.2++.deb

    * You should not add a c2 to your -dev package.

    * The exact placement of the c2 can be tricky. It's not terribly
      important; the important thing is that the new package conflicts
      with the old and has a different name. Stylistically, we prefer
      to keep the c2 adjacent to the soname number,
      e.g. libqt3c2-mt-odbc, but if your package ends in a ++, put the
      c2 after that.

    * Ensure that you're using g++-4.0 to build. You should have g++
      (>= 4:4.0) installed on the system you build on (or
      build-essential (>= 11) ).
      TODO: Proposal to bump the build-essential version for the ABI
      transition.

  * If you maintain a library or a program written in C++

    * Wait until all your dependencies have been uploaded in c2
      versions, and rebuilt on all architectures.

    * If your Depends: line isn't generated automatically, you'll need
      to change it too. But you should be using dpkg-shlibdeps anyway ;-)
      You should see a dependency on libstdc++6, if you see one on
      libstdc++5, something is wrong.

    * Upload and rejoice!

  * If your package contains no C++, do nothing more. You'll start
    building with the new gcc on your next upload.

  You should not rename your package to remove the c2 suffix
  until upstream changes their soname.

- Why don't we just change the sonames?

  Because upstream chooses the soname to match their API. If we change
  the soname then we render ourselves binary-incompatible with other
  distros and vendor-supplied binaries. This is important because the
  LSB3 intends to standardise the GCC 4.0 ABI; for Ubuntu/Debian to
  become binary-incompatible at this point would be the height of
  perversity.

  Of course, when your upstream does bump the soname, you can drop the
  c2 from the package name, just like very few libs still have a `g'
  on the end.

- How about versioned symbols?

  Versioned symbols don't even pretend to solve ABI transition
  problems. Not to mention there's the other-distro compatibility
  issue -- binaries compiled on Debian would not run on other distros.

- Why don't we put the libs in a different directory?

  Basically, it's too complex. For the glibc (.5 to .6) transition, we
  could do this because they used different dynamic linkers. For this
  transition, there is also little to gain in having full backwards
  compatibility to the old ABI. The only gain is that third party
  binary only applications that dynamically link to C++ using-libs
  (other than the stdc++ library itself) continue to work.  What about
  other architectures?

- The rules outlined above should make the autobuilders build your
  packages with GCC 4.0.

  TODO: check for other incompatibilities for non-release
  architectures,

  * i.e. sparc and hppa. I.e.: hppa libgcc1 (SJLJ) -> libgcc2
    (Dwarf2) transition. I.e.: sparc ABI change from 3.3 to 3.4.

  * The SPARC ABI changes should only relate to complex numbers or
    less used parts of the SPARC64 ABI.  Mathmatical packages probably
    should be NMU'd once glibc has been compiled with GCC 4.0 for
    SPARC.

- Help! My package doesn't build with GCC 4.0

  First search for the error in your package, not in GCC. g++-4.0 is
  more strict to the C++ standard than g++-3.3, and as such, things
  not written in standard C++, but written in an "extended subset" of
  it, using gnu extension classes that are no longer supported. See
  http://gcc.gnu.org/gcc-3.4/changes.html#cplusplus and
  http://gcc.gnu.org/gcc-4.0/changes.html

  If you find an internal compiler error (ICE), then submit a bug
  report. Please look at the error message that gcc emits: in most
  cases gcc asks for the preprocessed source file to be submitted
  together with the command line that was used to produce the
  file. Recompile the file using "-save-temps" and include the
  (compressed) .i or .ii file in the report.

  If you want help with debugging, download the gcc-snapshot package
  and retry compiling your package with this gcc. Please see the
  README in the package how this works. In no case should a package
  built by gcc-snapshot be uploaded to the archive.

  TODO Update the gcc-snapshot package to HEAD once 4.0 is released
  and in sid.

  If you really can't get your package fixed, you should change to
  build-depend on g++-3.4, and use it in the build process. If even
  g++-3.4 can't build your package, and your package depend on a
  library other than libstdc++, you're not likely to release with
  breezy/etch. We recommend you statically link to any C++ libraries
  which you use.

  TODO: Check for each architecture, if that's possible due to arch
  specific changes.

- How do I know what ABI a given g++ is using?

  The following command will show you the C++ ABI version being used
  by g++:

    g++ -E -dM - < /dev/null | awk '/GXX_ABI/ {print $3}'

- How do I know when all of my dependencies have been uploaded on all
  architectures?

  The madison command on merkel (accessible for Debian developers),
  followed by the package name of your dependencies will show you the
  latest version, and which archs that version is built for. You
  should run linda or lintian over your package, as they have a check
  for multiple C++ libraries being linked to a single binary. If you
  get an error about more than one libstdc++ being linked, not all of
  your dependencies are updated yet.

  TODO: update linda/lintian to discover packages linked against two
  different versions of a library (libgcc1/libgcc2,
  libstdc++5/libstdc++6)

- Why not use GCC 3.4 as the default compiler?

  Upstream did announce one more GCC 3.4.x release; with the
  availability of a newer released compiler version, the older
  branches usually get less attention. Because 3.4 and 4.0 are ABI
  compatible (at least on i386, amd64, powerpc and ia64), we can use
  GCC 3.4 as a fallback.



Reply to: