2013年12月22日日曜日

新規HDDにFedora20のインストール

Fedora20が2013年12月17日にリリースされました。HDDに新規にインストールする方法について書きます。Fedoraに関わらず、OSのインストール作業で行うのは以下です。
  1. PCの準備
  2. DVDイメージのダウンロード
  3. DVDイメージをDVDに書き込み
  4. PCをDVDから起動する
  5. インストーラに従ってインストールを行う
  6. ログインしてユーザーの設定
  7. アップデート

1.PCの準備


人によってどのようにPCの準備をするかは違うと思いますが、私は大抵は新しいHDDを買ってきて、 新しいHDDにインストールすることにしています。インストール後にデータを移行します。利点は間違って前のデータを消すことが無いこと、古いHDDがバックアップになることです。欠点はデータ移行で問題が出ることがあること、アプリの再インストールが必要なことです。

2.DVDイメージのダウンロード


Fedoraのホームページから、DVDイメージがダウンロードできます。私の場合はここから、デスクトップLIVEメディアでなく、インストールメディアでDVDをダウンロードしてインストールしています。色々とありますが、x86_64-インストールDVDの直接ダウンロードで良いと思います。Fedora-20-x86_64-DVD.isoがダウンロードされます。

3.DVDイメージをDVDに書き込み


DVD-Rメディアを準備して、DVD-Rにに書き込みします。Fedoraを使っている場合には、Braseroというソフトで、isoファイルを選択してイメージの書き込みをすれば良いです。Windowsは7や8では標準で対応しているので、エクスプローラでisoファイルを右クリックして、ディスクイメージの作成で、書き込みが出来ます。WindowsXPの場合はDeepBurnerなどのフリーソフトでも書き込みができます。

4.PCをDVDから起動する


HDDが空であれば、DVDドライブに3で書き込んだDVD-Rメディアを入れてPCを起動すれば、DVD-Rから起動するはずです。起動しない場合はBIOS画面を起動して、DVDドライブから起動するようにします。

BIOS画面はPCによって起動の仕方や、表示画面、設定の仕方がまちまちです。起動はPC起動時にDELキーやF1キーやESCキーなどを押す場合が多いです。一瞬画面に表示されることもあるので、それを参照してください。

起動後はカーソルキーなどで「Boot」のような名称のメニューを見つけてDVDドライブの優先度をあげてください。

最近はUEFIやFastBootなど仕様が複雑で一番の難関かもしれません。x86_64-インストールDVDはUEFIに対応しているので、DVDドライブが起動メニューに2つ出てきてUEFIが選択できるのであれば、そちらの方がいいです。

5.インストーラに従ってインストールを行う


ここからFedora独自です。FedoraではAnacondaというインストーラを使っているのですが、Fedora18からかなり変わりました。細かい設定をしないのであれば、Windowsなどと比べてもかなり簡単にインストールできると思います。

起動直後の画面、2番目がデフォルトで選択されていますが、Testは遅いので1番目のInstallを選択した方がいいです。



色々と画面に表示された後に、言語選択の画面。もちろん日本語にします。VirtualBox上だと最初から日本語になっていてびっくり。


以下の画面で!マークを無くせばイントールができます。「インストール先」のみ設定すれば良いです。



インストール先を選択する以下の画面になります。インストールするHDDにチェックが入っていることを確認して、左上の「完了」を押します。


 インストールのオプションを設定します。パーティションスキーマはLVMがデフォルトになっていますが、私は標準パーティションを使います。LVMや暗号化はHDDのデータの移行時に面倒が多いためです。選択後「続行」します。


せっかくのDVDからのインストールなので、ソフトウェアの選択でいくつかのソフトウェアを選択した方が良いかもしれません。私は開発系は入れるようにしています。


!マークが全て無くなったら、右下の「インストールの開始」でインストールが始まります。インストールをしながらユーザーの設定をします。ユーザーの設定は右側の「ユーザーの作成」だけで良いです。


「ユーザーの作成」では、ユーザー名とパスワードを入れます。管理者にするチェックとパスワードが必要であるチェックを入れます。左上の「完了」で元の画面に戻ります。


後は時間がかかりますが、インストールが終わるのを待ち、終了したらDVDを抜き、再起動します。


6.ログインしてユーザーの設定


ログインしてユーザーの設定をします。

ログイン画面でユーザーを選択してパスワードを入れます。


色々と設定を聞いてきますが、右上の「次へ」で進んでいけばいいです。





最後にGNOMEの使い方のヘルプが出て終了です。Linuxでは画面表示や設定の仕方などをかなり柔軟に変更できます。デスクトップ環境などといいますが、GNOMEというのはその一種でFedoraのデフォルトです。インストール時に選択できますし、後から追加することも可能です。


7.アップデート


Windowsでもそうですが、インストーラが出来た後にセキュリティなどに見つかった修正がたくさんあるはずなので、アップデートをした方が良いです。Fedoraでは、コマンドラインのyumを使うのが便利です。

まずは、端末を起動します。スーパーキー(Windowsキー)を押して、「term」と打つと、端末が出てくるので、選択します。


端末が起動できたら、

sudo yum update

と入力し、Enterキーを押します。


アップデートが開始されます。


まずは、ここまで。

2013年12月21日土曜日

SIMフリー時代に突入? Nexus5で節約

Nexus5が出たことでやっとSIMフリーの環境が整ってきたような気がしますね。これでdocomo, Au, Softbankなどのキャリアに高い通信費を払わずに済み、安くどこでもネットが出来るようになりました。

アンケートによると現在スマホの月額料金は平均で約7,000円だそうです。例え端末を0円で買ったとしても2年縛りで約168,000円になります。SIMカードは月額1000円ぐらいが普通です。Nexus5が40,000程度なので2年で64,000円。2年で10万円近く節約できることになります。

ただし、これらのSIMカードは、通信のみで、電話ができないこと(音声通話付きは月額1,600円程度のもある。またIP電話である程度代用可能)、SMSが出来ないこと(オプションで月額150円ぐらいの場合がある)に注意してください。

選択も色々とあって、ローソンでプリペイドSIMカードが買えるようになったり世界中で使える格安データ通信SIMのGIG Skyが出たり、と増えてきました。なぜか家電量販店では、SIMフリー端末がほとんど売られない状況で難しいかもしれませんが、これからSIMフリーが一般的に普及していくことを願っています。

私は最も安い月額490円のDTIのServersMan SIM LTEを使用していますが、Nexus5でも問題なく使用できています。当初は安定性に不安のあったDTIですが、最近では速度も安定してきた気がします。

Nexus5でServersMan SIM LTEの設定を行うには少し面倒がありますが、DTIのマニュアルのサイトを見ればSIMフリー端末の初心者でも全く問題なく設定できると思います。Nexus5はテザリングも問題なくできるので、他にタブレットなどを使用する場合にも便利です。

SMSがないSIMカードだとセルスタンバイ問題といって、セルスタンバイの部分が非常に電力を使う現象が出ることが有名です。セルスタンバイの圏外時間が100%になっていることで確認できます。Nexus5でもそれは起きています。


しかし、表示の問題だけで実質あまり影響がないという話もあります。上記をみていただいてもわかりますが、2日と半日は電池は持っており、気にするほどでは無さそうです。

気になる方はSMS付きのSIMカードを買うとよいかと思います。SMS付きの方がLINEなどを登録するのにも便利という利点もあります。

2013年12月16日月曜日

Fedora19でNexus5をroot化

Fedora19(64bit)でも特に問題なくNexus5をroot化できました。
root化については以下に説明があります。

http://forum.xda-developers.com/showthread.php?t=2507211

ここのサイトの下の方にNexus5のツールへのリンクがあります(「File」となっているところ)



 CF-Auto-Root-hammerhead-hammerhead-nexus5.zipをダウンロードします。

 次にNexus5を一旦電源を切り、ボリュームダウンと電源キーを両方押しながら再度起動します。以下のような画面となります。



