2014年2月10日月曜日

org-mode で blog 編集

Blogger の HTML 編集はとてもブラウザ上では厳しいので、Emacs 上で編集するための 仕組みを考えた。Emacs に付属の org-mode はアウトライン記述したテキストデータから HTML を出力する機能を備えているのでこれを利用する。

*.org のようなファイルに適当に文章を書いて、C-c C-e を実行すると他のテキスト形式 に変換することができる。例えば b を押すと HTML に変換されたテキストがブラウザ上 にプレビューされる。

ただし、このままでは目次や著者情報がそのまま表示されてしまうので、 以下の設定をテキストにあらかじめ記述しておく。

#+TITLE: org-mode で blog 編集
#+OPTIONS: title:nil toc:nil \n:nil num:nil author:nil creator:nil f:nil
#+TAGS: Emacs

最後の f:nil はテキスト中の数字を含むブラケット([])が footnote として 解釈されてしまうことを防ぐために指定している。 例えば配列のインデックスを書いたつもりで proc[1] と書いても [1] が footnote として解釈されてしまう。 (実はこの方法がわからず解決までかなり時間がかかってしまった、というのは内緒。 Emacs のディレクトリにある lisp/org/org-ext.el の org-export-with-footnotes というカスタム変数の定義にあるコメントを偶然見つけて気づいた・・・。)

以下に示すように、HTML への変換から Blogger に張り付ける部分のコピーまでを 自動的に行うための Emacs Lisp を書いた。

