我正在用ocaml开发一个项目,它需要我将它与OGDF外部c++库接口。这一切都在我的mac上运行,但现在我正试图使用Ocaml for windows (https://fdopen.github.io/opam-repository-mingw/),即MinGW Cygwin的Ocaml port创建一个Windows版本。在这个版本中,我可以将ocaml与C代码接口,它工作得很好,但只要我尝试在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,而是向t.c添加一个main()函数,那么它在包含外部库的x86_64-w64-mingw32-gcc下编译得很好。我尝试过包含一些其他的小型外部库,但它们并没有导致这个问题。
我的第一个想法是,问题可能与链接文件的编译方式不同有关,但我使用ocamlopt -configure提供的编译器和选项编译库和.cpp文件。如果它们都不是以相同的方式编译的,我就不会期望能够让tc.cpp分别与ocamlopt和外部库一起工作,但只有当我尝试使用这两者时才会得到错误。那么,这是Ocaml for windows或flexdll的问题,还是我安装其中一个的问题?我不知道下一步该尝试什么,任何想法、建议和/或对这里发生的事情的解释都将非常感谢。
发布于 2017-03-11 06:07:44
我有一个部分的答案。不知何故,这个问题来自flexdll。我改用Cygwin版本的ocaml和gcc,仍然有同样的问题。然后我重新编译了配置了-no-shared libs标志的ocaml,它使ocamlopt链接到了gcc而不是flexdll,现在一切都编译好了。
https://stackoverflow.com/questions/42656356
复制相似问题