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

understanding and completing conf-llvm #9853

Closed
gasche opened this issue Jul 16, 2017 · 16 comments
Closed

understanding and completing conf-llvm #9853

gasche opened this issue Jul 16, 2017 · 16 comments

Comments

@gasche
Copy link
Member

gasche commented Jul 16, 2017

As part of looking at #9810 with @thierry-martinez I realized that some packages that depend on LLVM are using their own depexts instead of using conf-* packages as advised by #5791. The llvm-configuration-related packages seem to have a fair bit of history (cc @whitequark, @jpdeplaix and @ivg), so I'm creating this issue to explain what I currently understand, propose a plan forward and ask questions.

Current state

If I understand correctly, there are two sort of conf-llvm packages:

  • conf-llvm has one version per LLVM version; it currently supports 3.4 and 3.8 only.
  • conf-bap-llvm has a single version which, when installed, dynamically selects between 3.4 and 3.8 depending on what is available.
  • both conf-llvm and conf-bap-llvm create a conf-llvm.config file whose values become opam variables, so after depending on any of them conf-llvm:version gives the currently available LLVM version, and conf-llvm:config gives the name of the relevant llvm-config executable.

Among OCaml packages that use LLVM, there are three categories:

  • package who use the conf-* packages. As far as I can tell, this is only the bap-llvm package (and thus the bap ecosystem). I don't understand if only conf-bap-llvm is used today and conf-llvm is legacy (that is my guess), or if both have their uses. (@ivg?)
  • packages who use their own depexts: clangml, llvm (llvmgraph just depends on llvm), and hardcaml-llvmsim
  • pure-OCaml packages that don't have a hard dependency on llvm (? I would guess that version bounds may still be required, @sagotch?): ollvm and ollvm-tapir.

Going forward

I would like to have one conf-llvm and one conf-clang package per LLVM and clang M.N version, for packages to be able to say "we depend on an external install of LLVM.3.9" for example.

I don't understand if packages like conf-bap-llvm that support several different llvm versions are actually necessary (and it feels a bit weird to me to have a conf-* package whose meaning is determined by OCaml packages that depend on it, rather than by independently-meaningful checks of the environment). Can the current conf-bap-llvm always be replaced by ("conf-llvm-3.4" | "conf-llvm-3.8") in dependencies?

Of course I would like to consolidate the depext-using package to rely on conf-llvm instead, and review the depext in the conf-* packages to support as many different systems as possible.

@gasche gasche mentioned this issue Jul 16, 2017
@kit-ty-kate
Copy link
Member

I personally wasn't aware of the purpose of the conf-* packages. I'll try to do a PR today to add the right conf-llvm packages.

@ivg
Copy link
Member

ivg commented Jul 20, 2017

The idea behind the conf-bap-llvm was described in the PR #7606. The reason why we need/want this package was to be able to install bap with a plain opam install bap on more distributions, or even opam depext --install bap The logic is more complex, then (conf-llvm.3.4 | conf-llvm.3.8) (see below) thus we factored it out into another package, that is bap-specific. I wouldn't say that the meaning of the package depends on a dependent. I envision this package as a part of configuration system that queries the environment and prepares it for the bap installation. In our case, conf-bap-llvm:installed predicate, means, that the configuration environment is ready for the bap-llvm installation. May be I'm stretching the initial idea of conf packages a little bit more than it was originally designed.

The logic behind

The logic of the bap-llvm dependency, that is denoted by (conf-bap-llvm | conf-llvm) is informally the following: if conf-llvm is installed then use whatever user prescribed. Otherwise, depending on the OS type install either 3.4, 3.8, or a default version of llvm. Then search through all known and supported names of the llvm-config tool or use the LLVM_CONFIG variable if a user provided an explicit path to it.

Basically, this is an attempt to overcome opam limitations that doesn't allow us to pass configuration parameters to the configuration script.

@dbuenzli
Copy link
Contributor

@gasche Given @ivg's feedback what do you think should be done now ?

Basically, this is an attempt to overcome opam limitations that doesn't allow us to pass configuration parameters to the configuration script.

Regarding this I'm getting less and less convinced that opam packages should try to propagate configuration information among them.

I think that opam conf-* packages should be able to probe for external dependencies by consulting the opam managed and non-opam managed world but that the same discovery logic should be part of the packages themselves by consulting the environment in which they are installed (regardless whether this is happens in an opam setting or not).

