coq-community / manifesto

Documentation on goals of the coq-community organization, the shared contributing guide and code of conduct.
Other
68 stars 6 forks source link

Adding support for dune builds in coq-community projects #87

Open palmskog opened 4 years ago

palmskog commented 4 years ago

The dune build system solves many problems with make and coq_makefile for Coq libraries and plugins, not least flaky plugin builds. The tooling around dune, such as dune-release also automates many tedious maintenance tasks, e.g., creation of OPAM files and submitting pull requests to OPAM repositories.

Dune support for Coq projects is still experimental, but is expected to stabilize during 2020. Dune is also expected to become the default build system for Coq itself for version 8.12.0 (tentatively planned for release in mid-2020). Possible future extensions to dune for Coq include support for handling extracted OCaml code and for running alternative checkers such as coqchk.

I believe Coq-community projects should start to add (optional, non-default) support for building with dune. This has the benefit of helping dune developers to find Coq-specific issues, preparing projects for the official dune support for Coq projects, and increasing automation for coq-community maintainers. For Coq plugin projects, there is already a tutorial for adding dune build support.

Finally, there is now also a section in the dune manual defining Coq-related build options.

palmskog commented 4 years ago

To the best of my knowledge, as of December 2019, dune support for Coq has the following limitations:

Consequently, we initially aim to use dune for batch/installation builds, e.g., in CI.

palmskog commented 4 years ago

@ejgallego for coq-community project releases that happen post Coq 8.12.0 which have dune support, do you see any reason against having the corresponding opam packages in the Coq opam archive use dune for building? (Assuming native compilation is not an issue.)

Moreover, do you currently recommend any specific bounds on the dune/language version? For example, is the following reasonable:

(lang dune 2.5)
(using coq 0.2)
ejgallego commented 4 years ago

Hi @palmskog , I think that would be a very interesting experiment; the bounds you propose are fine IMHO, however we still expect the Coq build language to evolve before the "1.0" release, so certainly maintainers should expect to have some churn. A few things that will change:

Moreover, when we reach 1.0 , we will likely deprecate all other lang versions, and give like 3/5? releases for people to adapt.

On the other hand developments picking the dune + dune-release toolchain is essential as to get a good amount of feedback towards the 1.0 version of the language, so that effort would be really appreciated.

Zimmi48 commented 4 years ago

@palmskog Should we close this as a duplicate of coq-community/templates#38 / solved issue?

palmskog commented 4 years ago

Unfortunately I consider this issue far from solved. For the longer term, I would really like to use dune everywhere in coq-community, including in all new packages for the Coq opam archive.

However, if we use Dune before 1.0, based on what Emilio says above, it seems we are setting ourselves up for future compatibility issues. coq_makefile will basically "always work", while a package using Dune 2.5 / Coq-0.2 may need its Dune version restricted in the future, or require patching. So my current stance is something like:

rgrinberg commented 4 years ago

some variables such as %{coq:config} should appear so it is easier for people to support different Coq versions.

Is conditional compilation something that is often used in Coq projects? We could add conditional compilation in the style of OCaml for Coq in dune.

palmskog commented 4 years ago

Is conditional compilation something that is often used in Coq projects? We could add conditional compilation in the style of OCaml for Coq in dune.

I think conditional compilation is currently underused because it's so hard to script for in build scripts - figuring out the current Coq version in a Makefile accurately is very hard. The most high-profile examples I can think of are CompCert and VST, whose releases were patched by Michael Soegtrop to work across several versions of Coq by manual patches, see some of this work in the Coq Platform.

palmskog commented 3 years ago

