Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow missing libraries #7847

Merged
merged 3 commits into from Jul 17, 2020
Merged

Conversation

maxim-belkin
Copy link
Member

@maxim-belkin maxim-belkin commented Jun 28, 2020

  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same change?
  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes? Here's an example.
  • Have you successfully run brew style with your changes locally?
  • Have you successfully run brew tests with your changes locally?

This enables formula creators/editors to say that the formula can have broken linkage by adding allow_missing_libs to the formula definition.
Things to consider:

  1. Shall this be a bit more precise and affect broken_dylibs only?
  2. Shall this be always false on a Mac and define allow_missing_libs on Linux only (under extend/os/linux/linkage_checker)?

CC @sjackman @iMichka

@maxim-belkin
Copy link
Member Author

Testing this on root formula (Homebrew on Linux Docker container):

$ brew linkage --test root
Missing libraries:
  libASImage.so
  libCling.so
  libCore.so
  libEG.so
  libFTGL.so
  libFoam.so
  libGLEW.so
  libGX11.so
  libGed.so
  libGeom.so
  libGpad.so
  libGraf.so
  libGraf3d.so
  libGui.so
  libHist.so
  libHistFactory.so
  libImt.so
  libMLP.so
  libMathCore.so
  libMathMore.so
  libMatrix.so
  libMinuit.so
  libMultiProc.so
  libNet.so
  libNew.so
  libPhysics.so
  libProof.so
  libProofPlayer.so
  libRCsg.so
  libRGL.so
  libRHTTP.so
  libRIO.so
  libROOTBrowserv7.so
  libROOTDataFrame.so
  libROOTGpadv7.so
  libROOTHist.so
  libROOTHistDraw.so
  libROOTNTuple.so
  libROOTVecOps.so
  libROOTWebDisplay.so
  libRint.so
  libRooFit.so
  libRooFitCore.so
  libRooStats.so
  libTMVA.so
  libThread.so
  libTree.so
  libTreePlayer.so
  libTreeViewer.so
  libWebGui6.so
  libXMLIO.so
  libXMLParser.so
  libXrdProofd.so
  libvdt.so
Broken library linkage ignored

[linuxbrew@docker] [Sun Jun 28 04:45:46] [Last Exit Code: 0]

@iMichka
Copy link
Member

iMichka commented Jun 28, 2020

Can we have a mechanism for macOS/Linux? I do not know any of these cases on macOS, and a few on Linux, so this is mosty a Linux-only "issue". The idea would be to have two different lists/functions for both OSes.

@maxim-belkin
Copy link
Member Author

maxim-belkin commented Jun 28, 2020

I'm not sure I understand the question/request. The way I implemented it here is that addition of allow_missing_libs line to formulae that have "broken" linkage should let them pass brew linkage --test test. I looked at the output of missing libs for root package and thought that listing specific library names would be an ovekill. In the current implementation, formulae in both homebrew-core and linuxbrew-core can do that. I can move things around to make it Linux-only -- I just need to know if this is what is wanted/needed.

@MikeMcQuaid
Copy link
Member

Can you provide an example usage of what the root formula would look like with this?

  1. Shall this be a bit more precise and affect broken_dylibs only?

Yes, I think so. I think this should specify a list of libraries (or even a glob) and there needs to be a match otherwise it's an error (so we are forced to remove these when they no longer reply).

  1. Shall this be always false on a Mac and define allow_missing_libs on Linux only (under extend/os/linux/linkage_checker)?

If we have no usage on macOS so far: yes, I think so. In that case the DSL should be designed in such a way that we could add it on macOS later if need be and be clear that it only applies to Linux now.

Nice work @maxim-belkin!

@maxim-belkin
Copy link
Member Author

Can you provide an example usage of what the root formula would look like with this?

In the current implementation, it'll look like this:

https://github.com/maxim-belkin/linuxbrew-core/blob/823efb5eb087a64c108aa5e5087cf3dcbe3e288c/Formula/root.rb#L57