ここで、PCにNexus5をUSBで接続し、Terminalで以下を行います。

$ sudo yum install glibc.i686 glibc-devel.i686 libstdc++.i686 
$ sudo yum install zlib-devel.i686 ncurses-devel.i686 
$ sudo yum install libX11-devel.i686 libXrender.i686 libXrandr.i686
$ unzip CF-Auto-Root-hammerhead-hammerhead-nexus5.zip
$ sh root-linux.sh

以下のように表示され、Nexus5が自動的に再ブートします。ここに書いてあるように全てのデータが削除されるのでご注意ください(FAILEDとなっている部分はすでにUnlock済みであったためと思われます)。




 

2013年12月8日日曜日

BitTorrent Sync と Raspberry pi で DropBox を置き換える

BitTorrent Sync と Raspberry pi で DropBox を置き換える方法についてです。ここを参考にさせていただきました。

なぜ BitTorrent Sync と Raspberry pi か?


現在は、パソコン・タブレット・スマートフォンなど複数のデバイスを使うマルチデバイスの時代と言われています。複数のデバイスで同じデータを扱うにはDropBoxなどのクラウドサービスにデータを置くことが主流です。しかし、代わりに BitTorrent Sync と言うを使うと以下の利点があります。

  • 容量に制限がない(デバイスの容量、加入ISPの帯域幅が制限となる)
  • Wi-Fiを使用している時には、Wi-Fiで同期をするため、ISPに帯域幅の制限される心配が少ない
  • Google Readerのようにサービスが終了する心配が少ない
  • サービス提供側にデータを覗かれる心配が少ない

一方、弱点としては常に同期をとる時にはデバイスの電源を入れておく必要がある欠点がありました。そこで、Raspberry Piを使用し、Raspberry Piを電源入れっぱなしのサーバー(サービスを提供するパソコン)にすることで問題を解決します。Raspberry Pi には以下の利点があります。

  • 安上がり(すでにある物を使えば、部品を全部揃えても一万円程度)
  • 消費電力が少ない(多くても3W。1KW/hが30円と高めに見積もっても、1年電源入れっぱなしで790円)
  • サーバーの知識が少なくても出来る(情報が多い)

ただし、壊れた場合などは自己責任になったり、欠点もまだあります。


導入の説明


なるべくパソコンにあまり詳しく無い方にも分かりやすいように、Raspberry PiをBitTorrent Syncのサーバにするための説明したいと思います。しかし、ソフトウェアのインストールやエクスプローラの使い方などある程度の知識を持っていることが前提ですので、ご了承ください。またBitTorrent Syncのパソコンやスマートフォンでの使い方は別のページを参照してください。

部品の購入


部品を揃えます。以下の部品が準備に必要です。一緒の物を買う必要はないですし、最初のルーターを除いて、残りは準備に必要なだけです。すでに同種のを持っているのであれば、一時的にそれを使用すれば良いです。私はすでに持っている物を使用したので、下記の動作保証はできません。

必要な物説明
UPnPに対応したルーター最近ではほとんどの方が家に無線LANのルーターを持っているのではないかと思います。大抵はUPnPに対応しているので、それを使えば良いです。また今回は有線のポートがあるタイプを想定します。詳細はルーターの説明書を見てください。例(→)はBUFALLOの一番安い製品ですが、たぶんコレでも大丈夫と思われます。
SDカードを読み書きできるパソコンWindowsでもMac OS XでもLinuxでも可能ですが、今回の説明ではWindowsを使用します。SDカードスロットがある機種の場合には、それを使えばよいですし、無い機種の場合には、USBのアダプターがありますので、それを使用します。Amazonでは安いのが無かったのですが、アダプターは例の(→)よりもっと安い物もあります。安物で十分です。
モニタまたはテレビRaspberry Piのセットアップ時に表示を行います。PCのモニタまたはHDMI端子のあるテレビでも良いです。地デジ対応テレビであれば、大抵HDMI端子が付いていると思われます。
HDMIの接続ケーブルテレビにつなぐ場合にはHDMIの通常のケーブルで良いです。PCのモニタにつなぐ場合には、HDMIをDVIに変換するケーブルが必要になるかもしれません。私はPCのモニタにDVIで接続したため、例の(→)ケーブルを持っていたので使用しました。
USBマウスUSBマウスなら何でも良いです。トラブルを避けるなら有線の方が良いです。例(→)はなるべく安いを選びましたが、もっと安いのがあるかもしれません。
USBキーボードUSBキーボードなら何でも良いです。トラブルを避けるなら有線の方が良いです。例(→)はなるべく安いを選びましたが、もっと安いのがあるかもしれません。


以下はサーバーとして使用開始後も必要です。ネットワークケーブルを除いて残りの3つは私が実際に買った物なので、動作確認できています。

必要な物説明
Raspberry PiRaspberry Pi 本体とケースです。黒い方が置いていて違和感が少ないと思い、私は黒のケースを選んでいます。RSコンポーネントなどからでも買えますが、Amazonでも十分安いと思います。
電源microUSBで5Vで700mA以上の供給ができる物であれば、何でも良いです。大抵のスマホ用のAC充電器であれば、問題ないです。例(→)のAC充電器は1Aです。
SDカード32GBUSB接続の大容量HDDをつなぎ、そこにデータを置くことも可能ですが、今回の説明ではSDカード内にデータを置くため、大きめのサイズのSDカードを使います。約30GBはデータを置けますし、HDDを追加すると消費電力も増えるので、まずはSDカードのみで始めるのが良いかと思います。
ネットワークケーブル有線ネットワークのケーブルなら何でもよいです。例の(→)は1mですが、ルーターの近くに置くのであればもっと短くても良いです。Raspberry Piを置く場所を考えて長さを決めてください。


SDカードにRaspberry PiのOSを入れる


Raspberry Piはお店で買うWindowsパソコンと違い、OSと言うものを入れる必要があります。SDカードを読み書きできるパソコンを使ってSDカードにOSを入れます。
  1. Raspberry Pi のダウンロードページから Raspbian のイメージをダウンロードします。2013年12月現在は、 2013-09-25-wheezy-raspbian.zip です。圧縮された形式となっています。
  2. 2013-09-25-wheezy-raspbian.zip を解凍してください。2013-09-25-wheezy-raspbian.imgというイメージファイルが出来ます。
  3. SDカードをPCに接続し、ドライブ番号を確認してください。ドライブ文字はエクスプローラの左の列で(例えばG:のように)確認できます。
  4. Win32 Disk Imager と言うソフトウェアをダウンロードします。同様にzipファイルとなっています。
  5. zipファイルを解凍して、Win32 Disk Imagerを実行します。管理者で動作させる必要あるかもしれないので、右クリックして「管理者で実行する」を選択してください。
  6. 上記で解凍したイメージファイルを選択してください。
  7. SDカードのドライブ文字を選択してください。正しいドライブを選択するよう注意してください!間違えるとパソコンを壊すことになります。もしSDカードスロットを使用していて、SDカードのドライブ文字が表示されない場合には、USBのアダプタを使用してください。
  8. Writeをクリックし、書き込みが完了するのを待ちます。
  9. Win32 Disk Imagerを終了して、SDカードを取り出してください
  10. これでSDカードへの書き込みは完了です。

Raspberry Pi にSDカードやケーブル等をつなぐ


Raspberry Pi にSDカードやケーブル等をつなぎます。以下の画像を参考にしてください。Raspberry Pi は電源スイッチが無く、電源線をつなぐとすぐに起動します。そのため、電源は最後につないでください。



Raspberry Pi を起動してOSのセットアップをする


電源線をつなぐとRaspberry Piが起動して、画面に文字が流れた後、以下のような画面が表示されます。


