引き続き、書籍 CUDA BY EXAMPLE を読み進めています。
Chapter 4のジュリア集合 - Wikipediaを描画するプログラムjulia_cpu.cu
をビルドするのにやたら苦労したので、やったことをまとめておきます。OSはUbuntu 16.04 LTSです。
julia_cpu.cuのビルド
まず、gl/glut.hがシステム上に存在しないことからGLUTを入れる必要があることが分かったので、sudo apt-get install freeglut3-dev
でインストールしました。
次に、nvccコマンドで以下のようにビルドを試みますが、失敗します。
$ nvcc julia_cpu.cu -lglut ../common/cpu_bitmap.h(49): warning: conversion from a string literal to "char *" is deprecated ../common/cpu_bitmap.h(49): warning: conversion from a string literal to "char *" is deprecated /usr/bin/ld: /tmp/tmpxft_00006f4f_00000000-10_julia_cpu.o: シンボル 'glDrawPixels' への未定義参照です libGL.so.1: error adding symbols: DSO missing from command line collect2: error: ld returned 1 exit status
まず、共有ライブラリ周りに問題がないかを調べました。libglut.so
をlocateコマンドで探すと、/usr/lib/x86_64-linux-gnu
にあることがわかります。
$ locate libglut.so /usr/lib/x86_64-linux-gnu/libglut.so /usr/lib/x86_64-linux-gnu/libglut.so.3 /usr/lib/x86_64-linux-gnu/libglut.so.3.9.0
このlibglut.so
が依存するライブラリをlddコマンドで追うと、すべてのライブラリに到達できているように見えます。(もし見つからない依存ライブラリがあれば"not found"とは表示される)
$ cd /usr/lib/x86_64-linux-gnu $ ldd libglut.so linux-vdso.so.1 => (0x00007fff910f7000) libGL.so.1 (0x00007f476d237000) libX11.so.6 (0x00007f476cefd000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f476cbf4000) libXi.so.6 (0x00007f476c9e4000) libXxf86vm.so.1 (0x00007f476c7de000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f476c414000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f476c210000) libGLX.so.0 (0x00007f476bfe0000) libGLdispatch.so.0 (0x00007f476bd12000) libxcb.so.1 (0x00007f476baf0000) /lib64/ld-linux-x86-64.so.2 (0x00007f476d723000) libXext.so.6 (0x00007f476b8de000) libXau.so.6 (0x00007f476b6da000) libXdmcp.so.6 (0x00007f476b4d4000)
次に、もう一度最初のエラーメッセージで検索をかけると、How to compile codes on CUDA OpenGL interop from the book CUDA BY EXAMPLE by Jason Sanders & Edw - NVIDIA Developer Forumsがヒットしました。これによると、-lGL -lGLU
を加えるという回答があります。
最初は-lGL
を追加から始めます。以下のコマンドを試しますが、今度はlibGL.soが見つからないと言われてしまいます。
$ nvcc julia_cpu.cu -lGL -lglut ../common/cpu_bitmap.h(49): warning: conversion from a string literal to "char *" is deprecated ../common/cpu_bitmap.h(49): warning: conversion from a string literal to "char *" is deprecated /usr/bin/ld: -lGL が見つかりません collect2: error: ld returned 1 exit status
しかし、 /usr/lib/x86_64-linux-gnu/
には libGL.so
という名前のシンボリックが存在していたはずだから、libGL.soが見つからないと言われるのは心外です。このシンボリックリンクが指す先をfileコマンドで調べると、リンクが壊れていることがわかりました。
$ file /usr/lib/x86_64-linux-gnu/libGL.so /usr/lib/x86_64-linux-gnu/libGL.so: broken symbolic link to mesa/libGL.so
なので、以下のように手動でlibGL.soのリンクを張り直しました。(注意:自己責任でお願いします)
$ sudo mv libGL.so libGL.manually-moved.so $ sudo ln -s libGL.so.1.0.0 libGL.so
このあともう一度サンプルをビルドすると、警告は出たままですが無事ビルドが通りました。
$ nvcc julia_cpu.cu -lGL -lglut ../common/cpu_bitmap.h(49): warning: conversion from a string literal to "char *" is deprecated ../common/cpu_bitmap.h(49): warning: conversion from a string literal to "char *" is deprecated
苦労の末の戦果品として以下を捧げます。
julia_gpu.cu のビルド
おまけで julia_gpu.cu
のビルドについても触れておきます。プログラム中の
cuComplex( float a, float b ) : r(a), i(b) {}
の行を
__device__ cuComplex( float a, float b ) : r(a), i(b) {}
と書き換える必要がありました。(参考:c - CUDA Errors while running "CUDA By Example" julia_gpu.cu - Stack Overflow)