I came across an arrangement of libraries where using dune
produces confusing results (well, at least to me).
The fully functioning (and somewhat minimized) example of this can be found at https://github.com/martinslota/ocuzzle-module-initialization. It’s a bit hard to present succinctly because it seems related to the way linking does or does not happen. But here’s an attempt to paste it here all in one spot:
File: q_and_a/q_and_a.ml
module type Question = sig
val question : string
end
module Make_question () : Question = struct
let question = "How much is 6 * 9?"
end
module Make_answer (Q : Question) = struct
let () = Printf.printf "Making answer for question: %s\n" Q.question
let answer = 42
end
module Question : Question = struct
let question = "What's on your mind?"
end
File: q_and_a/dune
:
(library
(name q_and_a))
File: cases/case1.ml
module Question = Q_and_a.Make_question ()
module Answer = Q_and_a.Make_answer (Question)
File: cases/case2.ml
module Question = Q_and_a.Question
module Answer = Q_and_a.Make_answer (Question)
File: cases/dune
(library
(name cases)
; (library_flags (:standard -linkall))
(libraries q_and_a))
File: mystery.ml
let () =
Printf.printf "Case 1 question: %s\n" Cases.Case1.Question.question;
Printf.printf "Case 2 question: %s\n" Cases.Case2.Question.question
File: dune
:
(executable
(name mystery)
(libraries cases))
If you run this, you should see the following:
$ dune exec mystery/mystery.exe
Making answer for question: How much is 6 * 9?
Case 1 question: How much is 6 * 9?
Case 2 question: What's on your mind?
However, if you uncomment the ; (library_flags (:standard -linkall))
line above, then you should see this instead:
$ dune exec mystery/mystery.exe
Making answer for question: What's on your mind?
Making answer for question: How much is 6 * 9?
Case 1 question: How much is 6 * 9?
Case 2 question: What's on your mind?
Is this the expected behaviour?