如何在OCaml中编译多个文件?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在OCaml中编译多个文件?相关的知识,希望对你有一定的参考价值。
我目前正在教自己ocaml
我的编程语言课程,我在ocaml
编译多个文件时遇到问题。
我在get_file_buffer.ml
文件中定义了一个函数
get_file_buffer.ml
的源代码
(*
Creating a function that will read all the chars
in a file passed in from the command argument.
And store the results in a char list.
*)
let read_file char_List =
let char_in = open_in Sys.argv.(1) in (* Creating a file pointer/in_channel *)
try
while true do
let c = input_char char_in in (* Getting char from the file *)
char_List := c :: !char_List (* Storing the char in the list *)
done
with End_of_file ->
char_List := List.rev !char_List; (* End of file was reaching, reversing char list *)
close_in char_in; (* Closing the file pointer/in_channel *)
(* Need to figure out how to catch if the file was not openned. *)
;;
我试图在我的main.ml
中调用该函数
main.ml
的源代码
(* Storing the result of read_file to buffer which buffer is a char list reference *)
let buffer = ref [] in
Get_file_buffer.read_file(buffer);
print_string "\nThe length of the buffer is: ";
print_int (List.length !buffer); (* Printing length of the list *)
print_string ("\n\n");
List.iter print_char !buffer; (* Iterating through the list and print each element *)
为了编译程序,我使用的是MakeFile
Makefile内容
.PHONY: all
all: test
#Rule that tests the program
test: read_test
@./start example.dat
#Rules that creates executable
read_test: main.cmx get_file_buffer.cmx
@ocamlc -o start get_file_buffer.cmx mail.cmx
#Rule that creates main object file
main.cmx: main.ml
@ocamlc -c main.ml
#Rule that creates get_file_buffer object file
get_file_buffer.cmx: get_file_buffer.ml
@ocamlc -c get_file_buffer.ml
当我运行我的test
的Makefile
规则时,我得到错误:Error: Unbound module Get_file_buffer
。
我一直试图用这些问题作为参考:Compiling multiple Ocaml files和Calling functions in other files in OCaml。
但是我还没能让程序正确编译。如何正确编译上面的代码以使程序正常运行?
而不是逐个构建* .ml文件。您有几个更好的选择,既高效又有效。
像这样使用ocamlbuild和Makefile。
将main.ml
重命名为start.ml
并使用以下Makefile
。
$ cat Makefile
.PHONY: all test
all: start test
test: start
@./start.native get_file_buffer.ml
start:
ocamlbuild start.native
$ make ....
使用沙丘(以前的jbuilder),这是目前最为连贯的ocaml构建工具。
一个。在与jbuild
文件相同的目录中创建*.ml
文件。
$ cat jbuild
(jbuild_version 1)
(executable
((name start)))
$ jbuilder build start.exe
$ jbuilder exec - ./start.exe get_file_buffer.ml
如果你愿意,你可以使用make
通过创建dune/jbuilder
来驱动Makefile
。
$ cat Makefile
.PHONY: all test
all: start test
test: start
jbuilder exec -- ./start.exe get_file_buffer.ml
start:
jbuilder build start.exe
$ make
为OCaml编写正确的Makefile很复杂:OCaml编译器倾向于生成多个文件,而这些文件不是Makefile正常处理的东西,而且确切的依赖图可能依赖于编译器标志(例如-opaque
或-no-alias-deps
)和版本(字节码,本机没有flambda,本机与flambda)的编译器。这就是为什么到目前为止最简单的解决方案是使用像jbuilder / dune(http://dune.readthedocs.io/en/stable/)或ocamlbuild(https://github.com/ocaml/ocamlbuild/blob/master/manual/manual.adoc)这样的构建系统。
附: :在你的情况下,你确实错过了main.cmx
对get_file_buffer.{cmi,cmx}
的依赖。
我认为问题是main.cmx
应该依赖于get_file_buffer.cmx
。否则make
可能会首先尝试编译main.cmx
,在这种情况下,当然无法找到模块Get_file_buffer
,因为它尚不存在。
更准确地说,main.cmx
的编辑也取决于gen_file_buffer.o
。但由于该文件与gen_file_buffer.cmx
同时创建,你应该没问题。 (据我所知,make
无法指定单个规则同时创建多个文件。)
以上是关于如何在OCaml中编译多个文件?的主要内容,如果未能解决你的问题,请参考以下文章