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

Track original source location in lib_info/dune_package #1750

Merged
13 commits merged into from
Jan 21, 2019

Conversation

andreypopp
Copy link
Member

@andreypopp andreypopp commented Jan 10, 2019

This allows to communicate original source locations between installed (dune) libraries so we can construct .merlin files with S directives pointing right to them for installed libs. Thus allowing merlin to see original sources.

This is useful when lib is opam-pinned or esy-linked. I think we can set orig_src_dir to None for all other installed packages (based on profile?).

@andreypopp andreypopp requested a review from trefis as a code owner January 10, 2019 12:49
src/lib_info.ml Outdated
match Path.drop_build_context dir with
| None -> None
| Some src_dir ->
Some Path.(of_string (to_absolute_filename (in_source (to_string src_dir))))
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 is weird and maybe can be done easier but Path is confusing for me at the moment.

Copy link

Choose a reason for hiding this comment

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

in_source (to_string src_dir) should be the identity, you can replace it by src_dir

@rgrinberg
Copy link
Member

The idea is fine, but how do we control which sources to use in the .merlin file? If a package is installed via opam, then the original source dir will be ephemeral.

@andreypopp
Copy link
Member Author

andreypopp commented Jan 10, 2019 via email

@ghost
Copy link

ghost commented Jan 10, 2019

What about controlling this behaviour with a command line switch/environment variable? In practice, we probably don't want to store these paths by default as it will hurt reproducibility, but esy could enable it via the environment variable.

@andreypopp
Copy link
Member Author

What about controlling this behaviour with a command line switch/environment variable?
In practice, we probably don't want to store these paths by default as it will hurt reproducibility, but esy could enable it via the environment variable.

Won't such option be overly specific? Doesn't dune already have dev vs release build modes — we can generate such paths only in dev mode. I think that will be useful for opam-pinned packages as well (they can define build command optionally using dev profile if pinned is true in opam).

@rgrinberg
Copy link
Member

rgrinberg commented Jan 10, 2019

I think that will be useful for opam-pinned packages as well (they can define build command optionally using dev profile if pinned is true in opam).

Given that you need to go through editing the opam file, I think that makes the feature not very useful. So it makes it even more of an option that only esy would configure.

@andreypopp andreypopp force-pushed the andreypopp/track-orig-src branch 2 times, most recently from 539dd2c to e73162c Compare January 11, 2019 11:42
@andreypopp
Copy link
Member Author

I proceeded with not emitting orig_src_dir in non dev profile (related: should we make profile type kind = Dev | Release and profile = Profile of kind | Custom of kind * name?).

I had to add a sanitisation step for blackbox test which replaces test's root path with $TESTCASE_ROOT token against which we could match in test expectations.

(modules ((name Y) (obj_name c__Y) (visibility public) (impl)))
(wrapped true)))

Build with "release" profile
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 is a new test case but diff doesn't make it obvious.

@@ -330,6 +332,8 @@ Include variants and implementation information in dune-package
(name foo.vlib)
(kind normal)
(virtual)
(orig_src_dir
$TESTCASE_ROOT/dune-package-info/vlib)
Copy link
Member Author

Choose a reason for hiding this comment

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

I'm not sure it's ok this breaks on the next line here.

@andreypopp andreypopp changed the title [DISCUSSION] Track original source location in lib_info/dune_package Track original source location in lib_info/dune_package Jan 11, 2019
@andreypopp andreypopp force-pushed the andreypopp/track-orig-src branch from fdb164f to 297926c Compare January 11, 2019 12:22
@rgrinberg
Copy link
Member

It just occurred to me that it's possible to implement this feature without touching dune-package at all.

The only reason why dune doesn't know that some external packages are actually local is because they get filtered out by -p. Well it shouldn't be hard to change dune to remember which library definitions it has skipped.

@andreypopp
Copy link
Member Author

The only reason why dune doesn't know that some external packages are actually local is because they get filtered out by -p. Well it shouldn't be hard to change dune to remember which library definitions it has skipped.

What does it mean "actually local" — being a part of the same workspace? Then this isn't the case always in esy: it allows you to link packages from outside:

{
  "resolutions": {
    "@opam/dune": "link-dev:../path/to/dune/checkout"
  }
}

@rgrinberg
Copy link
Member

I see. So my suggestion wouldn't work after all. Would it be possible for esy to just pass the linked packages to dune somehow? Changing dune-package is a touchy issue for us, so I'd prefer that we refrained from doing so unless we really had no other way.

