Hi,
I have written a library “ocaml_component_framework” with dune intended to be used locally (in another repo that does not use dune but a legacy makefile).
When I run “opam pin add .” it runs, I can see the package appearing in “opam list” packages.
Now I am trying to import the package from a repo that use a makefile with “ocamlfind ocamlopt …” command. The entire command is
ocamlfind ocamlopt -thread -linkpkg -g -pp "camlp5o -I ../../lib/dcg -I ../../lib/ipp pa_dcg.cmo pa_ipp.cmo" -w -u-s-y -package biniou -package easy-format -package yojson -package atd -package atdgen -package logs -package opium -package cohttp-lwt-unix -package uuidm -package ocaml_component_framework -I ../../lib -I ../../lib/dcg -I ../../lib/ipp -I ../../sewelis/src -c server.ml
my server.ml file starts with
open Ocaml_component_framework
...
but when I launch the command, I get
File "_none_", line 1:
Error: Unbound module Ocaml_component_framework
make: *** [makefile:36: server.cmx] Error
The package is install locally and linked via the -package ocaml_component_framework
option, how could I bypass this error ?
Best
Does it appear in ocamlfind -list
? What does the installed META
file look like?
When I run ocamlfind -list
, the package appears. When I run ocamlfind query ocaml_component_framework
, it returns
/home/frelang/.opam/4.13.1/lib/ocaml_component_framework
When I go to this folder, I get 3 files : dune-package
, META
and opam
. The META file is empty.
the dune-package looks like
(lang dune 3.16)
(name ocaml_component_framework)
(version 2368c27)
(sections (lib .) (bin ../../bin))
(files (lib (META dune-package opam)) (bin (ocaml_component_framework)))
the opam file looks like
# This file is generated by dune, edit dune-project instead
opam-version: "2.0"
version: "2368c27"
synopsis: "A short synopsis"
description: "A longer description"
maintainer: ["Maintainer Name"]
authors: ["Author Name"]
license: "LICENSE"
tags: ["topics" "to describe" "your" "project"]
homepage: "https://github.com/username/reponame"
doc: "https://url/to/documentation"
bug-reports: "https://github.com/username/reponame/issues"
depends: [
"ocaml"
"dune" {>= "3.16"}
"odoc" {with-doc}
]
build: [
["dune" "subst"] {dev}
[
"dune"
"build"
"-p"
name
"-j"
jobs
"@install"
"@runtest" {with-test}
"@doc" {with-doc}
]
]
dev-repo: "git+https://github.com/username/reponame.git"
It’s probably because your META
file is incorrect.
In general, I am confused why your Dune package looks like this. You seem to be trying to do a lot of stuff that Dune will do correctly for you without any configuration: among others it will generate and install the right META file so I would suggest something like this instead:
(lang dune 3.16)
(name ocaml_component_framework)
(generate_opam_files true)
(package
(name ocaml_component_framework)
(depends ocaml))
And then when you use opam pin
it will pick up the generated OPAM file, run the build which will generate the right .install
file which refer to the META
file and then ocamlfind
should be able to load your library.
Of course you also need to give your library a public_name
, otherwise it doesn’t get installed. It’s well possible that this is why there is no library.
I have a public name for my library. the dune
file looks like
(library
(name ocaml_component_framework)
(public_name ocaml_component_framework)
(modules component componentDefinition componentInput componentManager componentOutput componentRouteBuilder customMediaType dbConnector fetchUrlRoute internalReturns microService parameter parameters rawContentInputRoute response_ return returns route routeManager routePaging selfDescribe task taskDef typeFormatConstraints typesFormatsConstraintsManager value)
(libraries core yojson opium lwt cohttp cohttp-lwt-unix uuidm str))
I think that you refer to dune-project
as the dune package file. (otherwise I do not know how to edit the dune package file). my dune-project
file looks like
(lang dune 3.16)
(name ocaml_component_framework)
(generate_opam_files true)
(source
(github username/reponame))
(authors "Author Name")
(maintainers "Maintainer Name")
(license LICENSE)
(documentation https://url/to/documentation)
(package
(name ocaml_component_framework)
(synopsis "A short synopsis")
(description "A longer description")
(depends ocaml dune)
(tags
(topics "to describe" your project)))
So it should conform with the file you describe.
the META file is generated automatically by dune, I guess ?
Ah ok, I misunderstood. Thus I’m retracting my previous claim and say that your project looks all very sensible.
It could be that pinning picked up your repo as a git repo and the changes in your project were not committed yet. You could try unpinning and then pin again using opam pin add --kind=path .
and see whether this will install the right library archives and META
files in /home/frelang/.opam/4.13.1/lib/ocaml_component_framework
.
(As a last resort you could go around opam
and use dune install
to install the library into your switch. However generally I would recommend against it because then OPAM does not know about it and can’t install the correct dependencies etc, thus it would be better to try to get opam pin
working)
If you have the repo public somewhere I can give it a try and see if it works on my machine.
Thank you for response. I cannot share with you the repository because it is private for now, but I appreciate the proposal.
Now it works better. after unpinning and pinning again with --kind=path, the folder build by opam at /home/frelang/.opam/4.13.1/lib/ocaml_component_framework
is now populated and my META file looks like
description = ""
requires = "cohttp cohttp-lwt-unix core lwt opium str uuidm yojson"
archive(byte) = "ocaml_component_framework.cma"
archive(native) = "ocaml_component_framework.cmxa"
plugin(byte) = "ocaml_component_framework.cma"
plugin(native) = "ocaml_component_framework.cmxs"
But it still cannot compile my binary. I got an error
ocamlfind ocamlopt -thread -linkpkg -g -pp "camlp5o -I ../../lib/dcg -I ../../lib/ipp pa_dcg.cmo pa_ipp.cmo" -w -u-s-y -package biniou -package easy-format -package yojson -package atd -package atdgen -package logs -package opium -package cohttp-lwt-unix -package uuidm -package ocaml_component_framework -I ../../lib -I ../../lib/dcg -I ../../lib/ipp -I ../../sewelis/src -o server nums.cmxa str.cmxa bintree.cmx common.cmx iterator.cmx myseq.cmx lSet.cmx cis.cmx intmap.cmx intset.cmx intrel2.cmx intreln.cmx find_merge.cmx dcg.cmxa ipp.cmxa domain.cmx patterns.cmx program.cmx generation.cmx notation.cmx ComponentDefinition.cmxa server.cmx
ocamlfind: [WARNING] Package `mtime.clock.os': Deprecated, use the mtime.clock library.
File "_none_", line 1:
Error: Cannot find file ComponentDefinition.cmxa
make: *** [makefile:11: server] Error 2
ComponentDefinition.cmxa is not build by opam, while I get a cmxa for the package with ocaml_component_framework.cmxa
. For ComponentDefinition I get cmi, cmt and cmx files. Do you know how to bypass this ?
my server.ml looks like
let () = Ocaml_component_framework.ComponentDefinition.componentDefinition
~log_level:(Some Logs.Info) ()
...
Does it work if you just remove ComponentDefinition.cmxa
from your Makefile rule ?
Thank you, that was it!
Big thanks for helping me overcoming this issues, I’m still quite new to Ocaml and struggle from time to time. Now it works!