我正在開發一個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還是我安裝其中一個問題?我對接下來要嘗試的東西感到不知所措,並且對這裏發生的任何想法,建議和/或解釋將非常感激。
我的猜測:這是一個靈活鏈接限制。 '-ccopt -pthread'(這對'-ccopt -link -ccopt -pthread'是同一性的)不能被flexlink理解。它可以將它傳遞給gcc工具鏈。然而,flexlink試圖自己解析符號,然後失敗,因爲它不知道'-pthread'的含義。 – rafix
Flexlink絕對似乎是罪魁禍首 - 請參閱下面的答案。包括或不包括-pthread標誌在破損版本或工作版本中似乎沒有任何區別,但OGDF和其他不會導致問題的庫之間的區別可能在於OGDF處於活動狀態做一些使用Posix線程的東西。 –