2017-03-07 109 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版本。 –