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 to embed the version inside executables #1930

Closed
wants to merge 1 commit into from
Closed

Allow to embed the version inside executables #1930

wants to merge 1 commit into from

Conversation

ghost
Copy link

@ghost ghost commented Mar 11, 2019

This PR allows users to embed the version (as returned by git describe --always --dirty) inside installed executables.

Spec

The following expression will always evaluate to the version once the binary is installed:

Dune_build_info.V1.get_version "%%VERSION%%"

During the build, it will be a dummy string, ensuring that embedding the version inside the executable doesn't hurt the development experience.

Implementation

When the string passed to get_version is already substituted, it is returned as it. This ensures that the right version is reported either for pinned or released packages.

When the string %%VERSOIN%%, the version is read from an internal buffer inside the dune.build-info library. This buffer is a placeholder that is filled by dune install.

Future work

Fill in the placeholder for binaries that are promoted to the source tree. This will give an easy workflow for users who deploy binaries directly without going through a package manager.

@ghost ghost requested review from emillon and rgrinberg as code owners March 11, 2019 09:06
try
let s = Unix.readlink (Path.to_string path) in
Path.relative (Path.parent_exn path) s
with _ ->
Copy link
Member

Choose a reason for hiding this comment

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

Which exception is this designed to catch? The one raised by Unix.readlink? If that's teh case, I would simply surround Unix.readlink with that.

Copy link
Author

Choose a reason for hiding this comment

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

indeed, I'll do that

@bobot
Copy link
Collaborator

bobot commented Mar 11, 2019

Do you plan to be able to allow the same thing for libraries?

@ghost
Copy link
Author

ghost commented Mar 11, 2019

For library, we would need a fresh module so that different libraries can have their own build info. Maybe a field like this:

(library
 (name foo)
 (build_info_module build_info))

and this would add a Build_info module to the library which would be rewritten the same way.

@bobot
Copy link
Collaborator

bobot commented Mar 11, 2019

For library, we would need a fresh module so that different libraries can have their own build info

We don't need a fresh name, if the library is wrapped. So we could restrict the feature to wrapped library with a fixed module name.

In any case, for uniformity could we plan the same syntax for executables and libraries ?