ここでセットアップ作業を行います。操作の仕方はカーソルキーで移動して、Enterキーでメニューの選択します。下側の<Select>や<Finish>を選択するときには、タブキーで下側と上側を切り替えます。

  1. 「Expand Filesystem」 を選択してください。SDカードの32GB全体を使用するようにします。少しすると最初の画面に戻ります。
  2. 「Internationalisation Options」を選択すると以下の画面になります。ここでは日本語環境のセットアップを行います。
  3. 「Change Locales」を選択してください。使用する言語の選択を行います。日本語の「ja_JP.UTF-8」と念の為に英語の「en-US.UTF-8」を選択してください。[*]が選択されたのが、選択された状態です。
  4. 次にデフォルトの言語を聞いてくるので、「ja_JP.UTF-8」を選択してください。
  5. 最初の画面に戻ったら、次は「Internationalisation Options」→「Change Timezone」を選択してください。タイムゾーンの設定(時刻を日本に合わせる)を行います。ここでは「Asia」→「Tokyo」と順に選択してください。
  6. 再度最初の画面に戻ったら、次は「Internationalisation Options」→「Change Keyboard Layout」を選択してください。日本語キーボードを使用できるようにします。ここでは「Generic 105-key (Intl) PC」→「Ohter」→「Japanese」→「Japanese - Japanese (OADG 109A)」→「The default for the keyboard layout」→「No compose key」→「No」と順に選択してください。
  7. 最初の画面において「Finish」→「Yes」で再起動します。
  8. 再起動するとメッセージが流れて、「raspberrypi login:」と表示されます。ここで「pi」と入力しEnterキーを押すと、「Password:」と表示されるので「raspberry」と入力し(入力した文字は見えません)、Enterキーを押します。次に「pi @raspberrypi ~ $」と表示されるので、「startx」と入力してEnterを押してください。
  9. Windowsに似た画面が表示されたと思います。操作もWindowsに似ているので問題ないかと思います(ただ動作は遅いですので、待ちながら操作してください)。以上でセットアップは終了です。

BitTorrent Syncのセットアップをする


BitTorrent Syncのソフトウェアをダウンロードし、起動時に動作するようにします。

  1. Midoriというブラウザ(インターネットに接続するソフト)がありますので、それを起動します。右上辺りにアイコンがあるので、タブルクリックで起動します。
  2. 「http://www.bittorrent.com/sync」のサイトを表示し、 「Get BitTorrent Sync フリー ダウンロード」をクリックします。
  3. 「Linux」の「ARM」をクリックすると、「btsync_arm.tar.gz」を保存するかどうか聞いてきますので保存します。
  4.  LXTerminalをを起動します。右真ん中あたりにアイコンがあるのでダブルクリックして起動します。
    mkdir ~/.btsync && cd ~/.btsync
    mv ~/btsync_arm.tar.gz ~/.btsync
    tar -xvf btsync_arm.tar.gz
    sudo leafpad /etc/init.d/btsync
    
  5. 4の最後の行の入力が終わるとテキストエディタが起動するので、テキストエディタに次のように入力して「ファイル」-「保存」で終了します(もちろんコピペで良いです)。
    #! /bin/sh
    # /etc/init.d/btsync
    #
    
    # Carry out specific functions when asked to by the system
    case "$1" in
    start)
        /home/pi/.btsync/btsync
        ;;
    stop)
        killall btsync
        ;;
    *)
        echo "Usage: /etc/init.d/btsync {start|stop}"
        exit 1
        ;;
    esac
    
    exit 0
    
  6.  テキストエディタが終了したら、またLXTerminalで続けて以下のように入力してください。2行目を行った所で警告が表示されるかもしれませんが、気にしないでください。
    sudo chmod 755 /etc/init.d/btsync
    sudo update-rc.d btsync defaults
    sudo /etc/init.d/btsync start
    sudo mkdir -p /media/SYNC
  7.  再度Miroriのブラウザに戻って、「http://127.0.0.1:8888」のサイトを表示してください。 BitTorrent Syncの設定画面が表示されれば、BitTorrent Syncが動作していることになります。管理者の設定をした後下記の右側のような画面になります。
  8. 右上のボタンの「Preferences」をクリックして表示されるウィンドウで「Language」を「日本語」にし、「Save changes」で終了すると、画面が日本語に変わります。
  9. 「フォルダの追加」で シークレットキーを入力する(すでにBitTorrent Syncを使っていてキーがある場合)または、生成ボタンを押して生成して(新規に作成する場合)、フォルダを/media/SYNCに選択してください。(このフォルダに同期するデータが保存されます)。
  10.  9で新規に作成した場合は、シークレットキーを覚えておいてください。他のパソコンやスマートフォンから同期の設定をするときに使用します。
  11. 以上でBitTorrent Syncのセットアップは完了です。

Raspberry Pi をBitTorrent Syncのサーバーとして動作させる


BitTorrent Syncセットアップが終了したら、一旦終了させます。「ログアウト」すると起動直後の文字の画面に戻るので、ここで「sudo halt」と入力します。画面が流れ、真っ黒になったら電源線を抜いてください。

ケースにRaspberry Piを入れて後はUSBキーボードとUSBマウスとHDMIケーブルは抜いてしまい、ネットワークケーブルと電源線だけにします。電源を入れた後に他のパソコンやスマートフォンなどと同期ができていることを確認してください。

私もこの状態で1周間ほど電源を入れっぱなしにして動作させていますが、問題なく動作しており、なかなか便利に使っています。

本当は上記の設定だけでなく、日本語入力の設定や、IPアドレスの設定、パスワードの変更もしておいた方が良いですが、とりあえずRaspberry PiをBittorent Syncのサーバーとして動作させるまでは以上です。

2013年12月7日土曜日

Nexus5 (Android4.4 Kitkat)でFlash Playerを使用する方法について

Nexus5、非常に魅力的ですが、Android4.4 KitkatではFlash Playerが使えなくなるという話があり、買うのを迷っていました。しかし、Android4.4 KitkatでもFlash Playerを使うことができると判明して買ってしまいました。

Kitkat Nexus5  Flash Playerで検索すると「使用できない」という検索結果がたくさん出てきますが、使えますよ!元ネタは↓のxdaの記事です。

http://forum.xda-developers.com/showthread.php?p=47958533#post47958533

ただ、Dolphin Browserのインストールでハマりました。下の画像のように上記のリンクからDolphin Browserをインストールしようとすると「このアイテムはお住まいの国でご利用いただけません」となってしまいます。



Google PlayでDolphin Browser を検索すると、下の画像のように日本語版のDolphin Browserが出てくるのですが、この日本語版は10.1.2JPというバージョンで、本家の10.1.2と少し違う物となっているようで、これをインストールしてもFlash Playerが動作しないようです。


そこで、ここからDolphinBrower.apk(10.1.2)をインストールしたところ、無事、Flash Playerが動作しました。Dolphin JetpackはGoogle Playからインストールすれば問題ありません。

最近はFlash Playerのベンチマークとして「艦これ」が使われているようですが、残念ながら私はやっていないので、Nexus5の速度については不明です。

紹介したリンク先のDolphinBrower.apkがウィルスなど大丈夫かは不明なので、インストールの際にはご自身の責任で行っていただくよう、よろしくお願いします。

KitKatではブラウザはChromeとなりましたし、 PC版ChromeやChrome OSでは、PPAPI版のFlash Playerが入っているので、将来的にはAndroidでも同様にFlash Playerが気軽に使えるようになることを期待します。

追記1:Android4.4.2にアップデートしても動作します!
追記2:XDAのサイトから10.2.0がダウンロードできますので、そちらを利用した方が良いです。
追記3:XDAのサイトからはダウンロードできなくなりましたので、10.2.0の最新をここからダウンロードしてください。 10.2.0ではJetpackは必要ないようです。10.2.0JPは動作確認していません。

