链接ocaml for windows与外部c库接口时出错 我正在开发一个OCAM的项目,它需要我与OGDF外部C++库接口。这一切都在我的mac上运行,但现在我正试图使用OCAMLForWindows()创建一个windows版本,Ocaml的MinGW Cygwin端口。在这个版本中,我可以将ocaml与c代码连接起来,它工作得很好,但是一旦我尝试在c代码中包含一个外部库,我就会从链接器中得到错误,在本例中是flexdll()。该链接器表示,它无法解析整个库中的“释放”、“恢复”和“获取”地址的符号

链接ocaml for windows与外部c库接口时出错 我正在开发一个OCAM的项目,它需要我与OGDF外部C++库接口。这一切都在我的mac上运行,但现在我正试图使用OCAMLForWindows()创建一个windows版本,Ocaml的MinGW Cygwin端口。在这个版本中,我可以将ocaml与c代码连接起来,它工作得很好,但是一旦我尝试在c代码中包含一个外部库,我就会从链接器中得到错误,在本例中是flexdll()。该链接器表示,它无法解析整个库中的“释放”、“恢复”和“获取”地址的符号,windows,mingw,ocaml,linker-errors,Windows,Mingw,Ocaml,Linker Errors,以下是一个玩具示例: My.ml文件t.ml: external print : unit -> unit = "print" let () = Printf.printf "platform: %s\n" (Sys.os_type); print () My.cpp文件tc.cpp: #include <stdio.h> #include "caml/mlvalues.h" #define CAML_NAME_SPACE //#include <ogdf/b

以下是一个玩具示例:

My.ml文件t.ml:

external print : unit -> unit = "print"

let () =
  Printf.printf "platform: %s\n" (Sys.os_type);
  print ()
My.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;  
}  
像这样,它可以很好地编译,但是如果我在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的问题,还是我安装其中一个的问题?我不知道下一步该做什么,如果您有任何想法、建议和/或解释,我将不胜感激。

我有一个部分答案。这个问题不知何故来自flexdll。我转而使用Cygwin版本的ocaml和gcc,但仍然存在同样的问题。然后,我重新编译了配置了-no shared libs标志的ocaml,这使ocamlopt链接到gcc而不是flexdll,现在一切都编译好了。

我猜:这是flexlink的限制。”-flexlink不理解ccopt-pthread'(与'-ccopt-link-ccopt-pthread'相同)。它可以将其传递给gcc工具链。然而,flexlink试图自行解析符号,但失败了,因为它不知道
-pthread
所隐含的含义。flexlink显然是罪魁祸首——请参阅下面的答案。包含或不包含-pthread标志似乎没有任何区别,无论是在已损坏的版本中,还是在工作版本中,但也许OGDF和其他不会引起问题的库之间的区别在于OGDF正在积极地使用Posix线程。我还能够通过手工编辑配置文件,最终在没有flexdll的情况下编译一个mingw版本的ocaml,并且能够使用该版本的ocaml编译我的原始项目。该项目还使用了lablgtk2库,因此我必须使用ocaml的重新编译版本重新编译该库。
$ 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