我正在开发一个ocaml项目,要求我将它与OGDF外部c ++库连接。它已全部启动并在我的Mac上运行,但现在我正在尝试使用Ocaml for Windows(https://fdopen.github.io/opam-repository-mingw/),Ocaml的MinGW Cygwin端口创建一个Windows版本。在这个版本中,我可以使用c代码连接ocaml并且它工作正常,但是当我尝试在该c代码中包含外部库时,我从链接器获取错误,这是flexdll(https://github.com/alainfrisch/flexdll)案件。链接器说它无法解析整个库中_Unwind_Resume和__emutls_get_address的符号。
这是一个玩具示例:
我的.ml文件t.ml:
external print : unit -> unit = "print"
let () =
Printf.printf "platform: %s\n" (Sys.os_type);
print ()
我的.cpp文件tc.cpp:
#include <stdio.h>
#include "caml/mlvalues.h"
#define CAML_NAME_SPACE
//#include <ogdf/basic/Graph.h>
extern "C" value print(value unused) {
printf("hello from C\n");
return Val_unit;
}
我的makefile:
t.exe: t.ml tc.o
ocamlopt -verbose -ccopt -pthread \
-cclib -lstdc++ -w s \
-ccopt -L../cdeg/ogdf/_release \
-cclib -lOGDF \
tc.o t.ml \
-o t.exe
tc.o: tc.cpp
x86_64-w64-mingw32-gcc -c \
-march=x86-64 -mtune=generic -O2 -mms-bitfields -Wall -Wno-unused \
tc.cpp \
-I../cdeg/ogdf -L../cdeg/ogdf/_release -lOGDF \
-I ~/.opam/4.04.0+mingw64c/lib/ocaml \
-lstdc++ -pthread -o tc.o
像这样,它都可以快速编译,但是如果我取消注释tc.cpp中的ogdf include行,我会得到以下输出:
$ make
x86_64-w64-mingw32-gcc -c \
-march=x86-64 -mtune=generic -O2 -mms-bitfields -Wall -Wno-unused \
tc.cpp \
-I../cdeg/ogdf -L../cdeg/ogdf/_release -lOGDF \
-I ~/.opam/4.04.0+mingw64c/lib/ocaml \
-lstdc++ -pthread -o tc.o
ocamlopt -verbose -ccopt -pthread \
-cclib -lstdc++ -w s \
-ccopt -L../cdeg/ogdf/_release \
-cclib -lOGDF \
tc.o t.ml \
-o t.exe
+ x86_64-w64-mingw32-as -o "t.o" "C:\OCaml64\tmp\camlasme5f9bd.s"
+ x86_64-w64-mingw32-as -o "C:\OCaml64\tmp\camlstartupf2b3f1.o" "C:\OCaml64\tmp\camlstartup101e51.s"
+ flexlink -chain mingw64 -stack 33554432 -exe -o "t.exe" "-LC:/OCaml64/home/Nathaniel.Miller/.opam/4.04.0+mingw64c/lib/ocaml" -pthread -L../cdeg/ogdf/_release "C:\OCaml64\tmp\camlstartupf2b3f1.o" "C:/OCaml64/home/Nathaniel.Miller/.opam/4.04.0+mingw64c/lib/ocaml\std_exit.o" "t.o" "C:/OCaml64/home/Nathaniel.Miller/.opam/4.04.0+mingw64c/lib/ocaml\stdlib.a" "-lstdc++" "-lOGDF" "tc.o" "C:/OCaml64/home/Nathaniel.Miller/.opam/4.04.0+mingw64c/lib/ocaml\libasmrun.a" -lws2_32
** Cannot resolve symbols for ../cdeg/ogdf/_release\libOGDF.a(PoolMemoryAllocator.o/
PreprocessorLayout.o/
extended_graph_alg.o/
graph_generators.o/
random_hierarchy.o/
simple_graph_alg.o/
CPlanarEdgeInserter.o/
... [a bunch of other .o files from the library]...
UpwardPlanarModule.o/
UpwardPlanarSubgraphModule.o/
UpwardPlanarSubgraphSimple.o/
VisibilityLayout.o/
):
_Unwind_Resume
__emutls_get_address
** Cannot resolve symbols for ../cdeg/ogdf/_release\libOGDF.a(basic.o):
_Unwind_Resume
File "caml_startup", line 1:
Error: Error during linking
make: *** [makefile:20: t.exe] Error 2
如果我没有将它连接到ocaml,而是将一个main()函数添加到t.c,它在包含外部库的x86_64-w64-mingw32-gcc下编译就好了。我尝试过包含其他一些小型外部库,但它们并没有引起这个问题。
我的第一个想法是,问题可能与链接文件有关,并非所有编译方式都相同,但我使用ocamlopt -configure
给出的编译器和选项编译了库和.cpp文件。如果它们都没有以相同的方式编译,我也不希望能够让tc.cpp单独使用ocamlopt和外部库,但我只是在尝试使用时遇到错误都。这是Ocaml for windows,flexdll,还是我安装其中一个的问题?我对接下来的尝试感到茫然,对此处发生的任何想法,建议和/或解释都将非常感激。
答案 0 :(得分:1)
我有一个部分答案。问题是以某种方式来自flexdll。我转而使用带有gcc的Cygwin版本的ocaml,仍然有同样的问题。然后我重新编译了使用-no-shared-libs标志配置的ocaml,这使得ocamlopt与gcc而不是flexdll链接,现在所有内容都会编译。