2013年12月1日日曜日

Fedora の全てのパッケージで -Werror=format-security

Phoronixの記事によるとFedoraの全てのパッケージで、コンパイル時のgccのオプションに-Werror=format-securityを付けることになるそうです。

これは、フォーマット文字列攻撃(または書式文字列攻撃)という有名なセキュリティの脆弱性を防ぐのに有効なコンパイルオプションです。IPAの記事が詳しいです。

例えば、以下のようなプログラムtest.cをコンパイルします。

#include <stdio.h>

int main()
{
        char str[] = "test";        

        printf(str);
        printf(str, NULL);
        return 0;
}

この関係のオプションは警告を出力する -Wformat などがありますが、それぞれ以下の画像のようになり、-Werror=format-securityでは7行目で警告でなくエラーとなり、コンパイルに失敗します。8行目のようにprintf()に第2引数があればエラーにならないようです。



Fedoraのパッケージは10,000近くあると言われていませすが、そのうち400ぐらいが影響を受けるそうです。結構あるものですね。

それはともかく、Fedora20でユーザー切り替えでパスワードが暴露される不具合が見つかったそうで・・・12月10日に出る予定でしたが、また延期されるのでしょうか・・・


2013年11月24日日曜日

日経Linux2013年12月号

昔、BASICマガジンからプログラムの勉強をはじめました。今はコンピュータ系やプログラミングの雑誌も減って寂しいものです。そんな中、今私が定期的に購入しているのは「日経Linux」です。Linuxの勉強のためですが、それほど中身を読む時間がないのが残念です。

今月の記事の紹介とその感想です。

特集1
 Ubuntuデスクトップでスタート!
 サーバー超マスター100ステップ

私はFedoraをデスクトップで使っていますが、困ったことにあまりサーバーとしては使っていないです。なかなかサーバーとして使う用途が思いつかないので、その当たりでいい説明があると良いのですが・・・

特集2
 激安ボードで即楽しめる!
 知識ゼロから始めるLinuxモノ作り

Raspberry Pi、BeagleBone Black, Arduino, mbed,を使った電子工作の記事です。初心者向けで、LEDと温度センサーを使ったものです。RPiでLEDはやってみたのですが、すぐに飽きました(笑)。やはり使い道が必要ですね。

特集3
 要注目のモバイルLinux!
 最新Chrome OSで 軽量マシン

実際にはChrome OSでなく、オープンソース版のChrominum OSをビルドからインストールまでを行う記事です。WindowsXPの期限が切れた後のノートPCに入れると良さそうな感じがします。

特別連載
 Windows ユーザーのためのLinux超入門
 第3回 主要アプリケーションとパッケージ管理

WindowsXPの期限切れが迫る中、Linuxは選択肢の1つですが、移行は難しいですね。Linuxを初めて使ったとき、Windowsよりも便利な点があって驚いたのですがまずはインストールが難関です。

まつもとゆきひろの言語の世界
第7回 JavaScript

Rubyを開発したまつもとゆきひろさんの記事で楽しみな記事の1つです。色々なプログラミング言語の思想などがまとめられています。

#!シス管系女子Season2
第2話 鍵認証で安全にログインしよう

みんとちゃんのボケがいつも楽しみです(笑)
 

マンガでこういう風に分かりやすく説明できるのは羨ましいです。


C/C++ 演算

コンピュータで一番得意なのは足し算や掛け算などの演算でしょう。

value = 3 * 4 + (-4) / (1 + 1);

まずはデータとして値を代入する必要がありますが、それを示すのがイコール(=)です。C/C++では以下の点が注意です。
  1. 数学的なイコールと意味が違い、代入を意味する。
  2. イコールの左側を左辺値といい、変数の必要があり、変数の値を書き換える。
  3. イコール自身も式となっており、代入値を返す。
最後の3の意味が分かりにくいかもしれませんが、以下のように右辺に書くこともでき、足し算などと同様に扱うことができると言うことです。ある意味2がイコール特有の処理と言えるかもしれません。

value2 = (value = 3 * 4 - (-4) / (1 + 1));


残りの文はアスタリスク(*)が掛け算、スラッシュ(/)が割り算を示す演算を表すということ意外は数学的な記述とほとんど同じで意味が解ると思います。演算には優先順があり括弧内から計算して行きます。また加減算より乗除算の方を先に計算します。最初の記述では、4という結果がvalueに代入されます。演算を表す文字を演算子と言い、通常の計算に使う演算子は算術演算子と言い、他にも余り(剰余)の計算でパーセント(%)があります。

C/C++として特徴的な演算子として 代入と計算を一緒に出来る演算子があることです。これは別の書き方ができますが、よく使うことからソースコードを簡単に書くことができるようにしたものです。

同等の式備考
value++;value = value + 1;全体の評価が終わった後に+1する。
++value;value = value + 1;全体の評価を行う前に+1する。
value--;value = value - 1;全体の評価が終わった後に-1する。
--value;value = value - 1;全体の評価を行う前に-1する。
value += 10;value = value + 10;+=の他にも-=,*=,/=,%=,&=,|=,^=が使用できる。

++value; と++value;の違いは分かりにくいですが、a = ++value; a = value++;と他の演算と記述すると違いが分かります。前者では、aにvalue+1が代入され、後者ではaにvalueが代入されます。



C/C++らしい演算子としては、他に2進数での計算を行うビット演算子があります。00110を1のシフトの場合に01100と左にシフトする左シフト(<<)、00011と右にシフトする右シフト(>>)があります。またビットごと論理和、論理積、排他的論理和、論理否定をおこなう演算があります。論理和など聞きなれない言葉かもしれませんが、意外とよく使うため、覚えておいた方が良いです。

aba | b (論理和)a & b (論理積)a ^ b (排他的論理)~a (論理否定)
000001
011011
101010
111100



また用途は計算と全く違うのですが、C/C++では演算子となっているもので、比較演算子があります。下記は「もしaが3と等しかったらaを1引く」と言うプログラムですが、このa == 3 のような条件を指定する部分も比較を行う演算子となっています。

if (a == 3) a--;

比較演算子には小なり(<)、小なりイコール(<=)大なり(>)、大なりイコール(>=)、非等価(!=)、等価(==)があります。これらの演算の結果はC++の場合にはbool型と言う型となり、trueまたはfalseのどちらかの演算結果となります。C言語の場合には、int型で比較結果が真(正しい)のとき1を偽(間違っている)のとき0の演算結果となります。

 代入(=)も演算子であり、以下の文も記述としては間違いではないのでコンパイル時にエラーとなりません。等価(==)と間違えないように注意が必要です。(gccの場合、コンパイル時に-Wallというオプションを付けることで条件のところで代入(=)が使用されていた場合にで警告を出すことは可能です)

if (a = 3) a--;



また、このような真偽の専用の演算子として、論理演算子の論理否定(!)、論理和(||)、 論理積(&&)があります。ビット演算子と違いビットごとの演算はせず、値が0であれば0と、値が0以外であれば1として計算をします。

また論理和(||)、 論理積(&&)は唯一演算を端折る場合がある演算子なので注意が必要です。例えば以下の式の場合、a == 1の比較演算を行い、偽だった場合には、b == 2 と c = 2の処理は行いません。左から演算していくときにその後の演算がどうであっても、結果が偽となるためです。しかし、b == 2 については問題ないとしてもその後、c = 2 の代入が行われないことは、その後cの値を使用するときに前の比較演算の影響が出ることになります。

(a == 1) && ((b == 2) && (c = 2))


他にもprintf()という関数の呼出をこれまで使っていましたが、この記述も関数呼出の演算子とみなされます。そのため、 以下のような記述も可能です。

 a = a + printf("Hello");