(Something similar is also needed for share directories @emillon #1185)

@ghost
Copy link
Author

ghost commented Mar 11, 2019

Well, we can't reuse the same library. For instance, if a and b are two independent libraries that depend directly on dune.build-info, what should Dune_build_info.V1.get ... return when both are linked as part of the same executable?

Alternatively, we could pass the name of the library to the function call: Dune_build_info.V1.get_library_version ~libname:"a" "%%VERSION%%"

@bobot
Copy link
Collaborator

bobot commented Mar 11, 2019

Well, we can't reuse the same library.

Yes, they must be prefixed by the library name like any other module of the library. So in your example the modules are A_Dune_build_info and B_Dune_build_info and the alias module provide the alias Dune_build_info for both wrapped libraries. So Dune_build_info will return the version of a in one case and b in the other case.

@ghost
Copy link
Author

ghost commented Mar 11, 2019

What would the feature look like from the point of view of the user?

@ghost
Copy link
Author

ghost commented Mar 11, 2019

(basically I believe that we agree on the implementation, but not on how it's presented)

@ejgallego
Copy link
Collaborator

Dune_build_info.V1.get_library_version ~libname:"a" "%%VERSION%%"

That's fairly interesting as it would allow to easily dump the version of all libs used in by a particular executable.

@bobot
Copy link
Collaborator

bobot commented Mar 11, 2019

Yes, the disagreement is just on how the user access the feature And finally the difference is indeed very small with yours. It could be that instead of

Dune_build_info.V1.get_library_version ~libname:"a" "%%VERSION%%"

We would have:

Dune_build_info.V1.A.get_library_version "%%VERSION%%"

For each library in the libraries field. My proposition seems too overkill.

Could we remove the need for the "%%VERSION%%" in the source code? dune subst could create a file with all the information so that A_Dune_build_info is created directly with the right information.

@ghost
Copy link
Author

ghost commented Mar 12, 2019

I see. I feel like the ~libname:"a" is going to lead to a much simpler system overall, i.e. will less code generation (code generation is always an additional source of troubles). Regarding the implementation, instead of generating one module in each library, I was thinking of generating one single module at link time with the version of all libraries. For external libraries, the version would be hardcoded in the generated .ml file. For internal ones, we would use the placeholder method.

Additionally, I feel slightly uneasy at the idea of implicitly adding modules to users' libraries. One the other hand, adding an implicit module at link time when the special dune.build-info library is used seems fine.

Could we remove the need for the "%%VERSION%%" in the source code? dune subst could create a file with all the information so that A_Dune_build_info is created directly with the right information.

That seems fine yes. In fact, this file already exists: it's the opam file.

@ghost
Copy link
Author

ghost commented Mar 12, 2019

I'll do the change to not have to write %%VERSION%%

@ghost ghost changed the title Allow to embed the version inside executables [WIP] Allow to embed the version inside executables Mar 12, 2019
@agarwal
Copy link
Member

agarwal commented Mar 19, 2019

Additionally, I feel slightly uneasy at the idea of implicitly adding modules to users' libraries. One the other hand, adding an implicit module at link time when the special dune.build-info library is used seems fine.

I agree that adding a module to a user's library is a bit weird, but it's also a bit weird to add to a user's executable. So I'm wondering why not support it in libraries in the first place?

In our code, we use build information in quite a few places, and so we generate an About module (essentially what you are calling Dune_build_info) in our libraries. If this information was only available in our executables, we'd have to parameterize a bunch of library functions with the build info, and then pass in those values in our executables. That should be easy enough, but having it in the library would be a little nicer. Another slight benefit is you can then load your library into utop and also see the values there.

@ghost
Copy link
Author

ghost commented Mar 20, 2019

Well, we are not really adding anything to executables here. Basically the user depends on the library dune.build_info and the code of this library contains all the relevant information.

In any case, libraries can also depend on dune.build_info and query their own version this way. For instance, once we support get_library_version, then you could simply call get_library_version "foo" inside library foo.

Before libraries are linked into executable, the version information is already available. For instance in the META file. This PR is basically just about embedding the information into the final executable so that it stays available once the executable is deployed. But for instance, if you target opam then all this is almost useless: the version is already provided by opam. This PR just adds a bit of plumbing so that prog --version reports the right thing without hassle.

@agarwal
Copy link
Member

agarwal commented Mar 20, 2019

Sorry, I probably I misunderstood several things. I thought Dune_build_info was a module that gets generated. Otherwise, I don't really get #1930 (comment), which talked about mapping the library name to a submodule name.

I think you're providing what we need, but just to clarify our needs are:

  • Ability to easily embed version, git commit IDs, and build time into our libraries.
  • Would be nice to get also the same information for dependencies.
  • Fast dev cycle. Rebuilding multi-library projects should not be slowed down by forced recompilation on every build (originally discussed at Meaning of project_root and workspace_root variables #1848 (comment)).
  • Robustness to different modes of deployment. Maybe the code gets deployed with access to the .git directory or maybe it gets released as a tarball.

You may have eliminated this need, but to achieve the fast dev cycle, we currently leave a dummy string in our about.ml file during normal dev and substitute with the actual git commit upon deployments only. To achieve that, we needed a build rule that allows logic like "if profile = dev then do nothing else
rebuild about.ml". Instead of dune's profile, we'd be happy to use something else like an environment variable, but we couldn't find any dune feature allowing this. So instead our rule uses deps (universe), so as far as dune is concerned, it always has to run. Then the rule's action is a custom script to which we pass %{profile}.

@bobot
Copy link
Collaborator

bobot commented Mar 21, 2019

Sorry, I probably I misunderstood several things. I thought Dune_build_info was a module that gets generated

I think it is, but it is not added to the executable but to a dune library (Dune.build_info) which is linked into the executable. So technically yes, we are generating a module, but it is explicitly asked by the user. In the case of libraries we would have to add the module regardless of if the dune library is used.

@ghost
Copy link
Author

ghost commented Mar 21, 2019

Yep, that's the idea.

@agarwal I believe this PR ticks all the boxes. It also leaves a dummy string during development to achieve fast development cycle. However, the criterion for using a dummy string vs the real info is a bit different:

  • for release tarballs, then we effectively immediately hard-code the real info
  • when working in the development repository, we systematically use a dummy string. Well in fact a placeholder with a magic string inside that is then substituted by the real info before deployment. i.e. dune rewrites the executables before deploying them

In this PR, the only time this rewriting happens is when calling dune install, so if you wanted to deploy your executables another way, you would have to first install them in a temporary destination and copy them from there. I was also thinking to allow "promoting" executables to the source tree, and dune would rewrites them as well when doing so.

@agarwal
Copy link
Member

agarwal commented Mar 21, 2019

the only time this rewriting happens is when calling dune install

That's good for us. Thank you!

@jberdine
Copy link
Contributor

This doesn't seem to work when the .git directory is in an ancestor of the workspace root. Paths of exes to install are converted to relative paths and .git is only looked for along that. What about using e.g. git rev-parse --show-toplevel to find the .git dir?

@ghost
Copy link
Author

ghost commented Mar 25, 2019

That seems fine

@ghost
Copy link
Author

ghost commented Jun 1, 2019

Re-opened: #2224

@jberdine
Copy link
Contributor

This doesn't seem to work when the .git directory is in an ancestor of the workspace root. Paths of exes to install are converted to relative paths and .git is only looked for along that. What about using e.g. git rev-parse --show-toplevel to find the .git dir?

Is it me, or is it still the case that the .git directory needs to be in the workspace root? I seem to still observe this, and the File_tree.nearest_vcs code still seems to only consider the argument relative path, not its ancestors.

@ghost
Copy link
Author

ghost commented May 28, 2020

I just gave it a try and it seems to work with Dune 2.5; with a .git above the workspace root, Dune will still pick it up and use it for dune-build-info. Do you have a reproduction case?

@jberdine
Copy link
Contributor

Thanks for checking. That sounds like the situation I have, so it's not obvious. I'll try to extract a small repro.

@jberdine
Copy link
Contributor

Just a minor update: I'm no longer convinced that the issue I see is related to .git being above the workspace root. It seems that sometimes the version stamping happens as expected in both situations, and sometimes it does not (that is, Build_info.V1.version is None). We are also encountering this with ocamlformat: ocaml-ppx/ocamlformat#1133.

@ghost
Copy link
Author

ghost commented Jun 30, 2020

@jberdine I'm adding a flag to help debug this issue: #3589

Could you try it the next time you observe this issue?

@jberdine
Copy link
Contributor

Ok, I just tried this by pinning dune to #3589 and checking out ocaml-ppx/ocamlformat#1133. I don't see any output from the new flag, am I doing it wrong?

$ dune clean && rm -rf _install
$ dune build bin/ocamlformat.exe _build/default/ocamlformat.install
File "_none_", line 1:
Warning 58: no cmx file was found in path for module Build_info__Build_info_data, and its interface was not compiled with -opaque
$ dune install --debug-artifact-substitution --prefix=_install ocamlformat
Installing _install/lib/ocamlformat/META
Installing _install/lib/ocamlformat/dune-package
Installing _install/lib/ocamlformat/opam
Installing _install/bin/ocamlformat
Installing _install/share/emacs/site-lisp/ocamlformat.el
Installing _install/doc/ocamlformat/CHANGES.md
Installing _install/doc/ocamlformat/LICENSE.md
Installing _install/doc/ocamlformat/README.md
Installing _install/man/man1/ocamlformat.1
$ ./_install/bin/ocamlformat --version
unknown
$ dune --version
2.5.1-318-ge85c3a4e

@ghost
Copy link
Author

ghost commented Jun 30, 2020

So I just tried the same and it does work as expected for me. In particular, I don't get warning 58. I think we should focus on that first, because this is very odd.

What version of OCaml are you using?

Could you also try doing the build with -j 1? And if you still get the error, with -j 1 --sandbox symlink? To check if it's not some invalid dependencies specification.

@jberdine
Copy link
Contributor

I'm using ocaml 4.10.0. I just retried using -j 1 and got the same behavior, and then with -j 1 --sandbox symlink and still got the same. This test was using macos, but note that @gpetiot also observed the missing version but without warning 58 on linux.

@jberdine
Copy link
Contributor

For info, here is the _build/log file with an instance of warning 58.

build_log.gz

@ghost
Copy link
Author

ghost commented Jul 1, 2020

What version of dune-build-info are you using? Also, could you give the output of:

$ cat `ocamlfind query dune-build-info/dune-package

?

@ghost
Copy link
Author

ghost commented Jul 1, 2020

And also:

$ cat _build/default/bin/.ocamlformat.eobjs/build_info_data.ml-gen

in the ocamlformat repo

@jberdine
Copy link
Contributor

jberdine commented Jul 1, 2020

dune-build-info is pinned to the #3589:

$ opam list | grep dune-build-info
dune-build-info         2.6.0          pinned to version 2.6.0 at git+file:///Users/jjb/src/dune#debug-artifact-substitution

but curiously ocamlfind doesn't find it:

$ ocamlfind query dune-build-info/dune-package
ocamlfind: Package `dune-build-info/dune-package' not found

And build_info_data.ml-gen is:

$ cat _build/default/bin/.ocamlformat.eobjs/build_info_data.ml-gen
let eval s =
  let len = String.length s in
  if s.[0] = '=' then
    let colon_pos = String.index_from s 1 ':' in
    let vlen = int_of_string (String.sub s 1 (colon_pos - 1)) in
    (* This [min] is because the value might have been truncated
       if it was too large *)
    let vlen = min vlen (len - colon_pos - 1) in
    Some (String.sub s (colon_pos + 1) vlen)
  else
    None
[@@inline never]

let p0 = eval "%%DUNE_PLACEHOLDER:64:vcs-describe:1:.%%%%%%%%%%%%%%%%%%%%%%%%%%"

let version = p0

let statically_linked_libraries =
  [ "format_", p0
  ; "base.base_internalhash_types", Some "v0.13.0"
  ; "base.caml", Some "v0.13.0"
  ; "sexplib0", Some "v0.13.0"
  ; "base.shadow_stdlib", Some "v0.13.0"
  ; "base", Some "v0.13.0"
  ; "cmdliner", Some "v1.0.4"
  ; "astring", Some "0.8.4"
  ; "fpath", Some "0.7.2"
  ; "stdio", Some "v0.13.0"
  ; "unix", Some "[distributed with Ocaml]"
  ; "import", p0
  ; "compiler-libs", Some "[distributed with Ocaml]"
  ; "compiler-libs.common", Some "[distributed with Ocaml]"
  ; "result", Some "1.5"
  ; "ppx_derivers", None
  ; "ocaml-migrate-parsetree", Some "1.7.3"
  ; "odoc.model", Some "1.5.1"
  ; "odoc.compat", Some "1.5.1"
  ; "odoc.parser", Some "1.5.1"
  ; "menhirLib", Some "20200624"
  ; "parse_wyc", p0
  ; "seq", Some "[distributed with OCaml 4.07 or above]"
  ; "re", Some "1.9.0"
  ; "uucp", Some "13.0.0"
  ; "uuseg", Some "13.0.0"
  ; "bytes", Some "[distributed with OCaml 4.02 or above]"
  ; "uchar", Some "distributed with OCaml 4.03 or above"
  ; "uutf", Some "1.0.2"
  ; "uuseg.string", Some "13.0.0"
  ; "token_latest", p0
  ; "compat", p0
  ; "dune-build-info", Some "2.5.1-318-ge85c3a4e"
  ; "ocamlformat_lib", p0
  ]

@ghost
Copy link
Author

ghost commented Jul 1, 2020

Sorry, I was missing a backquote in the ocamlfind command, it should have been:

$ cat `ocamlfind query dune-build-info`/dune-package

I wanted to check that it did have the special_builtin_support field, but the fact that the build_info_data.ml-gen file exists is an indication of that. The generated file looks good to me. So so far it seems that:

  • dune build produces the right implementation for Build_info_data with the placeholder as expected
  • dune install doesn't find this placeholder

One thing we should check is that the placeholder does end up in the produced binary. Could you try the following:

$ grep  '%%DUNE_PLACEHOLDER' _build/default/bin/ocamlformat.exe
$ strings _build/default/bin/ocamlformat.exe | grep -o '%%DUNE_PLACEHOLDER............................................%%'

@ghost
Copy link
Author

ghost commented Jul 1, 2020

One thing I noticed looking at he log: you are using an opam local switch. I'm not using one. I wonder if that makes a difference. I'm trying with a local switch now to check.

@emillon
Copy link
Collaborator

emillon commented Jul 1, 2020

As a data point, I'm using a local switch, and it's working as expected (no cmx warning, substitution works).

@jberdine
Copy link
Contributor

jberdine commented Jul 1, 2020

Just FTR, with the missing backquote ocamlfind is now happy:

$ cat `ocamlfind query dune-build-info`/dune-package                   ~/ocamlformat (dune-build-info|…)
(lang dune 2.7)
(name dune-build-info)
(version 2.5.1-318-ge85c3a4e)
(library
 (name dune-build-info)
 (kind normal)
 (archives (byte build_info.cma) (native build_info.cmxa))
 (plugins (byte build_info.cma) (native build_info.cmxs))
 (native_archives build_info.a)
 (main_module_name Build_info)
 (modes byte native)
 (modules
  (wrapped
   (main_module_name Build_info)
   (modules
    ((name Build_info)
     (obj_name build_info)
     (visibility public)
     (impl)
     (intf))
    ((name Build_info_data)
     (obj_name build_info__Build_info_data)
     (visibility public)
     (intf)))
   (alias_module
    (name Build_info__)
    (obj_name build_info__)
    (visibility public)
    (kind alias)
    (impl))
   (wrapped true)))
 (special_builtin_support
  (build_info (data_module build_info_data) (api_version 1))))

Neither grep (the mac's BSD one FWIW) nor strings find the placeholder.

This seems to be strange. I'd almost say that it's "just my machine" but it seems that @gpetiot has the same issue so there must be something going on.

@emillon
Copy link
Collaborator

emillon commented Jul 1, 2020

To make sure that the placeholder is linked in, do you have any input when you run:

objdump -t _build/default/bin/ocamlformat.exe  |grep Build_info_data

And if there are symbols:

gdb -batch -ex 'file _build/default/bin/ocamlformat.exe' -ex 'p (char[64]) camlBuild_info__Build_info_data__1'

and

gdb -batch -ex 'file _install/bin/ocamlformat' -ex 'p (char[64]) camlBuild_info__Build_info_data__1'

(if this work, first one should display

$1 = "%%DUNE_PLACEHOLDER:64:vcs-describe:1:.", '%' <repeats 26 times>

and second one:

1 = "=18:0.14.1-14-g4ce1948", ' ' <repeats 42 times>

@jberdine
Copy link
Contributor

jberdine commented Jul 1, 2020

objdump produces 142 lines for me, but gdb is dumping core, but I haven't used it in some time so that is not necessarily to be trusted, I'm investigating.

@jberdine
Copy link
Contributor

jberdine commented Jul 1, 2020

running gdb interactively seems to make it happy, but it doesn't find the symbol you indicated:

$ gdb _build/default/bin/ocamlformat.exe
GNU gdb (GDB) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin18.7.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from _build/default/bin/ocamlformat.exe...
(gdb) p (char[64]) camlBuild_info__Build_info_data__1
No symbol "camlBuild_info__Build_info_data__1" in current context.
(gdb) q

For reference, the output of objdump is:

$ objdump -t _build/default/bin/ocamlformat.exe |grep Build_info_data
00000001007d5df8 g     O __DATA,__data	_camlBuild_info__Build_info_data
00000001007d61b8 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_377
00000001007d61a0 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_378
00000001007d6188 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_379
00000001007d6170 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_380
00000001007d6158 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_381
00000001007d6140 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_382
00000001007d6128 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_383
00000001007d6110 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_384
00000001007d60f8 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_385
00000001007d60e0 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_386
00000001007d60c8 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_387
00000001007d60b0 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_388
00000001007d6098 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_389
00000001007d6080 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_390
00000001007d6068 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_391
00000001007d6050 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_392
00000001007d6038 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_393
00000001007d6020 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_394
00000001007d6008 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_395
00000001007d5ff0 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_396
00000001007d5fd8 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_397
00000001007d5fc0 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_398
00000001007d5fa8 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_399
00000001007d5f90 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_400
00000001007d5f78 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_401
00000001007d5f60 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_402
00000001007d5f48 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_403
00000001007d5f30 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_404
00000001007d5f18 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_405
00000001007d5f00 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_406
00000001007d5ee8 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_407
00000001007d5ed0 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_408
00000001007d5eb8 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_409
00000001007d5ea0 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_410
00000001007d5e88 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_411
00000001007d5e70 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_412
00000001007d5e58 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_413
00000001007d5e40 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_414
00000001007d5e28 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_415
00000001007d5e10 g     O __DATA,__data	_camlBuild_info__Build_info_data__Pmakeblock_416
000000010008eed0 g     F __TEXT,__text	_camlBuild_info__Build_info_data__code_begin
000000010008eee7 g     F __TEXT,__text	_camlBuild_info__Build_info_data__code_end
00000001007d6848 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_102
00000001007d6830 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_103
00000001007d6800 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_107
00000001007d67e8 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_108
00000001007d67b8 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_112
00000001007d67a0 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_113
00000001007d6778 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_118
00000001007d6738 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_127
00000001007d66e0 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_131
00000001007d66c8 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_132
00000001007d6698 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_136
00000001007d6680 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_137
00000001007d6650 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_140
00000001007d6610 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_144
00000001007d65f8 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_145
00000001007d65c8 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_150
00000001007d6598 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_155
00000001007d6560 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_159
00000001007d6548 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_160
00000001007d6508 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_164
00000001007d64f0 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_165
00000001007d6488 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_173
00000001007d6470 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_174
00000001007d6440 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_178
00000001007d6428 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_179
00000001007d6400 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_184
00000001007d63d8 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_189
00000001007d6388 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_193
00000001007d6370 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_194
00000001007d6320 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_198
00000001007d6308 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_199
00000001007d62d8 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_203
00000001007d62c0 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_204
00000001007d6288 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_208
00000001007d6270 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_209
00000001007d6200 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_221
00000001007d61e8 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_222
00000001007d6988 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_73
00000001007d6958 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_78
00000001007d6928 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_83
00000001007d68f0 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_88
00000001007d68c8 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_93
00000001007d6890 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_97
00000001007d6878 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_block_98
00000001007d6868 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_100
00000001007d6858 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_101
00000001007d6820 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_105
00000001007d6810 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_106
00000001007d67d8 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_110
00000001007d67c8 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_111
00000001007d6790 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_115
00000001007d6768 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_120
00000001007d6750 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_124
00000001007d6718 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_129
00000001007d66f0 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_130
00000001007d66b8 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_134
00000001007d66a8 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_135
00000001007d6668 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_139
00000001007d6630 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_142
00000001007d6620 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_143
00000001007d65e0 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_147
00000001007d65b0 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_152
00000001007d6580 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_157
00000001007d6570 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_158
00000001007d6530 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_162
00000001007d6518 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_163
00000001007d64d8 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_167
00000001007d64c8 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_171
00000001007d6498 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_172
00000001007d6460 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_176
00000001007d6450 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_177
00000001007d6418 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_181
00000001007d63f0 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_186
00000001007d63c8 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_191
00000001007d6398 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_192
00000001007d6360 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_196
00000001007d6330 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_197
00000001007d62f8 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_201
00000001007d62e8 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_202
00000001007d62a8 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_206
00000001007d6298 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_207
00000001007d6258 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_211
00000001007d6248 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_215
00000001007d6230 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_219
00000001007d6210 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_220
00000001007d61d0 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_224
00000001007d69c8 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_66
00000001007d69a0 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_70
00000001007d6970 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_75
00000001007d6940 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_80
00000001007d6908 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_85
00000001007d68e0 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_90
00000001007d68b0 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_95
00000001007d68a0 g     O __DATA,__data	_camlBuild_info__Build_info_data__const_immstring_96
00000001007d5de8 g     O __DATA,__data	_camlBuild_info__Build_info_data__data_begin
00000001007d69d8 g     O __DATA,__data	_camlBuild_info__Build_info_data__data_end
000000010008eee0 g     F __TEXT,__text	_camlBuild_info__Build_info_data__entry
00000001007d69e0 g     O __DATA,__data	_camlBuild_info__Build_info_data__frametable
00000001007d5de8 g     O __DATA,__data	_camlBuild_info__Build_info_data__gc_roots

@emillon
Copy link
Collaborator

emillon commented Jul 1, 2020

OK, I found something! these symbols are only used by flambda. I tried to reproduce with a flambda switch, and indeed this does not perform any substitution. I'll investigate to see if there's some constant folding going on.

@emillon
Copy link
Collaborator

emillon commented Jul 1, 2020

(the cmx warning appears as well)

@ghost
Copy link
Author

ghost commented Jul 1, 2020

Ah, interesting! @emillon maybe try this:

diff --git a/src/dune/link_time_code_gen.ml b/src/dune/link_time_code_gen.ml
index ac860e3fd..a3f9ee93f 100644
--- a/src/dune/link_time_code_gen.ml
+++ b/src/dune/link_time_code_gen.ml
@@ -160,7 +160,7 @@ let build_info_code cctx ~libs ~api_version =
   pr buf "[@@inline never]";
   pr buf "";
   Path.Source.Map.iteri !placeholders ~f:(fun path var ->
-      pr buf "let %s = eval %S" var
+      pr buf "let %s = eval (Sys.opaque_identity %S)" var
         (Artifact_substitution.encode ~min_len:64 (Vcs_describe path)));
   if not (Path.Source.Map.is_empty !placeholders) then pr buf "";
   pr buf "let version = %s" version;

That should prevent flambda from doing clever things. Though I would have thought the [@@inline never] was enough.

@emillon
Copy link
Collaborator

emillon commented Jul 1, 2020

Yes that fixes it (the cmx warning is still there, though)! I'll open a PR on dune to fix that.

@jberdine
Copy link
Contributor

jberdine commented Jul 1, 2020

Oh, I'm sorry, I completely forgot (to mention) that I am using an flambda-enabled compiler.

emillon added a commit to emillon/dune that referenced this pull request Jul 1, 2020
This ensures that they are not inlined when using flambda.
See discussion in ocaml#1930.

Signed-off-by: Etienne Millon <[email protected]>
emillon added a commit to emillon/dune that referenced this pull request Jul 3, 2020
This ensures that they are not inlined when using flambda.
This problem is only present in OCaml 4.10.0, so it is fine not to patch
on 4.02 where `Sys.opaque_identity` is not available.
See discussion in ocaml#1930.

Signed-off-by: Etienne Millon <[email protected]>
emillon added a commit to emillon/dune that referenced this pull request Jul 6, 2020
This ensures that they are not inlined when using flambda.
This problem is only present in OCaml 4.10.0, so it is fine not to patch
on 4.02 where `Sys.opaque_identity` is not available.
See discussion in ocaml#1930.

Signed-off-by: Etienne Millon <[email protected]>
emillon added a commit that referenced this pull request Jul 6, 2020
This ensures that they are not inlined when using flambda.
This problem is only present in OCaml 4.10.0, so it is fine not to patch
on 4.02 where `Sys.opaque_identity` is not available.
See discussion in #1930.

Signed-off-by: Etienne Millon <[email protected]>
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.

7 participants