2015年6月29日月曜日

GTK+を自力でインストールしてみよう① GTK+インストールガイドの翻訳

量が多くて正確さと読みやすさに欠けているがわかりづらいが、雰囲気はこんな感じ。
Google翻訳を使いながらインストールガイドを私なりに素人翻訳したものを以下にのせておく。

あまり英語は得意ではないので、間違ってたら教えてください。

Compiling the GTK+ libraries

GTK+ライブラリのコンパイル - それ自体+ GTKをコンパイルする方法

Building GTK+ on UNIX-like systems

この章では、構築し、UNIXやLinuxなどのUNIX系のシステム上でGTK+をインストールを対象にしています。 Microsoft WindowsでGTK+をコンパイルする場合、詳細が異なっており、必要なツールはオペレーティングシステムに含まれていませんので、軌道に乗るのは幾分困難です。

我々はGTK+をコンパイルする方法の詳細に入る前に、我々は、オペレーティングシステムのベンダーから、または独立した情報源のいずれかから、多くの場合、ご使用のオペレーティング·システム用のGTK+のビルド済みのバイナリパッケージが利用可能になることを言及する必要があります。パッケージのようなセットが利用可能である場合、それをインストールすることで、GTK+それを自分で構築するよりもはるかに高速でプログラミングされます。実際に、あなたも既にすでにシステムにGTK+をインストールしている場合があります。


UNIX系のシステムでGTK+は、標準GNUビルドシステムを使用しています。
  • autoconfを使用してパッケージ構成と、移植性の問題を解決。
  • automakeはGNUコーディング規約に準拠たメイクファイルのビルド。
  • libtoolはマルチプラットフォームで共有ライブラリをビルド。

あなたは、分散ソースパッケージからGTK+を構築している場合は、これらのツールをインストールする必要がありません。ツールの必要な部分は、すでにソースパッケージに含まれています。しかし、それは、これらのツールを使用しているパッケージはどのように機能するかについて少し知っておくと便利です。ソースパッケージは、次のようなtar.bz2やtar.xz圧縮ファイルにまとめられて配布されます。
tar xvfj gtk+-3.2.0.tar.bz2
tar xvfJ gtk+-3.2.0.tar.xz


作成されたトップレベルディレクトリで、あなたは、パッケージにMakefile.inと呼ばれるテンプレートmakeファイルを取り、お使いのオペレーティングシステム用にカスタマイズされたメイクファイルを作成するために実行するシェルスクリプトと呼ばれる構成があるでしょう。 configureスクリプトは、パッケージをビルドしてインストールする方法を決定するために、さまざまなコマンドライン引数を渡すことができます。最も一般的に有用な引数は、パッケージがインストールされている場所を決定する--prefix引数です。/opt/ gtkにパッケージをインストールするにはconfigureを次のように実行します:

./configure --prefix=/opt/gtk

すべてのオプションのリストは--help引数を指定してconfigureを実行することにより確認できます。一般的に、デフォルトは右であり、信頼されるべきです。 configureを実行した後、makeコマンドでパッケージを構築し、それをインストールすることができます。

make
make install


あなたはあなたがインストールしているディレクトリへの書き込み権限を持っていない場合は、一時的にmake installを実行する前に、ルートに変更する必要があります。またLinuxなどのシステムでシステムディレクトリにインストールしている場合、あなたは後にldconfigを実行新しくインストールされたライブラリが発見されるようにインストールを確認する必要があります。

いくつかの環境変数は、configureを実行する前に設定でパス有効にします。 CPPFLAGSに含まれる内容には Cコンパイラに渡すオプションが含まれており、どのファイルをインクルードするファイルを検索する場所をコンパイラに伝えるために使用されます。 LDFLAGS変数は、リンカーに対し同様の方法で使用されています。最後にPKG_CONFIG_PATH環境変数はデフォルトと異なるライブラリを使用してプログラムをコンパイルする際に、pkg-configがファイルを探すときに使用する(下記参照)検索パス設定が含まれています。あなたはGTK+と、その依存関係のあるファイルを/opt/gtkにインストールしようとする場合、あなたはこれらの変数を次のように設定することをお勧めします:

CPPFLAGS="-I/opt/gtk/include"
LDFLAGS="-L/opt/gtk/lib"
PKG_CONFIG_PATH="/opt/gtk/lib/pkgconfig"
export CPPFLAGS LDFLAGS PKG_CONFIG_PATH


システムのダイナミックリンカが新しくインストールしたライブラリを見つけることができるようにLD_LIBRARY_PATH環境変数をセットする必要がある。

さまざまなライブラリによってインストールされているユーティリティのバイナリが発見されるようにPATH環境プログラムをセットする必要がある。

LD_LIBRARY_PATH="/opt/gtk/lib"
PATH="/opt/gtk/bin:$PATH"
export LD_LIBRARY_PATH PATH