The latter seem to be more inline with what @ygrek suggests in this #3093 (comment) where opam also happen to be part of the "host" configurator by extending the environment to enable access for what it does install itself.

Basically the conf-* packages should just be packages to check for external, versioned information and allow to trigger external install via depexts. It also seems that in the interest of clarity of error reporting something better is needed in opam regarding these conf-* packages: somehow failure to install these should rather be seen as a "solver" error --- some dependencies are missing or are not up-to-date but it's none of my business to install them --- rather than an install error, which is what effectively a failing conf-* gives you.

@ivg
Copy link
Member

ivg commented Aug 19, 2017

Basically the conf-* packages should just be packages to check for external, versioned information and allow to trigger external install via depexts.

Wasn't they named conf-* for the reason that they are representing system configuration? Maybe, then, they should be named something like system-*, e.g., system-llvm, then it will make more sense.

Anyway, the problem is that "just check for external" is not enough, as for us it is more like a search problem. There can be multiple installations of llvm in a system, and when a user orders OPAM to install conf-llvm.3.4 I should do my best to pick this version in the system not any other. Thus I need to get a path to llvm-config so that I can query for the right flags.

My personal view is that OPAM's interaction with the system is broken or even doesn't exist. Given that OPAM is a source based package manager, like emerge or pip, we definitely need some mechanisms that will allow us to convey system specific configuration data to the build system. So far the only mechanism that we have is the conf packages, and I don't see why I can't use them for that.

@dbuenzli
Copy link
Contributor

Wasn't they named conf-* for the reason that they are representing system configuration? Maybe, then, they should be named something like system-*, e.g., system-llvm, then it will make more sense.

Why not.

There can be multiple installations of llvm in a system, and when a user orders OPAM to install conf-llvm.3.4 I should do my best to pick this version in the system not any other. Thus I need to get a path to llvm-config so that I can query for the right flags.

I fail to see why you can't do this in the package themselves.

we definitely need some mechanisms that will allow us to convey system specific configuration data to the build system. So far the only mechanism that we have is the conf packages, and I don't see why I can't use them for that.

I certainly did think at a certain point that this was opam's role but I'm less and less sure this is a good idea. opam's role in my opinion should rather be to setup the right context for packages to install but I'm less sure it should be the medium itself that conveys configuration information.

As far as your packages are concerned they should be able to install in a context that is not necessarily managed by opam, the fact that opam is being used to install your packages should be a detail. For examples if your packages assume the opam infrastructure as a given or peruses its mecanisms beyond reason it may become difficult to package your software for system packagers.

@ivg
Copy link
Member

ivg commented Aug 21, 2017

I fail to see why you can't do this in the package themselves.

Sure, there are several reasons.

First, we can have several packages that depends on one system package, that why we factor the configuration computation from them to the conf package. This is a minor issue actually, as of course we are not required to follow software engineering practices in package specifications, but still.

Second, we may depend on different versions of a system package, e.g., llvm-3.4 and llvm-3.8, though our OCaml package has totally different versioning bap-llvm.1.0, bap-llvm.1.1, etc. So when a user wants to install bap-llvm with llvm-3.4 he issues opam install conf-llvm.3.4 bap-llvm.

Finally, a pure technical problem, in the build and configuration scripts we can only query flags that are defined in other packages, not in the package itself. And since we would like that our opam file is as declarative as possible we would like to have

    ./configure ---with-llvm-version=%{conf-llvm:version}%"

instead of just ./configure and some magic that finds some version of llvm underneath the hood.

As far as your packages are concerned they should be able to install in a context that is not necessarily managed by opam, the fact that opam is being used to install your packages should be a detail. For examples if your packages assume the opam infrastructure as a given or peruses its mecanisms beyond reason it may become difficult to package your software for system packagers.

That's actually is the problem as BAP is designed to be easily installable with a common package manager. We follow the regular ./configure; make; make install mantra with a configure script that enables and disables certain behaviors as well as provides mechanisms for adapting the build system for the system. We have debian packages and rpms and BAP is included in NixOS distribution. So the problem is not on the bap side, the problem is that I need to pass options to the configure script, and the only mechanism that I have are the conf-* packages.

@ivg
Copy link
Member

ivg commented Aug 21, 2017

I would like to have one conf-llvm and one conf-clang package per LLVM and clang M.N version, for packages to be able to say "we depend on an external install of LLVM.3.9" for example.

