2017-03-07 1 views
1

ocaml에서 OGDF 외부 C++ 라이브러리와 인터페이스해야하는 프로젝트를 개발 중입니다. 그것은 모두 최대 내 Mac에서 실행하지만 지금은 Windows 용 Ocaml (https://fdopen.github.io/opam-repository-mingw/), Ocaml의 MinGW Cygwin 포트를 사용하여 Windows 버전을 만들려고합니다. 이 버전에서는 ocaml을 C 코드로 인터페이스 할 수 있지만 올바르게 작동하지만 해당 C 코드에 외부 라이브러리를 포함 시키려고하면이 경우 flexdll (https://github.com/alainfrisch/flexdll) 인 링커에서 오류가 발생합니다. 링커는 라이브러리 전체에서 _Unwind_Resume 및 __emutls_get_address에 대한 심볼을 확인할 수 없다고 말합니다.외부 C 라이브러리와 Windows 용 Ocaml 인터페이스 오류 연결

내 .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 라인을 포함, 나는 다음과 같은 출력을 얻을 : 내가 OCaml의 그것에 연결, 대신 그것을 TC에 따라 주() 함수를 추가하지 않으면

$ 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 

는 x86_64-에서 잘 컴파일 외부 라이브러리가 포함 된 w64-mingw32-gcc. 내가 몇 가지 다른 작은 외부 라이브러리를 포함하여 시도하고 그들은이 문제가 발생하지 않았다.

내 첫 번째 생각은 링크 된 파일이 모두 동일한 방식으로 컴파일되지 않았을 수도 있지만 컴파일러와 .cpp 파일을 ocamlopt -configure에 의해 주어진 파일로 컴파일했습니다. 그리고 만약 그들이 모두 같은 방식으로 컴파일되지 않았다면 tc.cpp가 ocamlopt와 외부 라이브러리를 가지고 개별적으로 작업 할 수있을 것이라고 기대하지는 못했지만, 둘 다 사용하려고 할 때만 오류가 발생합니다. Windows 용 Ocaml이나 flexdll에서 이러한 문제가 발생합니까? 아니면이 중 하나를 설치 했습니까? 나는 다음에 무엇을 시도 해야할지를 놓치고 있으며, 여기서 일어나는 일에 대한 아이디어, 제안 및/또는 설명이 매우 감사 할 것입니다.

+0

내 생각 엔 flexlink 제한입니다. '-ccopt -pthread'('-ccopt -link -ccopt -pthread'와 동일)는 flexlink에서 이해할 수 없습니다. 그냥 gcc toolchain으로 전달할 수 있습니다. 그러나 flexlink는 심볼 자체를 해결하려고 시도하고 실패합니다. 왜냐하면'-pthread'가 무엇을 의미하는지 알지 못하기 때문입니다. – rafix

+0

Flexlink는 분명히 범인 인 것 같습니다. 내 대답은 아래를 참조하십시오. -pthread 플래그를 포함하거나 포함하지 않는 것은 깨진 버전이나 작업 버전에서 차이가없는 것 같지만 문제를 일으키지 않는 OGDF와 다른 라이브러리 간의 차이점은 OGDF가 활발히 활동한다는 것입니다 Posix 스레드를 사용하는 일을합니다. –

답변

1

부분적인 답변이 있습니다. flexdll에서 문제가 발생했습니다. gcc에서 ocaml의 Cygwin 버전을 사용하기로 전환했지만 여전히 동일한 문제가있었습니다. 그런 다음, -no-shared-libs 플래그로 구성된 ocaml을 다시 컴파일합니다. 그러면 ocamlopt가 flexdll 대신 gcc와 링크됩니다. 이제 모든 것이 컴파일됩니다.

+0

나는 또한 수동으로 구성 파일을 편집하여 flexdll없이 mcw 버전의 ocaml을 컴파일 할 수 있었고 원래 프로젝트를 컴파일하기 위해 해당 버전의 ocaml을 사용할 수있었습니다. 이 프로젝트는 또한 lablgtk2 라이브러리를 사용하므로, 컴파일 된 버전의 ocaml로 다시 컴파일해야했습니다. –