Skip to content

meson: fix build with lld on linux#183

Open
natthias wants to merge 1 commit into
latchset:masterfrom
natthias:master
Open

meson: fix build with lld on linux#183
natthias wants to merge 1 commit into
latchset:masterfrom
natthias:master

Conversation

@natthias

Copy link
Copy Markdown

Currently, building on a system with clang fails with
clang: error: unknown argument: '-export-symbols-regex=^jose_.*'
as they are not 1:1 compatible. This fixes this by explicitly checking for clang and falling back to the FreeBSD check, which also uses clang.

Not sure if this is the correct solution, but jose now successfully builds with both clang and gcc.

@hdholm

hdholm commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

It looks to me like v15 built with clang correctly (see https://github.com/latchset/jose/actions/runs/27129994139 ) Is there some detail I'm missing about the clang build on which you're seeing this?

@natthias

natthias commented Jun 13, 2026

Copy link
Copy Markdown
Author

Ahh yea, a bit too fast there. This is not the fault of clang itself, but rather using lld as the linker instead of bfd. Converting this to a draft as this is definetly not the correct solution.

edit:
Interestingly, gcc only treats ld.lld: warning: cannot find entry symbol xport-symbols-regex=^jose_.*; not setting start address as a warning, and not and error.

@natthias
natthias marked this pull request as draft June 13, 2026 10:01
@natthias

Copy link
Copy Markdown
Author

Yea, so the issue seems to be exactly what the freebsd faced in #152.
Perhaps checking for lld and then falling back to the --undefined-version invocation is a more scalable solution going forward?

@natthias

Copy link
Copy Markdown
Author

Now explicitly checks for lld instead of clang.

@natthias
natthias marked this pull request as ready for review June 14, 2026 23:01
@natthias natthias changed the title meson: fix build with clang on linux meson: fix build with lld on linux Jun 14, 2026

@sergio-correia sergio-correia left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an operator precedence issue in the compound boolean that regresses version-script support on GNU ld. --undefined-version is an lld-only flag (introduced in LLD 16) and does not exist in GNU ld, so the second probe always fails with GNU ld, causing fallback to the coarser regex export. Splitting into nested if/else for lld vs non-lld (matching the FreeBSD branch pattern) should fix it.

Not in this diff, but related: lines 6 and 10 use build_machine.system() to choose linker flags, but host_machine.system() is correct here since the flags apply to the output binary, not the build host. meson.get_compiler('c') already returns the host compiler, so using build_machine for the platform check is inconsistent. The root meson.build already uses host_machine.system() for the FreeBSD licensedir check. This is pre-existing and could be addressed separately.

Comment thread lib/meson.build
Comment on lines +20 to +28
if cc.get_linker_id() != 'ld.lld' and not cc.links(
code,
args: version_script_flags,
name: '-Wl,--version-script=...',
) or not cc.links(
code,
args: version_script_flags + ',--undefined-version',
name: '-Wl,--version-script=...',
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Meson, and binds tighter than or, so this condition parses as:

(cc.get_linker_id() != 'ld.lld' AND NOT cc.links(plain))
OR
(NOT cc.links(with_undefined_version))

The second clause applies to all linkers, not just lld. Since --undefined-version is an lld-only flag (introduced in LLD 16) and does not exist in GNU ld at all, the second probe will always fail on GNU ld, regressing version-script support on every GNU ld system.

Would it be better to split this into nested if/else for lld vs non-lld? That matches the FreeBSD branch pattern and avoids the precedence trap:

if cc.get_linker_id() == 'ld.lld'
  if not cc.links(code, args: version_script_flags + ',--undefined-version',
                  name: '-Wl,--version-script=... (lld)')
    flags = ['-export-symbols-regex=^jose_.*']
  else
    flags = [version_script_flags]
  endif
else
  if not cc.links(code, args: version_script_flags,
                  name: '-Wl,--version-script=...')
    flags = ['-export-symbols-regex=^jose_.*']
  else
    flags = [version_script_flags]
  endif
endif

Comment thread lib/meson.build
if cc.get_linker_id() != 'ld.lld' and not cc.links(
code,
args: version_script_flags,
name: '-Wl,--version-script=...',

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both cc.links() calls use the same name: '-Wl,--version-script=...', so Meson's configure output doesn't distinguish which probe passed or failed. Maybe use different names like '-Wl,--version-script=... (plain)' and '-Wl,--version-script=... (--undefined-version)' to make build logs easier to read.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants