2012-10-07 30 views
5

Soy nuevo en Ocaml e intento escribir una pequeña aplicación de ejemplo. Estoy usando ocamlc versión 3.11.2 bajo Linux Ubuntu 10.04. Quiero compilar dos archivos:Compilación de varios archivos Ocaml

a.ml 
b.ml 

Archivo b.ml utiliza definiciones de a.ml. Por lo que yo entiendo, puedo usar ocamlc -c para realizar compilación solamente. Puedo llamar al ocamlc una vez más cuando tengo todos los archivos .cmo para vincularlos a un ejecutable. Además, cuando compilo un archivo que usa definiciones de otro archivo, tengo que decirle al compilador en qué archivo .cmi buscar las definiciones externas.

Así que mi idea era utilizar:

ocamlc -i -c a.ml > a.mli 
ocamlc -c a.mli b.ml 
ocamlc -o b a.cmo b.cmo 

Las primeras obras de paso y produce archivos a.mli y a.cmo, pero cuando se ejecuta el segundo paso me sale

File "b.ml", line 1, characters 28-31: 
Error: Unbound value foo 

donde foo es una función que se define en a.ml y se llama en b.ml.

Así que mi pregunta es: ¿cómo puedo compilar cada archivo fuente por separado y especificar las interfaces que se importarán en la línea de comandos? He estado buscando en la documentación y, por lo que puedo entender, debo especificar los archivos .mli que se incluirán, pero no sé cómo.

EDITAR

Aquí algunos detalles más. a.ml archivo contiene la definición

let foo = 5;; 

archivo b.ml contiene la expresión

print_string (string_of_int foo)^"\n";; 

El ejemplo real es más grande, pero con estos archivos ya tengo el error informé anteriormente.

EDIT 2

He editado el archivo b.ml y reemplazado con fooA.foo y esto funciona (foo es visible en b.ml a pesar de que tengo otro error de compilación que no es importante para esta pregunta). Supongo que es más limpio escribir mis propios archivos .mli explícitamente, como sugiere

+1

¿ha abierto A en B ?, porque de lo contrario esto no tiene sentido. –

+0

No. ¿Debo definir un módulo en A y abrirlo en B? Por el momento, todas las definiciones en A son globales (no tengo módulo). – Giorgio

+1

Hay un módulo implícito para cada archivo OCaml. Entonces su archivo 'a.ml' define un módulo llamado' A'. –

Respuesta

5

Sería más claro si mostrara el código que no funciona. Sin embargo, como señala Kristopher, el problema más probable es que no especifique en qué módulo se encuentra el foo. Puede especificar el módulo explícitamente, como A.foo. O puede open A y simplemente use el nombre foo.

Para un pequeño ejemplo, no importa, pero para un gran proyecto debe tener cuidado de no usar open con demasiada libertad. Desea la libertad de utilizar buenos nombres en sus módulos, y si abre demasiados, los buenos nombres pueden entrar en conflicto entre sí.

5

Primero corrige el problema unbound value, según lo explicado por la respuesta de Jeffrey. Este es un comentario sobre los comandos que está utilizando.

Descomponer la compilación en varios pasos es una buena forma de entender lo que está sucediendo. Si desea escribir su propio a.mli, lo más probable es que oculte algunos valores del módulo A, entonces su comando ocaml -i -c a.ml > a.mli es una buena forma de obtener una primera versión del archivo y luego editarlo. Pero si usted no está tocando a.mli, entonces no es necesario para generarlo: también puede introducir directamente

ocamlc -o foo a.ml b.ml 

que producirá a.cmo, b.cmo y la exectuable foo.

(También generará a.cmi, que es la versión compilada de a.mli, que se obtiene mediante la emisión de ocamlc -c a.mli. Del mismo modo que también generará b.cmi).

Tenga en cuenta que el orden importa: debe proporcionar a.ml antes de b.ml en la línea de comandos. De esta forma, al compilar b.ml, el compilador ya ha visto a.ml y sabe dónde encontrar el módulo A.


Algunos más comentarios:

  • Tienes razón en su párrafo "Por lo que yo entiendo".
  • que realmente no incluyen un archivo separado, es más como importación en Python: los valores del módulo de A están disponibles, pero bajo el nombre A.foo. El contenido de a.ml no se ha copiado en b.ml, sino que se han accedido a los valores del módulo A, definidos en a.ml y su versión compilada a.cmo.
  • si está usando este módulo A en b.ml, puede pasar cualquiera de los siguientes en la línea de comandos antes b.ml:
    • a.mli, que se compilan en a.cmi
    • a.cmi Si ya ha compilado a.mli en a.cmi
    • a.ml o su versión compilada a.cmo si no necesita escribir su propio a.mli, es decir, si la interfaz por defecto del módulo A te conviene. (Esta interfaz es simplemente cualquier valor de a.ml).