Where a library without expanded ppx_inline_tests is located in `_build`? (Need help with camlp5)

I’m writing a library with ppx_inline_test and I want to link this library to my ppx and camlp5 rewriters. For historical reasons I was compiling PPX and camlp5 rewriters using custom dune (rule ...) stanza. When I added PPX inline tests to my library I realized that my manual linking to %{project_root}/lib/lib1.cmxa is wrong: by some reason this library is preprocessed for running inline tests, so it depends on Ppx_inline_test_lib__Runtime. Where is the version of my library without inline tests? I don’t know. The solution I found is to use default executable stanza and it looks like it is indeed a proper solution (no troubles with absence of linkall flag, etc.)

But things are more complicated with Camlp5. It is required to use a custom executable mkcamlp5.opt to link rewriter properly (a Dynlink-related module is generated under the hood and being compiled to my rewriter). That’s why I can’t manage to get the same result while using dune’s executable stanza. Could you help with that?

Questions:

  • Can I find in _build two versions of my library at the same time: one for tests and one without? I believe specifying right one will lead to the shortest fix.
  • Will abandoning of mkcamlp5.top be a better solution? @Chet_Murthy

demo: GitHub - Kakadu/ppx_inline_test_and_camp5

Kakadu,

just to level-set, you’re using camlp5 to preprocess your source, and then compiling using ppx_inline_test. I see no reason why camlp5 should be relevant to your problem, but in any case, to test that out, you can just preprocess to OCaml source (instead of AST) and then camlp5 should be completely out-of-the-picture. Again, just to test.

But as to your problem, if I understand correctly, you’re trying to use ppx_inline_test, and want to produce two versions of your object-module: one with, and one without, your tests. I don’t know if this is possible with ppx_inline_tests.

I will note that a long time ago, I reverse-engineered how dune invoked and compiled ppx_inline_test-based tests, and you can find examples in the tests-inline directory of the camlp5/pa_ppx project.

Also, finally, if you are using the pa_ppx_inline_test facility of camlp5/pa_ppx, I’m happy to debug that, just give me an example testcase.

No, I’m compiling a library that uses ppx_inline_test and linking this library to my camlp5 rewiter.

The current issue is that wrong library (with tests being expanded) is being linked to my camlp5 rewriter: wrong version of my library is being linked by mkcamlp5.opt.

I should either

  1. understand right location of my library without tests and pass it to mkcamlp5.opt, or
  2. create camlp5 rewriter with executable stanza, trying to understanding what is implicitly being linked by camlp5.opt first.

OK, let’s back up and simplify. You’ve written a program with inline-tests, and you want to produce a version of the program without those inline-tests – for whatever reason. I don’t know if this is possible, but that would be what I would research in the ppx_inline_test documentation and source: how can I compile my code to remove all the inline-tests.

Honestly, I suspect the answer is: “you cannot”, and that that is the right one. Here’s why: those inline-tests are going to reference libraries, maybe call special functions meant only for testing, and you can’t conditionalize those references to remove then when you remove the inline-tests. So why bother making a special case for removing them? Just make the special case for running them, not for removing them.

But hey, maybe I’m wrong. Certainly, a little PPX rewriter that removed inline-tests would be … trivial to write, I mean *trivial. It’s consists in removing str-items of the form

[%%test ....]
[%%test_xxx ....]

for xxx in {test,module,eq,unit,result,pred}. Probably simplest to remove any str-item extension whose name starts with “test_”.

Is that all you want? B/c that’s almost as simple as ppx_here. Heck, maybe there’s a PPX extension out there that does that, shipped as part of ppx_inline_test ?

Kakadu,

Some more thoughts. You’re asking for two versions of your library to be compiled, one with and one without the inline-tests, right? But this sort of behaviour is specifically for ppx_inline_tests, and not for any other PPX rewriter. So how could you expect dune to be able to do this? To even know about this ? It would seem completely out-of-character for a build system to know about the details of specific PPX extensions, right? This is where you’d want your build-system to be programmable, right?

I think the answer you’re going to find is: “find a way to conditionally-compile your inline-tests”.

Yes. The only “but” is that dune should be able to do it already without too much of my interference. Basically it compiled my code to executable using inline_tests="enabled"

(cd _build/default && .ppx/bfcab61e6a21ecf6d2f80029fc1ef484/ppx.exe \
  --cookie 'inline_tests="enabled"' 
  --cookie 'library-name="lib1"' 
  -o lib/HelpersBase.pp.ml --impl lib/HelpersBase.ml 
  -corrected-suffix .ppx-corrected -diff-cmd - -dump-ast)

or it compiles code to library by specifying --cookie 'inline_tests="disabled"'.

The problem is that by some reason I get a library _build/default/lib/lib1.cmxa which requires Ppx_inline_test_lib__Runtime and it shouldn’t be normally happening with ppx_inline_test. Actually, now I understand even less where this stuff should be fixed: in camlp5 or somewhere else…

Imagine N different PPX extensions, each of which can be compiled either enabled or disabled. Heck, imagine various PPX extensions where if some are enabled, then others MUST be enabled, but perhaps further others could be either enabled or disabled. This is an impossible situation for dune to be able to figure out, unless you’re assuming that dune knows, someplace deep inside, about the various constraints that obtain between various PPX rewriters.

And you’d get 2^N different libraries – again, imagine the gymnastics that dune would need to go thru.

Dune has special stanza (inline_tests). It explains dune that if we need to compile library to testing executable we need to pass cookie 'inline_tests="enabled"' and all PPX extension will expand itself.
Also it compiles a libary as a library by passing 'inline_tests="disabled"' to all N ppx extensions and these extension, if they indeed related to tests, decide that testing is not required and just remove let%test ... expressions.

The issue is resolved.

So you’re saying that dune has special support for ppx_inline_test. That’s hilarious! I guess I knew-and-then-forgot, since I reverse-engineered ppx_inline_test to figure out how to invoke it from Makefiles, but wow, that’s too funny.

Dune doesn’t have special support of ppx-inline-test per se. Dune has special support of libraries decorated by we need to generate tests executable from it and PPX extensions for tests have special support of 'inline_tests="enabled"' command line switch.

Case in point, I was able to setup an alcotest testing package that works like ppx_inline_test, but uses alcotest underneath: Files · master · Kiran Gopinathan / ppx-inline-alcotest · GitLab

Thanks! It will be useful for me in the future but right now it gives same compilation errors. It looks like I did a few horrible mistakes in dune files.

IIRC, Dune compiles only one version of a library with inline_tests. Running tests or not is done at runtime.