森北出版株式会社刊 「Springs of C」サポートwebページ

2020年7月8日更新

このページでは、森北出版株式会社刊の「Springs of C」に関するサポート情報を掲載しています。本の紹介はこちらから。


ライブラリやサンプルプログラム


既知の問題とそれらへの対処方法

以下の情報はだいぶ古くなっており、最近のCygwin環境/macOS環境ではあまり役に立たない情報かもしれませんが資料としていちおう残しておきます。
最近のCygwin (Cygwin 64bit版)での対応はこちらにまとめました。

本書のサンプルプログラムを実行する場合の、既知の問題とそれらへの対処方法を説明します。

  1. CygwinでGLUTプログラムのリンクができない(単純なミス)
    コンパイル時に以下のように_glut*や_gl*という関数へのリンクエラーが大量に発生する場合には、まずはライブラリの並びの問題が考えられます。
    game.o:game.c:(.text+0x39): undefined reference to `_glutInit'
    game.o:game.c:(.text+0x4d): undefined reference to `_glutInitWindowSize'
    game.o:game.c:(.text+0x59): undefined reference to `_glutCreateWindow'
       :
    game.o:game.c:(.text+0x3452): undefined reference to `_glutBitmapCharacter'
    collect2: ld はステータス 1 で終了しました
    make: *** [game.exe] エラー 1
    このような場合、コンパイルするときのライブラリの並び順、すなわち-l***の並び順が以下の通りになっているか確認してください。
    % gcc -Wall -I/usr/include/opengl hoge.c -lglpng -lglut32 -lglu32 -lopengl32


  2. CygwinでGLUTプログラムのリンクができない(libglut-develの問題)
    ライブラリの並び順の確認をしてもまだリンクエラーが直らない場合は、Cygwinのlibglut-develパッケージの問題が考えられます。C:\cygwin\usr\include\GLとC:\cygwin\usr\include\w32api\GLの両方にglut.hが存在していないでしょうか(後者の場所にglut.hが存在しない場合はこちらを参照)?前者はX11用のライブラリであり、後者はWindows DLLを使用するためのものです。両者で関数呼び出しの方法が異なるため、リンクエラーの原因となるようです(参考)。これは単にlibglut-develパッケージのバグと思われますので、そのうち解決されるでしょう。とりあえずこのバグを回避するにはlibglut-develを削除するのが手っ取り早いので、Cygwinのインストーラsetup.exeを起動し、パッケージの選択画面

    でGraphicsをクリックし、さらにその中の"libglut-devel"を

    のように"Uninstall"にしてください。あとはインストーラに任せておけば自動的にX11用の関連ファイルを削除してくれます。


  3. glu.hでsyntax errorが発生する
    glu.hのsyntax errorなどでコンパイル自体に失敗する場合は、コンパイル時に(ダブルクォーテーションまで含めて)"-Dwchar_t=unsigned short"というオプションを付け足してみるとうまくいくかもしれません(参考)。


  4. glutBitmapCharacter()による文字が表示されないことがある
    テクスチャ機能が有効になっていると、glutBitmapCharacter()による文字が表示されない場合があるようです(参考)。その場合、glDisable(GL_TEXTURE_2D);という1行をglutBitmapCharacter()の前に加えてみてください。


  5. Mac OS Xで実行したときにout of memoryエラーが出る
    ウィンドウのタイトルに2バイト文字が含まれているとGLUTがout of memoryエラーを出して実行できません。プログラム中のglutCreateWindow("・・・")に2バイト文字(日本語など)のウィンドウタイトルが指定されていないか確認してください。


  6. Cygwin環境のメッセージが文字化けする
    Cygwin環境で日本語が文字化けすることがあります。これは、CygwinのメッセージはUTF-8という文字コードで書かれていますが、WindowsのコマンドプロンプトはSJISという文字コードのみに対応しておりUTF-8の表示には対応していないことが原因です。以下のようにして環境変数を設定することでこの問題を回避できます。
    1. コントロールパネルを開き、右上の検索窓に「環境変数」と入力し、[環境変数を編集]をクリックします(Windows 7/Vistaの場合。XPの場合は[コントロールパネル]→[システム]→[詳細設定]→[環境変数])。
    2. 環境変数を編集するためのダイアログが表示されます。上が「ユーザー環境変数」、下が「システム環境変数」となっています。上の方の[新規]をクリックしてください。
    3. 変数名LANGに変数値ja_JP.sjisを(大文字小文字もこの通りに)設定してください。
    4. Cygwin Bash shellを開き、たとえばmake --helpのようにしてみてmakeのヘルプメッセージの日本語が文字化けしていないか確認してください。


  7. Linux環境でGLUTを使ったプログラムにSegmentation Faultが出る
    Linux環境で使われているOpenGLドライバのハードウェアアクセラレーション機能をオフにすると回避できるようです(参考)。通常は単に実行ファイル名を指定して./a.outのようにプログラムを起動していますがこれをLIBGL_ALWAYS_INDIRECT=1 ./a.outのようにします。


  8. Linux環境でウィンドウのタイトルバーの文字が化ける
    ソースプログラムを記述する際に使った文字コード(通常はUTF-8)に、ウィンドウマネージャのタイトルバーのフォントが対応していないと文字化けします。たとえばUbuntu 11.04であれば「外観の設定」([システム]→[設定]→[外観の設定])からタイトルバーのフォントを変更できます・・・が、UTF-8に対応しているはずのフォントを指定しても文字化けします。これはGLUT内部の問題かも・・・。


  9. Ubuntu 11.10以降にglpng-devパッケージがない
    Ubuntu 11.10以降用のglpng-devパッケージは標準のリポジトリから削除されてしまったようで、apt-getコマンドからはインストールすることができません(2013年9月現在)。コマンドラインから次の手順でインストールを行ってください(%はプロンプト)。
    % sudo apt-get update
    % sudo apt-get -y install freeglut3-dev
    % mkdir tmp (作業用のフォルダを適当な名前で作ってください。ここではtmpとします)
    % cd tmp
    % wget ftp://ftp.usa.openbsd.org/pub/OpenBSD/distfiles/glpng-1.45/glpng.zip
    % unzip glpng.zip (解凍したら、glpng.htmをwebブラウザで開いて目を通してください)
    % cd src/
    % make -f Makefile.LINUX
    % cd ../lib/
    % sudo cp libglpng.a /usr/lib/
    % cd ../include/GL/
    % sudo cp glpng.h /usr/include/GL/
    % cd ../../../
    % rm -rf tmp/ (作業用のフォルダごと消します)
    上から5行目のwgetでファイルが取得できない場合はここからダウンロードしてください。

  10. Xcode 4.2.1以降での動作確認
    脱稿後にXcode 4.2.1, Xcode 4.3, Xcode 4.4, Xcode 4.5, Xcode 4.6, Xcode 5.1, Xcode 7.3, Xcode 8.1がリリースされましたが、glpngを使ったプログラムの正常動作を確認しております。


  11. Xcode 4.3以降でコマンドラインからgccが呼べない
    Xcode 4.3以降はApp Store経由でアプリケーションフォルダに直接インストールされる形になりました。同時に、従来コマンドラインから呼び出しが可能であったgccコマンドが使えなくなっています。これを手動で使えるようにするにはこちらのページをご覧ください。過去に一度Command Line Toolsをインストールされた場合でも、その後App Store経由でソフトウェアアップデートがかかっている場合はCommand Line Tools自体のアップデートがないかご確認ください(Xcodeのメニューから[Xcode]→[Preferences...]→[Downloads]→[Components]の順にクリックして"Command Line Tools"の行のボタンが[Update]になっていたらクリックして更新してください)。Xcode 8.1ではコマンドラインツールがXcode本体と同時にインストールされるようです。


  12. glpng.zip付属のTest.cが実行時にエラーで止まる
    glpngのオリジナルアーカイブであるglpng.zipに含まれるサンプルプログラムを実行するとエラーで止まることがあります。Mac OS Xですと次のようなエラーメッセージになります。
    $ ./a.out
    Apr 14 13:36:15 xxx a.out[3266] <Error>: kCGErrorInvalidConnection: CGSGetCurrentCursorLocation: Invalid connection
    Apr 14 13:36:15 xxx a.out[3266] <Error>: kCGErrorFailure: Set a breakpoint @ CGErrorBreakpoint() to catch errors as they are logged.
    Apr 14 13:36:15 xxx a.out[3266] <Error>: kCGErrorInvalidConnection: CGSGetCurrentCursorLocation: Invalid connection
    Apr 14 13:36:15 xxx a.out[3266] <Error>: kCGErrorInvalidConnection: CGSNewWindowWithOpaqueShape: Invalid connection
    2012-04-14 13:36:15.863 a.out[3266:507] GLUT Fatal Error: internal error: NSInternalInconsistencyException, reason: Error (1002) creating CGSWindow on line 263
    もしくはLinuxですと(Ubuntu 13.04の例)次のようなエラーメッセージになります。
    % ./a.out
    freeglut ERROR: Function <glutCreateWindow> called without first calling 'glutInit'.
    これは、Test.cが適切にGLUTの初期化を行っていないためです。Test.cの67行目が
    void main() {
    となっていますが、これを
    int main(int argc, char **argv) {
    のように書き換え、71行目のglutInitDisplayMode()の前の行に
    glutInit(&argc, argv);
    という1行を追加してください。

  13. Ubuntu 12.04/12.10/13.04/13.10/14.04/14.10/15.04での動作確認
    脱稿後にUbuntu 12.04/12.10/13.04/13.10/14.04/14.10/15.04がリリースされましたが、32ビット版と64ビット版の両方で、glpngを使ったプログラムの正常動作を確認しております。glpngのインストールについてはこのページの「既知の問題とそれらへの対処方法」の9番をご覧ください。コンパイル方法は本誌のp.111に記載されているものがそのまま使えます。


  14. ダブルバッファリングにしたら画面が表示されなくなった
    本書p.131の、14.3.13項の末尾には「・・・ glFlush()をglutSwapBuffers()で置き換えるだけで、・・・」という記述がありますが、glFlush()を消さずに、glFlush()のあとにglutSwapBuffers()を加えると直る場合があるようです(こちらこちらをみると、glutSwapBuffers()の内部でglFlush()を呼んでいるとも書かれていますが・・・)。


  15. OS X 10.8 (Mountain Lion)以降での動作確認
    脱稿後にOS X 10.8 (Mountain Lion)とOS X 10.9 (Mavericks)とOS X 10.10 (Yosemite)とOS X 10.11 (El Capitan)とmacOS 10.12 (Sierra)がリリースされましたが、glpngを使ったプログラムの正常動作を確認しております。ただし、Mavericks以降では、OpenGLの関数が非推奨扱い(今後廃止予定)となったため、"warning: 'xxxx' is deprecated: first deprecated in OS X 10.9"といった警告が大量に出ます。これを表示させないようにするには、gccのコンパイルオプションに-Wno-deprecatedを付加してください。ただし、OpenGL以外の非推奨APIの使用についての警告も非表示になりますのでご注意ください。FAQの21番22番ももご覧ください。


  16. 数学ライブラリをリンクしているはずなのにリンクエラーがでる
    Linuxで以下のようなエラーが出た場合は、数学ライブラリのリンク順を変更してみてください(-lglpngよりも後ろに-lmを持ってくる)。
    % gcc -Wall main.c -lm -lglpng -lglut -lGLU -lGL
    /usr/bin/ld: /usr/lib/gcc/i686-linux-gnu/4.7/../../../../lib/libglpng.a(pngrtran.o): シンボル 'pow@@GLIBC_2.0' への未定義参照です
    /usr/bin/ld: 注: 'pow@@GLIBC_2.0' は DSO /usr/lib/gcc/i686-linux-gnu/4.7/../../../i386-linux-gnu/libm.so 内で定義されているのでリンカのコマンドラインに追加してみてください
    /usr/lib/gcc/i686-linux-gnu/4.7/../../../i386-linux-gnu/libm.so: could not read symbols: 無効な操作です
    collect2: エラー: ld はステータス 1 で終了しました

    % gcc -Wall main.c -lglpng -lglut -lGLU -lGL -lm
    % (コンパイル成功)


  17. CygwinでGLUTプログラムのリンクができない(OpenGLパッケージの問題)
    コンパイル時に以下のように_glut*や_gl*という関数へのリンクエラーが大量に発生する場合で、ライブラリの指定ミス(このページの「既知の問題とそれらへの対処方法」の1番)ではない場合、C:\cygwin\usr\include\w32api\GLにglut.hというファイルが存在するかどうか確認してください。
    game.o:game.c:(.text+0x39): undefined reference to `_glutInit'
    game.o:game.c:(.text+0x4d): undefined reference to `_glutInitWindowSize'
    game.o:game.c:(.text+0x59): undefined reference to `_glutCreateWindow'
       :
    game.o:game.c:(.text+0x3452): undefined reference to `_glutBitmapCharacter'
    collect2: ld はステータス 1 で終了しました
    make: *** [game.exe] エラー 1
    もしC:\cygwin\usr\include\w32api\GLにglut.hというファイルが存在していなければ、OpenGLパッケージを手動でインストールする必要があります(最近のCygwinインストールパッケージでは、OpenGLパッケージがobsolete(時代遅れ)扱いになり、特に指定しない限りインストールされなくなってしまったようです)。Cygwinのインストーラsetup.exeを起動し、パッケージの選択画面で"Hide obsolete packages"のチェックをはずしてください。

    すると、パッケージの選択肢として、下の方に"_obsolete"が追加されます。

    上図の赤で囲んだ部分で、+の部分をクリックすると_obsoleteパッケージツリーが開きます。"opengl: OpenGL-related libraries"を探し、下図では"Keep"(お使いの環境では別の表記になっているかもしれません)となっている部分をクリックして"Install"に変更します。

    あとは"次へ"をクリックしてインストールを完了させてください。C:\cygwin\usr\include\w32api\GLにglut.hというファイルが作られ、本書の方法でコンパイル・リンクができるようになると思います。


  18. CygwinでGLUTプログラムのリンクができない(GLUT_ATEXIT_HACKの問題)
    次のように、エラーメッセージの中にWithExitという単語が見える場合があります。
    % gcc -Wall -I/usr/include/opengl openwindow.c -lglut32 -lglu32 -lopengl32
    /cygdrive/c/Users/xxx/AppData/Local/Temp/ccrO2Yob.o:openwindow.c:(.text+0x1c): undefined reference to `___glutInitWithExit@12'
    /cygdrive/c/Users/xxx/AppData/Local/Temp/ccrO2Yob.o:openwindow.c:(.text+0x3c): undefined reference to `___glutCreateWindowWithExit@8'
    /cygdrive/c/Users/xxx/AppData/Local/Temp/ccrO2Yob.o:openwindow.c:(.text+0x5c): undefined reference to `___glutCreateMenuWithExit@8'
    collect2: ld はステータス 1 で終了しました 
    この場合、プログラム冒頭の
    #include <GL/glut.h>
    となっている部分の前の行に
    #define GLUT_DISABLE_ATEXIT_HACK
    という1行を追加してみてください。これは、ウィンドウの閉じるボタン([X])をクリックしたときにGLUTのプログラムを自動的に終了するためにGLUTに加えられている改変をオフにするという意味です。これをオフにするので、副作用として、[X]をクリックしてもプログラムが終了しないようになります(ウィンドウは消えるがコマンドプロンプトには反応がないまま)。プログラムを終了させる際はコマンドプロンプト上でCtrl+Cキーを押してください。


  19. CygwinでGLUTプログラムのコンパイルができない(64ビット版Cygwinの問題)
    GLUTを使ったプログラムをコンパイルしようとするとそもそも"GLUT/glut.h : No such file or directory"と言われたり、libglut32がなかったり、といった場合は、64ビット版のCygwinを使っていないか確認してください。Cygwinのwebページで配布されているsetup-x86_64.exeを使ってインストールをすると64ビット版のCygwinがインストールされます。setup-x86.exeを使ってインストールをすると32ビット版のCygwinがインストールされます。どちらがインストールされているか不明な場合は、コマンドラインから uname -a と入力するとわかります。下の例のように、uname -aで表示される文字列の後ろの方にi686とついていれば32ビット版、x86_64なら64ビット版です。残念ながら、64ビット版CygwinではGLUT自体が(obsoleteとしてすらも)提供されなくなっています。GLUTをソースからコンパイルして導入するか(当方では動作未確認)、32ビット版Cygwinをお使いください。glpngも64ビット版コンパイラでコンパイルし直す必要がありますが当方では未確認です。原理的には、4GB以上のメモリを必要とするようなプログラムを使わないのであれば64ビット版Cygwinは意味がありません。
    32ビット版Cygwinでは
    % uname -a
    CYGWIN_NT-6.1-WOW64 xxxxx 1.7.17(0.262/5/3) 2012-10-19 14:39 i686 Cygwin

    64ビット版Cygwinでは
    % uname -a
    CYGWIN_NT-6.1-WOW64 xxxxx 1.7.17(0.270/5/3) 2013-08-31 20:37 x86_64 Cygwin


  20. CygwinでGLUTプログラムのコンパイルができない(w32api用OpenGLがなくなった問題)
    2014年9月頃(?)から、CygwinのOpenGLパッケージがobsolete(「既知の問題とそれらへの対処方法」の17番)ですらなくなり、ばっさりなくなってしまいました。次の方法で、過去のOpenGLパッケージを手動でインストールすれば本書に掲載の通りのやり方でコンパイルや実行ができます($はプロンプト)。WindowsのコマンドプロンプトからCygwinのコマンドが呼べるようにパスが通してある場合でもCygwin Terminalを起動して作業してください(opengl-1.1.0-10.tar.bz2に含まれる/usr/lib/というディレクトリがコマンドプロンプトからはc:\cygwin\usr\libとして見えないため)。
    1. Cygwin Terminal(もしくはCygwin Bash shell)を起動します。手順3以降でエラーがでる場合は、ここでCygwin Terminalのアイコンを右クリックして「管理者として実行」としてからお試しください。
    2. $ cd /
    3. $ wget http://http://teacher.nagano-nct.ac.jp/ito/Springs_of_C/opengl-1.1.0-10.tar.bz2
    4. $ bzip2 -dv opengl-1.1.0-10.tar.bz2
    5. $ tar xvf opengl-1.1.0-10.tar
    6. $ rm opengl-1.1.0-10.tar



  21. MacOSでglpngを使うプログラムがコンパイルできない
    glpngmac.dmgに同梱されている説明では glpng.frameworkをインストールする先が/System/Library/Frameworksと なっていますが、比較的新しいMac OSではフレームワークのインストール先が変更されている場合があり、その場合はコンパイルに失敗します。その場合、 なんでもよいので適当なC言語のプログラム(glpngやOpenGLを使わないものでOK)を gcc -v hoge.c のように-vをつけてコンパイルしてみてください。そのときに大量に画面表示がありますが、
    /System/Library/Frameworks (framework directory)
    /Library/Frameworks (framework directory)
    のように、「パス名 (framework directory)」のように表示される行を探します。参考までに、筆者のOS X El CapitanのXcode 7.3では上記の2行のように、macOS SierraのXcode 8.1では
    /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/
    のように長いパスになりました。 複数のパス名が表示された場合、いずれか一つを適当に選びます(OSのシステム防御機能"System Integrity Protection"により、/Systemなど一部のディレクトリにはアクセスが禁止されますのでその場合は別のディレクトリをお試しください)。 ターミナルから、open /Library/Frameworks のようにしてそのパス名をopenコマンドに与えるとFinderでそのディレクトリが開きます。ここにglpng.frameworkをコピーします。


  22. MacOSで実行するときに"dyld: Library not loaded: ..."というエラーがでる
    ホームディレクトリのLibrary/Frameworks/にglpng.frameworkをコピーすると 解決される場合があります。ホームディレクトリにLibraryディレクトリが ない場合は作成してください。 ターミナルから
    $ mkdir -p ~/Library/Frameworks/
    $ open ~/Library/Frameworks/
    と入力すればディレクトリが作成されてFinderで開かれます。


  23. MacOSで"warning: 'glutInit' is deprecated: first deprecated in macOS 10.9 - OpenGL API deprecated. (Define GL_SILENCE_DEPRECATION to silence these warnings) "という警告がでる
    ソースコードの冒頭に
    #define GL_SILENCE_DEPRECATION
    という1行を加えるとWarningを抑制することができます。


  24. MacOSで"'glutInit' has been explicitly marked deprecated here"というエラーがでる
    Xcodeを入れると、ターミナルからgccと入力したときに実際はclangが呼び出されます。これとは別にHomebrewやMacPortsなどでgcc(clangではなくてgccそのもの)をインストールするとGLUTのプログラムをコンパイルしようとしたときにエラーで止まることがあります。ターミナルからgcc -vと入力して"Apple clang version 11.0.3"のような1行が表示されればそれはclangです。



各種リンク