上述のようにC/C++の記述は演算子の固まりで出来ています。これらの演算子は全て繋げて書くことができますが、全ての演算子には足し算と掛け算では掛け算を先に行うように優先順位と言うものが存在します。例えば以下の場合にはaにどのような値が入るでしょうか?

 a = 3 << 1 + 1;

答えは12になります。左シフト(<<)より加算(+)の方が優先順位が高いため 3 << (1 + 1)と同等になるためです。

さらに優先順位が同じ場合には、結合規則が存在し、左から右に計算していくものと、右から左に計算していくものがあります。例えば加算(+)は左から右で a + b + c + d の記述は ((a + b) + c) + d と同等です。代入(=)は右から左で a = b = c = d は a = (b = (c = d))と同等になります。

 詳しくはWikipediaなど他の資料を参考してください。 他にも様々な演算子があったり、演算子は意外と奥が深いですが、C言語は演算子の記述の固まりであることと、優先順位に困った時には括弧を付けて優先順位をコントロールすることなど、注意点を覚えておけば、まずは良いかと思います。

2013年11月17日日曜日

Fedora 20 Beta (GNOME 3.10)

Fedora 20 の Beta版が出ました。でもあまり変わっているところは無い気がします。カーネルのバージョンも3.11でした。12/10に正式版が出る予定です。

Fedora 20 になって一番変わる所と言えばGNOME3.10かもしれません。そこで、簡単にレビューです。GNOME 3.10の紹介の詳細についてはここです。

まず、UbuntuでiBus1.5について問題になっていたので日本語入力についてです。Fedoraでは比較的問題は無いのですがやはり分かりにくいです。日本語キーボードを使うには入力ソースに「日本語」というものと「日本語(かな漢字)」の2つを入れる必要があります。一旦「日本語」に変えると「日本語(かな漢字)」もキーボードのレイアウトが切り替わるという不思議な仕様となっています。これはFedora 19と変わらずです。




見た目が大きく変わったのは、メニューとヘッダーバーです。よりグラフィカルに、より表示エリアを大きくということでしょうか。もともとツールバー部分もタイトルバーと同様に掴んで移動などができました。これはタッチインターフェースでは掴みやすく便利と思っていたのですが、狭くなってしまいました。表示エリアが大きくなって良かったのだろうか・・・。


新しいソフトウェアとして、「ソフトウェア」や「地図」があります。「ソフトウェア」は今までのGUIのパッケージインストーラに比べると使いやすそうですが、やはりコマンドラインのyumの方が便利な気がします。「地図」はGoogle Mapに比べれば全然使えないのでしょうが、日本でも市の検索ぐらいは使えそうです。ちなみにこの「地図」はJavascriptで作られているようです。


それと細かい所ですが、Gnome3.10ではスクロールバーを2秒ほど掴んでいると、スクロールバーの線が細くなり、より細かくスクロールできるようになっています。しかし、GTK+3のライブラリを使っているところだけのようで、GTK+2を使っていると思われるFirefoxなどでは使えなさそうでした。

C/C++ 数値と名前と変数

動画や画像に音楽などコンピュータは色々なことができますが、
コンピュータの基本は電気が流れる流れないの0と1の世界です。

0と1だけで表した数値を2進数と言います。通常私達がつかっているのは10進数で、

 1
 2
 3
 4
 5
 6
 7
 8
 9
10

の十個目で二桁になります。2進数の場合は

 1
10

と2個目で二桁になります。これらを10進数に割り当てれば数値が扱えることになります。 括弧内は2進数を10進数に変換するための計算式です。2の4乗とは 2×2×2×2→8です。

  1 → 1   (                            2の0乗 × 1)
 10 → 2   (              2の1乗 × 1 + 2の0乗 × 0)
 11 → 3   (              2の1乗 × 1 + 2の0乗 × 1)
100 → 4   (2の2乗 × 1 + 2の1乗 × 0 + 2の0乗 × 0)
   :
   :
10100 → 20 (2の4乗 × 1 + 2の3乗 × 0 + 2の2乗 × 1 + 2の1乗 × 0 + 2の0乗 × 0)

2進数の場合は、桁数が多くなりすぎますが、 10進数と2進数では桁上げのタイミングが違いすぎるので、 8進数や16進数が使われます。特に16進数がよく使われます。


10進数2進数8進数16進数
0000
1111
21022
31133
410044
510155
611066
711177
81000108
91001119
10101012A
11101113B
12110014C
13110115D
14111016E
15111117F
16100002010
17100012111
::::


そして2進数の1つの1と0のデータの単位をビット(bit)、16進数で2桁(2進数で8桁)の0〜FF(0〜255)の単位をバイト(byte)と呼びます。

プログラムで計算などを行うには、メモリを使いますが、コンピュータとしてはメモリも100番地と150番地のデータのように数値で区別して扱います。通常の場合は1つの番地に1バイトのデータを記憶できます。

しかし、こんな数値ばかりでメモリを管理していたら大変です。ソースコードでは大抵、メモリを管理するためには自分で名前を付けた「変数」を使用します。

階乗の計算のソースコードでは、value, fact, iが変数です。自由に名前を付けれますが、英字の大文字小文字、数字、アンダーバー(_)が使用できます。先頭に数字は使用できません。せっかく自由なので分かりやすい名前にしましょう。iは分かりにくく感じると思いますが、繰り返し処理に使用される因子(iterator)の意味から来ているもので、よく使われる定石みたいな物となっています。

この変数の前についているintは「型」といって、データの意味を表すものとなっています。main()内の先頭行ではvalue, fact, iがint型であることを宣言しています。

最近のPCでは、intは32bit(4バイト)で10進数だと−2,147,483,648 から 2,147,483,647の値のデータと言う意味です。計算結果がこの範囲を越えることをオーバーフローといい、計算結果が意図通りにならない原因の1つです。

小数点を扱いや、マイナスの扱いも2進数で扱います。どのように扱うかは、IEEE754や、2の補数を調べてみてください。

2013年11月10日日曜日

C/C++ 階乗の計算

コンピュータと言えば計算が得意です。ですから計算のプログラムを作ってみます。計算は階乗(factorial)の計算で、nという数字を与えた時に、1×2×3×4×・・・・×(n-1)×nという1からnまでを掛けた値になる計算です。なお0の階乗は1となります。

まずはどのように動くかという仕様を決めます。これだけのプログラムでも色々と考える必要があります。
  1. コマンドライン引数で階乗の数値を入力する。
  2. コマンドライン引数で入力した数値から階乗を計算する。
  3. 計算した結果をコンソールに表示する。
  4. 引数では数値を入力する。数値以外は0と見なす。
  5. 数値がマイナスの場合はエラーを表示し、2を返す。
  6. 小数点がついていた場合は、小数点以下を無視する。
  7. 引数の数が1つでない場合はエラーを表示し、1を返す。
  8. 値のオーバーフローは考慮しない。
上記のように動くソースコードを書きます。fact.cとします。


コンパイルし、実行を行うと以下のようになります。



ソースコードの解説を簡単にします。

ソース説明
main(int argc,  char *argv[])今回はmain()関数にint argc, char *argv[]という2つの引数がついています。argcは整数(int)で、引数の数を表します。argvは引数の文字列の配列を意味します。*や[]の意味はまた機会があれば説明します。とりあえずargv[1]などが一つ目の引数の文字列と解釈してください。
int value, fact, i;valueと、factと、iという名前の整数のデータ領域を作成しています。
if (argc != 2) {...}引数の数(argc)のチェックを行っています。引数の数にはコマンド自身の数も含まれるので引数が1つのときには2となります。!=2はargcが2で無いかどうかという計算で、その結果により、{...}内の処理を行います。