;; コードブロックをモードと同じ色でハイライト
(setq org-src-fontify-natively t)
;; "*" の h4 にする(Blogger の設定の都合)
(setq org-export-html-toplevel-hlevel 4)
(require 'noflet)
(require 'smartparens)
(defun export-html ()
  "Publish HTML file and copy it into clipboard."
  (interactive)
  (let ((buf (buffer-name)))
    ;; org-export の中で read-char-exclusive が ?H を返すように一時的に動的束縛
    ;; 新規ウィンドウが作成されないように switch-to-buffer-other-window を動的束縛
    (noflet ((read-char-exclusive () ?H)
             (switch-to-buffer-other-window (arg) (switch-to-buffer arg)))
      (org-export))
    (switch-to-buffer buf))
  ;; *Org HTML Export* バッファから Blogger に張る部分の HTML をコピーする
  ;; HTML のパースには smartparens を使用
  (with-current-buffer "*Org HTML Export*"
    (search-forward "<div id=\"content\">")
    (search-backward "<")
    (sp-kill-sexp nil 'yank)))
;; 適当なキーに割り当てる
(org-defkey org-mode-map "\C-ce" 'export-html))

まあ、この方法でも先頭に <h1 class="title"> タグが挿入されてしまうのだけれど、 タイトル欄にカット & ペーストするためにそのままでもよいかなと思っている。 一度タイトル欄に入力した後は、微修正のために毎回 publish する度に、 手作業で削除する羽目になるのだけれど。

一応、先日の howm と org-mode の連携方法を利用して Emacs 上でブログの執筆から 管理までを行えるようになった。howm 化することで一覧表示や検索が容易になるのが うれしい。

2014年2月9日日曜日

howm と org-mode の連携

howm のメモを org-mode でアウトライン的にするための tips など。 howm は 1.4.2、org-mode は Emacs 24.3 を使用した。

(require 's)
(require 'f)
;; howm を展開した場所(任意)に load-path を通す
(add-to-list 'load-path 
             (f-expand (s-concat user-emacs-directory "site-lisp/howm-1.4.2")))
;; *.org を開いたら howm-mode も起動する
(add-hook 'org-mode-hook 'howm-mode)
;; メニューの言語設定
(setq howm-menu-lang 'ja)
;; howm のメモを置くディレクトリ(任意)
(setq howm-directory (f-expand (s-concat user-emacs-directory "howm")))
;; howm ファイル名を設定する。org-mode を起動するため拡張子は .org にする。
(setq howm-file-name-format "%Y/%m/%Y-%m-%d-%H%M%S.org")
(require 'howm)

C-c , c で howm-create を実行すると自動的に org-mode になっているので、 org-mode のメモをアウトライン表記で記入するのみ。

2014年1月12日日曜日

main() の初期化処理

main() はカーネルが管理するヒープ領域とシステムプロセス proc[0] の設定を 行った後、newproc() により proc[1] を生成する。 newproc() を呼び出したコンテキスト(proc[0]) は 0 を返すので、

if (newproc()) {
    /* ... */
}
sched();

を実行すると sched() に入る。sched() では実行可能状態(SRAN)だが、 ロードされていないプロセスを探索するが、見つからないので sleep() する。 sleep() により、コンテキスト切り替え swtch() が発生して proc[1] が実行される。 swtch() では newproc() で proc[1] を生成する際に savu により保存した pc, r5 を retu により復帰させることでコンテキストを proc[1] に切り替えている。 また、swtch() からの return 1 にて上記の if (newproc()) の呼び出しから 戻り値 1 でリターンする。

いくつかのアセンブラコードの解析

copyseg は第一引数で指定したセグメントから第二引数で指定したセグメントへ 1 block 分のデータをコピーする。

_copyseg:
        mov     PS,-(sp)        ; PS を push (-2)
        mov     UISA0,-(sp)     ; UISA0 を push (-4)
        mov     UISA1,-(sp)     ; UISA1 を push (-6)
        mov     $30340,PS       ; 現モード = カーネル、前モード = ユーザ
        mov     10(sp),UISA0    ; 第一引数を UISA0 に設定
        mov     12(sp),UISA1    ; 第二引数を UISA1 に設定
        mov     UISD0,-(sp)     ; UISD0 を push
        mov     UISD1,-(sp)     ; UISD1 を push
        mov     $6,UISD0        ; UISD0 を read/write に設定
        mov     $6,UISD1        ; UISD1 を read/write に設定
        mov     r2,-(sp)        ; r2 を push
        clr     r0              ; r0 は VA=0(APF=0) 番地を指す
        mov     $8192.,r1       ; r1 は VA=8192(APF=1) 番地を指す
        mov     $32.,r2         ; コピーするカウンタ(1block分)
1:
        mfpi    (r0)+           ; r0(UISD0) からスタックに push
        mtpi    (r1)+           ; スタックから pop して r1(UISD1) へ移動
        sob     r2,1b           ; r2 に設定した回数まで繰り返し
        mov     (sp)+,r2        ; 以下、スタックから pop して元の値を復帰
        mov     (sp)+,UISD1
        mov     (sp)+,UISD0
        mov     (sp)+,UISA1
        mov     (sp)+,UISA0
        mov     (sp)+,PS
        rts     pc

clearseg は 0 番地から 32 word を 0 クリアする。 このとき仮想アドレスは UISA0 を通して物理アドレスに変換される。 物理アドレスへの対応は引数で指定した値を UISA0 の PAF に設定することで決定する。

_clearseg:
        mov     PS,-(sp)
        mov     UISA0,-(sp)
        mov     $30340,PS        ; 現モード = カーネル、前モード = ユーザ
        mov     6(sp),UISA0      ; 引数に指定した PAF を UISA0 に設定する
        mov     UISD0,-(sp)
        mov     $6,UISD0         ; 対応する UISD0 は read/write 設定
        clr     r0
        mov     $32.,r1
1:
        clr     -(sp)            ; 次の mpti がスタックから pop した値を使用するため 0 を先に push しておく
        mtpi    (r0)+
        sob     r1,1b            ; -1 した結果が 0 でなければ 2 word 前に分岐
        mov     (sp)+,UISD0
        mov     (sp)+,UISA0
        mov     (sp)+,PS
        rts     pc

saveu は user 構造体のメンバ ursav[2] にカレントスタックポインタと 環境ポインタ(r5)を保存する。引数は ursav へのポインタを与える。

_savu:
        bis     $340,PS         ; プロセッサ優先度を 7(最高) に設定
        mov     (sp)+,r1        ; リターンアドレスを pop
        mov     (sp),r0         ; 引数で指定した user 構造体のメンバ u_rsav
        mov     sp,(r0)+        ; カレントプロセスのスタックポインタを u_rsav[0]
        mov     r5,(r0)+        ; に保存し、r5 を u_rsav[1] に保存
        bic     $340,PS         ; プロセッサ優先度を 0(最低) に設定
        jmp     (r1)            ; 呼び出し元に戻る
_retu:
        bis     $340,PS         ; プロセッサ優先度を 7(最高) に設定
        mov     (sp)+,r1        ; リターンアドレスを pop
        mov     (sp),KISA6      ; KISA6 を引数で指定した物理アドレスに切り替える
        mov     $_u,r0          ; 構造体 u の先頭アドレスを取得
1:
        mov     (r0)+,sp        ; u_rsav[0] からスタックポインタを復帰
        mov     (r0)+,r5        ; u_rsav[1] から環境ポインタ(r5)を復帰
        bic     $340,ps         ; プロセッサ優先度を 0(最低) に設定
        jmp     (r1)            ; 呼び出し元に戻る

2014年1月7日火曜日

Pre K&R C の無名構造体を用いたバイトアクセス

UNIX V6 の Pre K&R C では無名の構造体のメンバが外部に公開されており、 -> 演算子を使って構造体メンバにアクセスできる。 (この時、必ずしも左辺値はポインタ型でなくてもよい。) 16bit の int 型へのポインタから無名構造体のメンバにバイトアクセスする方法を 実験してみた。

struct { 
    char a; 
    char b;
};

int main()
{
    register *p;
    register pa, pb;
    int x;

    x = (0125 << 8) | 0252;
    p = &x;
    printf("%d\n", *p);
    pa = (*p).a;
    pb = (*p).b;
    printf("%d %d\n", pa, pb);
    pa = p->a;
    pb = p->b;
    printf("%d %d\n", pa, pb);

    return (0);
}

実行結果は以下の通り。

# ed main.c
?
a
struct {        char a;         char b;};int main(){    register *p;    register pa, pb;        int x;          x = (0125 << 8) | 0252; p = &x; printf("%d\n", *p);     pa = (*p).a;    pb = (*p).b;    printf("%d %d\n", pa, pb);      pa = p->a;      pb = p->b;      printf("%d %d\n", pa, pb);      return (0);}
.
w
252
q
# cc main.c
# ./a.out
21930
-86 85
-86 85
#

x に 0x55AA ((0125 << 8) | 0252) を代入して、p に x へのポインタを代入する。 当然ながら、*p の値は 0x55AA (21930) になる。 ANSI C と同様に、(*p).a と p->a の結果は一致するが、p->a と p->b の値は それぞれ -86 と 85 になっている。これは、PDP11 がリトルエンディアンであるため、 16bit の p->b によってアクセスされるのは 0x55 (85) であると解釈できる。 同様に、p->a によってアクセスされるのは 0xAA であるが、構造体メンバ a が char 型なので符号拡張されて、0xFFAA (-86) になると解釈できる。

2013年12月6日金曜日

Installing Linux (Yocto) to DE2i-150

今年の夏ごろ(?)からずっとpre-order状態だったDE2i-150がようやく届いた。TerasicのDE2i-150はIntelのAtomプロセッサN2600(cedartrail)とCyclone IV FPGAがPCIリンクにより接続された基板であり、今までデスクトップPCにFPGAが乗ったPCIボードを接続していた構成がそのまま1枚の小さな基板にシュリンクしたようなイメージ(違うかもしれない)。DE2i-150にはあらかじめYocto ProjectのLinuxがインストールされており、とりあえず火入れして起動を確認したが、Terasicのサイトでディスクイメージ(ISOファイル)が配布されているのを知っていたので、おそらくこのディスクイメージからインストールできるのであろうと思い、適当に上書きインストールしてプリインストールのLinuxを早々に潰した。DE2i-150にはmSATA SSD 64GBが搭載されており、ここにLinuxをインストールすることになるのだが、GPTとしてパーティションがフォーマットされるので、そのままでは起動できずにかなり困った。実はインストール直後の状態でも、EFI System Partitionにブートローダは書き込まれており、システム起動時にEFI Shellがあるのでそこから起動させることも可能であるが、デフォルトではBIOSブートになってしまい自動的にEFIブートさせる方法がわからなかったので、GRUBを使ってGPTフォーマットされたパーティションをBIOSブートさせることにした。

インストールの流れは以下の通り。
  1. ISOファイルをUSBに書き込みUSBブート可能にする
  2. インスールが自動的に開始されるのでインストラクションに従う
  3. インストール完了後にリブート
  4. EFI Shellから手動で起動させる
  5. GNU partedをビルドする
  6. GNU partedでBIOS Boot Partitionを作成する
  7. /bootにGRUBをインストールする

ISOファイルをUSBに書き込みUSBブート可能にする

Terasicのサイトからダウンロードできるのはcore-image-sato-cedartrail-20130522214834.isoというディスクイメージであるが、これをUniversal-USB-Installer-1.9.5.1を利用してUSBブート可能にする。Universal USB Installerの使用方法は真面目に調査してないが、Step1では"Try Unlisted Linux ISO"を指定し、Step2では書き込むISOファイルを指定した。

インスールが自動的に開始されるのでインストラクションに従う

USBをDE2i-150に接続した状態で起動し、起動画面が表示されたところでF10を押す。起動メニューが表示されるので、"EFI BUFFALO USB Flash Disk"を選択する。GRUBのメニューからinstallを選択すると、自動的にmSATA SSDが検出されて下記のメッセージが表示されるのでyを選択する。
Found Drive at /dev/sda. Do you want to install this image there ? [y/n]
y
パーティションは/bootと/とswap領域が自動的に作成される。/bootにはカーネルイメージであるvmlinuzがあるので以下の作業を通して、最終的にはここからGRUBを利用して起動することにする。

インストール完了後にリブート

以下のメッセージが表示されたらインストールメディア(USB)を外してEnterにて再起動する。
Remove your installation media, and press ENTER
ただし、このままでは起動しない。本当はEFIブートできるはずなのだが、方法がわからなかったためGRUBを利用することにした。

EFI Shellから手動で起動させる

起動画面にて再びF10を押すとメニューが表示されるのでEFI Shellを選択する。EFI Shellが起動すると表示されるように、fs0がEFI System Partition (/bootにあたる)となっており、ここからEFIブートが可能である。以下のコマンドを実行するとLinuxが無事起動する。
Shell> fs0:
fs0:\> EFI\BOOT\bootia32.efi
なお、起動時にイーサネットを接続しておくと、DHCPでIPアドレスが取得できてネットワークにつながるようになり、外部からSSHで接続できるようになるため非常に便利。インストール直後はrootのパスワードはrootになっているはず。

GNU partedをビルドする

デフォルトではpartedがインストールされていないので、ソースコードからビルドする。ビルドにはlibuuidが必要なのでまず先にlibuuidのインストールから始める。ソースコードはUSBからコピーするか、もしくはインターネットからダウンロードする。
root@cedartrail:~# wget http://ftp.gnu.org/gnu/parted/parted-3.0.tar.gz
root@cedartrail:~# wget http://downloads.sourceforge.net/project/libuuid/libuuid-1.0.2.tar.gz
libuuidはconfigureとmakeで問題なくインストールできる。
root@cedartrail:~# tar zxvf libuuid-1.0.2.tar.gz
root@cedartrail:~# cd libuuid-1.0.2
root@cedartrail:~# ./configure
root@cedartrail:~# make && make install
partedはビルド作業を短縮するためreadline機能を省く。
root@cedartrail:~# tar zxvf parted-3.0.tar.gz
root@cedartrail:~# cd parted-3.0
root@cedartrail:~# ./configure --without-readline
root@cedartrail:~# make
ところが、lib/stdio.hの1050行目でgets()がないというエラーが起きるので、以下のようにfgets()に書き換える。
(修正前)_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
(修正後)_GL_WARN_ON_USE (fgets, "gets is a security hole - use fgets instead");
これでもまだエラーが起きる。
../libparted/.libs/libparted.so: undefined reference to `dm_task_set_major_minor'
とりあえずconfitureオプションに--disable-device-mapperを付加することでdevice mapperは無効化した。再度、makeを実行するとstdio.hが再生成されるので、先ほどと同様に1050行目のgets()を修正してmakeする。
root@cedartrail:~# ./configure --without-readline --disable-device-mapper
root@cedartrail:~# vi lib/stdio.h
root@cedartrail:~# make && make install

GNU partedでBIOS Boot Partitionを作成する

partedがインストールできたらmSATA SSDである/dev/sdaにBIOS Boot Partitionを作成する。BIOS Boot PartitionというのはGPTフォーマットされたディスクにGRUBをインストールするために必要なGRUB専用のパーティションである。GRUBはMBRの512バイトだけでは容量が足りず、後続のプログラムを置くためにさらにディスク領域を必要とする。従来のMBR方式ではMBRの直後のセクタにそのための領域をとっていたが、GPT方式ではMBRの直後にGPTのプライマリヘッダが配置されてしまうため、GRUBを置くためのスペースが取れない。したがって、BIOS Boot Partitionというものが必要となる。まずは/dev/sdaのパーティション情報を確認する。
root@cedartrail:~# parted /dev/sda
GNU Parted 3.0
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print free
print free
Model: ATA InnoLite mSATA D (scsi)
Disk /dev/sda: 64.0GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start   End     Size    File system     Name     Flags
        17.4kB  1049kB  1031kB  Free Space
 1      1049kB  19.9MB  18.9MB  fat16           primary
 2      19.9MB  60.8GB  60.8GB  ext3            primary
 3      60.8GB  64.0GB  3201MB  linux-swap(v1)  primary
        64.0GB  64.0GB  335kB   Free Space
パーティションテーブルはGPTでフォーマットされていることが確認できる。Yoctoインストーラによると/bootと/とswap領域が自動的に作成されるが、print freeで見てみると実は/bootの前に1MB程度の空き領域があることがわかる。これをすべてBIOS Boot Partitionに割り当てることにする。
(parted) mkpart primary fat16 17.4kB 1049kB
mkpart primary fat16 17.4kB 1049kB
Warning: The resulting partition is not properly aligned for best performance.
Ignore/Cancel? Ignore
Ignore
(parted) print free
print free
Model: ATA InnoLite mSATA D (scsi)
Disk /dev/sda: 64.0GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start   End     Size    File system     Name     Flags
 4      17.4kB  1049kB  1031kB                  primary
 1      1049kB  19.9MB  18.9MB  fat16           primary
 2      19.9MB  60.8GB  60.8GB  ext3            primary
 3      60.8GB  64.0GB  3201MB  linux-swap(v1)  primary
        64.0GB  64.0GB  335kB   Free Space

4番目のプライマリパーティションが新規に割り当てられた(File sytemの項目は反映されない?)。しかし、このままではこのパーティションがBIOS Boot PartitionであることをGRUBが認識できない。そのため、以下のようにbios_grubフラグをonにする。
(parted) set 4 bios_grub on
最終的に以下のような構成になる。
(parted) print free
print free
Model: ATA InnoLite mSATA D (scsi)
Disk /dev/sda: 64.0GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start   End     Size    File system     Name     Flags
 4      17.4kB  1049kB  1031kB                  primary  bios_grub
 1      1049kB  19.9MB  18.9MB  fat16           primary
 2      19.9MB  60.8GB  60.8GB  ext3            primary
 3      60.8GB  64.0GB  3201MB  linux-swap(v1)  primary
        64.0GB  64.0GB  335kB   Free Space

/bootにGRUBをインストールする

BIOS Boot Partitionを作成したのでGPTフォーマットされた/dev/sdaにもGRUBをインストールできるようになった。grub-installで/bootにGRUBのcore.imgや設定ファイルをインストールするため、まずは/bootパーティションをマウントする。/bootパーティションは/dev/sda1であることに注意。
root@cedartrail:~# mkdir /mnt/boot
root@cedartrail:~# mount /dev/sda1 /mnt/boot
そして、targetにi386-pc、boot-directoryに/mnt/bootを指定して/dev/sdaにgrub-installする。
root@cedartrail:~# grub-install --target=i386-pc --boot-directory=/mnt/boot /dev/sda
Installation finished. No error reported.
ここで一旦再起動してGRUBが起動することを確認する。まだGRUBの設定ファイルを用意していないので、GRUBのシェルが起動するだけである。lsでパーティション情報を表示させると以下のようになる。
grub> ls
(hd0) (hd0,gpt4) (hd0,gpt3) (hd0,gpt2) (hd0,gpt1)
ルートファイルシステムは(hd0,gpt2)であるが、カーネルイメージは/bootパーティションである(hd0,gpt1)にあることに注意する。したがって、とりあえず起動するには以下のように指定する。(GRUBは/dev/sda1にインストールしたcore.imgで起動しているので、/vmlinuzの/はこの場合/dev/sda1を示している。)
grub> linux /vmlinuz root=/dev/sda2 rw
起動後は解像度が低いがビデオの設定をしていないため。GRUBの設定ファイルは/bootディレクトリに用意されているので、これをコピーすれば設定は完了。
root@cedartrail:~# mount /dev/sda1 /mnt/boot
root@cedartrail:~# cat /mnt/boot/EFI/BOOT/grub.cfg
# Automatically created by OE
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
default=boot
timeout=10

menuentry 'boot'{
linux /vmlinuz  root=/dev/sda2 rw  quiet    video=LVDS-1:d console=ttyS0,115200 console=tty0
}
root@cedartrail:~# cp /mnt/boot/EFI/BOOT/grub.cfg /mnt/boot/grub/
以上で正常にLinuxが起動するようになる。

というか

Terasicは配布物をちゃんとドキュメント化して欲しいです。。

参考資料
http://www.gnu.org/software/grub/
http://www.gnu.org/software/parted/

2013年11月17日日曜日

Building Emacs 24.3 on Windows 7

Emacs を Windows 7 でビルドしたので作業メモ。GNU GCC の開発環境として MinGW はインストール済みであるとする。

ソースコードの準備

まずはソースコードを取得する。
ftp://ftp.ring.gr.jp/pub/GNU/emacs/
現時点でのリリースバージョンである24.3のソースコードemacs-24.3.tar.gzをダウンロードした。

IMEを使用するためにはパッチが必要になる。
http://sourceforge.jp/projects/gnupack/releases/
上記サイトからEmacsのバージョンに対応する最新の emacs-24.3-ime-2013-05-03.patch.tar.gz を取得した。パッチの適用方法は以下の通り。
$ tar zxvf emacs-24.3.tar.gz
$ tar zxvf emacs-24.3-ime-2013-05-03.patch.tar.gz
$ cd emacs-24.3
$ patch -b -p1 < ../emacs-24.3-ime-2013-05-03.patch

ライブラリの準備

GnuWinPackagesから以下のライブラリをダウンロードする。それぞれ、dll が入っている "Binaries" の他に "Developer files" である *-lib.zip も必要になる。libxpm に関してはソースコードも必要になる。
  • jpeg-6b-4-bin.zip
  • libpng-1.2.37-bin.zip
  • libungif-4.1.4-1-bin.zip
  • tiff-3.8.2-1-bin.zip
  • xpm-3.5.1-1-bin.zip (xpmはSourcesも必要)
  • zlib-1.2.3-bin.zip
続いて、libxml2 を準備する。Downloads のページにある win32 にはWindows用にコンパイルされたバイナリが置いてある。
最後に GnuTLS を準備する。Download にある GnuTLS for Windows から以下をダウンロードした。
  • gnutls-3.2.6-w32.zip
ダウンロードしたファイルを伸長して以下のようなディレクトリ構成にする。
  • C:\lib\gnutls
  • C:\lib\gnuwin32
  • C:\lib\libxml
さらに、GnuWin32 の libxpm はソースコードのアーカイブに入っている simx.h が必要になる。xpm-3.5.1-1-src.zip を伸長して、src\xpm\3.5.1\libXpm-3.5.1-src\lib\simx.h を C:\lib\gnuwin32\include\X11 にコピーする。

Configure & make

ビルドオプションを設定するために以下のようなスクリプトファイル ~/configure を用意した。
#!/bin/sh
cmd /c ".\configure.bat \
    --with-gcc \
    --no-debug \
    --enable-w32-ime \
    --cflags -O3 \
    --cflags -fno-tree-vectorize \
    --cflags -mthreads \
    --cflags -DRECONVERSION \
    --cflags -DDOCUMENTFEED \
    --cflags \"-DIMR_DOCUMENTFEED=7\" \
    --cflags -Ic:/lib/gnutls/include \
    --cflags -Ic:/lib/gnuwin32/include \
    --cflags -Ic:/lib/libxml/include"

dos2unix ../src/config.h
--no-debug はデバッグ情報をバイナリに含めないために指定した。-O3 で最適化する場合、gccが誤ったコードを生成するらしいので、-fno-tree-vectorize も一緒に指定している。--enable-w32-ime は IME を有効にするためであるが、IME 関連と思われる -DRECONVERSION, -DDOCUMENTFEED, -DIMR_DOCUMENTFEED=7 に関しては他のサイトを参考にした。また、適宜 -I オプションでライブラリのヘッダファイルに対するサーチパスを設定する。最後の dos2unix は configure.bat 後に生成される config.h の改行文字が LF と CR+LF が混在してしまいコンパイルに失敗するので、LF に統一するために必要になる。
$ cd nt
$ ~/configure
$ make bootstrap
$ make install INSTALL_DIR=~/bin/emacs-24.3-20131117

参考情報

2013年11月8日金曜日

Call C# program from PowerShell script

PowerShellからC#を呼び出すという話。 大きなファイルを扱ったり時間のかかる計算を行うにはPowerShellだと厳しいので、そのような処理をC#に投げる方法を記す。
# hello.ps1
Add-Type -Path "hello.cs"
$h = New-Object Hello
$h.hello()
Add-Typeには-TypeDefinitionでソースコードの文字列からC#の型を追加することもできるが、-Pathで別ファイルに書かれたソースコードを指定することもできる。
// hello.cs
using System;
public class Hello {
    string s;

    public Hello(string s) {
        this.s = s;
    }
    
    public void hello() {
        Console.WriteLine("hello, {0}!", s);
    }
}