Bug 258820 - Multiple ports fail to build with USE_LTO: libffi.a strip: file format not recognized (propose: disable building static library)
Summary: Multiple ports fail to build with USE_LTO: libffi.a strip: file format not re...
Status: Open
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Ports Framework (show other bugs)
Version: Latest
Hardware: Any Any
: --- Affects Some People
Assignee: Kubilay Kocak
URL:
Keywords: needs-qa
Depends on:
Blocks: 258822
  Show dependency treegraph
 
Reported: 2021-09-30 22:50 UTC by Piotr Kubaj
Modified: 2023-04-05 15:20 UTC (History)
10 users (show)

See Also:
koobs: maintainer-feedback? (emaste)
koobs: maintainer-feedback? (dim)


Attachments
patch (700 bytes, patch)
2021-09-30 22:50 UTC, Piotr Kubaj
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Piotr Kubaj freebsd_committer freebsd_triage 2021-09-30 22:50:04 UTC
Created attachment 228298 [details]
patch

Ports generally should not build static libraries.

This also breaks build with USE_LTO=yes:
libtool: install: /usr/bin/install -c .libs/libffi.lai /wrkdirs/usr/ports/devel/libffi/work/stage/usr/local/lib/libffi.la
libtool: install: /usr/bin/install -c .libs/libffi.a /wrkdirs/usr/ports/devel/libffi/work/stage/usr/local/lib/libffi.a
libtool: install: strip --strip-debug /wrkdirs/usr/ports/devel/libffi/work/stage/usr/local/lib/libffi.a
strip: file format not recognized
Comment 1 Kubilay Kocak freebsd_committer freebsd_triage 2021-09-30 23:08:00 UTC
I've seen many examples of consumers / users requesting static libraries being made available where they weren't for their use cases. 

-1 on disabling static libraries in favour of understanding ways that these cases should generally being handled.
Comment 2 Piotr Kubaj freebsd_committer freebsd_triage 2021-10-01 09:18:16 UTC
OK, then what about conditionally disabling it?

.if defined(USE_LTO)
CONFIGURE_ARGS+=--enable-static=no
.endif

This will make it possible to build libffi and attempt to build more dependencies.