value = atoi(argv[1]);
引数の文字列argv[1]を整数値に変換して、valueに代入しています。文字列のままでは計算ができないためです。atoi()というのは文字列を整数値に変換するライブラリ関数です。stdlib.hに入っているのでstdlib.hを#includeしています。
if (value < 0) {...}引数を整数値に変換したvalueが0より小さい場合に{...}の処理をします。
fact = 1;factというデータ領域に1を代入します。
for (i = 1; i <= value; i++) {...}繰り返し処理を行い、階乗を求めています。(1)iのデータ領域に1を代入します。(2)iがvalue以下の値か調べ、iがvalue以下の値であれば、{...}の処理を実行し、そうでなければ{...}の次の行の処理に移ります。(3){...}内の処理が終わったらi++を実行します。i++はiの値をi = i+1と同じ意味でiの値に1つ値を足します。
fact = fact * i;アスタリスク(*)は掛け算の意味です。iが1つずつ加算するのを繰り返すことで、階乗を計算します。
printf("factorial = %d¥n", fact);
階乗の値を出力します。printf()で表示する文字列の指定内のパーセント(%)には意味があり、%dは整数(int)の表示を行うことを意味します。文字列の後ろの引数に%dに表示するデータを列挙します。

複雑になりましたが、それは今回のプログラムがユーザーからのコマンドラインからの入力が増えたことが原因です。これでもオーバーフローを考慮しないなど、処理が少なくなるようにサボっています(17の階乗でなるはずの無いマイナス値となっているのはオーバーフローのためです)。

通常の場合、プログラムはユーザーの入力に対し、何かの処理を行います。ユーザーの入力は何があるか分からないので、入力を制限する処理を入れたり、どのような入力でもチェックによりエラーを返すなどの処理を入れなくてはいけません。そうしないと 想定外の問題が起こることになります。

この想定外の問題をいかにして少なくすることができるかが、プログラマの腕の見せ所の1つです。

それと、今回はCPUの処理(演算と制御)の部分とメモリ(データ領域の作成)の部分がHello Worldに比べて多く増えています。それらについてはまた次回。

2013年11月4日月曜日

MinGW + MSYS で日本語

C/C++ Hello Worldでは、わざと日本語の使用を避けていました。日本語を扱うには色々と問題があり、設定などが難しかったためです。

gccのコンパイルで警告になることがある

printf("Hello World¥n");でなく、 printf("こんにちは¥n”);とした場合は問題になりませんが、printf("ソフトウェア¥n”);とした場合にはコンパイル時に警告が表示されます。

なぜかというと円マーク(¥)が原因です。円マークは文字コードが0x5Cなのですが(Linuxでは0x5Cの表示がバックスラッシュ(\)の場合もあります)、Windowsが標準で使用している文字コードのCP932(ShiftJISの一種)では、「ソ」は0x83,0x5Cの2バイトとなっていて、コンパイラが2つ目の0x5Cを円マーク(¥)と間違うためです。他にも「表」などが同様に問題があります。


その対策では、--input-chaset=CP932というオプションを付けます。するとgccは文字コードをUTF-8 に変換してからコンパイルします。しかし、これだけではprintf()で文字化けします。--exec-charset=CP932とすることで、実行ファイル内部の文字列をCP932に変換します。



そもそもvimで日本語入力ができない

まずはvimで日本語が化けます。この対策で、.vimrcの最後の行に
set enc=japan
と入れると良いようです。ここを参照させていただきました。

しかし、日本語入力はうまく行きません。Alt+半角/全角で日本語入力への切換ができるのですが、vimの画面では変な風にスクロールしていってしまいます。
この対策にはminttyを使うと良いようです。以下でセットアップできます。

$ mingw-get install msys-mintty

"mintty -"(ハイフンが必要)を実行するか、msys.batを起動するときに -minttyオプションを付けるとminttyがが起動します。mintty上で起動したvimであれば日本語入力が出来ます。ここを参照させていただきました。以下はminttyの画面です。



さらに日本語ファイル名を使う

上記ではlsで日本語のファイル名がまた文字化けしますし、入力もできません。以下を行うと日本語ファイル名が使えるようになります。

/etc/profileのファイルを編集して最後に以下を追加します。
alias ls='ls --show-control-char'

また、~/.inputrcを編集して16行目以降を以下のように変更します。
# disable/enable 8bit input
set meta-flag on
set input-meta on
set output-meta on
set convert-meta off

同じくここを参照させていただきました。

MinGW + MSYS で GTK+3

GTK+のバージョン3はなかなかWindows版が出なかったのがやっと出たようです。インストール方法も載っていますが、MSYSで使うのであれば、より簡単かもしれません。

all-in-on bundleをダウンロードして、C:¥MinGW¥msys¥1.0に解凍して上書きします。

その後、MSYS上で以下のコマンドを実行します。
$ pango-querymodules > \etc\pango\pango.modules
$ gdk-pixbuf-query-loaders > \lib\gdk-pixbuf-2.0\2.10.0\loaders.cache
$ gtk-query-immodules-3.0 > \lib\gtk-3.0\3.0.0\immodules.cache

たぶん、これでいいはず・・・
コンパイル方法も全く一緒で、これと同じプログラムが動きます(-mwindowsオプションは付けたほうが良いかもしれませんが)。

C/C++ Hello World ウィンドウ表示(GTK+)

Linuxにおいてもウィンドウ表示のHello Worldを作成してみます。

Linuxでウィンドウアプリケーションを作るにはツールキットと言われるソフトを使用します。GTK+や、Qt(キュート)が有名です。GTK+は少々使いにくいかもしれませんが、C++でなくC言語から使えるのが特徴です。

まずは、GTK+の開発環境をインストールします。

Fedoraの場合
$ sudo yum install gtk3-devel

Ubuntuの場合
$ sudo apt-get install libgtk-3-dev

hello2.cは以下のように作成します。
#include <gtk/gtk.h>

int main(int argc, char *argv[])
{
        GtkWidget *dialog;

        gtk_init(&argc, &argv);
        dialog = gtk_message_dialog_new(NULL, 
                                GTK_DIALOG_DESTROY_WITH_PARENT, 
                                GTK_MESSAGE_OTHER,
                                GTK_BUTTONS_OK,
                                "Hello!"
                                );
        gtk_dialog_run(GTK_DIALOG(dialog));
        gtk_widget_destroy(dialog);
        return 0;
}

コンパイルを以下のように行い、実行します。
$ gcc hello2.c `pkg-config --cflags --libs gtk+-3.0`
$ ./a.out

すると以下のようになウィンドウが表示されます。


少し難しいですが、簡単に各項目の説明をします。
項目説明
mainmain()関数はargc, argv, envの3つの引数を持つことができます。今までは全て省略していました。envのみ省略もできます。
int argcコマンドライン引数の数が渡されます。
char *argv[];コマンドライン引数の文字列の配列が渡されます。
GtkWidget *dialog;dialogという名前のウィンドウをこれから作ることを宣言します。
gtk_init()GTK+を使用する前に必須の初期化を行います。
gtk_message_dialog_new()メッセージを表示するだけの簡単なウィンドウdialogを作成します。一つ目の引数は、親ウィンドウを指定します。二つ目の引数は動作を指定します。三つ目の引数はどのようなアイコンを出すかを指定します。4つ目の引数はOKボタンを出す事をしていします。5つ目の引数は、表示する文字列です。
gtk_dialog_run()dialogを表示し、OKが押されるまで待ちます。
gtk_widget_destroy()作成したdialogを削除します。