We are planning to remove the conf-bap-llvm package. This will reduce our flexibility and will require extra work from a user on some older linux distributions, like Jessie, though given that 3.8 becomes available on more and more modern distributions we can pay this price.

We will also make all conf-llvm packages more consistent, and all of them will provide a path to llvm-config, that we consider as a witness of availability of the llvm library in the system.

@dbuenzli
Copy link
Contributor

So the problem is not on the bap side, the problem is that I need to pass options to the configure script, and the only mechanism that I have are the conf-* packages.

Maybe but in the long term I doubt this is the right mecanism, something along these lines would be a better fit.

@ivg
Copy link
Member

ivg commented Aug 21, 2017

Maybe but in the long term I doubt this is the right mecanism, something along these lines would be a better fit.

Oh definitely, here we are on the same page. I mostly see the conf- packages as a nasty workaround, that is totally non-intuitive and too opam specific. So yes, configuration variables is the mechanism that I'm eagerly waiting. Unfortunately, it didn't land up even in opam-2.0, so for the next five or more years we a stuck with the conf packages.

Unless it is possible to implement them as a plugin, so that this behavior can be back ported to opam.1 and opam.2.

@ivg
Copy link
Member

ivg commented Aug 25, 2017

@dbuenzli, since you're here. I see the following solution to the #10164 problem and to the conf-llvm problem in general. We shouldn't use OPAM version to version conf-packages, and should follow the debian style versioning, e.g., instead of having conf-llvm.{3.4,3.8,...} we should have different packages conf-llvm-3_4, conf-llvm-3_8, etc. All of them may have versions, e.g., conf-llvm-3_4.0.1, where 3_4 represents the version of the system package, and 0.1 represents the version of particular configuration script, that checks it. Thus opam will never try to upgrade the conf package, unless a better configuration script is available.

What do you think of this?

@whitequark
Copy link
Member

@ivg This has partly very good consequences, and partly not so much.

  • The good consequence is that this scheme can adequately represent the way sonames function. (Q: What about Windows?)
  • The bad consequence is that specifying compatibility with a range of LLVM versions becomes confusing. Sure, you could have a conf-llvm.3.8 that depends on conf-llvm-3_8 (which is bad enough), but then how do you depend on the particular version of configuration scripts?

@gasche
Copy link
Member Author

gasche commented Aug 26, 2017

I believe that OPAM supports disjunctions in package formulas, so we could do conf-llvm-3_8 {>= "0.2"} | conf-llvm-4_0 for example.

@ivg
Copy link
Member

ivg commented Aug 27, 2017

I believe that OPAM supports disjunctions in package formulas

OPAM supports disjunctions, but they doesn't work with the depext plugin, e.g., if you will say conf-llvm.3.4 | conf-llvm.3.8 it will install dependencies for both 3.4 and 3.8.

The bad consequence is that specifying compatibility with a range of LLVM versions becomes confusing.

Not sure whether it is confusing... but this is the reality. LLVM changes its interface every release, so every time we need to update our bindings. The releases end up into distributions with a serious delay. There are still distributions that have only 3.4. So BAP indeed may use three specific versions of LLVM no one is better than another.

but then how do you depend on the particular version of configuration scripts?

That's what I'm talking, we should separate the concept of a version of a configuration script and a version of a system package. OPAM shouldn't track system packages versions, they should be opaque to OPAM and be just a part of the name. In our case, there shouldn't be any conf-llvm package, but rather conf-llvm-3_4, conf-llvm-3_5, ..., conf-llvm-3_8, etc. Each of this packages will have its own version, e.g., conf-llvm-3_4=0.1 that will denote a version of a configuration script, denoting that the higher the version the better the script capabilities.

@whitequark
Copy link
Member

Exactly how would you propose to write a package that works with any version of LLVM from 3.4 to 4.0? Basic IR construction hasn't changed in all this time.

@ivg
Copy link
Member

ivg commented Aug 28, 2017

Exactly how would you propose to write a package that works with any version of LLVM from 3.4 to 4.0?

I'm not sure whether you're asking me, and if yes, then I'm not getting the question. I'm not proposing to write a package that works with any version of LLVM. Concerning the IR, BAP, in particular, doesn't use this part of LLVM, we are depending on MC library, that defines machine code generation and disassembly. They do change a lot between versions.

@github-actions
Copy link
Contributor

This issue is stale because it has been open 90 days with no activity. Remove the stale label, or comment, or this will be closed in 15 days.

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

No branches or pull requests

5 participants