@andreypopp
Copy link
Member Author

Changing dune-package is a touchy issue for us, so I'd prefer that we refrained from doing so unless we really had no other way.

Instead of changing dune-package we could place dune-package.dev with dev
related metadata (orig_src_path only at first but there can be potentially
more in the future).

OCAMLPATH (findlib) config is already used to communicate about installed
OCaml artifacts in the esy project (or system/switch wide in case of opam). I
think adding additional package dev metadata there makes sense. But I'm open for suggestions.

@ghost
Copy link

ghost commented Jan 14, 2019

BTW, when a package is pinned via opam, the build still happens in a temporary directory, so the value that would be stored here wouldn't be useful.

It seems to me that using an environment variable is the best option here. It's true that this is a very specific setting, but on the other hand most of the time storing the original source directory doesn't make sense. Even if we store it in a separate .dev file, it still doesn't feel right to install such files with temporary paths.

@andreypopp
Copy link
Member Author

It seems to me that using an environment variable is the best option here. It's
true that this is a very specific setting, but on the other hand most of the
time storing the original source directory doesn't make sense. Even if we store
it in a separate .dev file, it still doesn't feel right to install such files
with temporary paths.

Ok, makes sense.

What would be the name/value of such environment variable? Something like (using
s-expressions):

DUNE_LIB_SOURCES='(lwt "/path/to/lwt" fmt "/path/to/fmt")'

@andreypopp
Copy link
Member Author

Hm... on a second thought I'm not sure how esy would be able to construct such
environment variable as it doesn't know about ocamlfind libraies which packages
are shipping.

@andreypopp
Copy link
Member Author

Ok, sorry for the noise, I think now you meant controlling that behaviour as passing a boolean flag via environment. I agree, that could work. What would be the name of such environment variable? DUNE_STORE_ORIG_SOURCE="true" or something else?

@ghost
Copy link

ghost commented Jan 14, 2019

Yep, that's what I meant. I suggest DUNE_STORE_ORIG_SOURCE_DIR to be more precise.

@andreypopp
Copy link
Member Author

@diml thanks! Will update this PR with that.

@andreypopp
Copy link
Member Author

This is ready for review.

@rgrinberg
Copy link
Member

It's a bit annoying to introduce another environment variable for this. Why can't this setting live in the workspace file?

@andreypopp
Copy link
Member Author

@rgrinberg the only reason I can think of is that users will need to configure dune-workspace if they want to merlin to work correctly in multi package environments. I'd prefer esy to be able to do this automatically somehow but generating dune-workspace isn't very convenient.

@rgrinberg
Copy link
Member

rgrinberg commented Jan 15, 2019

I'd prefer esy to be able to do this automatically somehow but generating dune-workspace isn't very convenient.

It will not be necessary [1]

@andreypopp
Copy link
Member Author

@rgrinberg I guess before that we could manually set dune-workspace file. Ok, is the stanza (store_orig_source_dir) ok for dune-workspace then?

@ghost
Copy link

ghost commented Jan 15, 2019

Hold on, one big advantage of using specific environment variables is that it makes composition easy. For instance, I believe that it is now generally accepted that OCAMLPARAM is a pain to use and that specific variables would have been better.

@rgrinberg why is it annoying to introduce new environment variables?

@jordwalke
Copy link
Contributor

I have to chime in here to say that some kind of env var does seem better to me (than the alternative) because it's something package authors can't know to configure - only the package manager knows what's linked for the purposes of dev vs. release. I don't have many opinions on exactly what the env var looks like, but this is the one remaining feature blocking a very great monorepo workflow for esy and dune which allows you to "absorb" external packages into your local monorepo temporarily while developing.

@andreypopp andreypopp force-pushed the andreypopp/track-orig-src branch from 54b8cc5 to dda8f43 Compare January 17, 2019 13:11
@andreypopp
Copy link
Member Author

Thanks for the feedback @diml, I believe I've addressed all points.

@rgrinberg
Copy link
Member

rgrinberg commented Jan 17, 2019

The reason why I wanted to started with a workspace option is that it avoids having to remember which vars can be overridden via the environment.

On the other hand, there's nothing wrong with an individual env var even if there a workspace the option.

@ghost
Copy link

ghost commented Jan 17, 2019

Yh that's true. In this case, I expect that this variable will be set by another tool most of the time.

@ghost
Copy link

ghost commented Jan 17, 2019