コンパイル時には`pkg-config --cflags --libs gtk+-3.0`を指定します。「`」は日本語キーボードでは「@」のキーをShiftキーを押しながら入力すると表示される文字です。これを指定するとpkg-configのコマンドの表示結果をそのままコマンドに渡すことができます。pkg-configは、GTK+で必要なヘッダーファイルの場所と、ライブラリを指定する引数を表示するコマンドです。

GTK+の詳細についてはここにリファレンスマニュアルがあります。ただし全部英語です。

C/C++ Hello World ウィンドウ表示(Windows)

コンソールにHello Worldを表示するプログラムを作りましたが、ウィンドウに表示をした方がプログラムを作った気になるかもしれません。そこでウィンドウにHello Worldを表示するプログラムの作成です。

Windowsの場合、多くのライブラリがMicrosoftから提供されており、Win32 API、.NET Framework API、WinRT API、MFC、ATLなど色々とあります。この中で最も原始的なWin32 APIがC言語と相性がいいので、それを使用します。

プログラムは以下です。



以下のようにコンパイルし、実行します。
$ gcc hello2.c -mwindows
$ ./a.exe
すると以下のようなウィンドウが表示されます。


ソースコードはコンソール版とかなり違います。違いを簡単にまとめます。
コンソール版 ウィンドウ版 説明
#include<stdio.h> #include<windows.h> Win32 APIの使用のために、windows.hを組み込みます。
int main() int _tWinMain() ウィンドウでは、最初に実行される関数がmain()では無いです。WinMain()またはwWinMain()となります。一つ目と二つ目の引数は過去に使用していましたが、今は使用していません。 三つ目の引数はコマンドライン引数です。四つ目はウィンドウの表示状態です。
printf() MessageBox() MessageBoxは単純なウィンドウを表示するWin32 APIの関数です。一つ目の引数は親ウィンドウで今回は無いのでNULLです。二つ目の引数はウィンドウ内に表示する文字列、三つめの引数はタイトルの文字列、四つ目の引数はOKボタンを出す事を指定しています。

Win32 APIには、ANSI版とUNICODE版の二つの関数があります。#include<tchar.h>が、その二つの関数の切り替えの仕組みの一つだと考えてください。_T()によって文字列をANSIとUNICODEで切り替えます。_tWinMain()もANSI版のWinMain()とwWinMain()に切り換えられ、MessageBox()もANSI版のMessageBoxA()とMessageBoxW()に切り換えられます。面倒ですが切り替えが出来るように作成した方が将来的に良いかと思われます。

コンパイル時には、-mwindowsというオプションを付けています。これはWindowsの実行形式にはコンソール版とウィンドウ版の二通りがあり、このオプションを付けないとコンソール版となってしまうからです。コンソール版では実行時に必ずコンソールを作成します。エクスプローラからa.exeを実行すると違いがよくわかると思います。

Win32 APIはウィンドウ関係だけでなく、Windowsのほとんどの機能が提供されています。MSDN LibraryのサイトにおいてWindows開発→Windows 2000と辿った所にドキュメントがあるため、Win32 APIの詳細はそれを参照してください。

2013年11月3日日曜日

C/C++ Hello World が動く仕組み

Hello Worldのプログラムを作って動かしたのですが、これがどうやって動いているかを説明します。

まずは、コンピュータの仕組みから説明します。コンピュータは基本的に次の3つから出来ています。


メモリ ↔ CPU ↔ I/O(Input/Output)


キーボードやマウス、ディスプレイにHDDはどこか?というとI/Oにつながっています。

そして、ご存知のようにコンピュータは電気で動いています。電気が流れる・流れないの2つの状態を大量にメモリに持っています。CPUでその電気の流れる・流れないの状態を取得したり、変更したりします。またCPUはキーボード等からI/Oを通じて電気の流れる・流れないを取得したり、ディスプレイに電気の流れる、流れないを渡して表示を行ったりすることができます。

単純に流れる・流れないは 2値(ディジタル)ですが、2値をたくさん組み合わたデータを操作することで色々なことができるのがコンピュータです。



さて、Hello Worldの仕組みに戻ります。a.exe(a.out)というファイルが作られたのですが、このファイルは実行形式のデータとなっています。画像は単に画像形式に、文書は文書形式になっているだけで、コンピュータは2値を組み合わせたデータを扱うと言う点に違いはないです。

実行形式のデータはOSによって中身が違っており、WindowsではPE(Portable Executable)という形式になっており、LinuxではELF(Excutable and Linkable Format)という形式になっています。gccなどのコンパイラはコンパイルすることでこれらの形式のファイルを作ります。

実行形式のファイルを実行する操作を行うと、OSが実行形式をI/Oを通じてHDDからファイルをメモリ上に展開します。 そして、main()という名前の関数から実行を行うようになっています。

CPUの部分では、以下の手順で実行を行っています。

printf();の実行
 ↓
return 0; の実行

メモリの部分では、プログラム自身と"Hello World\nGood bye\n"などの文字列を記憶しています。

I/Oの部分はプログラムを書くのが難しい部分です。そこで他の人(OS提供元など)が作ったプログラムを組み込み、それを使います。その組み込むプログラムのことをライブラリと言い、ヘッダーファイル(○○.h)と一緒に提供されます。

#include<stdio.h> では、標準I/O(Standard I/O)と言うものを組み込んであり、コンソールに表示を行う機能など、WindowsでもLinuxでも使えるような機能が提供されています。

ライブラリの組み込みは通常は、コンパイル時のオプションで指定する必要があります。しかしC言語の標準的な機能は、何も指定しないでもデフォルトで組み込まれるようになっています。

 以下のように"-v"オプションを付けてコンパイルを行うとコンパイルで何を行っているかの詳細が表示されます。

$ gcc -v hello.c

最後の辺りで -lmsvcrt などの文字が出てくると思います。これらがデフォルトで組み込まれたライブラリです(-lがライブラリを指定するオプションでmsvcrtというライブラリを組み込んだと言うことになります)。

Hello Worldの仕組みについては以上です。Hello Worldでも、大きいプログラムでも、コンピュータの基本が「CPU」、「メモリ」、「I/O」であることから、これらを操作する処理を書くことがプログラムを書くこと、になります。

2013年10月27日日曜日

64bit化の利点と欠点

最近Appleの製品が64bit化したことで、64bit化についての話が盛り上がっているようです。しかし、Windowsの64bit化の際には、あまり意味がないと冷静な意見が多かったのに対して、Appleの場合は理由もなく絶賛されている気がするのですが、気のせいでしょうか?

Ubuntuも今まで32bitが奨励でしたが、Ubuntu 13.10より64bit版が奨励されるようになりました。 メモリが2GB以下の場合は32bit版を奨励するようです。

実際64bit化の恩恵は少ないと思われます。速度的にはベンチマークを見ても確かに早くはなるのですが、この種の計算が一般に使われるとは思いません。

利点

よく言われる64bit化の利点は、32bitでは最大でも4GBのメモリしか使えない問題が解決できることでしょう。最近はメモリの値段も安くなりましたし、4GBメモリの搭載ぐらいは当たり前になってきたので、64bit化も良いかと思います。 ただしiPhone5Sは1GBメモリのようで、意味はないです。

IntelのCPUの場合には、64bit化によりレジスタの数が増えているので、それも高速化に役立つようです。

その他、大きな整数値が速い利点もありますが、32bitでも 40億近い数値が扱えますので、普通は必要ないでしょう。

欠点

欠点はサイズが大きくなることでしょう。

  1. 32bit版と64bit版を両方動かすためのシステムのサイズの拡大
  2. 32bit版と64bit版を両方動かすためのアプリケーションのサイズの拡大
  3. アプリケーション自身のサイズの拡大
通常64bit版はシステム側に32bit版のアプリケーションを動作をさせるための仕組みが入っています。Fedoraでは /lib64 の他に、/libが32bit用のフォルダがありますし、Windowsも C:¥Windows¥System32の他にC:¥Windows¥SysWOW64という32bit用の動作のためのフォルダが出来ます。

アプリケーションも64bit専用のものは、32bit版では動作しないため、アプリケーションは64bit用と32bit用の2つを用意する必要があります。普通の人は64bit版や32bit版などの区別を考えたくないので、それは避けたいです。Appleではユニーバーサルバイナリと言うものがあるので、それを使うことになるかもしれません。しかし、単に2つの実行ファイルを合わせて1つに見せかけるだけなので、ファットバイナリ(サイズの大きいバイナリ)と言われています。

そして64bit用のアプリケーション自身も持つデータも一部が2倍になります。そこそこ良く使われるアドレスのデータが64bitになるのは影響が大きそうです。

たぶんAppleは今までも互換性を重要視していないので1,2の欠点克服のために32bit版はいつか捨てることにするのでしょう。きっと今回の64bit化は将来に32bitを捨てるために早めの準備をし始めただけで、しばらくは利点より欠点の方が多いと思われます。


X32 ABIの話

Linuxでは欠点の3の対策として「64bit化でのレジスタ増加による高速化は利用して、アドレスは32bit」というX32 ABIと言うものが使えるようになっています。アドレスが64bitになることで4GB以上のメモリの使用ができるのですが、そこまでメモリを使うアプリケーションは少ないと考えられるためです。しかし欠点の1に関してはさらにサイズが増えることになります。

Fedora19ではX32 ABI用を使うためのパッケージも無いようですし、カーネル
もconfigを見るとCONFIG_X86_X32=yとなっていませんでした。FedoraでX32 APIを使うにはカーネルのビルドから行う必要があり少し面倒そうです。

Ubuntuでは、X32 ABIを使用できるようになっているようです。以下のように32bit版のビルド環境をインストールすれば、X32 APIのコンパイルも出来るようになります。
$ apt-get install lib6-dev-i386

コンパイルは-mx32オプションを使用します。
$ gcc -mx32 test.c

なお、通常の64bitや、32bitのアプリケーションと作るときのオプションは-m64, -m32です。

-mx32でコンパイルした実行ファイルをlddで確認すると、/lib32x/libc.so.6が使われています。またobjdump -f で確認するとfile formatがelf32-x86-64となっているなど、32bitと64bitが混合されているような表示となっています。


追記:後藤弘茂氏によるとARM32bit命令は変態命令セットのため、「アドレス空間のメリットは3番目」とのことですが、x86のレジスタ数はARM32bitより更に少ないですし、セキュリティも指紋センサーのみにしか使えないなら、やはり64bitの利点ではないような気がする・・・

C/C++ Hello Worldと文法

C/C++の準備が終わった所で、Hello Worldを作ります。Hello Worldは一番最初に作るプログラムとしては有名で、単に Hello World と表示するだけのものです。
以下の様に入力します。

最初にhelloというディレクトリを作ってそのディレクトリに移動しています。
vimでhello.cでソースコードを書いて保存します。

hello.cの中身は以下のように書きました。


一番したの:wqは保存して終了です。
それで、gccというコマンドによって、hello.cをプログラムに変更します。この変更作業をコンパイルといい、gccのようなソフトウェアをコンパイラと言います(厳密には少し違いますが)。

プログラムの名前は、Windowsの場合、a.exeという名前になります。 Linuxの場合は、a.outという名前になります。
 ./a.exeと入力しEnterキーを押すとa.exeという名前のプログラムが実行され、 ソースコードに書いた文字が表示されます。

またhello.c内でLinuxの場合は、円マーク(¥)を記述した部分はバックスラッシュ(\)と表示されるかもしれません。

最後のlsコマンドで、a.exeとhello.cのファイルがあることが確認できると思います。

hello.cの文法について説明します。文法とはどのように記述をするか、と言うことです。この文法に従ってソースコードを書かないとgccを行ったときにエラーとなります。

#include <stdio.h>

最初に#から始まっている行は(青字で見難いですが)、C/C++言語では特殊な行でマクロと呼ばれています。先ほど、gccコマンドで実行ファイルを作成しましたが、実際には、gccコマンドでは以下が行われています。

プリプロセス → コンパイル → リンク

#で始まる行はプリプロセスによって、処理され文法もC言語本体とは異なります。
includeは意味がある単語で、分割できません。 例えば下記のようにincとludeの間にスペースを入れます。

#inc lude <stdio.h>

すると、下記のようにエラーが表示されます。エラーが表示された場合、プログラムは作成されないので、ソースコードを修正して再度コンパイルを行う必要があります。




マクロの文法を意味のある単語に分割すると以下のようになります。

単語 説明
# マクロであることを示します。
include 指定した機能を使用する事を宣言するために使います。実際に行っていることは別のC言語のファイルを取り込むだけです。
<stdio.h> stdio.hと言う名前の機能を使用することを示します。機能はOS(またはコンパイラ)が最初から用意している機能です。
自分で作った機能の場合には"myfunc.h"のように"で括ります。

改行
マクロの終了を意味します。マクロでは改行が意味を持ちます。マクロを終了したくない場合には¥(\)で繋ぎます。例えば以下のようにします。
#include ¥
<stdio.h>

この単語の間には空白文字(スペースキーで入力した文字)をどれだけ入れても問題ないです。

その他がC言語本体となります。「関数」については後述します。
単語 説明
int 次の関数main()の返り値の型を示します。C言語では省略可能で、省略するとintとみなされますが、省略しないことを奨励します。
main mainという名前の関数名で、機能を記述することを示します。
( ここから関数の引数の記述を開始すると言う意味です。
) ここで関数の引数の記述を終了すると言う意味です。
{ ここから関数の中身の記述を開始するという意味です。
printf printfというコンソールに文字列を表示する関数を実行することを意味します。stdio.hに機能が含まれています。
( ここから関数の引数の記述を開始すると言う意味です。
"Hello World¥nGood bye\n" 関数に渡す引数を記述しています。この記述はプログラムの動作とは関係ないデータで、ソースコードに直接記述するデータをリテラルといい、このダブルコーテーション(")で括ったデータは文字列のデータのため、文字列リテラルと言います。
) ここで関数の引数の記述を終了すると言う意味です。
; printfから始まった機能の記述の終了を意味します。
return main関数を次に指定された値で終了することを意味します。
0 返り値を示します。この記述はプログラムの動作とは関係ないデータで、ソースコードに直接記述するデータをリテラルといい、数値だけのデータは数値リテラルと言います。
; returnから始まった機能の記述の終了を意味します。
} ここで関数の中身の記述を終了すると言う意味です。
これらの単語の間には空白類文字(スペース、改行、タブ)をどれだけ入れても問題ないです。マクロは空白のみで、C言語部分は改行やタブもOKです。単語の大文字小文字は区別するのでreturnをReturnなどと記述するとコンパイルできません。

文字列リテラルについてもう少し詳しく話します。リテラル内の¥文字は特殊な意味を持ち、¥nは改行を意味します。円マーク自体を表示したい場合は¥¥と2つ繋げて文字列リテラル内に書くと1つの¥が表示されます。文字列リテラル内で改行は出来ません。長い文字を分割したい場合は、一旦ダブルコーテーション"で終了し、改行してから再度ダブルコーテーション(")で記述します。

以下はNGです。

        printf("Hello World¥n
                Good bye¥n");

以下はOKです。
        printf("Hello World¥n"
              "Good bye¥n");


main()やprintf()は関数と呼び、データを扱って処理を行う機能のひと塊を指定します。関数はデータを受け取り、処理をして、データを返します。

このプログラムではmain()の機能を自分で作って、すでにあるprintf()の機能を使用しています。main()ではデータの受け取りはしていませんが、0を返しています。printf()では、 "Hello World¥nGood bye\n"のデータを受け渡しています。返り値も戻ってきていますが、その返り値に対して何もしていません。

main()は少し特殊な関数でプログラムが実行されると一番最初に呼ばれる関数です。main()関数の返り値はコンソール上で以下の様にechoコマンドで表示することができます。

$ echo $?

文法に関してはとりあえず以上です。最初の頃は機能の終了を示すセミコロン(;)を入力し忘れやすいかもしれません。 色々なところに改行や空白を入れたり、終了を意味する記述を削除したりして、コンパイルを試すと文法について詳しく解ってくると思います。