Dependencies(依存関係)

    あなたはGTK+ウィジェットツールキットをコンパイルする前に、あなたのシステムにインストールされ、様々な他のツールやライブラリを持っている必要があります。(上記のGTK+を作成するときに使用されたautoconfのようなツールとは区別される。)

    ビルドプロセス中に必要な2つのツールは、PKG-configとGNU makeです。

    PKG-configはGTK+ライブラリで使用されているライブラリーに必要なコンパイルフラグを追跡するためのツールです。 (各ライブラリーに対し、バージョン番号の情報と共にそのライブラリに必要なコンパイルフラグが含まれている小さな.pcテキストファイルが標準の場所にインストールされています。

    GTK+のmakefileは、ほとんどのmakeの異なるバージョンで動作します、しかし、いくつかの非互換性があるように傾向があるので、GTK+チームはお使いのシステムでそれをインストールして使用していない場合はGNU makeをインストールすることをお薦めします。 (これはmakeではなく、gmakeと呼ばれます。)





    GTK+が依存するライブラリの一部は、GTK+チームによってによって維持されている:GLib、GdkPixbuf、Pango、ATK、GObject Introspection。他のライブラリは、別々に維持されています。

  • GLibライブラリは、高レベルのデータ型、Unicodeの操作、およびCプログラムのオブジェクトと型システムのような非グラフィカルな機能コア提供しています。これは、GTK+のFTPサイトまたはこちらから入手可能です。 

  • GdkPixbufライブラリには、さまざまなファイル形式でイメージをロードするための機能を提供します。それはここにあります。 

  • pangoは国際化されたテキストを処理するためのライブラリです。それはここにあります。 

  • ATKはアクセシビリティツールキットです。これは、スクリーンリーダーなどのアクセシビリティ技術は、グラフィカル·ユーザ·インターフェースと対話することを可能にする一般的なインターフェイスのセットを提供します。それはここにあります。 

  • Gobject Introspectionは、言語バインディングが利用可能なイントロスペクションデータを作成するためのフレームワークです。それはここにあります。


外部依存関係
  • GNU libiconvをライブラリは、あなたのシステムが文字エンコーディング間の変換を行うためのiconv()関数を持っていない場合にGLibをビルドするために必要とされます。最近のほとんどのシステムはiconv()を持っています。 
  • GNU gettextパッケージのlibintlのライブラリはお使いのシステムがメッセージ翻訳データベースを扱うためのgettext()の機能を持っていない場合に必要とされています。 
  • Xウィンドウシステムのライブラリは、PangoのとGTK+を構築するために必要とされています。既にこれらがシステムにインストールされているはずですが、オペレーティングシステムのベンダーが提供するこれらのライブラリのための開発環境をインストールする必要がある可能性があります。 
  • fontconfigのライブラリはフォントの検索と、フォント名と照合するための標準的な方法を含むPangoを提供します。 
  • Cairoは、ベクトルグラフィックスと画像合成をサポートしているグラフィックスライブラリです。 PangoのとGTK+の両方が、それらのグラフィックのためにCairoを使用しています。 
  • libepoxyは異なるOpenGLライブラリ間の違いを抽出するライブラリです。 GTK+は、クロスプラットフォームのGLのサポートのためにそれを使用しています。 
  • Waylandのライブラリは、WaylandのバックエンドとのGTK+をビルドするために必要とされています。 
  • shared-mime-infoパッケージは、GTK+の強い依存関係はありませんが、それはGTK+によって間接的にGIOが使用しているMIMEタイプの定義が含まれています。GDK-pixbufは、MIMEタイプの検出可能な場合にGIOを使用します。これが機能するためには、共有MIME-infoがインストールされる必要があり、XDG_DATA_DIRSはconfigure時に応じて設定。それ以外の場合は、GDK-pixbufは組み込みのMIMEタイプの検出にもどります。

Building and testing GTK+

最初に、必要な外部依存関係がインストールされていることを確認してください: pkg-config、GNU make、JPEGとPNGとTIFFのライブラリ、FreeType、そして必要に応じてlibiconvとlibintl(※これらはCに含まれてる?).
※「jpeg lib」で検索すると、それらしき物が見つかった。他も同様?

これらのパッケージの構築に関する詳細な情報を取得するには、個々のパッケージに付属のマニュアルを参照してください。 Linuxシステムでは、それはあなたがPKG-config設定を除いて、既にインストールされて、これらのすべてを持っている可能性があります。

GTK+ライブラリのビルドとインストールはGLib, Pango, ATK, then GTK+の順で行ってください。

各ライブラリーについては、configure、make、make installの順で上記のインストールしてください。運がよければ、これはすべてスムーズに行き、GTK+アプリケーションのコンパイルを開始する準備ができていますよ。あなたはGTK+をgtk3-demoプログラムを実行して、インストールをテストすることができます。

configureスクリプトの1つに障害が発生したり、実行中のmakeが失敗した場合は、表示されたエラーメッセージをよく見ます。これらは多くの場合、何が悪かったのかについての有益な情報を提供します。configureに失敗した場合、テストコンパイル中のエラーなどの追加の情報がファイルconfig.logの中に書き込まれます。このファイルの最後の100行は何が悪かったのかを明確にします。他のすべてが失敗した場合は、GTKリストメーリングリストで助けを求めることができます。詳細については、Mailing lists and bug reports(3) を参照してください。

Extra Configuration Options

通常のオプションに加えて、GTK+ライブラリのconfigureスクリプトは、追加の引数の数をサポートしています。 (他のGTK+ライブラリのためのコマンドライン引数は、これらのライブラリと一緒に配布資料に記載configure

[ --disable-modules | --enable-modules ] [[--with-included-immodules=MODULE1,MODULE2,...]] [ --enable-debug=[no/minimum/yes] ] [ --disable-Bsymbolic | --enable-Bsymbolic ] [ --disable-xkb | --enable-xkb ] [ --disable-xinerama | --enable-xinerama ] [ --disable-gtk-doc | --enable-gtk-doc ] [ --disable-cups | --enable-cups ] [ --disable-papi | --enable-papi ] [ --enable-xinput | --disable-xinput ] [ --enable-packagekit | --disable-packagekit ] [ --enable-x11-backend | --disable-x11-backend ] [ --enable-win32-backend | --disable-win32-backend ] [ --enable-quartz-backend | --disable-quartz-backend ] [ --enable-broadway-backend | --disable-broadway-backend ] [ --enable-wayland-backend | --disable-wayland-backend ] [ --enable-mir-backend | --disable-mir-backend ] [ --enable-introspection=[no/auto/yes] ] [ --enable-installed-tests | --disable-installed-tests ]

--disable-modules and --enable-modules
通常、GTK+は、要求に応じてロードされているほとんどの共有ライブラリのように入力メソッドモジュールをビルドしようとします。 --disable-モジュール引数は、彼らはすべての代わりにGTK+ライブラリに静的に構築されるべきであることを示しています。これは、静的にリンクされたバイナリを生成するために必要とする人々のために有用です。--disable-modules--enable-modulesも指定されていない場合、configureスクリプトは、共有モジュールがシステム上で動作するかどうかを自動検出しようとします。

--with-included-immodules
このオプションでは、あなたが直接GTK+の共有ライブラリに含めるどの入力方法モジュールを指定することができ、ロード可能なモジュールとしてそれらを構築する場合とは対照的です。

--enable-debug
種々デバッグサポートをオンにします。 'no'に設定するとg_assert()、g_return_if_fail()、g_return_val_if_fail()と異なるオブジェクト型の間のすべてのキャストのチェックが無効になります。「minimum」に設定するとキャストのチェックが無効になります。「yes」に設定すると実行時のデバッグが可能になります。デフォルトの設定は「minimum」です。致命的なクラッシュを含む単純な警告による多くのバグの変化によってほとんどがバグのないソフトウェアであっても不安定にする傾向があります。このように--enable-debug=noはGTK+の安定版リリースには使用しないでください。

--disable-Bsymbolic and --enable-Bsymbolic
彼オプション--disable-Bsymbolicは-Bsymbolic関数リンカーフラグの使用をオフにします。あなたはLD_PRELOADを使って、GTK+の機能をオーバーライドする場合にのみ必要です。

--enable-explicit-deps and --disable-explicit-deps
--enable-explicit-depsが指定されている場合、GTK+は、GTK+に応じてプログラムがリンクされているときPCファイルに依存するライブラリの完全なセットを書き込みます。それ以外の場合は、GTK+はGTK+ライブラリと標準ライブラリのみを参照します。デフォルトでGTK+はシステムが必要としない限り明示的な依存関係を無効にします。(--enable-staticを指定した場合、静的ライブラリの構築の強制、明示的な依存関係が書き込まれライブラリの依存関係は静的ライブラリとして動作しません)--enable-explicit-deps or --enable-staticを指定すると、GTK+のライブラリのバージョンが変更になった時に互換性の問題を引き起こす可能性があるため、可能な限り避ける。

--disable-xkb and --enable-xkb
デフォルトでconfigureスクリプトはXライブラリでサポートされているXKB拡張がGTK+を用いてリンクされているかどうかを自動検出しようとします。
これらのオプションは、明示的にGTK+はXKB拡張をサポートするかどうかを制御するために使用することができます。

--disable-xinerama and --enable-xinerama.  
デフォルトでは、configureスクリプトは、それらが発見された場合のXineramaのライブラリをリンクしようとします。これらのオプションは、明示のXineramaを使用するかどうかを制御するために使用することができます。これらの拡張機能には、グラフィックタブレットなどの入力デバイスに拡張されたインタフェースを提供します。このサポートがでコンパイルされると、特殊なGTK+のプログラムによりサブピクセルの位置、、複数の同時入力デバイスへのアクセス取得、デバイスが提供す圧力や傾きの「軸」を追加。

--disable-gtk-doc and --enable-gtk-doc.
GTK-docパッケージがGTK+に付属のリファレンスドキュメントを生成するために使用されます。それは、様々な追加の依存関係をインストールする必要があるため、GTK-docに関するデフォルトサポートは無効になっています。あなたはGTK-docのがインストールされているとGTK+を変更している場合は、--enable-gtkの-docので渡すことによって、GTK-docのサポートを有効にすることができます。有効になっていない場合は、GTK+と一緒に配布前に生成されたHTMLファイルがインストールされます。

--disable-cups and --enable-cups.  
デフォルトでは、configureスクリプトはカップライブラリが検出された場合のカップ印刷のバックエンドを構築しようとします。これらのオプションは、明示的にカッププリントバックエンドを構築する必要があるかどうかを制御するために用いることができます。

--disable-papi and --enable-papi
デフォルトでは、configureスクリプトは、PAPIライブラリが検出された場合、PAPI印刷のバックエンドを構築しようとします。これらのオプションは、明示的PAPI印刷バックエンドを構築する必要があるかどうかを制御するために用いることができます。

--disable-packagekit and --enable-packagekit
デフォルトでは、configureスクリプトはPackageKitのライブラリが発見されたオープンしてダイアログた場合のためのPackageKitのサポートを構築しようとします。これらのオプションは、明示的PackageKitのサポートを構築する必要があるかどうかを制御するために用いることができます。

--enable-x11-backend, --disable-x11-backend, --enable-win32-backend, --disable-win32-backend, --enable-quartz-backend, --disable-quartz-backend, --enable-broadway-backend, --disable-broadway-backend, --enable-wayland-backend, --disable-wayland-backend --enable-mir-backend, and --disable-mir-backend.
GDKのための特定のバックエンドを有効にします。これらのオプションのいずれも指定されない場合はプラットフォームがWindowsでない限り、x11のバックエンドがその場合、デフォルトは、Win32で、デフォルトで有効になります。いずれかのバックエンドが明示的に有効または無効になっている場合は、他のプラットフォームが自動的に有効にされません。サポートされている他のバックエンドは、OS X用のクォーツのバックエンドであります

--enable-introspection
イントロスペクションのサポートなしで構築します。デフォルトは「自動」です。

--enable-installed-tests or --disable-installed-tests.
システムのテストをインストールするかどうか。有効にした場合、テストとそのデータは、$ {libexecdir}/ GTK+/インストール、テストでインストールされています。試験のためのメタデータは、+{PREFIX}/共有/インストール検定/ GTK$にインストールされます。インストールのテストを実行するには、GNOMEデスクトップテストランナーを使用することができます。
されています。)

オプションの説明は、私にはどう使えばよいかちょっとわからないものが多かった。

ひとまず、インストールを進めていきたい。

以下個別記事に続く。

2015年6月26日金曜日

gccコマンドで引数-lを使ってリンクするときの注意点と、実行ファイルとライブラリの依存関係

例えば、次のような「test.c」というファイルがある場合。
log10(x)はmath.hをインクルードしなければ使えない関数である。

#include <stdio.h>
#include <math.h>

void main() {
    double x = 100;
    x = log10(x);
      printf("%f\n",x);
    return ;
}

これを端末で次のようにコンパイルしようとすると、
gcc -o test test.c
以下のエラーが出て失敗する。
 `log10' に対する定義されていない参照です
これは必要なライブラリとのリンクができなかったために起こる。

なので、引数-lを使って使うライブラリを指定する必要がある。
ここではlibm.aが必要なので次のどちらかのようにしてコンパイルすると、エラーは出ない。
 gcc -o test test.c -lm
 gcc test.c -lm -o test

ただし、順番を変えて次の場合はエラーが出て失敗する。
 gcc -o test -lm test.c
 gcc -lm -o test test.c 
 gcc -lm test.c -o test

一応、オブジェクトファイルを作ってから試してみたが、結果は同じ。
test.cよりも-lmが後に無いとダメらしい。
読み込んだ順番に処理するため、libm.aより後に読み込まれたものは関数が組み込まれないんだとか。(GCCコマンド・オプションのリンク処理用のオプションを参照。)

私のように「引数-lm入れればいいんでしょ〜」ぐらいの感覚で使ってしまうと、ドツボにハマるので気をつけましょう・・・・


ライブラリのことを調べていたら、依存関係を調べるコマンドを発見。
実行ファイルのライブラリの依存関係を調べるにはlddコマンドを利用するらしい。
ldd -v xxxx xxxxは実行ファイルオプション-vは詳細情報の追加
とすることで、リンクしている共有ライブラリを検索できる。

試した結果。
$ ldd test
linux-gate.so.1 =>  (0xb77cd000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xb7771000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75c3000)
/lib/ld-linux.so.2 (0xb77d0000)


意味しているところは、testを実行するにあたり、
linux-gate.so.1
libm.so.6
libc.so.6
/lib/ld-linux.so.2
という共有ライブラリが必要であり、「=>」の後のパスは実際にリンクされたライブラリ。

「リンクさせたのはlibm.aじゃなかったの?」と思ってライブラリの場所を、
 sudo find / -name "libm.a" -ls
で探してみたら
 /usr/lib/i386-linux-gnu/libm.a
にあった。ARアーカイブらしい。
同じディレクトリに共有ライブラリlibm.soのリンクも発見。上記のアドレスはそのリンク元の模様。
何らかの処理でこうなっているのだろうが、よくわからん。

ちなみに、lddでコマンドは/binディレクトリに入って調べると、各コマンドに必要なライブラリを調べることができるようだ。

2015年6月25日木曜日

Netbeansの使い方 新規プロジェクトの作成

C言語の新規プロジェクト作成。
プロジェクトとは複数のソースファイルの集まりのことだが、ここではひとつのソースファイルだけ扱う。

まずは右上にあるアイコンから「新規プロジェクト」を選ぶ。

どの言語を使ったプロジェクトか選択できるので、「C/C++プロジェクト」を選択し、「次へ」。

保存先等を設定。「mainファイルの作成」の右にある選択ダイアログでは「C」を選んでおく。

「終了」を押してプロジェクトが作成された。

プロジェクトツリーにあるソースファイルをダブルクリックすると、「mainファイルの作成」にチェックが入っていたならファイルがひとつあるはず。
これをさらにダブルクリックすると、右側に内容が表示される。

stdio.hとstdlib.hのインクルードと、main関数が記述されている程度。
上のほうにある再生アイコン「プロジェクトを実行」を押すと、すぐに書いたコードがどのように働くか確認できる。

ちょっと動作確認。
そのまま実行してもなにも起こらないので、一文追加して次のようにしてみる。
int main(int argc, char** argv) {
     printf("Hello, world!");
    return (EXIT_SUCCESS);
}
これで実行すると、下にある出力ウィンドに「Hello, world」と表示されて実行が終了するはず。

NetBeansの使い方まとめ

導入編
本体の導入と、コンパイルやデバッグに必要なコマンドのインストールを行う。
統合開発環境(IDE)としてNetbeansを導入する。
NetBeansでビルドに必要なMakeの導入

Netbeansの使い方 新規プロジェクトの作成
記事を書いたら都度追加予定。

2015年6月24日水曜日

C言語のお勉強 プリプロセッサ指令

C言語でインクルードするヘッダーファイルを指定する際
#include <stdio.h>
といったように記述する。

この「#」を含むものはプリプロセッサ指令と呼ばれるもの
ヘッダファイルとプリプロセッサ
注意点として、このプリプロセッサ指令はC言語とは関係のない文なので、末尾に「;」をつける必要はない。

  • #include <xxxx.h>  標準システムディレクトリにあるヘッダファイル
  • #include "xxxx.h"    主に自作ヘッダ等。ディレクトリが異なる場合はパスを指定する。
  • #define xxxx yyyy   xxxxをyyyyに置き換える。
  • #undef xxxx            #define xxxxを無効化。未定義の0となる。
  • #if                            続く条件式を判定。
  • #ifdef xxxx              xxxxが定義されているかを判定し、処理を記述できる。
  • #ifndef xxxx            xxxxが定義されていないかを判定し、処理を記述できる。
  • #elseif                     #if、#ifdef、#ifndefの判定以外でさらに条件を判定。
  • #else                       #if、#ifdef、#ifndef、#elseifの判定がFALSEであった場合の処理。
  • #endif                     #ifdef、#ifndefのブロックの最後を示す。


※補足
#define xxxx yyyyのyyyy部分に簡単な関数を記述することでマクロとして利用できる。
C言語のマクロの基本について
ただし、定義に間違いがないように()の位置には要注意

#define xxxxで終わっている場合は未定義(0)になる。

#if、#ifdef、#ifndefは通常のif構文と同じように比較演算子を使ったり、入れ子構造にしたりすることができる。

#ifでしばしば使われるのが
defined(xxxx) xxxxが定義されているかどうかを判定する。
という演算子。

  • #if defined(xxxx)  #ifdef xxxxと同様。
  • #if !defined(xxxx) #ifndef xxxx同様。

ココらへんの使い分けがあるのかどうかは知らない。

プリプロセッサ指令をデバッグに利用することもできるらしい。
デバッグとプリプロセッサ指令

C言語のお勉強 ヘッダファイルとは?

ヘッダファイルとはなんぞや?

作成するアプリケーションの規模が大きくなるにつれ、コードは複雑になり、保守性も悪化する。
そのため予めサブルーチンを物理的に切り分け、拡張子.hの別のファイルとして(ヘッダファイル)作り、それを呼び出す(インクルードする)ことで保守管理や再利用が容易になる。


その中身はプリプロセッサ指令と、C言語のコードからできていて、インクルードする際に#include<xxxx>部分とそっくり入れ替わる。(C++では異なるらしい?)


ヘッダファイルの作り方

単純なものとしては、元のファイルから関数や変数の定義部分のコードを切り取ってヘッダファイルとして保存しておくだけ。ヘッダファイル自体はコンパイルは不要である。

インクルードすることでその部分が置換されるので、置換後のコード全体で整合性がとれていればOK。
そのためヘッダファイルの内部で関数を利用ていたとしても、その関数に必要なファイルのインクルードは必須ではない。


まだ私にはわからないが、実際の運用ではヘッダは宣言とし、実装部は別に分けるべきらしい。
グローバル変数や関数のプロトタイプ宣言にとどめておくとのこと。
ココらへんはライブラリの仕組みと利用についても勉強しなければいけなさそう。

C言語 (#include)自作ヘッダファイルを使ってみる
ヘッダファイルを作る

ヘッダファイル作成時の注意点

ヘッダファイルは作り方を間違えるとエラーが頻発する。
特に循環参照になってしまうと、デバッグは困難を極める。
インクルードする際は読み込まれる順番(上から)ので、場合によっては考慮する必要があるかもしれない。

ポイントとして

  • 他のヘッダファイルのインクルードを最低限に留める
  • 二重include防止用のインクルードガード
  • 単体でincludeできる
  • グローバル変数をextern宣言する
  • staticな関数やグローバル変数の宣言はできるだけ少なく。


ちなみに自作ヘッダファイルをインクルードするときは、「#include "xxxx.h"」にする。
「< >」で囲むのは、標準ヘッダファイルとのこと。


その7 ヘッダーファイルは慎重に扱わないと危険です
C言語の正しいヘッダファイルの書き方
C初心者が知っておきたいヘッダーファイルとリンクの基礎知識

よく使われていそうな単語


  • struct 構造体を表す。ここでは詳細は省略(構造体タグと構造体変数およびメンバ)
  • typedef xxxx yyyy xxxxをyyyyに置き換える。structと組み合わせてよく使われる。
  • enum 列挙体。詳細は省略。
  • extern 宣言のみを行う。

※#define等は最後に「;」をつける必要は無いが、これらはCのコードなので必要になる。

「宣言」と「定義」は異なる。

  • 宣言 その名前と型が存在することを示す。
  • 定義 実際にその中身を作成する。

といった感じ?

変数は宣言と同時に定義が行われるが、externを頭につけることで宣言のみしか行わない。
宣言は同じ型であれば何度でも行える。
これを利用してファイルを超えて共有されるグローバル変数で使用される。
逆に定義は複数あるとエラーになるため、使用には注意が必要。

分割の定石 
いまさらC言語のexternで悩む
変数にexternをつけるってどういうこと?




コメントの付け方
C, C ++ での書き方



2015年6月23日火曜日

GCCのまとめ

GCCについて
C言語でgccを使ったコンパイル① GCC導入とコンパイル時のエラーについて
C言語でgccを使ったコンパイル② インクルードとリンクについて基礎知識
C言語でgccを使ったコンパイル③ gccコマンドの基本的な使い方
C言語でgccを使ったコンパイル④ pkg-configの利用

gccコマンドで引数-lを使ってリンクするときの注意点と、実行ファイルとライブラリの依存関係


エラーについて
undefined reference to `ほにゃらら'

C言語でgccを使ったコンパイル④ pkg-configの利用

gccコマンドのディレクトリを参照するための引数は直接入力しようとすると非常に長い場合がある。
さらに、環境によって異なる場合がある。

そこで、コマンド置換を利用したpkg-configが便利

例えばgccの引数として利用する場合、以下のようにバッククオートで囲んでやる。
 gcc xxxx.c `pkg-config --cflags --libs gtk+-3.0`
すると、gccコマンドよりも先にバッククオートで囲まれた部分がコマンドライン上で実行され、その結果が置き換わってgccの引数として利用できる。

前回、恐ろしく長い引数だったのが、これだけで済むのは素晴らしい。
NetBeansのようなIDEを利用している場合にもこれを指定するオプションがあるので、利用すると便利。


引数は
--cflags -I(ヘッダファイル)に対応した引数を返す
--libs  -l(ライブラリ)に対応した引数を返す
を意味している。

gtk+-3.0の部分は.pc ファイル名。
pkg-configは予め登録された拡張子.pc ファイルをもとにして情報を返している。
ライブラリによってはpkg-configに対応しておらず、自動的に.pcが作られない場合もあるためすべてのライブラリで使えるわけではない。

私の場合、拡張子.pcのあるディレクトリを
 sudo find / -name "*.pc" -ls
で確認すると、以下のディレクトリの下でが見つかった。
/usr/share/pkgconfig/
/usr/lib/pkgconfig/
/usr/lib/i386-linux-gnu/pkgconfig/



ちなみにgdk-3.0はここだった。
/usr/lib/i386-linux-gnu/pkgconfig/gdk-3.0.pc
中身は以下の通り。
prefix=/usr
exec_prefix=${prefix}
libdir=/usr/lib/i386-linux-gnu
includedir=${prefix}/include
targets=x11 wayland

gtk_binary_version=3.0.0
gtk_host=i686-pc-linux-gnu

Name: GTK+
Description: GTK+ Graphical UI Library
Version: 3.10.8
Requires: gdk-3.0 atk cairo cairo-gobject gdk-pixbuf-2.0 gio-2.0
Requires.private: atk atk-bridge-2.0 pangoft2 gio-unix-2.0
Libs: -L${libdir} -lgtk-3 
Cflags: -I${includedir}/gtk-3.0 

直接.pcファイルを編集したり、環境変数を変更して参照するディレクトリを変更したりといったこともできるらしい。

pkg-config(今日覚えた呪文)

コマンド置換と言われる方法はバッククオートで囲む以外にも
 $(pkg-config --cflags --libs gtk+-3.0)
としても結果は同じ。こちらの方法ではネストできるのが違うところ。

C言語でgccを使ったコンパイル③ gccコマンドの基本的な使い方


詳細な使い方は以下を参照。
コンパイラ(gccコマンド)の使い方

gccの使い方
GCCコマンド・オプション


自分用にまとめてみると基本のパターンは次のようになる。

実行ファイルを作成する
 gcc -o yyyy xxxx1.c xxxx2.c
xxxx1.cとxxxx2.cをコンパイル,リンクして,yyyyという実行ファイルを作成する。
例は2つのファイルだが、1つだけ、あるいは3つ以上も同様。
-o yyyyを省略すると自動的にa.outという実行ファイルになる。

オブジェクトファイルを作成する
 gcc -c xxxx.c
コンパイルしてxxxx.oというオブジェクトファイルを作成する。
実行ファイルを作成する場合とほぼ同様。

オブジェクトファイルをリンクして実行ファイルを作成する。
 gcc -o yyyy xxxx1.o xxxx2.o
xxxx1.oとxxxx2.oをリンクして、yyyy という実行ファイルを作成する。
こちらも上と同様。



インクルードするヘッダファイルの場所を追加
 gcc -I/home/myhome/lib xxxx.c 
ヘッダファイルを探すためのディレクトリを標準システムより先に追加

リンクするライブラリがあるディレクトリとライブラリを追加。
 gcc -L/home/myhome/lib xxxx.c -lzzzz
-Lで標準システムディレクトリに加えて/home/myhome/libをさがし、
-l(小文字のエル)でlibzzzz.aというライブラリとリンクを指定。
ライブラリ名前後の「lib」と「.a」が省略された形となる点に注意。


引数のまとめ
  • -c  コンパイルのみ
  • -o  実行結果のファイル名を-oの直後にくる文字列に指定。
  • -I (大文字のアイ)インクルードするヘッダファイルのあるディレクトリの追加。
  • -L  ライブラリを探すディレクトリを追加。
  • -l (小文字のエル)ライブラリの指定。

他にもあるが、ここでは割愛。
実行ファイルやオブジェクトファイルを作成するのは容易だが、GtkやSDLを利用する場合はヘッダファイルやライブラリが標準システムディレクトリ以外の場所にあるので、その場所を指定しなければならないため、引数がとても長くなる。

例えばSDLでは以下のサイトのサンプルをコンパイルしようとすると、
第268回 SDLで夢のオリジナルゲーム開発
 gcc -o sdltest sdltest.c -lSDL -lSDL_image -lSDL_ttf -lSDL_mixer
のようにディレクトリを複数指定する必要がある。

さらにGTK+3ではヘッダファイルとライブラリを含むディレクトリを調べるための引数はひと通り書き出すと以下の通り。
-I/usr/include/gtk-3.0
-I/usr/include/atk-1.0
-I/usr/include/at-spi2-atk/2.0
-I/usr/include/pango-1.0
-I/usr/include/gio-unix-2.0/
-I/usr/include/cairo
-I/usr/include/gdk-pixbuf-2.0
-I/usr/include/glib-2.0
-I/usr/lib/i386-linux-gnu/glib-2.0/include
-I/usr/include/harfbuzz
-I/usr/include/freetype2
-I/usr/include/pixman-1
-I/usr/include/libpng12
-lgtk-3
-lgdk-3
-latk-1.0
-lgio-2.0
-lpangocairo-1.0
-lgdk_pixbuf-2.0
-lcairo-gobject
-lpango-1.0
-lcairo
-lgobject-2.0
-lglib-2.0
うん、多すぎて扱いきれません。

これを簡単にするための方法は次回。

C言語でgccを使ったコンパイル① GCC導入とコンパイル時のエラーについて

GCCはGNU Compiler Collectionの略らしい。
CやC++、Fortran、Javaといったソースコードで書かれたファイルをコンパイルしてくれる。
おまけに必要な関数を定義したライブラリもついてくる。

コード自体は標準的なテキストファイルでも作成できるけれど、実行ファイルを作るならコンパイラは必要。

導入方法自体はネット上で調べればすぐに見つかるので割愛。
Linuxならソフトウェアセンターとかパッケージマネージャ、あるいは端末上からコマンドでも導入できる。

GNUのコンパイラ群がなんたらかんたらとWikiには書いてある。
GNUコンパイラコレクション
本家本元はこちら
GCC, the GNU Compiler Collection


問題は、実際のコンパイル時に出てくるエラーだ。
これがもうウンザリするほど出てくるんだよね・・・

色々と引数を設定したりする必要があるんだけれど、それもまた初心者にはわかりづらい。
とりあえず、エラーが出て意味がわからなかったらここのサイトが参考になるかもしれない。
http://www.c3.club.kyutech.ac.jp/~Krypton/kit_items/cc_error.html
C3(Composite Computer Club)のホームページ奥深くから見つけたのだが、日本語で説明してくれているので参考になるかも。

一番最初に引っかかったのがリンカーオプションの設定だった。
ココらへんの詳細はまたいつか更新する。かも?

C言語でgccを使ったコンパイル② インクルードとリンクについて基礎知識

GCCは何をしているのか?

作ったコードをコンパイルしてくれるgccというコマンド。

実際にはこのコマンド自体がコンパイルを行っているわけではなく、
内部で他のコマンドを呼び出して処理を行っている。
 gccコマンドは呼び出し屋さん gccコマンドの裏側
 コンパイラは何をしているのか

C言語の場合ではをgccを実行すると
 ccp プリプロセッサ
 cc1 アセンブリコードへ変換(C++ではcc1plus)
 as マシン語へ変換
 ld リンク処理
といった処理を経て実行ファイルが完成。


※コンパイルに使うコマンドでmakeというのもあるが、
こちらはMakefileの情報を素にソースファイルを組み合わせてコンパイルする。
その処理の中にgccのコマンドが利用されていたりする。


最初にC言語の標準ライブラリのみを使った単純なコードを作って遊んでいた時点ではあまり意識していなかった。
しかし、ソースファイルを分割した場合や、Gtk+やSDLといったライブラリを必要とするコードをコンパイルしようとすると少々ややこしくなる。
インクルードとリンクを処理するためにgccのコマンドに長い引数が必要となるからだ。

インクルードとは?

includeは「含める」という意味。
プリプロセッサによってその場に展開されてコードの一部として扱われる。
第27章 インクルード


C言語のコード中では先頭部分に
 #include <stdio.h>
 #include "xxxx.h"
のように書かれており、ヘッダファイルと呼ばれる。
ヘッダファイルには関数や変数の宣言が含まれており、これをインクルードすればそれら関数等を利用できるようになる。(関数の本体は別のファイルであるライブラリに含まれている。)
これにより、よく利用される処理を簡単に何度も使うことができ、ソースファイルの中身もスッキリとさせることができる。

例えば、C言語でよく利用される関数は予めC言語の標準ライブラリに定義されている。
printfやscanfといった文字の入出力を行う関数は予めインクルードしなければ利用することができず、stdio.hをインクルードすることで使えるようになる。

また、gccコマンドで引数なしで参照されるディレクトリは限られているので、それ以外の場所にあるものについては指定する必要がある。


リンク処理とは?

コンパイルされたオブジェクトファイルを組み合わせる処理。
ヘッダファイル中で参照されているライブラリや、分割作成したモジュール等を結合して実行可能なファイルを作る。

コンパイルとリンク
externとモジュール
C言語でヘッダファイルstdio.hのなかに・・・



そんなわけで・・・
自動で認識してくれるディレクトリ以外にあるヘッダファイルをインクルードする場合や、ライブラリをリンクする場合、どこを探せばそれがあるのかをgccに教えてやらなければならない。

実際のコンパイル時の引数は別記事にて。

2015年6月22日月曜日

apt-getとaptitude

ネット上で拾ってきた.debや、.tar.gzを導入したり、フロントエンドのsynapticを利用したりする場合はやることがだいたい決まっているのだが、apt-getの場合は少々知識が必要かもしれない。

大抵のものはこのコマンドでインストールできるが、
ップデートしたからといって最新のソフトであるとは限らない点に注意。
配信元のサイトをチェックすると、より新しいバージョンが配布されていることもある。

apt-getの使い方

apt-getコマンドの解説はこちらを参照。
【 apt-get 】 パッケージを取得してインストール/アップデートする
apt-get - パッケージの操作・管理 - Linuxコマンド
apt-getコマンドのまとめ
不要になったパッケージを削除してくれる、autoremove

実行時にはほとんどの場合で管理者権限が必要なので「sudo」を頭につけること。
aptのデータを更新。
 apt-get update         パッケージリストの更新
 apt-get upgrade               パッケージをアップグレード(ソフトの更新)


パッケージの検索。
 (apt-get install auto-apt) auto-aptを未導入ならまずこれを。
 (auto-apt update)
 auto-apt search xxxx
他にも
 apt-cache search xxxx      依存を含むパッケージ検索
 apt-file search xxxx              探したいファイルやライブラリが含まれているパッケージを検索


実際のインストール
 apt-get install xxxx                xxxx をインストール

アンインストール
 apt-get remove xxxxx               アンインストール(設定ファイルはそのまま)
 apt-get --reinstall install xxxx     アンインストール(設定ファイルも)

不要パッケージ自動除去
 apt-get autoremove
※一度このコマンド実行後、何をしてもデスクトップ上に壁紙以外すべてが表示されなくなったことがあった。要注意かも。

リポジトリの追加
 add-apt-repository ppa:user/ppa-name
     user に該当ユーザー名、ppa-name に該当パッケージ名を指定

※直接編集する場合は
 /etc/apt/soureces.list
あまり追加しすぎてもトラブルの原因となるそうなので、よく調べてから追加したい。

開発環境の導入?
apt-get install build-essentials

ほとんどのソフトのものはapt-getで導入できるが、そうでないものは「/optディレクトリに入れるのが一般的」と、どっかのサイトで見た。そうなの?
ちなみにyumのリポジトリ(Lubuntuデフォルトでは存在しない。)
  /etc/yum.conf





aptitudeの使い方


詳細はこちら

コマンドラインでも使えるがインターフェースもあってこちらのほうが高性能?
引数の意味はapt-getとほぼ同様。

aptitude update
aptitude safe-upgrade    削除なしで更新
aptitude full-upgrade      削除ありの更新

aptitude download xxxxx       .debファイルのダウンロードのみ

aptitude search xxxx                  xxxxを検索
aptitude show xxxx                  xxxxの情報
aptitude install xxxx                   インストール
aptitude remove xxxx              アンインストール(設定ファイルはそのまま)
aptitude purge xxxx                 アンインストール(設定ファイルも)
aptitude reinstall xxxx              再インストール

ログの保存や関連するパッケージの管理を含めるので、利用できるなら利用すべきかも。
aptitudeのログは以下に保存されている。
/var/log/aptitude


2015年6月21日日曜日

NetBeansでビルドに必要なMakeの導入(ついでにデバッガgdbも)

NetBeansを使ってC言語のコードを書いた後、ビルドしようとすると、
コンパイラとmakeコマンドが必須と言われる。


makeコマンドとは?
コンパイラは記述されたコードをコンピュータが実行可能な形にする作業。
そのコードが長くなると、複数のファイルに分割する場合がある。
分割されたファイルを組み合わせるコマンドがmakeであり、その設計図がMakefileと呼ばれるものである。

・・・と私は記憶している。

コンパイラやmakeがない場合、
sudo aptitude install gcc
sudo aptitude install make
(あるいはapt-get install 〜を利用。)
を端末上で実行すればインストールできる。

必須では無いが、デバッガであるgdbも同様にインストールできる。

/usr/bin/にファイルができているので、

それぞれを指定してやれば利用できるようになる。





makeに関して
参照: 79.ソースファイルからのインストール
MAKE入門
【make】コンパイル等の処理を自動的に行う

そのうちmakeについても詳細な記事を書きたい。





ディレクトリ構造の概要

Windwosユーザーの私がかなり困ったことの一つとして、
ディレクトリの構造が全然違うことだった。

ディレクトリとは要はフォルダのことなのだが、
Windowsではドライブがあって、その下にWindows本体や、プログラム、ユーザー毎のフォルダといったように分かれていた。

ところが、Linuxではまずルートと呼ばれる「/」があり、そこに見慣れないディレクトリがたくさんある。
usrを開けばまた同じようなディレクトリが並んでいるし、ルートとは別にrootというディレクトリがあるし、刺したUSBはどこにあるのかわからないし、となにがなんだかさっぱりだった。

そんなわけで、Linuxのディレクトリについて調べてみた。
たくさんあるが、参考にしたのは以下のサイト


詳細はリンク先のサイトにお任せするとして、重要そうなとこだけざっくりとした説明。
 /home ユーザーごとのドキュメントやデスクトップ、音楽等のディレクトリが配置されている。
 /bin  端末で使用できる管理に必要な基本コマンド
 /media USBメモリやCDのようなリムーバルメディアのマウントポイント(/mntは一時的な利用)
 /etc  設定ファイル
 /opt  パッケージ管理システムのインストール用のディレクトリ。
 /lib  基本的なコマンド実行に必要なライブラリ。
 /usr  ユーザーが設定する各種プログラムやライブラリ、設定ファイル等。
    中身の種類は多岐に渡り、とても重要なディレクトリ。

たいていのコマンドやライブラリを追加する場合は/usr以下の適切なディレクトリに入れる。

アプリケーションの場合は場合によって異なるが、
パッケージ管理システムを利用したインストール先として利用するなら/opt/
より簡単な実行ファイル一つ程度(コマンド)なら/usr/local/bin/ 



統合開発環境(IDE)としてNetbeansを導入する。

gccを導入後、最初のうちはテキストエディタでコードを書いてきたが、もっと楽に開発がしたい。

そこで統合開発環境(IDE)の導入を検討する。
メジャーどころはNetbeansEclipseだとか。
拡張性はEclipseのほうが高いらしいが、Netbeansの方が最初から色々と用意されていて便利らしいのでこちらを選択。

導入時に参考にしたのは以下のサイト。

JDK付きのNetBeansもあるのでこれを導入するのが早そう。

実際の導入方法

私が行った方法をまとめておく。ここではJDKとNetBeansは別々に導入している。
JDKがインストールされていないなら先に用意すること。
また、Javaが必要なら、こちらを参照されたし。
Linuxプラットフォーム用の32ビットJava....

インストーラーの実行方法

ダウンロードページから
NetBeans IDE ダウンロードバンドルの「すべて」を選択。

端末上からダウンロードしたディレクトリに入り、
 chmod +x netbeans-8.0.2-linux.sh 
でファイルを実行できるようにしておく。
 ./netbeans-8.0.2-linux.sh 
とすることでインストーラーが起動されるはず。
※この方法だと、/home/ゆーざー以下のディレクトリにしかインストールできないので、
頭にsudoをつけてルート権限で実行しておくと、好きな場所にインストールできる。



JDKをまだ導入していない場合。
このコンピュータでJava SE Development Kit (JDK)が見つかりませんでした
NetBeans IDEをインストールするにはJDK 7が必要です。JDKが正しくインストールされていることを確認し、インストーラをもう一度実行してください。
--javahomeンストーラ引数を使用して、有効なJDKの場所を指定できます。

JDKをダウンロードするには、http://www.oracle.com/technetwork/java/javase/downloadsにアクセスしてください
と、怒られる。その場合は下記を参照。

JDKの導入

こちらを参考にして行った。


まず、こちらから必要なJDKをダウンロード
 Java SE Development Kit 8 Downloads
私の場合、zxvf jdk-8u45-linux-i586.tar.gz というファイル。

/usr/libに好きな名前のディレクトリ(例えば「jvm」)を作って、そこにJDKを放り込んでやる。
パーミッションの関係から端末で行った方が楽そう。

まず、ディレクトリの作成
 sudo mkdir -p /usr/lib/jvm/
ダウンロードしたJDKのアーカイブファイルを移動。
 sudo mv jdk-8u45-linux-i586.tar.gz /usr/lib/jvm
アーカイブファイルの展開。
 sudo tar zxvf jdk-8u45-linux-i586.tar.gz
展開後は不要なので削除してOK。
 sudo rm jdk-8u45-linux-i586.tar.gz


それから再びnetbeans-8.0.2-linux.shを実行すると、インストーラーが起動する。
だめなら引数か環境変数をいじる必要ががるかも?
カスタマイズから必要な機能にチェックを入れれば、ほしい物だけインストール可。

このあとはインストール先のディレクトリや、先ほど用意した使用するJDKのディレクトリを指定するぐらい。

デスクトップ上にアイコンが作成され、これで使用ができるようになったはず。
以降はまた別記事にまとめたいと思う。






※ちなみに、aptitudeコマンドでもnetbeansがヒットしたので
 sudo aptitude install netbeans
を実行してみたところ7.0.1がインストールできた。
最新版ではなかったが、非常に簡単。
インストールして起動までしかやってないので、実用に耐えるかどうかは知らない。
不要なら
 sudo aptitude remove netbeans
で削除できる。

2015年6月19日金曜日

パッケージ管理システムの概要

Linuxではソフトウェアを管理するための仕組みとして「パッケージ管理システム」がある。
パッケージとは、使いたいアプリケーションに必要なソフトやライブラリをひとまとめにしたものである。場合によってはそのパッケージを動かすために別のパッケージが必要になることがあり、そういった依存関係を管理してくれるシステムである。

Windowsでは実行ファイルからプログラムのインストールをするだけで済む場合がほとんどなので、最初は少々違和感。というかものすごく面倒に感じた。


私の使っているLubuntuのようなDebian系ではAPT(Advanced Package Tool)ライブラリを利用するが、RPM(アールピーエム、RPM Package Manager)や、Yum(Yellowdog Updater Modified)という別のパッケージ管理システムを利用しているものもある。

それぞれ参照しているデータベース(リポジトリ)が異なったり、複数あったりといろいろ複雑。
そのうち別記事にしたい。


利用したいソフトがシステムツールのパッケージマネージャーやソフトウェアセンターから利用できる場合はこちらが手軽である。
それ以外の方法として、圧縮ファイルの形式で配布されるものを利用したり、端末上からコマンドを入力してインストールすることもできる。

ネット上で見かける形式としては

  • tar.gz  必要に応じて解凍、コンパイルが必要。特定のディレクトリに置く必要があるものも。
  • tar.bz2  同上。
  • bin  バイナリファイル。
  • deb  Debian系。APTと表示されていることもある?
  • rpm    Red Hat系
  • yum   内部でrpmを呼び出してより高度な機能をもたせたもの。

あたりがよく見る気がする。

それぞれの形式を扱うために必要なコマンド等は以下の通り。

  • tar          アーカイブの取り扱い。tarファイルを展開。
  • chmod   アクセス権の変更。バイナリファイルを実行可能にする。
  • dpkg       debファイルの操作。
  • dselect   Debian系のパッケージの操作。dpkgコマンドのフロントエンド
  • apt-get   Debian系のパッケージの操作
  • aptitude Debian系のパッケージの操作。apt-getのフロントエンドでありより強力。
  • rpm         Red Hat系のパッケージの操作
  • apt-rpm  aptのrpm対応版。
  • synaptic deb以外にもrpmに対応したフロントエンドのパッケージマネージャー。

ざっくりと調べてもこれだけある。
うん。ますます複雑だね〜

2015年6月18日木曜日

Lubuntu導入時にやったこと③ブラウザの設定

Chromeを導入

ブラウザは元からFireFoxがインストールされているが、他のPCでメインで使っている関係もあってChromeを導入。Chromiumより手間がかからなくて良い。

Chromeを導入方法は以下を参照。
Google Chrome のダウンロードとインストール
インストーラーでLinuxでもとても簡単に利用できる。
でも最近はブックマーク管理がますます使いづらくなったので、以前まで使っていたキツネをメイン利用に戻そうかな・・・



Linuxに対応していないサイトのへの対応

ChromeもFireFoxも現在はFlash Playerに対応してくれているのかLinuxでも普通に使える。
Youtube見るために以前はlibflashplayer.soをpluginsフォルダに入れてやらなければいけなかった気がするのだが・・・
Flash Playerの動向に関してはこちらを参照。
第340回 Firefoxで最新バージョンのFlashを使用するには


それよりもプラグイン以外の問題で「ご利用の環境では利用になりません」的な表示が出るサイトを何とかしなければならない。

ユーザーエージェントが問題なら
現時点のChromeなら以下のサイトの方法で一応解決できる。
Google Chromeでユーザエージェントを変更する
設定ツールによる方法もあったのだが、私が使っていたものはアップデートの際に使えなくなった。
また新しいものが出ているのかもしれないけれど、この問題に関してはLinuxの場合、FireFoxの解決法のほうが簡単だ。


FireFoxの場合はアドレスバーに
 about:config
と入力し、general.useragent.overrideの設定値を
 Firefox 32bit Mozilla/5.0 (Windows NT 6.1; rv:37.0) Gecko/20100101 Firefox/37.0
に変更する。(この場合Windows32bitのFireFoxバージョン37.0ですよ〜の意)
この項目がない場合は右クリックから新しく設定値を文字列として作る。
これは一例なので、他のものはユーザーエージェントで探してみるといい。

いい加減、Linuxにも対応してもらいたいもんだ・・・

Lubuntu導入時にやったこと②デフォルトのアプリケーション設定

LXsessionからデフォルト設定ができる。

ファイルマネージャー、ウェブブラウザ、メールソフトといったアプリケーションのほか、
ウィンドウマネージャー、電源管理なども設定ができる。

電源管理の自動起動

動画とか見ていて勝手にモニタが暗くなって困るので、xfce4電源管理はログイン時に自動起動させるようにしたほうが良いと思う。
「Core applications」タブの「Power manager」にxfce4-power-managerを入力。
「Autostart」タブの「電源の管理」にチェックを入れておく。

設定ファイルを直接いじる場合は
「~/.config/lxsession/Lubuntu/desktop.conf」
の内容を変更されたし。

Linuxのインプットメソッドについて

私が使っているLubuntuのインプット メソッド エディタ(IME)は「ibus」と言われるものだが、一体何もの?

ちょっと調べてみることにした。
とりあえずWiki調べ

インプットメソッド

インプットメソッド(IM)は単純に文字を入力するためのソフトウェア。
LubuntuのようなUnix系ではインプットメソッドとして

  • Fcitx
  • iBus
  • IIIMF
  • Maliit SCIM (IMEngines for SCIM)
  • uim
  • XIM
  • gcin
  • Xcin (OXIM)

があるらしい。iBus以外は全然知らなかった。
ibusを検索にかけると、現行のものは1.5.10なのだが、以前の1.4系に比べると批判的な意見が多いらしい・・・
切り替え設定さえイジっておけば私は特に不満は感じないんだけどね。

試しにFcitxを使ってみようと端末から導入しようとしたのだが、ちょっと面倒のようだ。
ソフトウェアセンター等からも導入可。
詳細はこちらを参照。
第297回 Ubuntu 13.10でインプットメソッドFcitxを活用する


インプットメソッドは導入済みなら「言語サポート」から変更できる。



インプット メソッド エディタ

インプット メソッド エディタ(IME)は漢字のようなキーボードから直接入力できないような文字を、入力の組み合わせによって実現するもの。
日本語入力システムとしてのIMEは
  • Anthy 
  • ATOK
  • Baidu
  • IME Canna
  • EGBRIDGE
  • Google 日本語入力(Mozc)
  • Japanist (OAK)
  • Katana
  • かわせみ
  • ことえり
  • Microsoft IME
  • FSKAREN
  • POBox
  • PRIME
  • Sj3
  • SKK
  • Social IME
  • Simeji
  • VJE
  • Wnn
  • WX
と、たくさんあるらしい。
デフォルトのAnthyは変換機能がイマイチな感じ。
しばらく使って入ればそこまで気にならなくなったので学習させればマシになるのかな?


インプットメソッド変更方法に関連することはこちらも参照。
Lubuntu導入時にやったこと①文字入力の設定









2015年6月16日火曜日

Lubuntuでスクリーンショットを便利に利用する

いつもは「Print Screen」キーを押して取り込んでいたのだが、
/home/ユーザー名
のディレクトリに保存されてしまってちょっと不便。
おまけにメニューとかウィンドウ以外の部分が撮りづらい。
そこで便利に利用できるように調べてみた。


「mtPaint」スクリーンショット撮影と同時に編集する

インストールするとデフォルトで入っていたこつは
Windowsのペイントのように手軽で機能豊富で便利っぽい。
スクリーンショットの機能もあって、メニューのアクションから「Time delayed screenshot」を選択すると、一定時間後に撮影して取り込み、すぐに編集できる。

設定からこのアクションのコマンド
 sleep 10; mtpaint -s &
の数値を編集すれば好きなタイミングで撮影ができるようになる。



openboxの設定をいじる。

通常通りキーボードからのスクリーンショットをカスタマイズするにはここを見る。※1
 /home/ユーザー名/.config/openbox/lubuntu-rc.xml
Leafpadでも見づらいけれど編集可。バックアップはちゃんと作っておこう。
PrintScreenキーが反応しない時はキーボードの配列もチェック!


こいつの編集で他のショートカットも変更できるけれど、
今回編集が必要な部分はデフォルトでこんな感じ。

スクリーン全体の撮影。
    <!-- Launch scrot when Print is pressed -->
    <keybind key="Print">
      <action name="Execute">
        <command>lxsession-default screenshot</command>
      </action>
    </keybind>

アクティブウインドウの撮影。
    <!-- Take a screenshot of the current window with scrot when Alt+Print are pressed -->
    <keybind key="A-Print">
      <action name="Execute">
        <command>lxsession-default screenshot window</command>

<keybind key="A-Print">
は押されるキー。
 Shift→S
 Alt→A
 Ctrl→C
 ウィンドウズのロゴキー→W
が省略されているぐらいで、ほかは周りを見ればなんとなく法則がわかると思う。

<command>lxsession-default〜</command>
ここが今回のキモ。
lxsessionでデフォルトに設定されているアプリケーションに対応させている。※2

この<command>〜</command>の中身部分を変えてやることでカスタマイズできる。
例えば・・・
scrot -e 'mv $f ~/PrintScreen/'
 ユーザーディレクトリのPrintScreenディレクトリ内に保存される。
scrot -u -e 'mv $f /home/ユーザー名/PrintScreen/'
 こちらはウィンドウの撮影。フルパスで指定した場合。

ちなみこちらはダメだった。
 sleep 10; scrot -e 'mv $f ~/PrintScreen/'
端末上で実行すると正常に動くけれど、コマンドタグ内に入れると反応しない。なんで? 


あとは一度ログアウトしてから設定したキーを試してみよう。

※1ドットで始まる隠しファイルの表示切り替えはウィンドウの表示から設定できるが、
キーボードのCtrl+Hが早い。
※2スクリーンショットマネージャーを導入していないので、scrotコマンドが設定されていた。ココらへんは他のディストリビューションでは異なるかもしれないので、コマンドの有無や引数のチェックが必要かも。


参考にしたサイトはこちら。

mtPaintの利用
パソコンユーザのつぶやき
キーや保存先のカスタマイズ
Lubuntu でスクリーンショットを撮る
xfce4-screenshooterの導入
lubuntuでのスクリーンショット
~/.config/openbox/rc.xmlに関する説明。
Help:Bindings

Lubuntuでパスワードが分からなくなった時は

一度、なにかの設定をしていたときに変更したパスワードが分からなくなったことがあった。
そんな場合、ユーザーごとにパスワードをリセットする方法がある。

どこから仕入れた情報だったか忘れてしまったが、
手元のメモによると以下のとおり。

起動時に「esc」を連打してリカバリモードで起動。
メニューに「root」的なものがあるので、それを選択。
コマンド入力で
 passwd ユーザー名
 新しいパスワード
 新しいパスワード
成功したら
reboot
と入力して再起動すればでOK!!
これで新しく設定したパスワードで操作が出きるようになるはず。

Lubuntu導入時にやったこと①文字入力の設定

Lubuntuの導入までは落ちてるイメージを光学ディスクに焼いて、それを起動すれば後は指示どおり。
ちなみに私のは14.04.1-UbuntuカーネルのLubuntu

インストールに関する情報はたくさんあるので、パーテーションの設定とかしない限りは面倒なことは特にないと思う。


インストール後、とりあえず一番最初に問題になったことは

日本語入力ができない


Windowsでは最初から簡単なのに、Lubuntuでは全角半角ボタンを押してもダメ。

そんな場合はまずメニューバー右下にあるキーボードマーク(IBusというアプリケーション)をクリックして「日本語-Japanese」ではなく「日本語-Anthy」を選ぶとマークが変わってAnthyが有効になる。この時点で全角半角の切り替えが有効になるはず。
このAnthyへの切り替えはCtrl+スペースキーでも可能。




インプットメソッドの切り替え方法

Ctrl+スペースとか表示を右クリックするのが嫌ならキーの設定を変更するとよい。

今いじったアイコン(IBus)を右クリックして出てくるメニューの「設定」を選ぶか、
右下の「Lubuntuのロゴ」 – [ 設定 ] – [ キーボード・インプットメソッド ]を選ぶと、
IBusの設定画面になる。



  • 全般タブのキーボードショートカットの「次のインプットメソッド」の右にある「・・・」ボタンをクリック
  • キーコードの右にある「・・・」をクリック。
  • 表示されるリストで「無効」を選択。すると、「新しいアクセラレータ」に表示が変わる。
  • ここで任意のキーを押して変更を適用する。

これでインプットメソッドの切り替え好きなキーに変更できたはず。

ちなみに私は、通常の全角半角の切り替えはそのまま使うので、
インプットメソッドの切り替えは「Ctrl+全角半角」にした。


Mozcの導入

Anthyが使い辛くてイヤな人は別のインプットメソッドも用意されているので、調べてみると好みのものが見つかるかも?
人気が高いのはMozcらしい。インストールの方法はいくつかあるけれど、端末(ターミナル)に抵抗がないならこれを利用すると早い。

ちなみに利用する端末のおすすめはメニューのアクセサリにあるLXTerminalだ。
マウス操作の右クリックでコピペもできるので利用しやすい。


打ち込むコマンドはこれだけ。
 sudo apt-get install ibus-mozc

どうしてもAnthyが存在するのが許せないなら
 sudo apt-get purge ibus-anthy
で設定ファイルも含めてアンインストールもできる。
このapt-getについてはまたそのうち。


その後は

  • インプットメソッドタブの「アクティブな入力メソッドのカスタマイズ」にチェック
  • 「インプットメソッド」の選択で「日本語」を選び、「Mozc」を追加
  • もし、Mozcが選択できないなら、一度ログアウトしてみる


これで先ほどのインプットメソッドの切り替えと同じ操作で使えるようになっているはず。
また、インプットメソッドタブまたは右下のアイコンからそれぞれの詳細設定もできる。

そもそものキーボード配列がおかしい場合

初期設定でミスったなどで、キーボードに表示された文字と画面に表示される文字が違うときは右下の「JP」と表示されているアイコンを右クリックすると、「キーボード配列の設定」という項目があるので、こちらを選択して「keep system layouts」のチェックを外すとキーボード配列を追加できるようになる。ここから変更すると治るかも?



これで文字入力が使いやすくなった。
それでもブラウザ上とかで切り替えがたまにうまく行かなかったりするのは謎。
インプットメソッドについてはこちらも参照。
Linuxのインプットメソッドについて

2015年6月15日月曜日

GTKでドロップを設定する。

ブログを書き始めた時点で詰まっていること。
それはGTKでのドラッグアンドドロップだ。

ドロップしてシグナルを発生させることはできるのだけれども、
肝心のドロップしたファイルのデータを取り出せない・・・



今のところここのサイトで勉強中。
 入門GTK+(PDF)
 GTK+でdrag and drop
    Drag and Dropリファレンス

詳細はこれらのサイトにお任せするとして、大まかに言えばドロップ側に必要なことは

  1. 受け入れるデータ型をGtkTargetEntry構造体型で宣言しておく。
  2. gtk_signal_connect()やgtk_builder_connect_signals()でシグナルを準備。
  3. gtk_drag_dest_set()でウィジェットにドロップができるようにする。
  4. 各種シグナルごとの動作を設定。

とのこと。

1〜3まではOK。
4もシグナルを発生させることはできるけれども、データを取り出そうとすると

 g_print("data->target = %s\n" , gdk_atom_name( data->target)) ;

の部分で下記のエラーが発生。

 error: dereferencing pointer to incomplete type

ポインタ参照時に型が不一致ということらしい。
名前が間違っているとか、インクルード不足とかが主な原因だとか。

自分のコードを色々と調べては見たものの、イマイチどこに問題があるのかわからなかった。

んが、よくよく考えてみるとリンカーオプションがマズかったかもしれない。
と、いうのも今まで参考にしてきたサイトはGTK+のバージョンが現行のものより古いのだ。

そんなわけで
`pkg-config --cflags --libs gtk+-3.0 gmodule-2.0`
から
`pkg-config --cflags --libs gtk+-2.0 gmodule-2.0`
に変更したところ・・・

エラー無しでビルドが通るではないか!
実行するとこれとはまた別の問題ですんなり動いてくれないのだが、
こうゆうパターンだと気づくまでにまる1日かかってしまった・・・

結局、GTKのバージョンの問題だったのか?
ここまでの経緯は以下のとおり。


GTKのドロップの設定をしていると、受け入れるデータの設定をするのに
GtkTargetEntryという型の構造体の配列を作る必要がある・・・らしい。


リファレンスはたぶんコチラ↓にあるの内容。
 Selections

プロセス間のデータのやりとりのための関数に関係するらしい。

これによると定義は以下の通り。
struct GtkTargetEntry {
    gchar *target;    ←?
    guint  flags;       ←GtkTargetFlags列挙体のメンバから選択する。
    guint  info;     ←後でシグナルハンドラに渡される任意の値。
};


targetの部分はmime型で受け入れ可能な形式を書き込むことになっているらしいが、
リファレンスを見ると、mimeという単語が出てこない。
ちなみにmimeとは
MIME の基礎
拡張子とMIMEタイプ
Multipurpose Internet Mail Extensions


GDK3のDrag and Dropリファレンス
GTK+3のDrag and Dropリファレンス

よくわからないので、改めてGTK+3のdrag-data-receivedシグナルを調査する。
なんか今までとやってきたのとちょっと違う気がする・・・・
GtkTargetListを使っているところとか。

ちなみに
GTK+2のdrag-data-receivedシグナル
・・・うーん。

サンプルコードがあったので、シグナルのコールバックに置き換えて実行してみると、
どのみちerror: dereferencing pointer to incomplete typeのエラーが出る。
結局ふりだしに戻るw

きっと何かしらのファイルが足りないんだろな〜

コールバックの引数を調べていると
oid cb_drag_data_received(GtkWidget *widget,
        GdkDragContext *context,
        gint x,
        gint y,
        GtkSelectionData *data,
        guint info,
        guint time_,
        gpointer user_data) {
    gboolean result = FALSE;
    gboolean delete = FALSE;

GtkSelectionData *data
がうまく読みとれていない。
gtkwidget.hを確認すると、
typedef struct _GtkSelectionData   GtkSelectionData;
となっており、さらにgtkselection.hで
struct _GtkSelectionData
{
  GdkAtom       GSEAL (selection);
  GdkAtom       GSEAL (target);
  GdkAtom       GSEAL (type);
  gint          GSEAL (format);
  guchar       *GSEAL (data);
  gint          GSEAL (length);
  GdkDisplay   *GSEAL (display);

};
であった。

試しにコード内で直接このGtkSelectionData構造体をコールバックの直前で宣言してみると、
エラーのもとになっているのはGSEALという関数のようだ。
struct _GtkSelectionData
{
  GdkAtom       GSEAL (selection);
  GdkAtom       GSEAL (target);
  GdkAtom       GSEAL (type);
  gint          GSEAL (format);
  guchar       *GSEAL (data);
  gint          GSEAL (length);
  GdkDisplay   *GSEAL (display);

};

さらに下記のように書きなおしてみる。
typedef struct _GtkSelectionData   GtkSelectionData;
struct _GtkSelectionData

{
  GdkAtom       selection;
  GdkAtom       target;
  GdkAtom       type;
  gint         format;
  guchar       *data;
  gint         length;
  GdkDisplay   *display;
};

これだとエラーが起こらずにコンパイルできて実行にも問題がなかった。

それではGSEALとはなんぞや?
gtkconfig.hでは
/* gdkconfig.h
 *
 * This is a generated file.  Please modify `configure.in'
 */
.
.
.

define GSEAL(ident)      ident
.
.
.

となっている。

構造体を隠すためのマクロらしいのだが、それよりも
This is a generated file.  Please modify `configure.in'の一文が気になる。
つまりは`configure.in'を修正しろとのこと。




2015年6月14日日曜日

Lubuntuってどんなもん?

今まで特に気にしてなかったけれど、改めてLinuxについて。

ディストリビューションが選ぶのに困るほど色々あるので幾つか試したことがある。
何年も前だが、例えば
  • Puppy
  • CentOS
  • KNOPPIX
  • Ubuntu
  • Xubuntu
  • Lubuntu
といったところ。

もともとWindowsばかりだったので、一番使いやすいのはUbuntuだったけれど、
このPCが非力すぎて結局Lubunutに落ち着くことになった。

ほんじゃ、Lubuntuとは?
とりあえずWikiでLinuxの中ではどのようなものなのか調べてみる。
LinuxディストリビューションDebian GNUベースのUbuntuの派生系がLubuntuとのこと。

Ubuntuのデスクトップ環境がUnity(以前はGNOME)に対し、LubuntuはLXDEを使用しているのが違い。

Unix系のデスクトップ環境はX Window Systemを共通して使用していて、
高スペックなGNOMEKDEが主流であり、軽量なXfceやLXDEは新しい部類にあたる。

LXDEのウィジェット・ツールキットはGNOMEやXfceと同じGTK+だったが、現行の3は評判が悪いようで
今後はKDEと同じQtに移行する予定らしい。

とりあえずC言語の勉強の一環としてGTK+はやってるけれど、あんまり深入りしないほうがいいのか?




undefined reference to `ほにゃらら'


GCCを使ってC言語のソースファイルをコンパイルした時に出るエラーの一つに

undefined reference to `ほにゃらら'(`ほにゃらら'に対する定義されていない参照です)

と出る場合がある。



使用した`ほにゃらら'という関数の定義が見つからないということなので、疑われるのは

  • 関数名の打ち間違い
  • インクルードするファイルが足りない

といったところ。


SDLを導入したばかりの頃、インクルードの仕組みや、コンパイルを全然理解していなかったので、
ネット上に落ちていたSDLを使ったコードを適当にコンパイルしようとして軽くハマった。


SDLやGTK+といったライブラリを利用したコードをコンパイルするには
それらをインストールするだけでなく、GCCのコマンドでオプションを設定してやる必要があるのだ。

例えばSDLならこんな感じで。
 gcc -o SDLtest SDLtest.c -lSDL -lSDL_image -lSDL_ttf -lSDL_mixer

詳細はまた追加するかも。

LinuxでC言語を始める

いきなりプログラミングをやろうと思っても、最初はどうすればよくわからんかった。

まず、一言にプログラミングといっても言語はいろいろあるし、どれがいいのか悩みどころだ。
「プログラミング」とググっただけでもいろんな情報があるしね。

とりあえずはC言語は押さえて損はなさそうだから、というのが選んだ理由だったりする。
(ちなみにWindowsのPCでも同じような理由でVBも同時進行で勉強中)



と、いうことで本題。

LinuxPCでC言語を扱うにはどうすればよいか?

はい、ド素人だったのでそんなことも知りませんでしたw

コード自体はテキストエディタ(LeafPadとかメモ帳)で全然OK
入門サイトあたりから簡単なものをコピペすればそれだけで完成。
viエディタとかいろいろあるけれど、貼り付けるだけなら無くても大丈夫。
C言語のソースファイルなら拡張子を「.c」にするのが習わし?


それでは

それをどうやって実行するのか?

そのためには作ったコードをPCに理解できるように変換するコンパイル作業が必要。
(厳密にはリンクも必要。)
そのための代表的なコンパイラがGCCである。


インストール方法などはググればすぐに出てくる。
ざっくり説明してくれているのがこのサイト↓
LinuxでC言語 - コンパイラ(gcc)のインストール
C言語の優しいコードもあります。

私の場合は端末から以下のコード。
 sudo apt-get install gcc
コマンドを使わなくてもパッケージマネージャかなんかでもあった気がする。
インストールが済めば、このコマンドでコンパイルしてから実行すればOK!



実際のコンパイルと実行は

端末上で「cd」コマンドなんかを駆使して作ったソースファイルがあるディレクトリまで移動。
そこまで辿り着いたら例えばそのファイルが「test.c」なら、
 gcc test.c 
と端末上で入力。すると同じディレクトリに「a.out」というファイルができるので、端末から
  /a.out 
と、入力すると、内容が実行される。


んが、単純なコードでもエラーが起こる場合がある!
特にまるごとコピペせずに一部だけとか、最初は練習だと思って手打ちした場合とかにね〜
よくやらかしたのは

  • 全角文字(スペースを含む)がある場合。
  • カッコやダブルクォートのとじ忘れ。
  • 最後のセミコロンのつけ忘れ。
  • スペルミス

といったところ。
警告だけで済む場合もあるけれど、コンパイルできないときはよく確認。

ココらへんのやさしいお話はコチラを参照
C言語プログラミングの初歩




2015年6月13日土曜日

このブログについて

個人的ないろいろ忘備録。
作った時点ではとりあえずプログラミングに関して投稿する予定。

私はExcelでVBAを利用したり、Accessでちょっとしたデータベースを作ったことはあるけれど、
プログラミングに関しては専門的に勉強したことが無いド素人である。

現在、VBとC言語についてなんとなく勉強中。
いろいろ調べていくうちにこんがらがってきたので、まとめのつもりで記録していくつもり。

一般的な情報は巷にあふれているので割愛して
ド素人の私が引っかかった部分を解説していこうと思う。

間違った内容があっても知りません。
・・・というか間違っていたらぜひ教えてください。お願いします!

ちなみに以下のようなものを使っています。
 GCC(コンパイラ)
    Glade(インターフェースデザイナ)
 NetBeans(統合開発環境)
 GTK(ウィジェット・ツールキット)

 anjuta(統合開発環境)※以前使ったけれど、動きがおかしくてやめた。
 SDL(マルチメディアライブラリ)※挫折中


ブログの編集は主にgoogleドキュメントで書きためたものを貼り付けて編集しているのだが、書体が崩れて扱いづらい・・・

GTKでファイルを表示するTreeを作ってみた

練習がてらに調べてつなぎあわせて作ったコードを公開してみる。
LinuxPCでhomeディレクトリを表示し、クリックするたびにその中身を読み込んでツリーを作ってゆく。

表示するウィジェットの設定はめんどいのでgladeを利用している。

ドラッグアンドドロップやダブルクリックした際のイベントは設定していないので、
ただディレクトリを表示するだけだが、色々と苦労した・・・

以下のmain.cと、glade_test_tree.gladeをメモ帳かなんかでテキトーに作成し、
ファイルのあるディレクトリに入ってコンパイルすれば行けるはず。
なお、画像ファイルとしてfolder.icoとdocument.icoもテキトーに用意して同じディレクトリに入れておく。

アイコン探すならここが便利かも。
iconizer.net

コンパイル次のコマンド
gcc -o test main.c `pkg-config --cflags --libs gtk+-3.0 gmodule-2.0`


main.cの中身。

#include <gtk/gtk.h>
#include<glade/glade.h>//gladeXMLから名前を引用できるようになったりする。
#include <glib.h>
#include <glib/gprintf.h>
#include <stdio.h>

GtkBuilder *builder; //

enum//カラムに設定する項目を列挙。N_COLUMNSは順番で2が割り当てられる。
{
    COLUMN_ICON, //0
    COLUMN_LABEL, //1
    COLUMN_IS_DIR, //2
    COLUMN_FULL_PATH, //3
    N_COLUMNS//4
};

typedef struct _TreeData TreeData;

struct _TreeData {
    gchar *label;
    gboolean isdir;
    gchar *fullpath;
};

static gint sort_func(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data) {//ソート用の関数。ちょっとよくわからん。
    gboolean is_dir_a, is_dir_b;
    gchar *name_a, *name_b;
    int result;

    gtk_tree_model_get(model, a,
            COLUMN_IS_DIR, &is_dir_a,
            COLUMN_LABEL, &name_a, -1);
    gtk_tree_model_get(model, b,
            COLUMN_IS_DIR, &is_dir_b,
            COLUMN_LABEL, &name_b, -1);
    if (!is_dir_a && is_dir_b) {
        result = 1;
    } else if (is_dir_a && !is_dir_b) {
        result = -1;
    } else {
        result = g_utf8_collate(name_a, name_b);
    }
    return result;
}

static void add_data(gchar *myDir, GtkTreeIter *parent) {
    GDir *dire;
    gchar *path;
    GtkTreeStore *store;
    store = (GtkTreeStore*) gtk_builder_get_object(builder, "treestore1");
    //gtk_tree_store_clear(store);
    GdkPixbuf *folder_pixbuf = gdk_pixbuf_new_from_file("folder.ico", NULL);
    GdkPixbuf *file_pixbuf = gdk_pixbuf_new_from_file("document.ico", NULL);

    //標準ソート関数の設定 よくわからん
    gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store), sort_func, NULL, NULL);
    //ソートに使用する項目の設定 よくわからん
    gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);


    GtkTreeIter iter; //構造体
    dire = g_dir_open(myDir, 0, NULL); //ディレクトリを開く
    if (!dire) return;
    if (dire) {
        const gchar *name;
        gboolean is_dir;
        while (name = g_dir_read_name(dire)) {
            if (name[0] != '.') {//位置文字目がドットの場合を除く(隠しファイルの除外
                path = g_build_filename(myDir, name, NULL); //ファイル名用のメモリ領域を確保した上で、ファイル名にパスを追加する
                is_dir = g_file_test(path, G_FILE_TEST_IS_DIR); //ディレクトリかどうかを調べている。
                gtk_tree_store_append(store, &iter, parent); //一番上のトップレベルなので、親を表す引数(3番目)はNULL
                gtk_tree_store_set(store, &iter,
                        COLUMN_ICON, (is_dir) ? folder_pixbuf : file_pixbuf,
                        COLUMN_LABEL, g_filename_to_utf8(name, -1, NULL, NULL, NULL),
                        COLUMN_IS_DIR, is_dir,
                        COLUMN_FULL_PATH, path,
                        -1); //トップレベルのアイコンとラベルの追加
                g_free(path);
            }
        }
    }
    g_dir_close(dire);
    g_object_unref(folder_pixbuf);
    g_object_unref(file_pixbuf);
}

gboolean cb_quit_dialog(GtkWidget *widget, gpointer user_data) {
    GtkWidget *dialog;
    gint result;
    //YESかNOを選択するダイアログを表示
    dialog = gtk_message_dialog_new(GTK_WINDOW(widget), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
            "終了します。\nよろしいですか?");
    result = gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
    //YESを選択した場合
    if (result == GTK_RESPONSE_YES) {
        //destroyシグナルが発生(指定したcb_destroy関数へ)
        gtk_main_quit();
        return FALSE;
    }//NOを選択した場合
    else {
        //何も発生しない
        return TRUE;
    }
}

void cb_tree_add(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data) {
    GtkTreeStore *store;
    GtkTreeIter parent_iter;
    gchar *name;
    gchar *mypath;
    gboolean *mydir;
    gboolean has_child;
    store = GTK_TREE_STORE(gtk_tree_view_get_model(tree_view));
    //store = (GtkTreeStore*) gtk_builder_get_object(builder, "treestore1");
    //クリックされたアイテムに対するGtkTreeIterの値を取得
    gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &parent_iter, path); //pathに対応するiterの確認
    gtk_tree_model_get(GTK_TREE_MODEL(store), &parent_iter, COLUMN_LABEL, &name, COLUMN_FULL_PATH, &mypath, COLUMN_IS_DIR, &mydir, -1); //iterに格納されている値を取り出す。
    if (&mydir) {
        has_child = gtk_tree_model_iter_has_child(GTK_TREE_MODEL(store), &parent_iter); //子があるかどうかのチェック
        if (!has_child) add_data(mypath, &parent_iter); //選択したものがディレクトリかつ、子が無いならツリーを追加
    }
    g_free(name);
    g_free(mypath);
    //g_free(mydir);
}


int main(int argc, char** argv) {
    GtkWidget *window;
    //GtkWidget *treeview;
    /* Gtkの初期化*/
    gtk_init(&argc, &argv);
    /* GtkBuilder作成 */
    builder = gtk_builder_new();
    /* gladeファイルの読み込み */
    gtk_builder_add_from_file(builder, "glade_test_tree.glade", NULL);
    //シグナル設定した関数を有効にする。
    gtk_builder_connect_signals(builder, NULL);
    add_data("/home", NULL);
    /* window1のオブジェクト取得 */
    window = (GtkWidget*) gtk_builder_get_object(builder, "window1");

    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}


glade_test_tree.gladeの中身。

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<interface>
  <requires lib="gtk+" version="3.10"/>
  <object class="GtkTreeStore" id="treestore1">
    <columns>
      <!-- column-name icon -->
      <column type="GdkPixbuf"/>
      <!-- column-name gchararray1 -->
      <column type="gchararray"/>
      <!-- column-name is_dir -->
      <column type="gboolean"/>
      <!-- column-name fullpass -->
      <column type="gchararray"/>
    </columns>
  </object>
  <object class="GtkWindow" id="window1">
    <property name="can_focus">False</property>
    <property name="default_width">200</property>
    <property name="default_height">500</property>
    <signal name="delete-event" handler="cb_quit_dialog" swapped="no"/>
    <child>
      <object class="GtkScrolledWindow" id="scrolledwindow1">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="shadow_type">in</property>
        <child>
          <object class="GtkTreeView" id="treeview1">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="vscroll_policy">natural</property>
            <property name="model">treestore1</property>
            <property name="search_column">1</property>
            <property name="hover_expand">True</property>
            <property name="level_indentation">15</property>
            <property name="enable_tree_lines">True</property>
            <property name="activate_on_single_click">True</property>
            <signal name="drag-data-received" handler="cb_drag_data_received" swapped="no"/>
            <signal name="row-activated" handler="cb_tree_add" object="treestore1" swapped="no"/>
            <child internal-child="selection">
              <object class="GtkTreeSelection" id="treeview-selection"/>
            </child>
            <child>
              <object class="GtkTreeViewColumn" id="treeviewcolumn2">
                <property name="title" translatable="yes">ファイル</property>
                <property name="alignment">8.9406970715799616e-10</property>
                <property name="reorderable">True</property>
                <property name="sort_indicator">True</property>
                <property name="sort_column_id">1</property>
                <child>
                  <object class="GtkCellRendererPixbuf" id="cellrendererpixbuf2"/>
                  <attributes>
                    <attribute name="pixbuf">0</attribute>
                  </attributes>
                </child>
                <child>
                  <object class="GtkCellRendererText" id="cellrenderertext2"/>
                  <attributes>
                    <attribute name="text">1</attribute>
                  </attributes>
                </child>
              </object>
            </child>
          </object>
        </child>
      </object>
    </child>
  </object>
</interface>