This commit is contained in:
parent
aa2ff7b2f0
commit
2f3113f55d
11742 changed files with 1223940 additions and 0 deletions
|
|
@ -0,0 +1,176 @@
|
|||
This test demonstrates private libraries that belong to a package. Such
|
||||
libraries are installed as public libraries under the package.__private__.<name>
|
||||
findlib name, and are only available to libraries and executables in the same
|
||||
package.
|
||||
|
||||
$ cat >dune-project <<EOF
|
||||
> (lang dune 2.8)
|
||||
> (package (name foo))
|
||||
> (package (name bar))
|
||||
> EOF
|
||||
|
||||
First, we define a private library:
|
||||
|
||||
$ mkdir private
|
||||
$ cat >private/secret.ml <<EOF
|
||||
> let secret = "secret string"
|
||||
> EOF
|
||||
$ cat >private/dune <<EOF
|
||||
> (library
|
||||
> (name secret)
|
||||
> (package foo))
|
||||
> EOF
|
||||
$ dune build @all
|
||||
|
||||
A public library may build against it:
|
||||
|
||||
$ mkdir public
|
||||
$ cat >public/dune <<EOF
|
||||
> (library
|
||||
> (name foo)
|
||||
> (libraries secret)
|
||||
> (public_name foo.bar))
|
||||
> EOF
|
||||
$ cat >public/foo.ml <<EOF
|
||||
> let foo = "from library foo " ^ Secret.secret
|
||||
> EOF
|
||||
$ dune build @install
|
||||
|
||||
The naming convention puts the artifacts of private libs under __private__:
|
||||
|
||||
$ ls _build/install/default/lib/foo/__private__/secret | grep -i \.cm
|
||||
secret.cma
|
||||
secret.cmx
|
||||
secret.cmxa
|
||||
secret.cmxs
|
||||
|
||||
Note the name mangling convention in the META file:
|
||||
|
||||
$ cat _build/install/default/lib/foo/META
|
||||
package "__private__" (
|
||||
directory = "__private__"
|
||||
package "secret" (
|
||||
directory = "secret"
|
||||
description = ""
|
||||
requires = ""
|
||||
archive(byte) = "secret.cma"
|
||||
archive(native) = "secret.cmxa"
|
||||
plugin(byte) = "secret.cma"
|
||||
plugin(native) = "secret.cmxs"
|
||||
)
|
||||
)
|
||||
package "bar" (
|
||||
directory = "bar"
|
||||
description = ""
|
||||
requires = "foo.__private__.secret"
|
||||
archive(byte) = "foo.cma"
|
||||
archive(native) = "foo.cmxa"
|
||||
plugin(byte) = "foo.cma"
|
||||
plugin(native) = "foo.cmxs"
|
||||
)
|
||||
|
||||
We want to see mangled names in the dune-package file as well:
|
||||
|
||||
$ cat _build/install/default/lib/foo/dune-package | grep __private__
|
||||
__private__/secret/.public_cmi/secret.cmi
|
||||
__private__/secret/.public_cmi/secret.cmt
|
||||
__private__/secret/secret.a
|
||||
__private__/secret/secret.cma
|
||||
__private__/secret/secret.cmx
|
||||
__private__/secret/secret.cmxa
|
||||
__private__/secret/secret.ml
|
||||
(libexec (__private__/secret/secret.cmxs bar/foo.cmxs)))
|
||||
(requires foo.__private__.secret)
|
||||
(name foo.__private__.secret)
|
||||
(byte __private__/secret/secret.cma)
|
||||
(native __private__/secret/secret.cmxa))
|
||||
(byte __private__/secret/secret.cma)
|
||||
(native __private__/secret/secret.cmxs))
|
||||
(native_archives __private__/secret/secret.a)
|
||||
(source (path Secret) (impl (path __private__/secret/secret.ml))))))
|
||||
|
||||
Cmi for secret library must not be visible for normal users. Hence they must be
|
||||
hidden.
|
||||
|
||||
$ grep __private__ _build/default/foo.install
|
||||
"_build/install/default/lib/foo/__private__/secret/.public_cmi/secret.cmi" {"__private__/secret/.public_cmi/secret.cmi"}
|
||||
"_build/install/default/lib/foo/__private__/secret/.public_cmi/secret.cmt" {"__private__/secret/.public_cmi/secret.cmt"}
|
||||
"_build/install/default/lib/foo/__private__/secret/secret.a" {"__private__/secret/secret.a"}
|
||||
"_build/install/default/lib/foo/__private__/secret/secret.cma" {"__private__/secret/secret.cma"}
|
||||
"_build/install/default/lib/foo/__private__/secret/secret.cmx" {"__private__/secret/secret.cmx"}
|
||||
"_build/install/default/lib/foo/__private__/secret/secret.cmxa" {"__private__/secret/secret.cmxa"}
|
||||
"_build/install/default/lib/foo/__private__/secret/secret.ml" {"__private__/secret/secret.ml"}
|
||||
"_build/install/default/lib/foo/__private__/secret/secret.cmxs" {"__private__/secret/secret.cmxs"}
|
||||
|
||||
We make sure that executables can use the secret library like they can use any other private library
|
||||
|
||||
$ mkdir bar
|
||||
$ cat >bar/dune <<EOF
|
||||
> (executable
|
||||
> (name bar)
|
||||
> (libraries secret))
|
||||
> EOF
|
||||
$ cat >bar/bar.ml <<EOF
|
||||
> print_endline "from bar.ml"
|
||||
> EOF
|
||||
$ dune exec ./bar/bar.exe
|
||||
from bar.ml
|
||||
|
||||
Now we try to use the library in a subproject:
|
||||
|
||||
$ mkdir subproj
|
||||
$ echo "(lang dune 2.8)" > subproj/dune-project
|
||||
$ cat >subproj/dune <<EOF
|
||||
> (executable
|
||||
> (name subproj)
|
||||
> (libraries foo.bar))
|
||||
> EOF
|
||||
$ cat >subproj/subproj.ml <<EOF
|
||||
> print_endline Foo.foo
|
||||
> EOF
|
||||
$ dune exec ./subproj/subproj.exe
|
||||
from library foo secret string
|
||||
|
||||
But we shouldn't be able to access it directly:
|
||||
|
||||
$ cat >subproj/subproj.ml <<EOF
|
||||
> print_endline Secret.secret
|
||||
> EOF
|
||||
$ dune exec ./subproj/subproj.exe
|
||||
File "subproj/subproj.ml", line 1, characters 14-27:
|
||||
1 | print_endline Secret.secret
|
||||
^^^^^^^^^^^^^
|
||||
Error: Unbound module Secret
|
||||
[1]
|
||||
|
||||
Now we make sure such libraries are transitively usable when installed:
|
||||
|
||||
$ mkdir use
|
||||
$ cat >use/dune <<EOF
|
||||
> (executable
|
||||
> (name run)
|
||||
> (libraries foo.bar))
|
||||
> EOF
|
||||
$ cat >use/run.ml <<EOF
|
||||
> print_endline ("Using library foo: " ^ Foo.foo)
|
||||
> EOF
|
||||
$ echo "(lang dune 2.8)" > use/dune-project
|
||||
$ export OCAMLPATH=$PWD/_build/install/default/lib
|
||||
$ dune exec --root use -- ./run.exe
|
||||
Entering directory 'use'
|
||||
Leaving directory 'use'
|
||||
Using library foo: from library foo secret string
|
||||
|
||||
But we cannot use such libraries directly:
|
||||
|
||||
$ cat >use/run.ml <<EOF
|
||||
> print_endline ("direct access attempt: " ^ Secret.secret)
|
||||
> EOF
|
||||
$ dune exec --root use -- ./run.exe
|
||||
Entering directory 'use'
|
||||
File "run.ml", line 1, characters 43-56:
|
||||
1 | print_endline ("direct access attempt: " ^ Secret.secret)
|
||||
^^^^^^^^^^^^^
|
||||
Error: Unbound module Secret
|
||||
Leaving directory 'use'
|
||||
[1]
|
||||
Loading…
Add table
Add a link
Reference in a new issue