2017-09-21 4 views
0

Certains modules livrés avec OCaml comme Unix et Bigarray ont leurs propres .cmx et .cmxa fichiers dans ocamlopt -where (qui est ~/.opam/4.03.0/lib/ocaml sur mon système dans mon commutateur de courant OPAM).OCaml détecter statiquement dépendance à la bibliothèque non Pervasives dans la distribution norme

Y at-il un moyen de déterminer sans avoir à recompiler les fichiers source dépendent des bibliothèques de ces « spéciales » dans la distribution standard? J'ai l'intention de consommer cette sortie plus tard dans un Makefile.

Le programme suivant example.ml

open Unix;; 

Unix.system "echo hi";; 

peut être compilé avec ocamlfind ocamlopt -package unix -linkpkg example.ml. Je ne suis pas sûr de savoir comment le compiler sans passer par le wrapper ocamlfind.

Je me demande s'il y a un moyen de détecter statiquement que la non liée en ce fichier module de Unix correspond à « quelque chose » dans la distribution standard et de faire rapport unix.cmxa en tant que dépendance. ocamldep ne semble pas le signaler comme une dépendance par défaut. Indique simplement que les différents fichiers d'objets et d'interfaces pouvant être produits à l'aide de example.ml dépendent de example.ml. J'espérais soit un message d'erreur se plaignant que ocamldep ne comprend pas le module Unix ou une indication qu'il est nécessaire de construire les objets.

$ ocamldep -all example.ml 
example.cmo example.cmi : example.ml 
example.cmx example.o example.cmi : example.ml 
+2

'ocamlfind ocamlopt -verbose -package unix -linkpkg example.ml' montre la commande exécutée pour compiler' example.ml'. – camlspotter

Répondre

1

Je comprends que votre question est:

Pour un nom de module donné, par exemple Unix, comment pouvons-nous trouver la bibliothèque qui lui fournit?

Malheureusement, il n'y a pas (encore) d'outil de ce type.

Si on limite l'espace de recherche aux bibliothèques viennent avec le compilateur OCaml lui-même, je le ferais:

$ ocamlobjinfo $HOME/.opam/4.03.0/lib/ocaml/*.cma | grep '^\(File\|Unit name\)' 

Cela liste tous les modules définis dans chaque archive. Vous pouvez ou ne pouvez pas trouver le nom du module dans le résultat.

Il est impossible en général, étant donné que la bibliothèque que vous cherchez peut ne pas être standard ou ne peut pas être installé localement. Vous pouvez utiliser des moteurs de recherche d'API comme ocamloscope mais ils ne couvrent jamais toutes les bibliothèques OCaml jamais écrites bien sûr.

1

Bien que les modules peuvent être emballés dans des bibliothèques avec des noms arbitraires, les interfaces de module conservent encore une pour une mise en correspondance entre les noms des modules de niveau supérieur et compilés noms de fichiers d'interface de module. Donc, si vous avez une erreur « Module non lié Xxx`, vous pouvez le faire

find ~/.opam -iname Xxx.cmi 

Si vous ne trouvez pas, cela signifie que cette bibliothèque n'est pas installé. Et actuellement, il n'y a aucun moyen bien établi pour savoir quel paquet fournit ce module, vous pouvez utiliser Google, demander aux gens sur les listes de diffusion ou des forums de discussion, ou essayer d'utiliser apt-file en espérant que la bibliothèque est une distribution standard.

Si la recherche retourné exactement un dossier, alors vous avez de la chance, vous avez le paquet. Le paquet peut contenir des fichiers objets de genres différents (.cmx - pour le code natif, .cmo - pour le bytecode), ainsi que des bibliothèques (.cma - est une collection de .cmo, .cmxa - est une collection de .cmx, et .cmxs est une version dynamique de .cmxs). La flexibilité d'OCaml, qui est à la fois un avantage et un fléau, permet à l'un de ces fichiers d'être manquant. Les bibliothèques bien maniables fournissent généralement tous ces fichiers, ainsi qu'une convention de dénomination que le nom du paquet correspond au nom de la bibliothèque. Mais si vous utilisez ocamlfind et que le dossier contient le fichier META, le nom du dossier est le nom du paquet que vous devez passer à ocamlfind afin de lier les bibliothèques de ce paquet.

Si vous avez plus d'un résultat, vous devez utiliser le bon sens pour déterminer laquelle des deux bibliothèques vous devez utiliser. Alternativement, vous pouvez essayer d'utiliser l'un et l'autre et voir lequel compile.

+0

Désolé, je ne pense pas avoir très bien expliqué ma question. La première chose que je veux faire est 1) détecter qu'un fichier source dépend d'un module nommé 'Unix', 2) détecter que' Unix' est fourni par quelque chose dans la distribution standard et obtenir le nom du fichier 'cm *' le fournir. Je n'essaie pas de traiter avec des modules tiers pour le moment. –