まず、以下のように dynamic link する場合は問題なくコンパイルが通る。
そこで static link で作成する事を考えてみる。
ところが -static を付けて static link しようとすると以下のようなエラーが発生する。
これは、
/usr/x86_64-w64-mingw32/sys-root/mingw/include/GL/freeglut_std.h を見ると、
FREEGLUT_STATIC ってマクロを見て条件分岐するコードが書いてあるので、
static link 時には FREEGLUT_STATIC マクロの定義が必要だという事が分かる。
そこで -DFREEGLUT_STATIC を追加してやると今度は以下のようなエラーが生じる。
とりあえず、glut 系の未定義シンボルは消えたが gl, wgl 系の未定義シンボルが大量に発生してしまっている。
ところが、ここで未定義とされているシンボルの多くは、-lopengl32 で参照される /usr/x86_64-w64-mingw32/sys-root/mingw/lib/libopengl32.a の中でちゃんと定義されている。
例えば __imp_glBitmap なら以下の通り。
glBitmap は以下のように定義されている。
結局、原因は、static link の場合は、依存関係を前から順に解決して行くので、depend される側はより後ろで -l しないといけないって事なんだそうな。
つまり、以下のようにすると、少なくとも OpenGL 周りの依存関係は解決したことが確認出来る。
あとは、これらの関数を提供している -lgdi32 と -lwinmm を追加して以下のようにすることでコンパイルに成功して単独で ./a を実行可能となった。
それから -static だと全部 static link にしちゃうけど、特定のライブラリだけ static link にしたい場合は -Wl,-dn,-lglut のように linker option を指定してやれば良いらしい。
標準ライブラリ関係で libgcc_s_seh-1.dll とか libstdc++-6.dll とかを要求される場合があるが、これらを狙い撃ちで static link させたい場合用には -static-libgcc と -static-libstdc++ オプションが用意されているようだ。
なお、-lglu32 -lopengl32 -lgdi32 -lwinmm はこれらのライブラリを個別に static link 指定してもファイルサイズに変化がなかった。
仕組み的には、これらのライブラリは *.a のみで *.dll.a が存在しないため、常に static link 用のライブラリを link しているという事らしい。
そもそもこれらのライブラリが呼び出す機能は Windows 標準の DLL で提供されているため、dynamic link か static link かとか関係なく、常に DLL から機能を呼び出すという事なのだろう。
$ x86_64-w64-mingw32-g++ gltest.cpp -static -lopengl32 -lglu32 -lglutしかし、mingw64-x86_64-freeglut パッケージでは freeglut が DLL 化されているため、このままでは実行時に以下のようにエラーが発生する。
$ ./a C:/Users/kou/Desktop/hoge/a.exe: error while loading shared libraries: libglut-0.dll: cannot open shared object file: No such file or directory従って、以下のように実行する必要がある。
$ PATH="/usr/x86_64-w64-mingw32/sys-root/mingw/bin:$PATH" ./a素の Windows から実行出来るようにわざわざ MinGW を使っているのに、これでは全然嬉しくない。
そこで static link で作成する事を考えてみる。
ところが -static を付けて static link しようとすると以下のようなエラーが発生する。
$ x86_64-w64-mingw32-g++ gltest.cpp -static -lopengl32 -lglu32 -lglut /tmp/ccWGm6k7.o:gltest.cpp:(.text+0x25): undefined reference to `__imp___glutInitWithExit' /tmp/ccWGm6k7.o:gltest.cpp:(.text+0x4c): undefined reference to `__imp___glutCreateWindowWithExit' /tmp/ccWGm6k7.o:gltest.cpp:(.text+0x72): undefined reference to `__imp___glutCreateMenuWithExit' /tmp/ccWGm6k7.o:gltest.cpp:(.text+0x189): undefined reference to `__imp_glutDisplayFunc' /tmp/ccWGm6k7.o:gltest.cpp:(.text+0x199): undefined reference to `__imp_glutKeyboardFunc' /tmp/ccWGm6k7.o:gltest.cpp:(.text+0x1bf): undefined reference to `__imp_glutMainLoop' collect2: error: ld returned 1 exit status
これは、
/usr/x86_64-w64-mingw32/sys-root/mingw/include/GL/freeglut_std.h を見ると、
FREEGLUT_STATIC ってマクロを見て条件分岐するコードが書いてあるので、
static link 時には FREEGLUT_STATIC マクロの定義が必要だという事が分かる。
そこで -DFREEGLUT_STATIC を追加してやると今度は以下のようなエラーが生じる。
$ x86_64-w64-mingw32-g++ -DFREEGLUT_STATIC gltest.cpp -static -lopengl32 -lglu32 -lglut /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_init.o):(.text+0x2d0): undefined reference to `__imp_timeEndPeriod' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_init.o):(.text+0x586): undefined reference to `__imp_GetDeviceCaps' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_init.o):(.text+0x5c4): undefined reference to `__imp_CreateDCA' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_init.o):(.text+0x619): undefined reference to `__imp_DeleteDC' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_init.o):(.text+0x624): undefined reference to `__imp_timeBeginPeriod' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_joystick.o):(.text+0x1d3): undefined reference to `__imp_joyGetDevCapsA' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_joystick.o):(.text+0x862): undefined reference to `__imp_joyGetPosEx' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_main.o):(.text+0x5f): undefined reference to `__imp_timeGetTime' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_main.o):(.text+0x173): undefined reference to `__imp_timeGetTime' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_main.o):(.text+0x186): undefined reference to `__imp_timeGetTime' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_main.o):(.text+0x3b7): undefined reference to `__imp_timeGetTime' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_main.o):(.text+0x5e8): undefined reference to `__imp_timeGetTime' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_main.o):(.text+0xab8): undefined reference to `__imp_wglMakeCurrent' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_main.o):(.text+0xabf): undefined reference to `__imp_wglCreateContext' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_main.o):(.text+0x1711): undefined reference to `__imp_wglGetCurrentContext' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_main.o):(.text+0x17b3): undefined reference to `__imp_wglCreateContext' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_main.o):(.text+0x197c): undefined reference to `__imp_wglCreateContext' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_main.o):(.text+0x19e2): undefined reference to `__imp_glViewport' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_menu.o):(.text+0x414): undefined reference to `__imp_glPushAttrib' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_menu.o):(.text+0x41b): undefined reference to `__imp_glDisable' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_menu.o):(.text+0x43e): undefined reference to `__imp_glMatrixMode' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_menu.o):(.text+0x454): undefined reference to `__imp_glPushMatrix' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_menu.o):(.text+0x45d): undefined reference to `__imp_glLoadIdentity' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_menu.o):(.text+0x4a7): undefined reference to `__imp_glOrtho' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_menu.o):(.text+0x4c2): undefined reference to `__imp_glColor4f' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_menu.o):(.text+0x4e3): undefined reference to `__imp_glVertex2i' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_menu.o):(.text+0x596): undefined reference to `__imp_glColor4fv' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_menu.o):(.text+0x712): undefined reference to `__imp_glRasterPos2i' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_menu.o):(.text+0x7ec): undefined reference to `__imp_glPopAttrib' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_menu.o):(.text+0x7ff): undefined reference to `__imp_glPopMatrix' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_state.o):(.text+0x2d4): undefined reference to `__imp_glGetIntegerv' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_state.o):(.text+0x394): undefined reference to `__imp_glGetIntegerv' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_state.o):(.text+0x412): undefined reference to `__imp_glGetBooleanv' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_state.o):(.text+0x5f2): undefined reference to `__imp_glGetIntegerv' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_state.o):(.text+0x657): undefined reference to `__imp_glGetBooleanv' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_state.o):(.text+0x676): undefined reference to `__imp_glGetIntegerv' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_state.o):(.text+0x68f): undefined reference to `__imp_glGetIntegerv' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_state.o):(.text+0x79f): undefined reference to `__imp_glGetIntegerv' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_state.o):(.text+0x7c3): undefined reference to `__imp_glGetBooleanv' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_state.o):(.text+0x7e2): undefined reference to `__imp_glGetIntegerv' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_state.o):(.text+0x83a): undefined reference to `__imp_glGetIntegerv' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_state.o):(.text+0x876): undefined reference to `__imp_glGetIntegerv' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_state.o):(.text+0x88f): undefined reference to `__imp_glGetIntegerv' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_state.o):(.text+0x8b4): undefined reference to `__imp_GetPixelFormat' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x18): undefined reference to `__imp_wglGetProcAddress' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0xdd): undefined reference to `__imp_wglMakeCurrent' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x179): undefined reference to `__imp_wglGetProcAddress' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x1a3): undefined reference to `__imp_wglDeleteContext' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x378): undefined reference to `__imp_GetDeviceCaps' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x38b): undefined reference to `__imp_ChoosePixelFormat' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x3ba): undefined reference to `__imp_DeleteDC' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x445): undefined reference to `__imp_wglGetCurrentContext' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x450): undefined reference to `__imp_wglGetCurrentDC' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x52c): undefined reference to `__imp_SetPixelFormat' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x535): undefined reference to `__imp_wglCreateContext' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x545): undefined reference to `__imp_wglMakeCurrent' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x575): undefined reference to `__imp_wglDeleteContext' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x5c1): undefined reference to `__imp_CreateDCA' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x5db): undefined reference to `__imp_SetPixelFormat' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x5f9): undefined reference to `__imp_wglGetProcAddress' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x813): undefined reference to `__imp_wglMakeCurrent' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0xc89): undefined reference to `__imp_glDrawBuffer' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0xc94): undefined reference to `__imp_glReadBuffer' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0xed5): undefined reference to `__imp_wglDeleteContext' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0xeed): undefined reference to `__imp_wglMakeCurrent' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_display.o):(.text+0xc6): undefined reference to `__imp_SwapBuffers' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_font.o):(.text+0x10b): undefined reference to `__imp_glPushClientAttrib' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_font.o):(.text+0x112): undefined reference to `__imp_glPixelStorei' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_font.o):(.text+0x17d): undefined reference to `__imp_glBitmap' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_font.o):(.text+0x184): undefined reference to `__imp_glPopClientAttrib' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_font.o):(.text+0x22c): undefined reference to `__imp_glPushClientAttrib' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_font.o):(.text+0x233): undefined reference to `__imp_glPixelStorei' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_font.o):(.text+0x273): undefined reference to `__imp_glBitmap' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_font.o):(.text+0x2e6): undefined reference to `__imp_glPopClientAttrib' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_font.o):(.text+0x596): undefined reference to `__imp_glVertex2f' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_font.o):(.text+0x635): undefined reference to `__imp_glTranslatef' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_font.o):(.text+0x756): undefined reference to `__imp_glTranslatef' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_font.o):(.text+0x75d): undefined reference to `__imp_glVertex2f' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_font.o):(.text+0x80f): undefined reference to `__imp_glTranslatef'
とりあえず、glut 系の未定義シンボルは消えたが gl, wgl 系の未定義シンボルが大量に発生してしまっている。
ところが、ここで未定義とされているシンボルの多くは、-lopengl32 で参照される /usr/x86_64-w64-mingw32/sys-root/mingw/lib/libopengl32.a の中でちゃんと定義されている。
例えば __imp_glBitmap なら以下の通り。
$ nm /usr/x86_64-w64-mingw32/sys-root/mingw/lib/libopengl32.a | awk -vRS="\n\n" /glBitmap/ dcvbs00012.o: 0000000000000000 b .bss 0000000000000000 d .data 0000000000000000 i .idata$4 0000000000000000 i .idata$5 0000000000000000 i .idata$6 0000000000000000 i .idata$7 0000000000000000 t .text 0000000000000000 I __imp_glBitmap U _head_lib64_libopengl32_a 0000000000000000 T glBitmap
glBitmap は以下のように定義されている。
$ grep glBitmap /usr/x86_64-w64-mingw32/sys-root/mingw/include/GL/gl.h WINGDIAPI void APIENTRY glBitmap(GLsizei width,GLsizei height,GLfloat xorig,GLfloat yorig,GLfloat xmove,GLfloat ymove,const GLubyte *bitmap);APIENTRY を疑って、-DAPIIENTRY とか -DAPIENTRY="declspec(dllexport)" とか -DAPIENTRY="declspec(dllimport)" とかやってみたがこれは的外れだった。
結局、原因は、static link の場合は、依存関係を前から順に解決して行くので、depend される側はより後ろで -l しないといけないって事なんだそうな。
つまり、以下のようにすると、少なくとも OpenGL 周りの依存関係は解決したことが確認出来る。
$ x86_64-w64-mingw32-g++ -DFREEGLUT_STATIC gltest.cpp -static -lglut -lglu32 -lopengl32 /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_init.o):(.text+0x2d0): undefined reference to `__imp_timeEndPeriod' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_init.o):(.text+0x586): undefined reference to `__imp_GetDeviceCaps' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_init.o):(.text+0x5c4): undefined reference to `__imp_CreateDCA' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_init.o):(.text+0x619): undefined reference to `__imp_DeleteDC' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_init.o):(.text+0x624): undefined reference to `__imp_timeBeginPeriod' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_joystick.o):(.text+0x1d3): undefined reference to `__imp_joyGetDevCapsA' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_joystick.o):(.text+0x862): undefined reference to `__imp_joyGetPosEx' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_main.o):(.text+0x5f): undefined reference to `__imp_timeGetTime' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_main.o):(.text+0x173): undefined reference to `__imp_timeGetTime' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_main.o):(.text+0x186): undefined reference to `__imp_timeGetTime' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_main.o):(.text+0x3b7): undefined reference to `__imp_timeGetTime' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_main.o):(.text+0x5e8): undefined reference to `__imp_timeGetTime' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_state.o):(.text+0x8b4): undefined reference to `__imp_GetPixelFormat' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x378): undefined reference to `__imp_GetDeviceCaps' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x38b): undefined reference to `__imp_ChoosePixelFormat' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x3ba): undefined reference to `__imp_DeleteDC' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x52c): undefined reference to `__imp_SetPixelFormat' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x5c1): undefined reference to `__imp_CreateDCA' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_window.o):(.text+0x5db): undefined reference to `__imp_SetPixelFormat' /usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libglut.a(libglut_la-freeglut_display.o):(.text+0xc6): undefined reference to `__imp_SwapBuffers' collect2: error: ld returned 1 exit status
あとは、これらの関数を提供している -lgdi32 と -lwinmm を追加して以下のようにすることでコンパイルに成功して単独で ./a を実行可能となった。
$ x86_64-w64-mingw32-g++ -DFREEGLUT_STATIC ../gltest.cpp -static -lglut -lglu32 -lopengl32 -lgdi32 -lwinmm
それから -static だと全部 static link にしちゃうけど、特定のライブラリだけ static link にしたい場合は -Wl,-dn,-lglut のように linker option を指定してやれば良いらしい。
標準ライブラリ関係で libgcc_s_seh-1.dll とか libstdc++-6.dll とかを要求される場合があるが、これらを狙い撃ちで static link させたい場合用には -static-libgcc と -static-libstdc++ オプションが用意されているようだ。
なお、-lglu32 -lopengl32 -lgdi32 -lwinmm はこれらのライブラリを個別に static link 指定してもファイルサイズに変化がなかった。
仕組み的には、これらのライブラリは *.a のみで *.dll.a が存在しないため、常に static link 用のライブラリを link しているという事らしい。
そもそもこれらのライブラリが呼び出す機能は Windows 標準の DLL で提供されているため、dynamic link か static link かとか関係なく、常に DLL から機能を呼び出すという事なのだろう。
以上、重要だったのは以下の2点であった
- freeglut を static link する場合は FREEGLUT_STATIC マクロを定義する必要がある
- gcc で static link する場合、参照されるオブジェクトは参照するオブジェクトよりも後に与える必要がある
- 静的ライブラリのリンク時にundefined referenceエラーが出る(gcc)
- akihiko’s tech note / 2009-11-22: あるシンボルが どのオブジェクトファイル/共有オブジェクトに含まれているか検索するスクリプト
- 何が中心かわからないブログ / 2014-12-21: MinGW-w64でlibwinpthread-1.dllの静的リンク
- stackoverflow / 2013-04-06: Static and Dynamic/Shared Linking with MinGW
タグ
コメントをかく