simotin13's message

simotin13といいます。記事の内容でご質問やご意見がありましたらお気軽にコメントしてください\^o^/

Elixir入門 ~2日目 リストとタプルを試す~

昨日はインタラクティブな環境iexを立ち上げてみたり、ファイルに書いたElixirのHello Worldを動かした。
まだ大してElixirの魅力とか特徴がつかめていない。

今日は、適当にデータ型をいくつか触ってみたり、昨日は触らなかったコンパイルを試してみる。

データ型

iexで少し遊んでみる。
iexの終了はCtrl-Cでabortを選べばいいみたい。

リスト

リストには何でも入る

[1, "abc", 3.14, false]

リストは内部的には、連結リストになっている。lispのconsセルと同じだ。
なので先頭に要素追加は速く、末尾への追加は遅いということらしい。

[0] ++ [1, 2, 3]

は早いけど、

[1, 2, 3] ++ [4] 

は遅い。

以下のような、指定したインデックスのオブジェクトも遅くなるそうだ。

 Enum.at(["a", "b", "c", "d"], 1)

みたいな書き方をする。

タプル

リストは連結リスト構造なのに対してタプルは配列という理解でよさそう。

tp = {1,2,3}

配列なので

tp[0]

でインデックスアクセスができそうだがそれはできない。
一般的な言語のインデックスアクセスに相当するのは

elem(tp,0)

のようなコードになる。

何をするにも関数を使う必要がある。関数プログラミングらしさを感じてきた。

コンパイル

Elixirのコードのコンパイル

$ elixirc ファイル名

コンパイルできる。

コンパイルすると、Elixir.ファイル名.BEAM

というファイルができる。


疲れたので続きは、また明日以降・・・

Elixir入門 ~1日目 導入~

コンパイラの授業でお世話になった石浦先生に教えて頂いたelixirを勉強してみることにしました。
(コンパイラの授業を受けた話はまだ書けていないのでそのうち書きたいと思います)

ちなみに石浦先生の研究室ではerlangFPGAの高位合成をする研究をしているそうです。
普段の記事は「です・ます調」で書いていますが、elixirの勉強の記事は個人的な記録としての意味合いが強いので、この勉強の記録は独白・口語体で書くことにします。
あと学習の過程を書いているのでその時点で間違ったことを書いている可能性はあります。
理解の度合いや指摘があれば直すと思いますが、もしここに書いている内容を参考にされる方は自己責任でお願いします。

はじまり

とりあえずがっつりelixirの勉強だけはできないだろうから毎日数行のコードを書いて行くことにする。
こういうのは本当に少しでもいいから毎日やった方がいいかもしれない。
コンパイラの勉強とかLinuxカーネルの勉強とか、やりたいことはいろいろあるし仕事関係の勉強もあるので時間はどうせたくさんは取れない。

なぜerlangにしなかったのか。

Elixirの文法がrubyに近いという噂を聞いたから。コツがつかめらたらerlangとかBEAMのレイヤも勉強したい。

参考書籍

プログラミングElixir

プログラミングElixir

サンプルプログラムのダウンロードもできる。

導入

elixir-lang.org

でインストール方法を調べる。

windows環境

とりあえずwindows用にインストーラを走らせてみた。
何も考えず「次へ」を押したので何が入ったとかよく分かっていない。

インストールが終わるとErlangがインストールされていた。elixirはErlang用のBEAMという仮想マシン上で動くらしいので、まぁそういうことなんだろう。
cygwinのコンソールからiexしてみても動かなかった。

後でパスを通そう。

Linux環境

VMLinux Mint上で、

$ sudo apt-get install elixir

してみた。

iexでインタラクティブなシェルが立ち上がったので多分大丈夫だろう。

Hello World

拡張子

elixirの拡張子は

.ex もしくは .exs にするのが習慣らしい。

.exはコンパイル済みのファイルに付け、 .exs はスクリプトに書くらしい。

感覚としては、Elixirは中間言語による仮想マシン方式とのことなので
Javaの .class と .java みたいな感じだろうか。
Javaと違ってコンパイルしなくても動かせる。LispHaskellと同じ。

IO.puts "Hello, World!"

スクリプト実行

コンパイルなしの実行はRubyPython等と同じで

$elixir ファイル名

とすればよい。

上記のコードをhello.exs に保存して動かす。

$ elixir hello.exs
Hello, World!

ちゃんと動いた。

iexでの実行

c ヘルパーという機能でiexからも実行できる

c "hello.exs"
Hello, World!
[]

評価された後[]が出ている。パッと見は空の配列に見えるけど、全てはリストで表現されているんだろうか。


コンパイルについてはなんか長くなりそうなので今日はこれまでにしておく。

CMakeでARM用にクロスコンパイルする

最近、オープンソースなどで配布されているソフトのビルドシステムがCMakeになっているのをよく見かけるようになりました。

CMakeはこれまでも何回か使ったことがありましたが、クロスコンパイルをしたいときの使い方を忘れてしまっていて、思い出すのに時間がかかったので備忘録として書いておきたいと思います。

CMakeでHello World

ロスコンパイルの前にC言語Hello WorldプログラムをCMakeを使って(セルフコンパイル)ビルドしてみます。

ビルドするコード

#include <stdio.h>

int main(int argc, char **argv)
{
	printf("hello world\n");
	return 0;
}

CMakeLists.txt を書く

CMakeLists.txtを最小限の構成で手っ取り早く書くとこんな感じです。

cmake_minimum_required(VERSION 2.8)
add_executable(helloworld main.c)

cmake_minimum_required は文字通りcmakeのバージョンです。
add_executable でターゲット名とソースファイルを指定します。

ビルド

cmakeの便利な点として、ソースファイルのディレクトリとオブジェクトの出力ディレクトリを分けてビルドできる点があります。
CMakeLists.txt があるディレクトリで、

$ mkdir build
$ cd build
$ cmake ..

とすると、作成したbuildディレクトリ内にMakefileなどビルドに必要なファイルが生成されます。

実行例はこんな感じです。

-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done

$ ls
CMakeCache.txt  CMakeFiles  Makefile  cmake_install.cmake

あとはこのbuildディレクトリでmakeコマンドを実行すればビルドできます。
私の環境だとコンパイラGCCが使われたようです。

$ make
Scanning dependencies of target helloworld
[ 50%] Building C object CMakeFiles/helloworld.dir/main.c.o
[100%] Linking C executable helloworld
[100%] Built target helloworld

$ ./helloworld 
hello world

ロスコンパイルを試す

これでCMakeによるセルフコンパイルの準備はできました。
ロスコンパイルを行う場合は、更にツールチェインファイルというファイルを作成する必要があります。
といっても大げさなものではなくて、文字通りクロスコンパイル時に使用するコンパイラの指定をするだけです。

今回はRaspberrypi でも実行できるので、クロスコンパイラとして arm-linux-gnueabihf-gcc を使ってみました。
私が試したビルド環境は64bit版の Linux mint です。

$ uname -a
Linux mint 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

Ubuntu系のOSであればインストールは、

$sudo apt install g++-arm-linux-gnueabihf

でインストールできると思います。

ツールチェインファイルの書き方

さて、本題のツールチェインファイルは以下のようになります。

ファイル名を arm-toolchain.cmake として、以下のような記述をします。

SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_C_COMPILER /usr/bin/arm-linux-gnueabihf-gcc)

ツールチェインファイルを書いたら、後はセルフコンパイルの時と同様にビルド用のディレクトリを作ってcmakeコマンドを実行します。

$ mkdir cross-build
$ cd cross-build
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=../arm-toolchain.cmake

セルフコンパイルの時との違いとして、

  • DCMAKE_TOOLCHAIN_FILE=../arm-toolchain.cmake

のようにツールチェインファイルのパスを指定してあげる必要があります。

-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/arm-linux-gnueabihf-gcc
-- Check for working C compiler: /usr/bin/arm-linux-gnueabihf-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done

$ make
Scanning dependencies of target helloworld
[ 50%] Building C object CMakeFiles/helloworld.dir/main.c.o
[100%] Linking C executable helloworld
[100%] Built target helloworld

$ file helloworld
helloworld: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=9bd916148cf9880f2494f47199e8c001244a450d, not stripped

ちゃんとARM用にクロスコンパイルできました。
かなりミニマムな構成でのビルドの例なので、実際にオープンソースのプロジェクトなどをビルドする際はもう少しオプションやパスの指定などが必要になってくるかと思います。

自分の雛形用として、Githubにおいています。もし参考にされる方がいらっしゃいましたらどうぞ。

gist.github.com

[2017/10/2 追記]
クロス環境向けのインクルードパスとかのプレフィックスはどうするんだろう・・・ってなったので追記しておきます。

クロス開発環境のプレフィックスについて

クロス開発環境を使う際には、クロスコンパイラが使用するインクルードパス・ライブラリパスの指定が必要になってきます。

cmakeを使ってプレフィックスパスを指定する場合は、

 -DCMAKE_INSTALL_PREFIX:PATH=クロス環境のプレフィックスパス

とすればよいようです。

上記の Raspberry pi の例だと、

$ cmake .. -DCMAKE_TOOLCHAIN_FILE=../arm-toolchain.cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr/arm-linux-gnueabihf/

のような感じになります。

感想

CMakeは書き方を覚えてしまえばMakefileを直接書くよりは楽といえば楽ですね。
昔はMakeの本を読んで一生懸命Makefileを書き方を勉強したものですが、Makefileは書かないとすぐに忘れてしまいます。

Makefileを書きたくないものぐさな私は、

$ echo "gcc main.c hoge.c -o target" > build.sh
$ chmod +x build.sh
$ ./build.sh

みたいなことをよくしています。

小規模な実験的なコードを書く場合はこのやり方でもよいのですが、プロジェクトが育ってくるとやはりビルド管理したくなります。

Makefileさえ知らない新人のころのあるプロジェクトでは、

ソースコード書いたらmfmkってコマンドを実行すればいいから」

と親切な先輩が教えくれた現場がありました。

あの便利な mkmf はLinux系のOSには標準では入っていないんですね。

依存関係とかを気にせずに特定のディレクトリのソースコード調べてMakefile生成するだけであれば簡単に作れそうに思います。気が向いたら作ってみたいです・・・

ウイルス性のいぼを自宅で治療した

最近、子供の足にウイルス性のイボができていたのですが、病院に行かずなんとか自力で治すことができました。

写真は治りかけの子供の患部の状態です。

削った後なのでかなりきれいになった状態ですが、(写真ではわかりづらいですが)赤いぶつぶつがまだ少し残っています。
*1

f:id:simotin13:20170904215656j:plain

[2017-11-18 追記]
この記事ですが、割と沢山の方に読んで頂いているようですので完治後の子供の写真を載せておきたいと思います。

f:id:simotin13:20171119005703p:plain

ウイルス性いぼによる赤い点々は完全になくなっています。
針で削ったこともあってか、皮膚は少し荒れていますが、イボ自体は完全に無くなりました。

*1:記事を書こうとは思っていなかったこともあり治療前から写真はとっていませんでした

続きを読む

WiFiのパケットをWireSharkでキャプチャする方法

スマホの通信(WiFi)をキャプチャする必要があり、少しネットを調べてみたのですが、あまりいい方法が見つからなかったので思いついた方法を試してみました。

試してみた結果、いい感じにスマホが送受信するパケットをWireSharkでキャプチャすることができたので記事として挙げておきたいと思います。

目次

  • 目次
  • 注意
  • 作戦
    • パソコンをWiFiのAPにする
  • 準備するもの
    • 注意点
  • 手順
  • その他のやり方は?
  • 追記

注意

紹介する方法はWindows7でしかできない方法になります。他のOSについては別途試したときに記事を書きたいと思います。

作戦

パソコンをWiFiのAPにする

WiFiのパケットをキャプチャする場合、WiFiルータのところでキャプチャする必要がありますが、ルーターの通信をキャプチャするとなるとできなくはないのですが、環境構築とかが少し面倒です。

他に手軽にできる方法が無いか考えて、パソコンをアクセスポイントにして流れてくるパケットをキャプチャするという方法を思いつきました。

今回試した環境は、Windows7のPCです。インターネットには有線LAN経由で接続した状態にします。

準備するもの

パソコンをWiFiのAPにする場合、親機になれるUSBの無線LANドングルがあれば実現可能です。

USB無線LANドングルは1つの独立したネットワークアダプタとして認識されるのでWireSharkでキャプチャするときも便利です。

いろいろ調べてみると、バッファローのWLI-UC-GNM2SであればWindows7であればWiFiの親機のになれるとのことで購入して試してみました。

続きを読む