libtool
[Top][All Lists]
Advanced

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

Libtool Roadmap


From: Alex Ameen
Subject: Libtool Roadmap
Date: Sun, 10 Apr 2022 14:46:44 -0500
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.7.0

Howdy, a few weeks ago I talked about sending out a road-map.
I've gotten that prepared today. This roadmap is informal, opinionated, and I encourage feedback and discussion on it. I have my own biases and opinions about things I like/dislike and want added based on my `libtool' usage over the years. However, I would be doing a disservice to users if I forced them to adopt "my way of using `libtool'" over their own. With that in mind it's important for y'all to share your own use cases and pain points so that I can address them. This might be more accurately called a "giant RFC dump" than a roadmap, because it's hard for me to imagine that this remains unchanged.

The only notable item I have not included here is some organizational changes concerning how bugs/patches are submitted ( currently there's 3 ways to submit bug reports and 2 of them are miserable to process ); but I'll address that in another thread.

Also note that in my discussion of "CI" ( Continuous Integration ) setup, I intend to provide sufficient abstraction that with some tailoring automated `libtool' testing can be accessible to other developers. This will not be a "core" feature of `libtool', it is rather a practical necessity for maintenance. I am not and will not be making commitments on behalf of the `libtool' team to gate releases based on regression for any particular combination of platforms or tools. Rather you can look at this as "I want to improve the existing Hydra infrastructure, make it more accessible, and find ways to support platforms which cannot natively run Nix or Hydra", this may mean creating more abstract job declarations in a format with can be processed by a wider range of CI tools, it may mean VMs will be used for some testing, it may mean that Hydra is dropped altogether ( unlikely ). Time will tell.


These tasks are what I have in mind for the immediate future. Long term I'd like to work more closely with the other Autotools teams to improve integration with the rest of the family, and make `libtool' more extensible, but those are conversations for another day.



                           ━━━━━━━━━━━━━━━━━
                            LIBTOOL-ROADMAP

                               Alex Ameen
                           ━━━━━━━━━━━━━━━━━


Table of Contents
─────────────────

1. Roadmap
.. 1. Improve `.la' libraries, or phase them out on certain platforms.
..... 1. Libtool should not use `libfoo.la' when `libfoo.EXT' are requested.
..... 2. Make installation of `.lt' libraries optional.
..... 3. Prevent over-linking of ELF binaries.
..... 4. Security
.. 2. Support `$ORIGIN' in ELF binaries’ `RPATH' and `RUNPATH' entries.
.. 3. Avoid use of wrapper scripts for `noinst_' and `nodist_' binaries.
.. 4. Refactor argument parsing, particularly parsing linker flags.
.. 5. Migrate platform, arch, and tool specific conditionals to `autoconf'.
.. 6. Expand usage of `M4SH' for creating `ltmain.sh' and `libtoolize.in'.
.. 7. Simplify `bootstrap' process.
.. 8. Make the creation of test cases more user friendly
.. 9. Create CI pipeline resources for distribution and tool maintainers
.. 10. Permit installable LTLIBRARIES to conditionally be “convenience libraries”





1 Roadmap
═════════

1.1 Improve `.la' libraries, or phase them out on certain platforms.
────────────────────────────────────────────────────────────────────

1.1.1 Libtool should not use `libfoo.la' when `libfoo.EXT' are requested.
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

  What I mean is, if I say `-lfoo', of `-l:libfoo.la', then go right
  ahead, do your thing `libtool'. However, when I went out of my way to
  say `-l:libfoo.so' or `/trust/the/user/libfoo.a', it is evil for
  `libtool' to silently decide that it knows best and decide to use
  `libfoo.la' regardless.
  • This behavior leads a large number of package managers and
    distributions to delete `.la' files before distributing binary
    tarballs.
  • This frequently leads to incorrect/unexpected libraries and flags
    being used because they were written as dependencies or inherited
    flags in a `.la' file.


1.1.2 Make installation of `.lt' libraries optional.
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

  • Closing Argument:
    ┌────
    │     libtool: link: warning: library `/tmp/usr/lib/libstdc++.la' was moved.
    │     libtool: link: warning: library `/tmp/usr/lib/libstdc++.la' was moved.
    │     libtool: link: warning: library `/tmp/usr/lib/libstdc++.la' was moved.
    │     libtool: link: warning: library `/tmp/usr/lib/libstdc++.la' was moved.
    │     libtool: link: warning: library `/tmp/usr/lib/libstdc++.la' was moved.
    │     libtool: link: warning: library `/tmp/usr/lib/libstdc++.la' was moved.
    │     libtool: link: warning: library `/tmp/usr/lib/libstdc++.la' was moved.
    │     libtool: link: warning: library `/tmp/usr/lib/libstdc++.la' was moved.
    └────
    Should people learn to use `DESTDIR'? Sure, but it’s hard enough to
    defend the usefulness of `.la' when it has a meltdown like this over
    binaries which were safely moved.


1.1.3 Prevent over-linking of ELF binaries.
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

  Unless a popular patch for `ltmain.sh' was applied to a project,
  `libtool' will over-link unneeded dependencies in ELF binaries. This
  often leads to unexpected/incorrect library load/initialization
  ordering, particularly in cases where libraries have circular
  dependencies.
  • “Libraries shouldn’t have circular dependencies” is not a valid
    excuse.
  • This has a measurable impact on performance in large applications,
    and makes interposing symbols nearly impossible.
  • This behavior severely aggravates C++ initialization ordering
    issues.
  • Makes the use of ELF filtering extensions impractical.


1.1.4 Security
╌╌╌╌╌╌╌╌╌╌╌╌╌╌

  The ability to pass flags to consumers is useful, but this behavior
  requires more visibility, and serious scrutiny concerning security.
  • Expecting users to inspect `.la' files recursively, or always build
    dry runs to audit flags is utterly fanciful.


1.2 Support `$ORIGIN' in ELF binaries’ `RPATH' and `RUNPATH' entries.
─────────────────────────────────────────────────────────────────────


1.3 Avoid use of wrapper scripts for `noinst_' and `nodist_' binaries.
──────────────────────────────────────────────────────────────────────

  “When possible” of course. While these scripts mean well, they are
  difficult to circumvent when a use case requires direct execution of a
  binary. Further, the availability of `$ORIGIN' on ELF platforms makes
  these wrappers unnecessary or counter-intuitive.


1.4 Refactor argument parsing, particularly parsing linker flags.
─────────────────────────────────────────────────────────────────

  • It’s incomprehensible, and inline comments indicate that for several
    years people have been unable to figure out why certain quirks like
    “libraries are in reverse order in this block for some reason”
    exist.
  • When performing any changes to the parser test cases should be
    created to ensure that behavior remains consistent ( unless a latent
    bug is fixed ).


1.5 Migrate platform, arch, and tool specific conditionals to `autoconf'.
─────────────────────────────────────────────────────────────────────────

  For example, if I configure `./configure --host_os='$(build_os)'', or
  if a compiler/linker is known at configure time, much of the runtime
  probing which is currently performed is redundant.
  • Obviously, for a global `libtool' install on a system, this
    optimization would not be performed. Rather this aims to optimize
    `ltmain.sh --> libtool' creation performed in a project tree
    alongside `autoconf'.


1.6 Expand usage of `M4SH' for creating `ltmain.sh' and `libtoolize.in'.
────────────────────────────────────────────────────────────────────────

  In practice I aim to split these scripts into smaller parts which are
  easier to read and reason about in isolation.
  • More modular snippets may be easier to unit test.
  • Use of `M4SH' may also permit users to patch/extend `libtool' more
    easily.
  • This will allow us to phase out `funclib.sh' over time, and align
    idiomatically with the other `autotools'.


1.7 Simplify `bootstrap' process.
─────────────────────────────────

  While the bootstrapping script is really more geared for maintainers
  and contributors working in the repository, as opposed to the source
  tarballs which users download, the existing process’ complexity and
  dependence on external repositories complicates efforts to build
  `libtool' using CI.
  • Use of `git' and reliance on a network connection to vendor external
    repositories during the bootstrap phase complicates conventional
    hashing approaches used to cache CI artifacts.
  • Requiring a network connection for bootstrapping raises security
    concerns which would make automatic testing of patch submissions
    unsafe.
  • Ideally bootstrapping `libtool' should be possible using a minimal
    tool-chain. Likely `coreutils' ( or equivalent ), `awk', `sed',
    `grep', `tar', `cc', `binutils' ( or equivalent ), `make',
    `autoconf', `automake', `m4', `findutils', `tar', and `xz'.
    Dependence on `texinfo', `help2man', etc could be optional.
  • Parts of `gnulib' which we require should be vendored. The existing
    bootstrap process checks out a specific commit of `gnulib' and
    `gl/bootstrap', so vendoring this code is functionally equivalent.


1.8 Make the creation of test cases more user friendly
──────────────────────────────────────────────────────

  While the existing documentation recommends that folks submitting
  issues create a test case which reproduces their problem, the
  complexity of the test suite makes that impractical.
  • The existing test suite is robust, and I have no intention of
    replacing it, however creating an avenue for contributors/users to
    draft simple `sh' scripts or minimal `autotools' projects for
    reproducing issues should be as user friendly as possible.
  • If creating test cases is not convenient, contributors and users
    simply won’t do it, and the burden of authoring these tests will
    fall to the `libtool' team. Often `libtool' team members do not
    readily have access to the effected platform, or lack experience
    with a given platform and tool-set’s quirks. A practical and
    predictable, consequence is that certain platforms and tool-chains
    lack robust testing.


1.9 Create CI pipeline resources for distribution and tool maintainers
──────────────────────────────────────────────────────────────────────

  This would likely be placed in a branch or separate repository. The
  goal here is that a declarative CI pipeline for testing `libtool' be
  drafted such that members of the `libtool' team, or external projects
  which want to integrate with `libtool' may self-host a set of CI jobs
  used to build and test `libtool' with parameterized inputs.
  • For example, if I am a `coreutils' contributor, it may be useful to
    drop in an alpha build of `coreutils' to see if it blows up
    `libtool'.
  • Similarly, if I am a `libtool' contributor, it may be useful to
    automatically test a matrix of `autoconf' and `automake' versions to
    see if we have broken compatibility with a particular release of
    those tools.
  • Currently we often don’t hear about changes which broke a niche
    combination of platform, arch, and tool-set combinations until after
    a release is out, and people submit issues. While it’s not possible
    to expand an infinite matrix of combinations, real time feedback for
    systems other than a team member’s daily driver could catch a large
    number of issues before they are released.


1.10 Permit installable LTLIBRARIES to conditionally be “convenience libraries”
───────────────────────────────────────────────────────────────────────────────

  This aims to support projects which produce different sets of
  libraries when a static vs. shared library build is being run. Largely
  this effects the handling of internal utility libraries with hidden
  symbol visibility.
  • For clarity “convenience” libraries are simply `PIC' `libfoo.a'
    libraries, or equivalent for a given platform.
  • This is particularly applicable to `noinst_PROGRAMS' used at build
    time which depend on installable libraries. A `noinst_PROGRAMS'
    executable would likely prefer linking with a static “convenience”
    library rather than a shared library, since they generally do not
    require a wrapper script.
  • With a plain `Makefile' it is trivial to produce either a
    `libfoo.so', static `libfoo.a', and `PIC' `libfoo.a' during a single
    run. `libtool'’s concept of “convenience” libraries make it
    difficult to replicate this workflow for arbitrary reasons.
  • Ex: Project wants to produce `libfoo.la' and `libbar.la' to make
    their public interfaces available to users. Both `libfoo.la' and
    `libbar.la' depend on `libquux.la', which does not contain “user
    facing” public interfaces. Project may wish to install `libfoo.so'
    and `libbar.so' which link `PIC' `libquux.a' with `hidden' symbol
    visibility when `-shared' is in effect, but may wish to install
    `libfoo.a', `libbar.a', and `libquux.a' when `-static' is in effect.
  • Ex: A project may wish to conditionally produce a `libquux.so', or
    roll `libquux.a' into `libfoo.so' such that `libbar.so' may satisfy
    its undefined references in for `libquux.la' through `libfoo.so'.
  • Ex: When performing unit tests linking `PIC' `libfoo.a' rather than
    `libfoo.so' into a test executable `mytest' allows `mytest' run
    without a wrapper, so that it may be moved to and run in arbitrary
    directories. Frankly if I’m authoring tests, the `libtool' wrapper
    over executables may be more of a headache than a convenience.
  • As niche as these use-cases may sound, there are variety of reasons
    for a project to produce any of `libfoo.so', static `libfoo.a', and
    `PIC' `libfoo.a' during a single build/install.
  • To accomplish this in existing releases of `libtool', project
    authors would be required to define `libquux.la' “twice”, once as a
    “convenience” library, and again as an installable `LTLIBRARY' with
    identical sources and flags. It might also be necessary for users to
    configure and/or build twice to get the desired outputs.
    My preference is “DRY”.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]