eatonphil
eatonphil

Reputation: 13672

OCamlfind local library unbound module

I am trying to use ocamlfind to install a library. I am using OCamlMakeFile. Here is my Makefile:

OCAMLMAKEFILE = OCamlMakeFile

RESULT = owebl
SOURCES = src/utils.ml src/verb.ml src/request.ml src/template.ml src/response.ml src/rule.ml src/handler.ml src/server.ml
PACKS = unix str

all: native-code-library byte-code-library
install: libinstall
uninstall: libuninstall

include $(OCAMLMAKEFILE)

So basically the library is a collection of modules that I want to distribute. A basic usage of the library is (main.ml):

open Response
open Rule
open Verb
open Server

let handler =
    Handler.create
        (StaticRouteRule.create "/" [GET])
        (FileResponse.create
            ~static_file:(FileResponse.StaticFile "/index.html")
            ())

let server = Server.create "0.0.0.0" 8080 [handler];;

server#serve

I compile the library just by running "make". It generates three files: "owebl.a, owebl.cma, owebl.cmxa". Then I install the library using ocamlfind:

ocamlfind install owebl META owebl.a owebl.cma owebl.cmxa

Oh, the META file is:

version = "0.1"
name = "OWebl"
description = "A Web Framework for OCaml"
archive(byte) = "owebl.cma"
archive(native) = "owebl.cmxa"
requires = "unix,str"

Everything works until I try to compile the above example that uses the library. I run:

ocamlbuild -use-ocamlfind -pkgs owebl main.native

And I get:

ocamlbuild -use-ocamlfind -pkgs owebl main.native
+ ocamlfind ocamlc -c -package owebl -o main.cmo main.ml
File "main.ml", line 1, characters 5-10:
Error: Unbound module Owebl
Command exited with code 2.
Hint: Recursive traversal of subdirectories was not enabled for this build,
  as the working directory does not look like an ocamlbuild project (no
  '_tags' or 'myocamlbuild.ml' file). If you have modules in subdirectories,
  you should add the option "-r" or create an empty '_tags' file.

  To enable recursive traversal for some subdirectories only, you can use the
  following '_tags' file:

      true: -traverse
      <dir1> or <dir2>: traverse

Compilation unsuccessful after building 2 targets (1 cached) in 00:00:00.
make: *** [fileserver] Error 10

I tried adding open Owebl to the beginning of main.ml but I just got "unbound module Owebl" similarly. I'm pretty lost as to why these modules are all unbound. What am I missing?

Upvotes: 1

Views: 1019

Answers (2)

ivg
ivg

Reputation: 35210

You should use LIB_PACK_NAME variable if you want to pack your modules under umbrella namespace, like OWebl, otherwise they will be available just as it is, e.g. Response, Rule, etc. Also, you should specify the mli files as well as ml files in SOURCES variable. And finally, you shouldn't forget to install cmi files, as well as .a files. Installing mli files is also considered a good tradition, although is not strictly required. Also, consider using OCamlMakefile installation facilities instead of custom installation script.

Upvotes: 2

camlspotter
camlspotter

Reputation: 9030

I am no longer using OCamlMakefile therefore am not sure, but assuming OCamlMakefile compiles things with -for-pack OWebl option and properly builds a packaged module owebl.cmo, you also need to install owebl.cmi.

OCaml compiler seeks cmi files to check the existence of modules and to get their type information. If not installed, the compiler cannot find it. cma and cmxa files are collections of objects and do not provide type information.

Upvotes: 0

Related Questions