This is an archive of the discontinued LLVM Phabricator instance.

[lld-macho] Provide an option to ignore framework-not-found errors coming from LC_LINKER_OPTIONS.
AbandonedPublic

Authored by oontvoo on Dec 16 2022, 9:56 AM.

Details

Reviewers
keith
int3
Group Reviewers
Restricted Project
Summary

This makes it a bit easier for our current users to move to LLD and avoid these framework-not-found errors.

I know there is an existing option to list the framework(s) to be ignored but in our user-case it is not practical to do that.

Diff Detail

Event Timeline

oontvoo created this revision.Dec 16 2022, 9:56 AM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptDec 16 2022, 9:56 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript
oontvoo requested review of this revision.Dec 16 2022, 9:56 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 16 2022, 9:56 AM

@keith Since you initially implemented these LC_LINKER_OPTION support, perhaps you could help reviewing this?
Thx

I wonder if at this point we should just implement LD64's behavior with an off-by-default flag to be more strict? Specifically they ignore these failures and collect the missing ones and only print about them in the case the link fails

lld/MachO/Options.td
99 ↗(On Diff #483570)

nit: accidental whitespace

104 ↗(On Diff #483570)

for these options we've been using dashes instead of underscores

I wonder if at this point we should just implement LD64's behavior with an off-by-default flag to be more strict? Specifically they ignore these failures and collect the missing ones and only print about them in the case the link fails

Honestly, I find LD64's behaviour a bit sketchy ... How would people feel about making these warnings (instead of errors)? (and of course, get rid of this new flag)
But no strong preference - either would work :)

oontvoo added a comment.EditedDec 16 2022, 12:02 PM

From offline discussions, we have a few options: (in no particular order)

  • make the new ignore_auto_link_errors behave like Apple's LD64, which is that it ignore the errors IFF the link succeeded
  • make framework-not-found errors from LC_LINKER_OPTION warnings instead of errors
  • make existing --ignore_linker_option understand a new special value * to mean "ignore not found errors IFF the link succeeded"

@int3 @thakis /et al : any thought/preference?

Making them warnings seems like a good compromise to me, since people can then use -fatal_warnings if they want to turn this into errors and we don't need a new flag. And if we do want a flag, we could add one to disable this particular warning -- warning-disabling flags have a ton of precedent, so that seems like a nice and cohesive approach to me.

If we make them warnings, you would actually be able to disable the warning today by passing --ignore-auto-link-option=Foo as well, without any new flags

I mean we could remove the somewhat special-purpose ignore-auto-link-option= flag then -- or rather, replace it with a no-warn-autolink flag. That wouldn't allow suppressing this on a per lib level, but that's probably fine?

The benefit of per library opt outs is you can make sure new violations don't sneak in. But either way we can deal with that part separately from this if we want to add a new flag like that

int3 added a comment.Dec 16 2022, 2:17 PM
This comment was removed by int3.
int3 added a comment.Dec 16 2022, 2:19 PM

Making them warnings seems like a good compromise to me, since people can then use -fatal_warnings if they want to turn this into errors and we don't need a new flag.

My understanding is that some third-party/system libraries have these unsatisfied dependencies baked in, so it's not something that's always fixable in the build. We shouldn't require people to turn off -fatal_warnings in their builds to support third-party unfixable stuff.

I'm leaning toward Vy's option #3 (extend existing flag, no new flags), though I think #1 is good too (would make it easier for people to drop in LLD into their builds)

oontvoo added a comment.EditedDec 19 2022, 11:10 AM

Hmm, unfortunately doesn't look like we have a majority here ... I guess how about we go with the option that requires the least API change which is #2 (ie., no new flag):

  • not-found-errors from LC_LINKER_OPTION are warnings by default
  • you can use the existing -ignore_linker_option to silence the warnings if desired.

P.S: This should be the least disruptive, too, because missing libraries/frameworks are already *errors* today - so we're not going to pollute the build logs any more than they're already broken. @int3 You're good with this? :) (You've pointed out that we shouldn't require people to turn off warnings, but this proposed change would not introduce more warnings/errors than whatever already exists)

Eh, in doubt I'd do what int3 recommends 😅

Eh, in doubt I'd do what int3 recommends 😅

I know I'd proposed this, but my reservation with #3 is that it's debatable how the the special * value interacts with others, eg., -ignore_linker_option=* -ignore_linker_option=foo -ignore_linker_option=bar could mean one of the two:

  • * overrides all other instances of ignore_linker_option
  • * covers all frameworks/libraries that are NOT foo or bar, specifically:
    • don't report errors for missing foo and bar even if the link failed
    • BUT don't errors for other missing framework only if the link succeeded (if the link failed, then report those errors)

Furthermore, this means that once a build sets -ignore_linker_option=*, new missing frameworks/libraries from bad LC_LINKER_OPTIONs will be ignored. This is bad because invalid LC_LINKER_OPTIONs aren't exactly "free" .

Ideally, I'd like to have a solution that:

  • tolerates existing violations well enough that users can switch linkers
  • AND at the same time prevents new violations. (if not "prevents" then at least makes users aware of new problems)

With that in mind, option 2 seems a bit better.

int3 added a comment.Dec 19 2022, 10:26 PM
This comment was removed by int3.
int3 added a comment.Dec 19 2022, 10:45 PM

Okay, you've convinced me. But just to clarify some of what I said earlier:

You've pointed out that we shouldn't require people to turn off warnings, but this proposed change would not introduce more warnings/errors than whatever already exists

Yes, but it still makes turning on -fatal_warnings harder. And I would like to be able to turn it on for most of our builds. (We are already looking at downgrading certain warnings internally to achieve this, but I would like to minimize the number of local patches.)

Furthermore, this means that once a build sets -ignore_linker_option=*, new missing frameworks/libraries from bad LC_LINKER_OPTIONs will be ignored.

I was thinking that we would still emit a non-warning message when we encounter missing frameworks that aren't explicitly ignored. But you're right, this is a deviation from how the existing -ignore_linker_option flag works for explicit ignores.

Anyway I realize that making them warnings isn't so bad because folks can use -ignore_linker_option to make the build warning-free. Turning on -fatal_warnings usually requires some build cleanup work anyway, so requiring people to figure out which libraries to ignore seems par for the course.

Eh, in doubt I'd do what int3 recommends 😅

Please push back if things don't make sense 😅 I'm not always thinking straight...

oontvoo updated this revision to Diff 484460.Dec 20 2022, 9:35 PM

Updated diff to implement option #2, whic is to make missing frameworks/libraries warnings instead of errors.

Thanks, all, for the inputs!

Okay, you've convinced me. But just to clarify some of what I said earlier:

You've pointed out that we shouldn't require people to turn off warnings, but this proposed change would not introduce more warnings/errors than whatever already exists

Yes, but it still makes turning on -fatal_warnings harder. And I would like to be able to turn it on for most of our builds. (We are already looking at downgrading certain warnings internally to achieve this, but I would like to minimize the number of local patches.)

Well, this patch can't make it any harder because it downgrades errors to warnings. In other words, such builds would be already broken - this would "unbreak" them, in exchange for some additional warnings

oontvoo updated this revision to Diff 484462.Dec 20 2022, 10:03 PM

updated warning msg in test

oontvoo updated this revision to Diff 484467.Dec 20 2022, 10:28 PM

added more tests for missing libaries (-l) too. Also included the files where the bad LC_LINKER_OPTION live to help debugging

int3 added a comment.Dec 21 2022, 8:54 AM

Well, this patch can't make it any harder because it downgrades errors to warnings. In other words, such builds would be already broken - this would "unbreak" them, in exchange for some additional warnings

Sorry I wasn't clear -- I meant that it makes it harder relative to the option where they aren't warnings at all. The point I want to make is that we shouldn't just use "this doesn't break existing builds that use LLD" as a guideline, since we are still trying to grow our userbase. We should try to make it as easy as possible to adopt LLD, and if someone has an existing build that uses ld64 together with -fatal_warnings enabled, we (ideally) shouldn't require them to disable it in order to switch.

lld/MachO/Driver.cpp
428

would be nice to have an explanatory comment here about why we are only emitting a warning

could we also update the comment here? It probably should now say that LLD will warn on missing libraries (instead of completely disallowing them), but that the --ignore-auto-link-option is useful for squelching those warnings entirely.

429–430

Error messages should be of the form toString(file) + ": $message" if there is a file involved. Not all the messages in LLD-MachO are of this format yet, but I'd like to migrate them all. This seems to be the prevailing format used in LLD-ELF.

also the message should probably say "referenced from LC_LINKER_OPTION"

lld/test/MachO/lc-linker-option.ll
140
144–145

most tests don't include the ld64.lld: prefix

also the message should say -lfoo, not -l foo (to reflect the actual input, & for consistency with the message used for not-found libraries on the CLI)

oontvoo updated this revision to Diff 484620.Dec 21 2022, 10:55 AM
oontvoo marked 4 inline comments as done.

addressed review comments:

  • put fileloc's at the beginning of the warn msg
  • remove ld64.lld from expected warning msgs in tests
  • add comments
oontvoo updated this revision to Diff 484621.Dec 21 2022, 10:56 AM

removed redundant whitespaces

After reading all this discussion, and seeing this well timed issue https://github.com/llvm/llvm-project/issues/59627 which is caused by this as well, I feel like we should take the opportunity to mirror ld64's behavior entirely, and potentially add a flag to opt-in to the more strict behavior that exists today. My opinion changed here since we talked about this last year because at least 5 people who have tried this have asked me about this specific issue. This issue is far more wide-spread than I originally thought in the community, and I don't think there's huge value in fixing these issues if your link succeeds anyways. Overall from this conversation it doesn't seem like anyone feels strongly enough about being strict on this issue that it justifies differing from ld64 and making adoption even just slightly harder.

I submitted https://reviews.llvm.org/D140491 with that approach if folks agree

int3 added a comment.Dec 21 2022, 2:00 PM

I feel bad for all the back-and-forth with @oontvoo's work, but in general I am in favor of things that improve ease of adoption. @keith's solution seems clean enough too. +1

I feel bad for all the back-and-forth with @oontvoo's work, but in general I am in favor of things that improve ease of adoption. @keith's solution seems clean enough too. +1

It's really not a big deal 😃 (I'd just like to see a solution submitted the sooner the better)

Keith's proposal LGTM , as long as we have that option to opt-in to the more strict because I still don't think bad limker-options are completely harmless. For one, they takes up space. For two, if our toolchains generate bad linker-options then we'd really like to know to fix the bug.

oontvoo abandoned this revision.Jan 3 2023, 5:54 PM

rescinding this in favour of D140491.
Thanks!