Windows7 SP1(64bit) でStack newに失敗しまくってハマった件
随分遅ればせながら、Haskell Platform 2014.2.0.0からstack-1.2.0へ移行してみたところ、いくつか不具合があったので記しておく。
stack setupでハマる
stack-1.2.0のインストーラからstackをインストールし、
$ stack setup
しようとするも、
TlsException (HandshakeFailed (Error_Protocol ("certificate has unknown CA",True,UnknownCa)))
とか出てGHCがインストールできない。
これはどうもインストールするべきGHCのパッケージ群のバージョン等の情報を与えていないせいのようで、適当なディレクトリに
https://github.com/commercialhaskell/stack/blob/master/stack-8.0.yaml
をDL。stack.yamlにリネームした上でカレントディレクトリに置き、
$ stack setup
を実行すると、上手くGHCのインストールが出来た。
stack newでハマる
適当にHello worldでもするかと思い、ホームディレクトリで
$ stack new helloworld
としようとするも、またしても
TlsException (HandshakeFailed (Error_Protocol ("certificate has unknown CA",True,UnknownCa)))
グーグル先生曰く、一度IEで適当なHTTPSのサイトを訪問するべしとか書いてあるけれど改善しない。
で、最終的にやってみたのが、stack newの時に参照するsnapshotのURL
https://www.stackage.org/download/snapshots.json
をIEで訪問する(ファイルを開くか保存するか聞いてくるので、適当に保存しておく)という方法。
これをやった後、再度
$ stack new helloworld
すると、なんとか上手く動作した。
もし同様にハマった方は一度お試しあれ。
補足
stack newの時にやった、shapshotへのアクセスを最初にやっておけば、stack setupの時もstack-8.0.yamlの導入は要らないかもしれない。
Raspberry PiでUSBに繋いだストレージ(USBメモリ・HDD・SSDなど)をマウントするちょっと素敵な方法
きっかけ
Raspberry Pi内のデータをUSBメモリにバックアップしたり、大きいデータを持つためにHDDをつないだりして、USBに複数のストレージデバイスが接続された時に、
- 各ストレージデバイスを一意に識別する方法
- 特に、全く同じ機種を複数接続したときに、それぞれを識別する方法
- 同じデバイスに対して、常に同じやり方でマウントできるようにする方法
- 特に、挿したUSBポートや、挿した順番とかに依存しない方法
を得たい。
Raspbianでは、/dev がUDEVによって管理されるので、その辺の設定ファイルを書く事で対処できる。
第1章 各デバイスのSERIAL IDが異なる場合
1. USBからストレージデバイスを全部外した状態で、Raspberry Piを起動。
ls /dev/sd*
で、「sdなんちゃら」(「なんちゃら」の所はアルファベット1文字になる)が出てこないのを確認。
2. 任意のストレージデバイスを1個だけ繋いでみる
ls /dev/sd*
すると、「sda」とか「sda1」とか出てくるはず。
場合によっては「sdb」とか「sdb1」とかかも。
ここでは「sda」「sda1」として話を進める。
3. マウントしてみて、どのデータを収めたデバイスなのかを確認する
※新品のデバイス2つを新たに接続したい場合とかのように、確認が不要な場合はこの項目は飛ばして下さい。
sudo mount /dev/sda1 /mnt
とか、
ls /mnt
とかやって、繋いだストレージデバイスがどれなのかを特定する。
確認したら、
sudo umount /dev/sda1
4. デバイスのIDを調べる
sudo udevadm info -q all -n /dev/sda
を実行すると、デバイスに関する情報がずらずらと表示される。
必要なのは、
E: ID_SERIAL=
の行。例えば、わたしの環境では、SanDiskのUSBメモリを繋いでいるので、
E: ID_SERIAL=SanDisk_Cruzer_Fit_00000000000000000000-0:0
みたいになる(数字の部分は適当に改変してます)。
「=」から右の部分をメモっておくとGOOD。
5. デバイスを外す
普通にUSB端子からズブッと抜いちゃいます。
7. UDEVのルールを書く
/etc/udev/rules.d 内に、このデバイスに6.で考えた名前を割り当てるためのルールファイルを書く。
ファイル名の先頭に出来るだけ大きな2桁の数字(99とか)を付ける。例えば、
99-usbmem_backup.rules
とか。
内容は以下を参考に。
SUBSYSTEM=="block", ENV{ID_BUS}=="usb", ENV{ID_SERIAL}=="SanDisk_Cruzer_Fit_00000000000000000000-0:0", SYMLINK+="usbmem_backup%n"
長いので行を分けているけれど、実際は一行で記述。
個別に変更する必要があるのは、
- 「ENV{ID_SERIAL}==」の右の部分。4.で調べたID_SERIALを使用。
- 「SYMLINK+=」の右の部分。6.で考えた名前を使用。
なおこのディレクトリはパーミッションの問題でrootしか書き込めないので、
- エディタをsudoで起動し、ファイルを作成する
- 他の場所にファイルを作成し、sudo cp でファイルをコピーする
のどちらかで対応。
8. 2~7を、接続したいデバイスそれぞれに対し実施する
9. 完了
特にudevを再起動する必要とかはなし。
デバイスを挿した時ごとに、/etc/udev/rules.d 内を実行する模様。
あとは /etc/fstab に書くなり、必要なときにmountするなり、ご自由に。
第2章 デバイスが同じSERIAL IDを持つ場合
そんな場合があるのかどうか確かめてはいないが、もしそうであった場合には、各デバイスを識別するには他の方法を使うしかない。
例えば、USBのどのポートに繋いだかという情報を元に設定するとか。
1. USBからストレージデバイスを全部外した状態で、Raspberry Piを起動。
第1章の1.と同じ。
3. マウントしてみて、どのデータを収めたデバイスなのかを確認する
第1章の3.と同じ。
4.デバイスの刺さっているUSBポート番号を調べる
第1章と同様に、コマンドラインで
sudo udevadm info -q all -n /dev/sda
を実行すると、デバイスに関する情報がずらずらと表示される。
今度は、必要なのは、
E: ID_PATH_TAG=
の行。例えば、わたしの環境では、SanDiskのUSBメモリを繋いでいるので、
E: ID_PATH_TAG=platform-bcm2708_usb-usb-0_1_2_1_0-scsi-0_0_0_0
とか、別のポートにつなぐと、
E: ID_PATH_TAG=platform-bcm2708_usb-usb-0_1_3_1_0-scsi-0_0_0_0
「=」から右の部分をメモっておくとGOOD。
5. デバイスを外す
第1章と同じ。
6. デバイスの固有の名前を考える。
第1章と同じ。
7. UDEVのルールを書く
/etc/udev/rules.d 内に、このデバイスに6.で考えた名前を割り当てるためのルールファイルを書く。
ファイル名の先頭に出来るだけ大きな2桁の数字(99とか)を付ける。例えば、
99-usbmem_backup.rules
とか。
内容は以下を参考に。
SUBSYSTEM=="block", ENV{ID_BUS}=="usb", ENV{ID_PATH_TAG}=="platform-bcm2708_usb-usb-0_1_2_1_0-scsi-0_0_0_0", SYMLINK+="usbmem_backup%n"
長いので行を分けているけれど、実際は一行で記述。
個別に変更する必要があるのは、
- 「ENV{ID_PATH_TAG}==」の右の部分。4.で調べたID_PATH_TAGを使用。
- 「SYMLINK+=」の右の部分。6.で考えた名前を使用。
なおこのディレクトリはパーミッションの問題でrootしか書き込めないので、
- エディタをsudoで起動し、ファイルを作成する
- 他の場所にファイルを作成し、sudo cp でファイルをコピーする
のどちらかで対応。
8. 2~7を、接続したいデバイスそれぞれに対し実施する
9. 完了
第1章と同じ。
ただし、USBのポート番号だけで判別している(何が挿さっているか見ていない)ので、実際に運用する場合には挿すUSBのポートを変えないように。
ちなみに、UDEVのルールにはワイルドカードが使えるので、
- USBのポート2か3に繋いだデバイスに指定の名前を付けたい
というような場合には、例えば
SUBSYSTEM=="block", ENV{ID_BUS}=="usb", ENV{ID_PATH_TAG}=="platform-bcm2708_usb-usb-0_1_[23]_1_0-scsi-0_0_0_0", SYMLINK+="usbmem_backup%n"
とかやると、USBのポート2か3に接続されたデバイスを、「/dev/usbmem_backup」等の名前にすることが可能。
さらに、
- USBの特定のポート(複数可)に接続された
- あるSERIAL IDを持ったデバイス
に対するルールも定義可能。
例えば、
SUBSYSTEM=="block", ENV{ID_BUS}=="usb", ENV{ID_PATH_TAG}=="platform-bcm2708_usb-usb-0_1_[23]_1_0-scsi-0_0_0_0", ENV{ID_SERIAL}=="SanDisk_Cruzer_Fit_00000000000000000000-0:0", SYMLINK+="usbmem_backup%n"
とか書いたら、USBのポート2か3に接続された、指定のSERIAL IDを持つデバイスを「usbmem_backup」等の名前にすることが可能。
Raspberry Piでユーザアカウントを追加する正しい方法
Linux Boxとして使うには罠が多い件について
Raspberry Pi2を買うまでは玄箱でちまちまやってきたわたしとしては、 /etc/shadow とか知らなかったのですよ。
で、ググりつつユーザアカウントでも追加してみるかと思ったところ、ハマってしまったわけで。
$ sudouseradd -m -g users -G adm,dialout,cdrom,sudo,audio,video,plugdev,games,netdev,input,spi,gpio foo
で、アカウントを有効化しようと思ったら、passwdコマンドかusermodコマンドでパスワードを設定しないといけない。
まず、passwdを使おうと思って、
$ sudo su - foo $ passwd foo 用にパスワードを変更中 現在のUNIXパスワード:
・・・今はパスワードなんか無いと言うに。
で、usermodの方を調べてみると、
- p password
とか書いてあるわけですよ。どないせえと。
で、強引に /etc/shadow のパスワードエントリをユーザpiからコピペしてきたりすると、 /etc/passwd との不整合が起こって、
$ sudo pwconv
とかやる羽目になったり。
正しい方法
で、色々見てて、passwdコマンドのmanpageを見てやっと分かった次第。それは、
- rootがpasswdコマンドを使う場合、現在のパスワードの入力を省略できる。
・・・これ。これをもっとアピールしてくれれば、・・・
で、正しい手順
- sudo useradd
でユーザアカウントを作成する - sudo passwd
でパスワードを設定する - パスワードを設定したらアカウントは有効化されるので、sudo usermod -U
とかはしなくて良い
- パスワードを設定したらアカウントは有効化されるので、sudo usermod -U
少しでもまともなUnixを触った人なら常識なんだろうけれど、シャドウパスワードとか何それ?、と言う人も恐らく触っていると思うので、誰かの役に立つことを願って。
Eclipse CDTで複数のMinGW環境を使い分ける(Windows)
悲しい出来事
Haskell Platform 2014.2.0.0をWindows7 Pro 64bitにインストールしたら、どうも内部でMinGWを使っている&環境変数PATHに登録してしまうようで、EclipseのCDTがこれをデフォルトのMinGW環境と認識してしまう模様。
で、既に入れてあったMinGW32/MSYSと、MinGW-w64を選択しようとしても、選択肢すら出てこない。
これを回避可能にするために、バッチファイルで対処してみたと言う話。
何をどうしたか
ひとまず、
- 環境変数PATHにHaskell Platform同梱のMinGWへのパスが通っているのはまずい
- Eclipseが起動するためには、JREへのパスが通っていないといけない
- 環境変数CPATH、CPLUS_INCLUDE_PATH、LIBRARY_PATH辺りはバッチファイルで設定する(Eclipseの環境設定ではしない)
- Win32用とWin64用のどちらをビルドするか選択したい
- その際、共通化できるものはしておきたい
- MinGWのアップグレードなどに対応しやすくしたい(同じ設定を複数ファイルに書かない)
ので、バッチファイルをWin32環境用とWin64環境用に分け、さらにそれぞれを3つのバッチファイルから構成する。
├┬ Win32用
│├ ○メインのバッチファイル eclipse_cdt_mingw32.bat
│├ ○環境変数PATH設定用(Win32/Win64共通部分) common_path.bat
│└ ○GCCの環境変数設定用 mingw32_gcc_envval.bat
└┬ Win64用
├ ○メインのバッチファイル eclipse_cdt_mingw64.bat
├ ○環境変数PATH設定用(Win32/Win64共通部分) common_path.bat
└ ○GCCの環境変数設定用 mingw64_gcc_envval.bat
以下、バッチファイルの例。
- common_path.bat
rem 後で更新することを考えて、パスを1つずつ追加していく rem これは個人的な設定の例です set PATH=C:\bin set PATH=%PATH%;C:\bin32 rem Windowsのコマンド類用 set PATH=%PATH%;%SystemRoot%\system32 set PATH=%PATH%;%SystemRoot% set PATH=%PATH%;%SystemRoot%\System32\Wbem set PATH=%PATH%;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\ rem JDK8u45では、以下のパスにJREの実行ファイルへのショートカットがインストールされる(それ以前のバージョンについては未調査) rem Eclipseが起動するためには必須 set PATH=%PATH%;C:\ProgramData\Oracle\Java\javapath rem ...
- eclipse_cdt_mingw32.bat
rem まず共通のパスを設定 call common_path.bat rem MinGW32独自のパス設定 rem ※バッチファイル内と環境変数で記述順が逆になるのに注意 rem おまけ:AMDのAPP SDKとか使っている人向け set PATH=C:\Program Files (x86)\AMD APP SDK\2.9-1\bin\x86;%PATH% set PATH=C:\opt\APPSDK\AMD APP SDK\2.9-1\bin\x86;%PATH% set PATH=C:\Program Files (x86)\AMD APP SDK\2.9-1\bin\x86;%PATH% rem MinGW32用のパス設定を追加 rem 具体的なパスは各自のインストール先フォルダの設定とか参照してください(これはかなり独自の設定なので) set PATH=C:\opt32\MinGW\bin;%PATH% set PATH=C:\opt32\MinGW\msys\1.0\bin;%PATH% set PATH=C:\opt32\MinGW\msys\1.0\local\lib;%PATH% set PATH=C:\opt32\MinGW\msys\1.0\local\bin;%PATH% rem GCC周りの環境変数を設定 call mingw32_gcc_envval.bat rem Eclipseを起動 rem ※このバッチファイルはEclipseのインストール先フォルダに置かれている start eclipse.exe
- mingw32_gcc_envval.bat
rem GCC周りの環境変数を設定 rem PATHと同じく、変更に対応しやすいよう1個ずつ設定 rem ※バッチファイル内と環境変数で記述順が逆になるのに注意 set CPATH=C:\Program Files (x86)\AMD APP SDK\2.9-1\include set CPATH=C:\opt32\MinGW\mingw32\include;%CPATH% set CPATH=C:\opt32\MinGW\lib\gcc\mingw32\4.8.1\include;%CPATH% set CPATH=C:\opt32\MinGW\include;%CPATH% set CPATH=C:\opt32\MinGW\msys\1.0\include;%CPATH% set CPATH=C:\opt32\MinGW\msys\1.0\local\include;%CPATH% set CPLUS_INCLUDE_PATH=C:\opt32\MinGW\lib\gcc\mingw32\4.8.1\include\c++ set LIBRARY_PATH=C:\Program Files (x86)\AMD APP SDK\2.9-1\lib\x86_64 set LIBRARY_PATH=C:\opt32\MinGW\mingw32\lib;%LIBRARY_PATH% set LIBRARY_PATH=C:\opt32\MinGW\lib;%LIBRARY_PATH% set LIBRARY_PATH=C:\opt32\MinGW\lib\gcc\mingw32\4.8.1;%LIBRARY_PATH% set LIBRARY_PATH=C:\opt32\MinGW\msys\1.0\lib;%LIBRARY_PATH% set LIBRARY_PATH=C:\opt32\MinGW\msys\1.0\local\lib;%LIBRARY_PATH%
- eclipse_cdt_mingw64.bat
rem まず共通のパスを設定 call common_path.bat rem MinGW-w64独自のパス設定 rem ※バッチファイル内と環境変数で記述順が逆になるのに注意 rem おまけ:AMDのAPP SDKとか使っている人向け set PATH=C:\Program Files (x86)\AMD APP SDK\2.9-1\bin\x86_64;%PATH% set PATH=C:\opt\APPSDK\AMD APP SDK\2.9-1\bin\x86_64;%PATH% set PATH=C:\Program Files (x86)\AMD APP SDK\2.9-1\bin\x86_64;%PATH% rem MinGW-w64用のパス設定を追加 rem 具体的なパスは各自のインストール先フォルダの設定とか参照してください(これはかなり独自の設定なので) set PATH=C:\Program Files (x86)\AMD APP SDK\2.9-1\bin\x86_64;%PATH% set PATH=C:\opt32\MinGW\msys\1.0\bin;%PATH% set PATH=C:\opt32\MinGW\bin;%PATH% set PATH=C:\opt32\MinGW\msys\1.0\local\bin;%PATH% set PATH=C:\opt\mingw-w64\x86_64-4.9.2-posix-seh-rt_v4-rev2\mingw64\opt\bin;%PATH% set PATH=C:\opt\mingw-w64\x86_64-4.9.2-posix-seh-rt_v4-rev2\mingw64\bin;%PATH% set PATH=C:\usr\local\lib;%PATH% set PATH=C:\usr\local\bin;%PATH% rem GCC周りの環境変数を設定 call mingw64_gcc_envval.bat rem Eclipseを起動 rem ※このバッチファイルはEclipseのインストール先フォルダに置かれている start eclipse.exe
- mingw64_gcc_envval.bat
rem GCC周りの環境変数を設定 rem PATHと同じく、変更に対応しやすいよう1個ずつ設定 rem ※バッチファイル内と環境変数で記述順が逆になるのに注意 set CPATH=C:\Program Files (x86)\AMD APP SDK\2.9-1\include set CPATH=C:\opt\mingw-w64\x86_64-4.9.2-posix-seh-rt_v4-rev2\mingw64\opt\include;%CPATH% set CPATH=C:\opt\mingw-w64\x86_64-4.9.2-posix-seh-rt_v4-rev2\mingw64\opt\lib\libffi-3.1\include;%CPATH% set CPATH=C:\opt\mingw-w64\x86_64-4.9.2-posix-seh-rt_v4-rev2\mingw64\lib\gcc\x86_64-w64-mingw32\4.9.2\include;%CPATH% set CPATH=C:\opt\mingw-w64\x86_64-4.9.2-posix-seh-rt_v4-rev2\mingw64\x86_64-w64-mingw32\include;%CPATH% set CPATH=C:\opt\mingw-w64\x86_64-4.9.2-posix-seh-rt_v4-rev2\mingw64\include;%CPATH% set CPATH=C:\usr\local\include;%CPATH% set CPLUS_INCLUDE_PATH=C:\usr\local\include\boost-1_58 set CPLUS_INCLUDE_PATH=C:\opt\mingw-w64\x86_64-4.9.2-posix-seh-rt_v4-rev2\mingw64\x86_64-w64-mingw32\include\c++;%CPLUS_INCLUDE_PATH% set LIBRARY_PATH=C:\Program Files (x86)\AMD APP SDK\2.9-1\lib\x86_64 set LIBRARY_PATH=C:\usr\local\lib;C:\opt\mingw-w64\x86_64-4.9.2-posix-seh-rt_v4-rev2\mingw64\lib;%LIBRARY_PATH% set LIBRARY_PATH=C:\opt\mingw-w64\x86_64-4.9.2-posix-seh-rt_v4-rev2\mingw64\x86_64-w64-mingw32\lib;%LIBRARY_PATH% set LIBRARY_PATH=C:\opt\mingw-w64\x86_64-4.9.2-posix-seh-rt_v4-rev2\mingw64\opt\lib;%LIBRARY_PATH% set LIBRARY_PATH=C:\opt\mingw-w64\x86_64-4.9.2-posix-seh-rt_v4-rev2\mingw64\lib\gcc\x86_64-w64-mingw32\4.9.2;%LIBRARY_PATH%
・・・うん、分かる人には既に分かっているし、知りたい人には分からないような例ですな(汗
Win32とWin64のどちらのバージョンをビルドするかで、 eclipse_cdt_mingw32.bat と eclipse_cdt_mingw64.bat を使い分けられたし(Eclipseを起動してから変更するとか、器用なことは出来ない)。