2017-03-07 66 views
1

我正在开发一个ocaml项目,需要我与OGDF外部C++库接口。它全部在我的Mac上运行,但现在我正在尝试使用Ocaml for Windows(https://fdopen.github.io/opam-repository-mingw/)创建一个Windows版本,即Ocaml的MinGW Cygwin端口。在这个版本中,我可以将ocaml与c代码连接起来,并且它可以正常工作,但只要我尝试在该c代码中包含外部库,就会从链接程序中获取错误,这是flexdll(https://github.com/alainfrisch/flexdll)。链接器说它无法解析整个库中_Unwind_Resume和__emutls_get_address的符号。链接错误接口ocaml的Windows与外部c库

这里是一个玩具例子:

我.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; 
} 

我的生成文件:

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 

像这样,它全部编译得很开心,但如果我unc omment的ogdf包括tc.cpp线,我得到下面的输出:

$ 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()函数来TC它编译下x86_64-就好包含外部库的w64-mingw32-gcc。我试过包括一些其他的小型外部库,它们不会导致这个问题。

我的第一个想法是,也许问题不是所有的编译方式都是相同的链接文件,但我编译了库和.cpp文件,编译器和ocamlopt -configure给出的选项。如果它们不是全部以相同的方式编译,我不希望能够通过ocamlopt和外部库单独获取tc.cpp,但是当我尝试使用两者时,我只会遇到错误。那么这是Ocaml for windows,flexdll还是我安装其中一个问题?我对接下来要尝试的东西感到不知所措,并且对这里发生的任何想法,建议和/或解释将非常感激。

+0

我的猜测:这是一个灵活链接限制。 '-ccopt -pthread'(这对'-ccopt -link -ccopt -pthread'是同一性的)不能被flexlink理解。它可以将它传递给gcc工具链。然而,flexlink试图自己解析符号,然后失败,因为它不知道'-pthread'的含义。 – rafix

+0

Flexlink绝对似乎是罪魁祸首 - 请参阅下面的答案。包括或不包括-pthread标志在破损版本或工作版本中似乎没有任何区别,但OGDF和其他不会导致问题的库之间的区别可能在于OGDF处于活动状态做一些使用Posix线程的东西。 –

回答

1

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

+0

我还能够通过手动编辑配置文件来最终编译一个没有flexdll的ocaml版本,并且能够使用该版本的ocaml编译我的原始项目。该项目也使用lablgtk2库,所以我必须重新编译以及重新编译的ocaml版本。 –