Since ports should link dynamically anyway, those failing ports will then be able to be investigated.
Comment 3 Kubilay Kocak freebsd_committer freebsd_triage 2021-10-02 01:55:59 UTC
(In reply to Piotr Kubaj from comment #2)

That's an option, but it doesn't appear to be a root cause fix?

Should $STRIP be attempting to strip static libraries?
Comment 4 Kubilay Kocak freebsd_committer freebsd_triage 2021-10-02 01:59:32 UTC
See also:

https://www.mail-archive.com/freebsd-pkg-fallout@freebsd.org/msg320137.html

This appears to be a broader (than LTO) issue, and an opportunity to remove workarounds (disabling static) that reduce choice and flexibility for our port/package consumers
Comment 5 Kubilay Kocak freebsd_committer freebsd_triage 2021-10-02 02:00:13 UTC
Several other ports fail in the same manner WITH_LTO (I will be reporting all affected ports as issues when i finish testing all local ports)
Comment 6 Kubilay Kocak freebsd_committer freebsd_triage 2021-10-05 00:12:59 UTC
A couple of us are partially through isolation of this issue, with further investigation required.

^Triage: Update summary to describe the broader issue category, as it affects multiple ports.
Comment 7 Daniel Engberg freebsd_committer freebsd_triage 2021-10-05 01:16:21 UTC
This a a bit troublesome in our tree, looking at other repositories they usually offer the static library as a separate package while we don't. There's also concerns about users foot-shooting if the option is available, see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=257623
We do have ports that require static libraries however we also have a lot of "unused" ones enabled at least as far as the ports tree goes. I guess one option would adding the static library as a flavour but that would be a huge task.
Comment 8 Kubilay Kocak freebsd_committer freebsd_triage 2021-10-05 06:03:13 UTC
(In reply to Daniel Engberg from comment #7)

Separating packages is orthogonal to addressing the root problem, sweeping the issue/question to a -static subpackage/flavor build.

The root issue appears to be elftoolchain strip not understanding LLVM IR from LTO builds in or for static libraries. It may turn out that strip tools 'shouldnt' need to support stripping LTO-d static libraries, but I haven't found evidence that this is the case.

So far I've additionally tried:

 - llvm-strip / llvm-objcopy --strip-debug (14.0-CURRENT #2 main-n249859-248682a5891)

   error: '/var/tmp/tmpfs0/usr/ports/devel/libuv/work/stage/usr/local/lib/libuv.a(libuv_la-fs-poll.o)': The file was not recognized as a valid object file

 - binutils: strip*: 

   Unable to recognise the format of file: file format not recognized (Note: this error is not fatal.)

 - Notable also, llvm-nm reports no errors on the same file.

I've been hunting authoritative upstream (llvm) references for bug reports or commits that hint at this issue, or how one should handle it, but haven't quite identified anything precisely on target.

Feedback from Ed (for elftoolchain), and Dim (for LLVM) would be great for leads here.

The ideal outcome here is the ability to strip debug symbols from static libraries built with LTO(thin), and ideally with the toolchain FreeBSD expects to have in the long-term (llvm's).

If that turns out to require some tweaks to upstream LLVM/Clang tools, then we may be able to separately port llvm-strip (with the fixes) until all supported LLVM/Clang releases in base contain the appropriately fixed versions. Alternatively, have elftoolchain's strip support it in the short term, and have that in ports, if its not there already.

Failing that, and down the list of desired partial resolutions, we could use a STRIP_MASK style setup for the strip framework mechanism, that supports excluding static libraries. Gentoo did this in the past when GNU strip was mangling static libraries [1] and its probably useful for us for other reasons too.

[1] https://github.com/InBetweenNames/gentooLTO/issues/49
Comment 9 Ed Maste freebsd_committer freebsd_triage 2021-11-22 15:58:07 UTC
(In reply to Kubilay Kocak from comment #8)
Your assumption is correct, when built with -flto the object file is LLVM IR rather than ELF.

$ cc -c -flto foo.o
$ file foo.o
foo.o: LLVM IR bitcode

A .a is just an archive of .o files (along with a symbol table), and isn't part of the strip issue per se.

A few points here:

- It usually doesn't make a lot of sense to strip .o or .a files.

- Stripping LLVM IR also doesn't make a lot of sense IMO.

- We could probably have ELF Tool Chain strip detect and ignore bitcode files - make no changes and exit with status 0.

- ELF Tool Chain ar can create a .a archive of LLVM IR .o files, but cannot parse the symbol tables in the .o files to create the archive symbol table.

- Longer term we will presumably migrate to LLVM's ar, nm, strip etc. (WITH_LLVM_BINUTILS) as it seems unlikely support will be added to ELF Tool Chain tools.

Given the above I suggest that in the short term we should just stop trying to strip libffi.a (and other .a archives in ports), and do nothing else until we have migrated to LLVM's tools. Having ELF Tool Chain strip ignore bitcode is probably straightforward, but it's not that useful if we don't also address ar.
Comment 10 Rene Ladan freebsd_committer freebsd_triage 2022-03-07 19:55:18 UTC
Maintainer reset.
Comment 11 f451 2022-08-16 22:19:29 UTC
A data point that might be relevant:

With recent -current and a poudriere jail in arm64 built with WITH_LLVM_BINUTILS= in its src.conf, databases/postgresql13-client fails testport at the install phase with

[00:12:01] strip: error: '/wrkdirs/usr/ports/databases/postgresql13-client/work/stage/usr/local/lib/_inst.67779_': not stripping symbol '.L.str.1' because it is named in a relocation
[00:12:01] gmake[3]: *** [../../../../src/Makefile.shlib:425: install-lib-static] Error 1

USE_LTO= is not present either in the host or in the poudriere src.conf.

The workaround was to remove 

<<<<<<<<<<<<<<
WITH_LLVM_BINUTILS=
>>>>>>>>>>>>>>

from src.conf for that poudriere jail instance, delete and build the jail again.

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=265878
Comment 12 Luna 2022-10-24 21:33:23 UTC
Is there a workaround for this issue?
Comment 13 Ed Maste freebsd_committer freebsd_triage 2023-04-05 15:20:28 UTC
(In reply to Luna from comment #12)
Right now the only workaround is to build without LLVM_BINUTILS set. See PR258872 for the WITH_LLVM_BINUTILS exp-run, and 
https://github.com/llvm/llvm-project/issues/47468 for the upstream LLVM issue for "not stripping symbol '.L.str.1' because it is named in a relocation"