@andreypopp thanks, just one last point I missed during the first review, otherwise it looks good.

@andreypopp andreypopp force-pushed the andreypopp/track-orig-src branch from 80910cb to 3d54e26 Compare January 21, 2019 12:42
This allows to communicate original source locations so we can construct
`.merlin` files with `S` directives pointing right to them for installed
libs.

This is useful when lib is opam-pinned or esy-linked. I think we can set
`orig_src_dir` to `None` for all other installed packages (based on
profile?).

Signed-off-by: Andrey Popp <[email protected]>
This replaces test case root with $TESTCASE_ROOT token against which we
can match in expectations.

Signed-off-by: Andrey Popp <[email protected]>
Signed-off-by: Andrey Popp <[email protected]>
Use `--store-orig-source-dir` command line flag (or
`DUNE_STORE_ORIG_SOURCE_DIR` env var) as suggested by @diml.

Signed-off-by: Andrey Popp <[email protected]>
Signed-off-by: Andrey Popp <[email protected]>
@andreypopp andreypopp force-pushed the andreypopp/track-orig-src branch from 3d54e26 to 6560587 Compare January 21, 2019 13:12
@andreypopp
Copy link
Member Author

Thanks for another round of feedback @diml, I believe I've address these points too. Also rebased on top of the current master to resolve conflicts.

@ghost
Copy link

ghost commented Jan 21, 2019

Thanks, LGTM

@ghost ghost merged commit cfabdd1 into ocaml:master Jan 21, 2019
@andreypopp andreypopp deleted the andreypopp/track-orig-src branch January 21, 2019 20:44
@andreypopp
Copy link
Member Author

Thanks!

rgrinberg added a commit to rgrinberg/opam-repository that referenced this pull request Feb 12, 2019
CHANGES:

- Second step of the deprecation of jbuilder: the `jbuilder` binary
  now emits a warning on every startup and both `jbuilder` and `dune`
  emit warnings when encountering `jbuild` files (ocaml/dune#1752, @diml)

- Change the layout of build artifacts inside _build. The new layout enables
  optimizations that depend on the presence of `.cmx` files of private modules
  (ocaml/dune#1676, @bobot)

- Fix merlin handling of private module visibility (ocaml/dune#1653 @bobot)

- unstable-fmt: use boxes to wrap some lists (ocaml/dune#1608, fix ocaml/dune#1153, @emillon,
  thanks to @rgrinberg)

- skip directories when looking up programs in the PATH (ocaml/dune#1628, fixes
  ocaml/dune#1616, @diml)

- Use `lsof` on macOS to implement `--stats` (ocaml/dune#1636, fixes ocaml/dune#1634, @xclerc)

- Generate `dune-package` files for every package. These files are installed and
  read instead of `META` files whenever they are available (ocaml/dune#1329, @rgrinberg)

- Fix preprocessing for libraries with `(include_subdirs ..)` (ocaml/dune#1624, fix ocaml/dune#1626,
  @nojb, @rgrinberg)

- Do not generate targets for archive that don't match the `modes` field.
  (ocaml/dune#1632, fix ocaml/dune#1617, @rgrinberg)

- When executing actions, open files lazily and close them as soon as
  possible in order to reduce the maximum number of file descriptors
  opened by Dune (ocaml/dune#1635, ocaml/dune#1643, fixes ocaml/dune#1633, @jonludlam, @rgrinberg,
  @diml)

- Reimplement the core of Dune using a new generic memoization system
  (ocaml/dune#1489, @rudihorn, @diml)

- Replace the broken cycle detection algorithm by a state of the art
  one from [this paper](https://doi.org/10.1145/2756553) (ocaml/dune#1489,
  @rudihorn)

- Get the correct environment node for multi project workspaces (ocaml/dune#1648,
  @rgrinberg)

- Add `dune compute` to call internal memoized functions (ocaml/dune#1528,
  @rudihorn, @diml)

- Add `--trace-file` option to trace dune internals (ocaml/dune#1639, fix ocaml/dune#1180, @emillon)

- Add `--no-print-directory` (borrowed from GNU make) to suppress
  `Entering directory` messages. (ocaml/dune#1668, @dra27)

- Remove `--stats` and track fd usage in `--trace-file` (ocaml/dune#1667, @emillon)

- Add virtual libraries feature and enable it by default (ocaml/dune#1430 fixes ocaml/dune#921,
  @rgrinberg)

- Fix handling of Control+C in watch mode (ocaml/dune#1678, fixes ocaml/dune#1671, @diml)

- Look for jsoo runtime in the same dir as the `js_of_ocaml` binary
  when the ocamlfind package is not available (ocaml/dune#1467, @nojb)

- Make the `seq` package available for OCaml >= 4.07 (ocaml/dune#1714, @rgrinberg)

- Add locations to error messages where a rule fails to generate targets and
  rules that require files outside the build/source directory. (ocaml/dune#1708, fixes
  ocaml/dune#848, @rgrinberg)

- Let `Configurator` handle `sizeof` (in addition to negative numbers).
  (ocaml/dune#1726, fixes ocaml/dune#1723, @Chris00)

- Fix an issue causing menhir generated parsers to fail to build in
  some cases. The fix is to systematically use `-short-paths` when
  calling `ocamlc -i` (ocaml/dune#1743, fix ocaml/dune#1504, @diml)

- Never raise when printing located errors. The code that would print the
  location excerpts was prone to raising. (ocaml/dune#1744, fix ocaml/dune#1736, @rgrinberg)

- Add a `dune upgrade` command for upgrading jbuilder projects to Dune
  (ocaml/dune#1749, @diml)

- When automatically creating a `dune-project` file, insert the
  detected name in it (ocaml/dune#1749, @diml)

- Add `(implicit_transitive_deps <bool>)` mode to dune projects. When this mode
  is turned off, transitive dependencies are not accessible. Only listed
  dependencies are directly accessible. (ocaml/dune#1734, ocaml/dune#430, @rgrinberg, @hnrgrgr)

- Add `toplevel` stanza. This stanza is used to define toplevels with libraries
  already preloaded. (ocaml/dune#1713, @rgrinberg)

- Generate `.merlin` files that account for normal preprocessors defined using a
  subset of the `action` language. (ocaml/dune#1768, @rgrinberg)

- Emit `(orig_src_dir <path>)` metadata in `dune-package` for dune packages
  built with `--store-orig-source-dir` command line flag (also controlled by
  `DUNE_STORE_ORIG_SOURCE_DIR` env variable). This is later used to generate
  `.merlin` with `S`-directives pointed to original source locations and thus
  allowing merlin to see those. (ocaml/dune#1750, @andreypopp)

- Improve the behavior of `dune promote` when the files to be promoted have been
  deleted. (ocaml/dune#1775, fixes ocaml/dune#1772, @diml)

- unstable-fmt: preserve comments (ocaml/dune#1766, @emillon)

- Pass flags correctly when using `staged_pps` (ocaml/dune#1779, fixes ocaml/dune#1774, @diml)

- Fix an issue with the use of `(mode promote)` in the menhir
  stanza. It was previously causing intermediate *mock* files to be
  promoted (ocaml/dune#1783, fixes ocaml/dune#1781, @diml)

- unstable-fmt: ignore files using OCaml syntax (ocaml/dune#1784, @emillon)

- Configurator: Add `which` function to replace the `which` command line utility
  in a cross platform way. (ocaml/dune#1773, fixes ocaml/dune#1705, @Chris00)

- Make configurator append paths to `$PKG_CONFIG_PATH` on macOS. Previously it
  was prepending paths and thus `$PKG_CONFIG_PATH` set by users could have been
  overridden by homebrew installed libraries (ocaml/dune#1785, @andreypopp)

- Disallow c/cxx sources that share an object file in the same stubs archive.
  This means that `foo.c` and `foo.cpp` can no longer exist in the same library.
  (ocaml/dune#1788, @rgrinberg)

- Forbid use of `%{targets}` (or `${@}` in jbuild files) inside
  preprocessing actions
  (ocaml/dune#1812, fixes ocaml/dune#1811, @diml)

- Add `DUNE_PROFILE` environment variable to easily set the profile. (ocaml/dune#1806,
  @rgrinberg)

- Deprecate the undocumented `(no_keep_locs)` field. It was only
  necessary until virtual libraries were supported (ocaml/dune#1822, fix ocaml/dune#1816,
  @diml)

- Rename `unstable-fmt` to `format-dune-file` and remove its `--inplace` option.
  (ocaml/dune#1821, @emillon).

- Autoformatting: `(using fmt 1.1)` will also format dune files (ocaml/dune#1821, @emillon).

- Autoformatting: record dependencies on `.ocamlformat-ignore` files (ocaml/dune#1824,
  fixes ocaml/dune#1793, @emillon)
This pull request was closed.
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