(not sure why the above link doesn't render into a code snippet 😕)

I think this should specify a list of libraries (or even a glob) and there needs to be a match otherwise it's an error (so we are forced to remove these when they no longer reply).

Makes sense. Shall it be implemented as a block or similarly to skip_clean?

If we have no usage on macOS so far: yes, I think so. In that case the DSL should be designed in such a way that we could add it on macOS later if need be and be clear that it only applies to Linux now.

OK, I'll update the PR accordingly. But just to make sure we're on the same page: do you expect formulae on macOS to respond false to .allow_missing_libs? (or whatever other name you may suggest -- I spent 1.3 seconds thinking about it) or fail on that call?

@MikeMcQuaid
Copy link
Member

(not sure why the above link doesn't render into a code snippet 😕)

Not the same repo.

In the current implementation, it'll look like this:

https://github.com/maxim-belkin/linuxbrew-core/blob/823efb5eb087a64c108aa5e5087cf3dcbe3e288c/Formula/root.rb#L57

Gotcha. Yeh, I think this should specify the libraries and have something in the name or a parameter that mentions linux.

Shall it be implemented as a block or similarly to skip_clean?

Similar to skip_clean works for me. Could even allow providing a regex (which errors if there's 0️⃣ matches).

OK, I'll update the PR accordingly. But just to make sure we're on the same page: do you expect formulae on macOS to respond false to .allow_missing_libs? (or whatever other name you may suggest -- I spent 1.3 seconds thinking about it) or fail on that call?

Thanks! I think it depends on whether the name is Linux-y or whether it takes a linux parameter. @Homebrew/linux thoughts?

@iMichka
Copy link
Member

iMichka commented Jun 29, 2020

I think we should go with linux in the method's name. We have done the same for on_macos/on_linux, where we have specific methods by OS, and not one generic method with a parameter.

By the way, I think the root libraries are files provided by root. Maybe there we would not need to specificy the list of files?
For openjdk though, there are also external shared libraries, so there a list might be useful.

Or we can just go for a list of files everywhere to be consistent. There won't be that many formuale needing this anyway (maybe 3-4).

@MikeMcQuaid
Copy link
Member

I think we should go with linux in the method's name. We have done the same for on_macos/on_linux, where we have specific methods by OS, and not one generic method with a parameter.

Or: it always has to be inside a on_linux block? My only concern is if we do at some point decide we need this on macOS that renaming this method is going to be a pain (and also we have no methods except on_linux that have linux in their name and only uses_from_macos for macOS which wouldn't ever be used on Linux anyway).

Or we can just go for a list of files everywhere to be consistent. There won't be that many formuale needing this anyway (maybe 3-4).

A middle-ground would be a glob. My only concern is this list is pretty long.

By the way, I think the root libraries are files provided by root. Maybe there we would not need to specificy the list of files?

If these are all files that are in lib: maybe just setting it without a list is enough?

@sjackman
Copy link
Member

Or: it always has to be inside a on_linux block?

👍

Bike shedding:

on_linux do
  ignore_missing_libraries %w[libASImage.so libCling.so libCore.so]
end

or perhaps skip_missing_libraries.

@MikeMcQuaid
Copy link
Member

on_linux do
  ignore_missing_libraries %w[libASImage.so libCling.so libCore.so]
end

Works for me 👍.

@maxim-belkin maxim-belkin force-pushed the allow_missing_libs branch 2 times, most recently from c6e78a8 to e165f45 Compare July 10, 2020 21:40
@maxim-belkin
Copy link
Member Author

maxim-belkin commented Jul 10, 2020

Updated. Formulae can now specify ignore_missing_libraries as an array of strings and/or regex-es:

ignore_missing_libraries ["libASImage.so", "libCling.so", "libCore.so", %r{libxcb\.so\.\d}]

brew style is now unhappy with the number of lines in formula.rb:

$ brew style formula.rb
== formula.rb ==
C: 52:  1: Class has too many lines. [1403/1400]

1 file inspected, 1 offense detected

@maxim-belkin
Copy link
Member Author

Shall we add a special case :self to allow missing linkages to libraries provided by the formula itself?

@sjackman
Copy link
Member

Shall we add a special case :self to allow missing linkages to libraries provided by the formula itself?

I'm inclined not to add the additional complexity. ignore_missing_libraries should be used relatively rarely.

@jonchang
Copy link
Contributor

I think this needs a rebase and a quick brew style --fix.

@jonchang
Copy link
Contributor

:shipit:

@jonchang jonchang merged commit 13f0d4a into Homebrew:master Jul 17, 2020
@jonchang
Copy link
Contributor

Thanks @maxim-belkin! Note that this shouldn't be used in formulae until we tag a release that contains this commit, but it can be tested on e.g. CI builds.

Copy link
Member

@MikeMcQuaid MikeMcQuaid left a comment

Choose a reason for hiding this comment

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

Nice work! Some comments that'd be nice to address.

Comment on lines +18 to +23
case x
when Regexp
x.match? lib
when String
lib.include? x
end
Copy link
Member

Choose a reason for hiding this comment

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

What about when it's neither? Would be nice to error in that case.

Copy link
Member Author

Choose a reason for hiding this comment

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

We can add some logic here but... shall we wait and see if there is a need for that? Right now I suspect there will be 0 use cases for that error-catching "else".

Copy link
Member

Choose a reason for hiding this comment

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

This will fail non-gracefully if there's a need for that. An else with a raise is minimal code to be maintained but will produce a nicer error message

Copy link
Member Author

Choose a reason for hiding this comment

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

This will fail non-gracefully if there's a need for that.

How would this fail? I thought it'll just quietly ignore it. I'm probably missing something... Anyways, I agree with adding an else but shall it odie or owarn?

Copy link
Member

Choose a reason for hiding this comment

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

Well, I guess "fail" is the wrong word here but "silently ignore the invalid non-String/non-Regex input" is probably a better one.

class << self
undef on_linux

def on_linux(&_block)
yield
end

def ignore_missing_libraries(*libs)
libs.flatten!
Copy link
Member

Choose a reason for hiding this comment

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

This will modify the caller which doesn't seem like what we'd want. Merging with libs.flatten seems better.

Copy link
Member

Choose a reason for hiding this comment

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

What will happen if you use this on macOS? I'd say it should have a custom error rather than "method not defined"

def broken_dylibs_with_expectations
output = {}
@broken_dylibs.each do |lib|
output[lib] = (unexpected_broken_libs.include? lib) ? ["unexpected"] : ["expected"]
Copy link
Member

Choose a reason for hiding this comment

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

Could this be an if? Bit hard to follow as-is.

@maxim-belkin maxim-belkin deleted the allow_missing_libs branch August 17, 2020 18:47
@BrewTestBot BrewTestBot added the outdated PR was locked due to age label Dec 17, 2020
@Homebrew Homebrew locked as resolved and limited conversation to collaborators Dec 17, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated PR was locked due to age
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants