链接错误接口ocaml for windows与外部c库

时间:2017-03-07 19:09:42

标签: windows mingw ocaml linker-errors

我正在开发一个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,还是我安装其中一个的问题?我对接下来的尝试感到茫然,对此处发生的任何想法,建议和/或解释都将非常感激。

1 个答案:

答案 0 :(得分:1)

我有一个部分答案。问题是以某种方式来自flexdll。我转而使用带有gcc的Cygwin版本的ocaml,仍然有同样的问题。然后我重新编译了使用-no-shared-libs标志配置的ocaml,这使得ocamlopt与gcc而不是flexdll链接,现在所有内容都会编译。