Based on the problems encountered by downstream maintainers when the Multinomials project switched to using Dune, in particular for opam releases (math-comp/multinomials#41), I think we should for the foreseeable future avoid requiring Dune for any project releases. In other words, as of fall 2021, Dune support in coq-community repos for CI and local developer use continues to be a good thing, but coq_makefile based build scripts should be retained whenever possible, with coq_makefile builds used in opam files for releases submitted to the Coq opam archive.

Zimmi48 commented 3 years ago

But what to do for monorepos then (hydra-battles, topology...)?

palmskog commented 3 years ago

Well, this is why I added the qualification "whenever possible", which should be read as "we continue to use Dune for releases where coq_makefile is practically infeasible". Also, both hydra-battles and topology are projects with seemingly no current downstream users.

strub commented 3 years ago

@palmskog Do you have an example of a project that uses both system (dune for the dev & coq_makefile for opam)?

palmskog commented 3 years ago

@strub here are some examples, we have a lot of these in coq-community now (I use this approach for nearly all the projects I maintain):

strub commented 3 years ago

Ok, I'll take the first and use it as a template.

Zimmi48 commented 3 years ago

IINM, all these examples use Dune in the .opam files committed in the repository, so this means that there will be a temporary desynchronization between that and the opam-coq-archive repo.

palmskog commented 3 years ago

Well, there is desynchronization between opam files for releases and the opam files in the repos (the former use coq_makefile and latter use Dune). I still have the repo opam file in synch with the extra-dev opam file in the Coq opam archive.

palmskog commented 1 year ago

An updated summary of how I view Dune use in Coq-community after the release of the 0.8 lang version with composition with theories installed in Coq's user-contrib ("Dune-Coq 0.8" vs. the old "Dune-Coq 0.3"):

On one hand, Dune-Coq 0.8 enables using Dune in the same way inside opam packages and locally - user-contrib is "just" another place where .vo files can reside. On the other hand, Dune-Coq 0.8 forces declaration of Coq logical path prefixes of all transitive dependencies, as in the following example:

This requirement of specifying transitive dependencies can easily lead to breakages if used in released packages, for example:

Due to the possibility and likelihood of such breakages, I don't think Dune-Coq 0.8 should be used by any Coq-community project release, i.e., as a build system used in an opam package based on a release archive. Using Dune-Coq 0.8 in CI is still fine, if maintainers are willing to update their project's (theories ...) every time a transitive dependency changes.

Projects that use Dune for monorepo packaging (several dune files in subdirectories) should stay on Dune-Coq 0.3 as long as possible (Dune maintainers have deprecated Dune-Coq 0.3).

ejgallego commented 1 year ago

Thanks for analysis @palmskog ; we will implement implicit transitive theory deps for 0.9.

I'd like to note however that implicit transitive dependencies are not inmune to breakage, they suffer the dual problem: injection of ghost dependencies. So your project depends on foo, which pulls library bar. Then foo decides not to depend on bar, your project fails to build as you didn't declare the dep.

That's possible to address with some linting "warning, shadow dep detected", but tricky (hint hint, let's write a paper folks)

IMHO experience in the OCaml world suggest we should be cautiuous as to assert what kind of breakage is more common, the data is unclear, def we have seen both kinds.

But in principle I agree that caution must be used with the current default, tho I think there are many other multi-package cases where the deps are under total control of the maintainers, so IMHO in these cases testing could help a ot the projects.

I think the way this kind of issues are handled are similar tho: when the CI fails, a version bound is added prior to the merge of the new package.

palmskog commented 1 year ago

@ejgallego I'm aware of the ghost dependency problem, and have addressed it recently in several MathComp-related packages (that now should depend directly on Hierarchy Builder). However, in my experience the ghost dependency ("underdependency") problem is less serious in practice than "overdepending" and requires less manual intervention

ejgallego commented 1 year ago

However, in my experience the ghost dependency "underdependency" problem is less serious than "overdepending" and requires less manual intervention.

Interesting, how it is more serious / requires more intervertion, do you have an example?

I can see how it can be more common if we assume that packages grow their deps in general, which is not actually a trivial assumption, but reasonable.

palmskog commented 1 year ago

Interesting, how it is more serious / requires more intervertion, do you have an example?

In Coq-community, we have seen underdependency issues related to MathComp, e.g., a package only depending on coq-mathcomp-algebra when it should also depend on coq-mathcomp-fingroup. However, if this becomes a problem, we just add in the missing dependency into the package definition. In the scenario with coq-foo/coq-bar/coq-quux, the only way to fix the situation is to (1) conditionally patch the sources of coq-foo or (2) add a dependency to the new coq-bar package or to the coq-foo package that it doesn't need. Both are in my view invasive.

ejgallego commented 1 year ago

In Coq-community, we have seen underdependency issues related to MathComp, e.g., a package only depending on coq-mathcomp-algebra when it should also depend on coq-mathcomp-fingroup.

I'm not sure I follow, coq-mathcomp-algebra pulls coq-mathcomp-fingroup, so why did the package had to add this dep?

ejgallego commented 1 year ago

If you mean the other case, I'm afraid you'd have to patch the source code too, if algebra drop the dep on fingroup dune, even if it has transitive deps, won't register that dep.

But you make an excellent point about package / build definitions being redudant (and that's in the way to be fixed I understand)

palmskog commented 1 year ago

But let's say that my package, coq-baz, depends only on coq-mathcomp-algebra at opam level, but at From X Require Y level, it also depends on coq-mathcomp-fingroup. If coq-mathcomp-algebra drops the dep on coq-mathcomp-fingroup, then coq-baz breaks because the coq-mathcomp-fingroup dep is still needed. However, all I'd need to do is edit the coq-baz package definition to include coq-mathcomp-fingroup and it should build again.

ejgallego commented 1 year ago

However, all I'd need to do is edit the coq-baz package definition to include coq-mathcomp-fingroup and it should build again.

Not in the Dune model, right? You'd need to update the dune file too.

Thanks for the examples because this is the only way I can check if things do work.

We have 4 cases indeed:

So indeed the problems are dual, so what the best default is depends a lot on the dynamic behavior of the deps over time.