svk のデバック出力

svk を使い始めてみたけれど,

$ svk update -s
Syncing https://svn.example.jp/repos/svn-repository
Retrieving log information from 17366 to 17986
名前がファイルシステムディレクトリを参照していません: パス 'branches/foo' は存在しません

と言われて, sync ができない.

エラーメッセージを検索しても出てこないので, LANG=C にしてやってみた.

$ LANG=C svk update -s
Syncing https://svn.example.jp/repos/svn-repository
Retrieving log information from 17366 to 17986
Name does not refer to a filesystem directory: Path 'branches/foo' not present

このエラーメッセージで検索しても, 原因がよくわからないので, svk をデバックしてみることに.

$ svk help environment

snip...

    $SVKLOGLEVEL

      The lowest log level that svk will present to the user. The log
      levels are: DEBUG, INFO, WARN, ERROR and FATAL. The default log level
      is INFO; this includes progress messages for long-running commands
      (such as sync). For non-interactive use (such as for cron jobs) it
      might be useful to set $SVKLOGLEVEL to WARN.

snip...

    $SVKSVNBACKTRACE

      (For debugging use only.) If this environment variable is set to a
      true value, any error message which comes from the Subversion
      libraries will be accompanied by a stack backtrace.

ということなので, 以下の環境変数を設定.

export SVKSVNBACKTRACE=1
export SVKLOGLEVEL=DEBUG
% env LANG=C svk update -s
Syncing https://svn.example.jp/repos/svn-repository
Retrieving log information from 17366 to 17986
Name does not refer to a filesystem directory: Path 'branches/foo' not present at /usr/local/lib/perl5/site_perl/5.8.8/SVK/Command.pm line 193
        SVK::Command::__ANON__('_p_svn_error_t=SCALAR(0x17b00c8)') called at /usr/local/lib/perl5/site_perl/5.8.8/mach/SVN/Delta.pm line 173
        eval {...} called at /usr/local/lib/perl5/site_perl/5.8.8/mach/SVN/Delta.pm line 173
        SVN::Delta::Editor::AUTOLOAD('SVN::Mirror::Ra::NewMirrorEditor=HASH(0x17a9968)', 'branches/foo', '_p_void=SCALAR(0x17b0038)', 122, 'SCALAR(0x17a9cf8)') called at /usr/local/lib/perl5/site_perl/5.8.8/SVN/Mirror/Ra.pm line 961
        SVN::Mirror::Ra::NewMirrorEditor::open_directory('SVN::Mirror::Ra::NewMirrorEditor=HASH(0x17a9968)', 'branches/foo', '_p_void=SCALAR(0x17b0038)', 122, 'SCALAR(0x17a9cf8)') called at /usr/local/lib/perl5/site_perl/5.8.8/mach/SVN/Delta.pm line 173
        SVN::Delta::Editor::AUTOLOAD('SVN::Simple::Edit=HASH(0x17a9d88)', 'branches/foo', '_p_void=SCALAR(0x17b0038)', 122, 'SCALAR(0x17a9cf8)') called at /usr/local/lib/perl5/site_perl/5.8.8/SVN/Simple/Edit.pm line 219
        SVN::Simple::Edit::open_directory('SVN::Simple::Edit=HASH(0x17a9d88)', 'branches/foo') called at /usr/local/lib/perl5/site_perl/5.8.8/SVN/Simple/Edit.pm line 131
        SVN::Simple::Edit::open_missing('SVN::Simple::Edit=HASH(0x17a9d88)', 'branches/foo') called at /usr/local/lib/perl5/site_perl/5.8.8/SVN/Simple/Edit.pm line 186
        SVN::Simple::Edit::find_pbaton('SVN::Simple::Edit=HASH(0x17a9d88)', 'branches/foo/branches', 'CODE(0x1641bf8)') called at /usr/local/lib/perl5/site_perl/5.8.8/SVN/Simple/Edit.pm line 298
        SVN::Simple::Edit::delete_entry('SVN::Simple::Edit=HASH(0x17a9d88)', 'branches/foo/branches') called at /usr/local/lib/perl5/site_perl/5.8.8/SVN/Mirror/Ra.pm line 552
        SVN::Mirror::Ra::mirror('SVN::Mirror::Ra=HASH(0x1740998)', 17365, 'HASH(0x1740d28)', 17366, 'Seasoft', '2008-06-22T03:18:31.871065Z', '\x{e3}\x{83}\x{aa}\x{e3}\x{83}\x{9d}\x{e3}\x{82}\x{b8}\x{e3}\x{83}\x{88}\x{e3}\x{83}\x{aa}\x{e4}\x{b8}\x{8a}\x{e3}\x{81}\x{ab}\x{e3}\x{81}\x{af}\x{e4}\x{b8}\x{8d}\x{e8}\x{a6}\x{81}\x{e3}\x{81}\x{a8}\x{e6}\x{80}\x{9d}\x{e3}\x{82}\x{8f}\x{e3}\x{82}\x{8c}\x{e3}\x{82}\x{8b}\x{e7}\x{a9}\x{ba}\x{e3}\x{83}\x{95}\x{e3}\x{82}\x{a9}\x{e3}\x{83}\x{ab}\x{e3}\x{83}\x{80}\x{e3}...', '_p_apr_pool_t=SCALAR(0x1740e38)') called at /usr/local/lib/perl5/site_perl/5.8.8/SVN/Mirror/Ra.pm line 704
        SVN::Mirror::Ra::__ANON__('HASH(0x1740d28)', 17366, 'Seasoft', '2008-06-22T03:18:31.871065Z', '\x{e3}\x{83}\x{aa}\x{e3}\x{83}\x{9d}\x{e3}\x{82}\x{b8}\x{e3}\x{83}\x{88}\x{e3}\x{83}\x{aa}\x{e4}\x{b8}\x{8a}\x{e3}\x{81}\x{ab}\x{e3}\x{81}\x{af}\x{e4}\x{b8}\x{8d}\x{e8}\x{a6}\x{81}\x{e3}\x{81}\x{a8}\x{e6}\x{80}\x{9d}\x{e3}\x{82}\x{8f}\x{e3}\x{82}\x{8c}\x{e3}\x{82}\x{8b}\x{e7}\x{a9}\x{ba}\x{e3}\x{83}\x{95}\x{e3}\x{82}\x{a9}\x{e3}\x{83}\x{ab}\x{e3}\x{83}\x{80}\x{e3}...', '_p_apr_pool_t=SCALAR(0x1740e38)') called at /usr/local/lib/perl5/site_perl/5.8.8/mach/SVN/Ra.pm line 492
        SVN::Ra::AUTOLOAD('SVN::Ra=HASH(0x1740628)', 'ARRAY(0x1740948)', 17366, 17986, 0, 1, 1, 'CODE(0x17407a8)') called at /usr/local/lib/perl5/site_perl/5.8.8/SVN/Mirror/Ra.pm line 707
        eval {...} called at /usr/local/lib/perl5/site_perl/5.8.8/SVN/Mirror/Ra.pm line 681
        SVN::Mirror::Ra::run('SVN::Mirror::Ra=HASH(0x1740998)', 'undef') called at /usr/local/lib/perl5/site_perl/5.8.8/SVK/Mirror.pm line 583
        SVK::Mirror::run_svnmirror_sync('SVK::Mirror=HASH(0x15c13e8)', 'HASH(0x15c6868)') called at /usr/local/lib/perl5/site_perl/5.8.8/SVK/Mirror.pm line 499
        SVK::Mirror::run('SVK::Mirror=HASH(0x15c13e8)') called at /usr/local/lib/perl5/site_perl/5.8.8/SVK/Command/Update.pm line 125
        SVK::Command::Update::run('SVK::Command::Update=HASH(0x152e3d8)', 'SVK::Path::Checkout=HASH(0x159c748)') called at /usr/local/lib/perl5/site_perl/5.8.8/SVK/Command.pm line 222
        eval {...} called at /usr/local/lib/perl5/site_perl/5.8.8/SVK/Command.pm line 220
        eval {...} called at /usr/local/lib/perl5/site_perl/5.8.8/SVK/Command.pm line 200
        SVK::Command::run_command('SVK::Command::Update=HASH(0x152e3d8)') called at /usr/local/lib/perl5/site_perl/5.8.8/App/CLI.pm line 79
        App::CLI::dispatch('SVK::Command', 'xd', 'SVK::XD=HASH(0xacc5c8)', 'output', 'undef') called at /usr/local/lib/perl5/site_perl/5.8.8/SVK/Command.pm line 164
        eval {...} called at /usr/local/lib/perl5/site_perl/5.8.8/SVK/Command.pm line 164
        SVK::Command::invoke('SVK::Command', 'SVK::XD=HASH(0xacc5c8)', 'update', 'undef', '-s') called at /usr/local/bin/svk line 169
perl in free(): warning: chunk is already free
perl in free(): warning: chunk is already free

と, 大量に出てきたので, 頑張ってみることにします...

正統派な Hello World

こんなのあるんですね.

Hello - GNU Project - Free Software Foundation

正真正銘, 正統な GNUHello World です.

GNU のソフトウェアを作る時のお手本」となっているようです.

下記よりダウンロードできます.

http://ftp.gnu.org/gnu/hello/

現在の最新は, 2.4 となっています. ChangeLog を見てみると,

2008-12-09  Karl Berry  <karl@gnu.org>

	* Version 2.4.

ということで, 最近でもきちんとメンテされているようです.
すばらしい...

ChangeLog の最初の方を見ると,

Thu Nov 24 00:00:01 1983  Richard M. Stallman  (rms at prep)

	* Begin GNU project; add copyleft.

Sat Apr  1 00:27:19 1978  Brian Kernighan  (bwk at research)

	* Initial version.

最初にカーニハンが作り, ストールマンによって GNU プロジェクトに Copyleft されています.

大御所たちが遊び心で作ったプログラムかと思いきや, ローカライズされてるし, configure もあるし, man も用意されてるし, ちゃんとしたテストケースもあり, さすがに無駄に凝ってます.

ソースコードも, とても美しいです. 素晴しい.

こういったプログラムをお手本にして学んでいきたいものですね.

FreeBSD のソースコードを Subversion で管理する


公式のドキュメント
には, まだ載ってないですが, 現在, FreeBSD はベースシステムのソースコードSubversion で管理しています.

2008年6月6日 FreeBSD CVSからSubversionへ,Linuxバイナリ互換機能 2.4.2から2.6.16へ,GNOME Online Desktop登場,Emacs 2.22登場他:FreeBSD Daily Topics|gihyo.jp … 技術評論社

リポジトリ情報など, あまり日本語の情報が無いので載せておこうと思います.

devel/subversion-freebsd のインストール

Subversion で $FreeBSD$ のタグを使うためのパッチを当てたものです.

$ cd /usr/ports/devel/subversion-freebsd
$ sudo make install

使用例

7.0-RELEASEを checkout するとき

# svn checkout http://svn.freebsd.org/base/release/7.0.0 /usr/src

7.1-RELEASE のセキュリティブランチを checkout するとき

# svn checkout http://svn.freebsd.org/base/releng/7.1 /usr/src

7.1-RELEASE から, 7.1-RELEASE のセキュリティブランチへ update するとき

# svn switch http://svn.freebsd.org/base/releng/7.1 /usr/src

Subversion 1.4.4 から 1.6.0 へのアップグレード

sshfs を使って, サーバー側のディレクトリを直接マウントして作業をする場合, サーバーとクライアント SVN のメジャーバージョンが一致していないと, とても不便なので, サーバー側をアップグレードしてみました.

subversion: Subversion 1.6 Release Notes

Subversion 1.6 is a superset of all previous Subversion releases, and is considered the current "best" release. Any feature or bugfix in 1.0.x through 1.5.x is also in 1.6, but 1.6 contains features and bugfixes not present in any earlier release.

ということなので, アップグレードしておいた方が今後も幸せになれそうです.

Subversion 1.6.1 がリリースされていますが, Ports Freeze 期間中なので, とりあえず 1.6.0 を入れます.

また, Trac も最新にしないと動かないようなので, ついでにアップグレード... と思ったのですが, かなりハマったので書いておきます.

環境は, FreeBSD 6.4-RELEASE, mod_dav_svnSubversion, mod_pythonTrac を動作させています.

neon26 を neon28 にアップグレード

/usr/ports/UPDATING を見ると,

subversion now uses neon-0.28.x (www/neon28) port, and automatic
portupgrade will fail because www/neon28 will conflict with installed
www/neon26 port.

ということなので, neon26 を neon28 にアップグレード.

$ sudo portupgrade -o www/neon28 neon26

Subversion と関連ライブラリをアップグレード

このあたりまでのやり方は, /usr/ports/UPDATING に書いてあります.

$ sudo portupgrade -o devel/subversion subversion-\*

ここまでやって apache をリスタートさせれば, Subversion 1.6.0 が問題無く動作するはず.

Trac のアップグレード

Subversion 1.6 にすると, Trac 0.11.4 にしないと動作しないようなので, 0.10.4 から 0.11.4 へアップグレード.

$ sudo portupgrade www/trac

とやれば, すんなりアップグレードできます.

下記を見て, httpd.conf に PythonInterpreter main_interpreter の行を追記します.

TracModPython – The Trac Project


   SetHandler mod_python
   PythonInterpreter main_interpreter
   PythonHandler trac.web.modpython_frontend 
   PythonOption TracEnv /var/trac/myproject
   PythonOption TracUriRoot /projects/myproject

しかし, apache をリスタートさせても, 真っ白な画面になって動きませんorz


   SetHandler mod_python
   PythonInterpreter main_interpreter
   PythonHandler mod_python.testhandler

として, /mpinfo にアクセスしても, うんともスンとも言いません.

Apache のエラーログにも何も出ませんorz

どうも, Location が全く反応しないようなので, mod_python を疑ってみます.

Python 2.4 から 2.5 へのアップグレード

いろいろ調べてみると, Python 2.5 の方が動作事例多いようなので, アップグレードしてみることに.

関連ライブラリをすべてアップグレードしなくてはならないので大変です...

SQLite もアップグレードしておきます.

$ sudo portupgrade -o lang/python25 python24-2.4.3_3 
$ sudo portupgrade -r -x python25-2.5.4_1 python25-2.5.4_1
$ sudo portupgrade -o devel/py-subversion subversion-python-1.4.3_2
$ sudo portupgrade -f py24-docutils-0.4
$ sudo portupgrade -f py24-mx-base-2.0.6
$ sudo portupgrade -f py24-setuptools-0.6c9
$ sudo portupgrade -f py24-Genshi-0.5.1_2
$ sudo portupgrade -f py24-pygments-1.0
$ sudo portupgrade -f -o py25-sqlite3-2.5.4_1 py24-pysqlite-2.3.5
$ sudo portupgrade -f py24-pytz-2009e
$ sudo portupgrade -f mod_python-3.3.1_2
$ sudo portupgrade sqlite3

最初, portupgrade -f py24-\* とやってみましたが, うまくいかなかったので一つずつやってます...

キレイに Python 2.5 の環境になったところで Apache をリスタート.

してみましたが, まだ真っ白な画面で動きません...

しかし, 今度は, Apache のエラーログが出ました.

[Sat Apr 18 22:14:26 2009] [notice] Apache/2.0.63 (FreeBSD) mod_ssl/2.0.63 OpenSSL/0.9.7e-p1 SVN/1.6.0 DAV/2 mod_python/3.3.1 Python/2.5.4 PHP/5.2.6 with Suhosin-Patch mod_fastcgi/2.4.6 configured -- resuming normal operations
Fatal error 'Recurse on a private mutex.' at line 986 in file /usr/src/lib/libpthread/thread/thr_mutex.c (errno = 0)
[Sat Apr 18 22:14:47 2009] [notice] child pid 58346 exit signal Abort trap (6)

Subversion の再インストール

どうも, thread まわりのエラーらしいのですが, 調べてみても原因よくわからず.

いろいろ悩んだあげく, ソフト/Bug Tracking/trac - discypus の下の方に sqlite-amalgamation をすると解消したとのコメントが.

こちらの環境では, Trac の画面が全く表示されないので, ちょっと現象が違うのですが...

Subverison の INSTALL にも下記のようにあるので, 再コンパイルしてみます.

13. SQLite (REQUIRED)

Subversion (starting with version 1.6) requires SQLite version
3.4.0 or above, and you can meet this dependency several ways:
* Use an SQLite amalgamation file.
* Specify an SQLite installation to use.
* Let Subversion find an installed SQLite.

To use an SQLite-provided amalgamation, just drop sqlite3.c into
Subversion's sqlite-amalgamation/ directory, or point to it with the
--with-sqlite configure option. This file also ships with the Subversion
dependencies distribution, or you can download it from SQLite:

http://www.sqlite.org/download.html

$ cd /usr/ports/devel/subversion
$ sudo make extract
$ cd work
$ sudo mkdir subversion-1.6.0/sqlite-amalgamation
$ sudo fetch http://www.sqlite.org/sqlite-amalgamation-3.6.11.tar.gz
$ sudo tar xvfz sqlite-amalgamation-3.6.11.tar.gz
$ sudo cp sqlite-3.6.11/sqlite3.c subversion-1.6.0/sqlite-amalgamation
$ cd ../
$ sudo make deinstall
$ sudo make reinstall

Apache をリスタートさせると, やっと Trac の画面が表示されました(汗)

あとは, trac-admin から Trac をアップグレードさせれば完了です.

$ sudo trac-admin /path/to/trac/project upgrade
$ sudo trac-admin /path/to/trac/project wiki upgrade
$ sudo trac-admin /path/to/trac/project resync

まとめ

根本原因が SubversionSQLite 依存関係だったのが盲点でした.

TracInstall – The Trac Project とか TracModPython – The Trac Project を見ると, Python 2.4 でも動きそうなので, Python のアップグレードは不要かもしれません.

2009-04-26 追記

svkリポジトリTrac を sync しようとしたら,

[Sun Apr 26 23:45:19 2009] [notice] child pid 87585 exit signal Abort trap (6)
Fatal error 'Recurse on a private mutex.' at line 986 in file /usr/src/lib/libpthread/thread/thr_mutex.c (errno = 2)

と, 同じようなエラーが出た. svk は気に入らないらしい. ううむ.

maven-assembly-plugin で実行可能な jar ファイルを作る

Java でバッチプログラムを作る際, class ファイルを jar にまとめてしまうことがよくあります.

しかし, 依存している外部の jar ファイルがある場合は, マニフェストファイルにクラスパスを書くか, --classpath などでクラスパスを指定しなくてはいけないため面倒です.

すべて jar ファイルに同梱してしまいたくなりますが, 外部 jar ファイルを一旦展開してから同梱しないと使えません.

こんな時に, maven-assembly-plugin を使うと便利です.

以下のような, pom.xml を用意します.

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>jp.example</groupId>
  <artifactId>example</artifactId>
  <packaging>jar</packaging>
  <name>Example Batch Application</name>
  <version>0.0.1-SNAPSHOT</version>
  <build>
    <sourceDirectory>src/main/java</sourceDirectory>
    <testSourceDirectory>src/test/java</testSourceDirectory>
    <outputDirectory>target/classes</outputDirectory>
    <testOutputDirectory>target/test-classes</testOutputDirectory>
    <defaultGoal>validate</defaultGoal>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
      </resource>
    </resources>
    <testResources>
      <testResource>
        <directory>src/test/resources</directory>
      </testResource>
    </testResources>
    <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>2.2</version>
          <configuration>
            <archive>
              <manifest>
                <mainClass>jp.example.command.Main</mainClass>
              </manifest>
            </archive>
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
          <descriptors>
            <descriptor>src/main/assembly/distribution.xml</descriptor>
          </descriptors>
        </configuration>
      </plugin>
    </plugins>
  </build>

 ... snip
	  
</project>

maven-jar-plugin の manifest 要素で, 実行するメインクラスを指定しています.

次に, src/main/assembly/distribution.xml を用意します.

<assembly>
  <id>distribution</id>
  <formats>
    <format>zip</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <dependencySets>
    <dependencySet>
      <unpack>true</unpack>
      <scope>runtime</scope>
      <outputDirectory>/</outputDirectory>
    </dependencySet>
  </dependencySets>
</assembly>

format は zip にしないと, 自分自身で生成した artifact の jar ファイルをうまく同梱してくれないようです.

includeBaseDirectory を false にすることで, zip ファイルにベースディレクトリを含めなくなります.

dependencySet で unpack を true に, outputDirectory を "/" に指定すると, 依存関係にある外部 jar ファイルを展開し, zip ファイルに含めてくれます.

ここでは, dependency の scope = runtime の jar ファイルのみを同梱します.

Maven2 から assembly:assembly ターゲットを実行すると, 外部 jar ファイルを同梱した ZIP ファイルが生成されます.

$ mvn assembly:assembly

... snip
	  
[INFO] [assembly:assembly]
[INFO] Reading assembly descriptor: src/main/assembly/distribution.xml
[INFO] Processing DependencySet (output=/)
[INFO] Building zip: /Users/nanasess/example/target/example-0.0.1-SNAPSHOT-distribution.zip
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 18 seconds
[INFO] Finished at: Mon Mar 30 23:32:28 JST 2009
[INFO] Final Memory: 37M/80M
[INFO] ------------------------------------------------------------------------

jar も zip も拡張子が違うだけで中身は一緒なので, このままでも実行できてしまいます.

jar の方が良ければ rename してやれば良いと思います.

こんな感じで実行できます.

$ java -jar target/example-0.0.1-SNAPSHOT-distribution.zip
Hello! World!

また, この方法を使うと "/META-INF/maven/groupId/artifactId/pom.properties" に artifactId, groupId, version が出力されます.

こんな感じのメソッドを作ると, コマンドラインからバージョン情報を出力したい時などに便利です.

    /**
     * pom.properties の内容から {@link Properties} を取得する.
     *
     * @return pom.properties から取得した {@link Properties}
     */
    private static Properties getPomProperties() {
        InputStream in = Main.class.getResourceAsStream("/META-INF/maven/groupId/artifactId/pom.properties");
        Properties properties = new Properties();
        try {
            if (in != null) {
                properties.load(in);
            }
        } catch (IOException e) {
            System.err.println(e.getMessage());
        }
        return properties;
    }

    /**
     * pom.properties からバージョン情報を取得し, 標準出力へ書き込みます.
     */
    private static void printVersion() {
        Properties properties = getPomProperties();
        String msg = properties.getProperty("artifactId", "<unknown>");
        String version = properties.getProperty("version", "<unknown version>");

        System.out.println(msg + " \"" + version + "\"");
        System.out.println("Java version: " + System.getProperty("java.version", "<unknown java version>"));
        System.out.println("Java home: " + System.getProperty("java.home", "<unknown java home>"));
        System.out.println("Default locale: " + Locale.getDefault() + ", platform encoding: "
                            + System.getProperty("file.encoding", "<unknown encoding>"));
    }
$ java -jar target/example-0.0.1-SNAPSHOT-distribution.zip --version
example "0.0.1-SNAPSHOT"
Java version: 1.6.0_07
Java home: /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home
Default locale: ja_JP, platform encoding: SJIS

Cocoa Emacs パッケージ

Cocoa Emacs をビルドする度に, Emacs.app/Contents/Resources 以下に elisp を入れるのが面倒なので, Makefile にしてみました.

$ make checkout
$ make emacsinstall
$ make apelinstall
$ make installlib

とすることで, CVS から checkout して,で外部 elisp のインストールまでできます.

2回目からは, make update で checkout ではなく update できます.

中身は決して美しくないので, ダメ出ししていただけたらと思います(汗)

#################################################################################
#
# Cocoa-Emacs Makefile
#
# $Id: 2009-03-24.txt 783 2009-07-25 08:38:21Z nanasess $
#
#################################################################################

PREFIX = /Users/nanasess/src/cocoa-emacs
RM = /bin/rm -rfv
TAR = tar xvzf
CURL = curl -O
SOURCE_DIR = $(EMACS_SRC) $(APEL_SRC) $(SKK_SRC) $(MEW_SRC) $(W3M_SRC) $(HOWM_SRC)

## Emacs Variables
EMACS_SRC = emacs
EMACS_APP = $(PREFIX)/$(EMACS_SRC)/nextstep/Emacs.app
EMACS = $(EMACS_APP)/Contents/MacOS/Emacs
EMACS_PREFIX = $(EMACS_APP)/Contents/Resources
EMACS_BINDIR = $(EMACS_APP)/Contents/MacOS/bin
INFO_DIR = $(EMACS_PREFIX)/info
SITE_DIR = $(EMACS_PREFIX)/site-lisp

# APEL Variables
APEL_SRC = apel
APEL_CFG = APEL-CFG
APEL_DIR = $(SITE_DIR)/apel
EMU_DIR = $(SITE_DIR)/emu
APEL_MAKE_ENV = PREFIX=$(EMACS_PREFIX) APEL_DIR=$(APEL_DIR) EMU_DIR=$(EMU_DIR) EMACS=$(EMACS)

# SKK Variables
SKK_SRC = skk/main
SKK_CFG = SKK-CFG
SKK_DATADIR = $(EMACS_PREFIX)/etc/skk
SKK_INFODIR = $(INFO_DIR)
SKK_LISPDIR = $(SITE_DIR)/skk
SKK_SET_JISYO = t

# howm Variables
HOWM_SRC = howm-test

# Mew Variables
MEW_SRC = mew

# W3M Variables
W3M_SRC = emacs-w3m

# Muse Variables
MUSE_SRC = muse-latest
MUSE_CFG = Makefile.defs

all:
	@echo "make checkout or make update"
	@echo "make emacsinstall"
	@echo "make apelinstall"
	@echo "make installlib"

################################################################################
# common targets
################################################################################

update:
	cd $(EMACS_SRC) && cvs -q update -dP
	cd $(APEL_SRC) && cvs -q update -dP
	cd $(MEW_SRC) && cvs -q update -dP
	cd $(W3M_SRC) && cvs -q update -dP

buildlib: skkbuild howmbuild mewbuild w3mbuild musebuild

installlib: skkinstall howminstall mewinstall w3minstall museinstall

cleanall: emacsdistclean apelclean apelcfgclean skkclean skkcfgclean howmclean mewclean w3mclean musecfgclean

sourceclean:
	$(RM) $(SOURCE_DIR) $(HOWM_SRC).* $(MUSE_SRC).*

checkout: sourceclean checkoutemacs checkoutapel checkoutskk checkouthowm checkoutmew checkoutw3m checkoutmuse

################################################################################
# checkouts
################################################################################

checkoutemacs:
	cvs -z3 -d:pserver:anonymous@cvs.savannah.gnu.org:/sources/emacs co $(EMACS_SRC)
checkoutapel:
	cvs -z9 -d :pserver:anonymous@cvs.m17n.org:/cvs/root co $(APEL_SRC)

checkoutskk:
	cvs -d :pserver:guest@openlab.jp:/circus/cvsroot checkout $(SKK_SRC)

checkouthowm:
	$(CURL) http://howm.sourceforge.jp/a/$(HOWM_SRC).tar.gz ;\
	$(TAR) $(HOWM_SRC).tar.gz

checkoutmew:
	cvs -d :pserver:anoncvs@anoncvs.mew.org:/cvsmew co $(MEW_SRC)

checkoutw3m:
	cvs -d :pserver:anonymous@cvs.namazu.org:/storage/cvsroot co $(W3M_SRC)

checkoutmuse:
	$(CURL) http://mwolson.org/static/dist/muse-latest.tar.gz ;\
	$(TAR) $(MUSE_SRC).tar.gz

################################################################################
# emacs targets
################################################################################

emacsbuild:
	cd $(EMACS_SRC); \
	./configure --with-ns; \
	make

emacsinstall: emacsbuild
	cd $(EMACS_SRC); \
	make install

emacsclean:
	cd $(EMACS_SRC); \
	make clean

emacsdistclean:
	cd $(EMACS_SRC); \
	make distclean

################################################################################
# apel targets
################################################################################

apelcfg:
	cd $(APEL_SRC); \
	echo '(setq PREFIX "$(EMACS_PREFIX)")' >> $(APEL_CFG); \
	echo '(setq APEL_DIR "$(APEL_DIR)")' >> $(APEL_CFG); \
	echo '(setq EMU_DIR "$(EMU_DIR)")' >> $(APEL_CFG); 

apelcfgclean:
	cd $(APEL_SRC); \
	$(RM) $(APEL_CFG); \
	cvs update $(APEL_CFG)

apelbuild: apelcfg
	cd $(APEL_SRC); \
	make what-where EMACS=$(EMACS); \
	make EMACS=$(EMACS); \

apelinstall: apelbuild
	cd $(APEL_SRC); \
	make install EMACS=$(EMACS);

apelclean:
	cd $(APEL_SRC); \
	make clean

################################################################################
# skk targets
################################################################################

skkcfg:
	cd $(SKK_SRC); \
	echo '(setq PREFIX "$(EMACS_PREFIX)")' >> $(SKK_CFG); \
	echo '(setq EMU_DIR "$(EMU_DIR)")' >> $(SKK_CFG); \
	echo '(setq SKK_DATADIR "$(SKK_DATADIR)")' >> $(SKK_CFG); \
	echo '(setq SKK_INFODIR "$(SKK_INFODIR)")' >> $(SKK_CFG); \
	echo '(setq SKK_LISPDIR "$(SKK_LISPDIR)")' >> $(SKK_CFG); \
	echo '(setq SKK_SET_JISYO $(SKK_SET_JISYO))' >> $(SKK_CFG);

skkcfgclean:
	cd $(SKK_SRC); \
	$(RM) $(SKK_CFG); \
	cvs update $(SKK_CFG)

skkbuild: skkcfg
	cd $(SKK_SRC); \
	make what-where EMACS=$(EMACS); \
	make EMACS=$(EMACS)

skkinstall: skkbuild
	cd $(SKK_SRC); \
	make install EMACS=$(EMACS)


skkclean:
	cd $(SKK_SRC); \
	make clean EMACS=$(EMACS)

################################################################################
# howm targets
################################################################################

howmbuild:
	cd $(HOWM_SRC); \
	./configure	--with-emacs=$(EMACS) --prefix=$(PREFIX) \
			--exec-prefix=$(EMACS_BINDIR); \
	make

howminstall: howmbuild
	cd $(HOWM_SRC); \
	make install

howmclean:
	cd $(HOWM_SRC); \
	make distclean

################################################################################
# mew targets
################################################################################

mewbuild:
	cd $(MEW_SRC); \
	./configure	--with-emacs=$(EMACS) --prefix=$(PREFIX) \
			--bindir=$(EMACS_BINDIR) --with-elispdir=$(SITE_DIR)/mew \
			--with-etcdir=$(SITE_DIR)/etc --infodir=$(INFO_DIR) \
	make && make info && make jinfo

mewinstall: mewbuild
	cd $(MEW_SRC); \
	make install && make install-info && make install-jinfo

mewclean:
	cd $(MEW_SRC); \
	make distclean

################################################################################
# w3m targets
################################################################################

w3mbuild:
	cd $(W3M_SRC); \
	autoconf; \
	./configure	--with-emacs=$(EMACS) --prefix=$(PREFIX) \
			--bindir=$(EMACS_BINDIR) --sbindir=$(EMACS_BINDIR) \
			--with-lispdir=$(SITE_DIR)/w3m --infodir=$(INFO_DIR) \
	make

w3minstall: w3mbuild
	cd $(W3M_SRC); \
	make install && make install-icons && make install-icons30

w3mclean:
	cd $(W3M_SRC); \
	make distclean

################################################################################
# muse targets
################################################################################

musecfg:
	cd $(MUSE_SRC); \
	echo 'EMACS = $(EMACS)' >> $(MUSE_CFG); \
	echo 'PREFIX = $(EMACS_PREFIX)' >> $(MUSE_CFG); \
	echo 'SITEFLAG = --no-site-file' >> $(MUSE_CFG); \
	echo 'DESTDIR  =' >> $(MUSE_CFG); \
	echo 'PREFIX   = $(PREFIX)' >> $(MUSE_CFG);\
	echo 'ELISPDIR = $(SITE_DIR)/muse' >> $(MUSE_CFG); \
	echo 'INFODIR  = $(INFO_DIR)' >> $(MUSE_CFG); \
	echo 'install_info = install-info --info-dir=$$(INFODIR) $$(1) || :' >> $(MUSE_CFG); \
	echo 'PROJECT     = muse' >> $(MUSE_CFG); \
	echo 'VERSION     = 3.12' >> $(MUSE_CFG); \
	echo 'MANUAL      = muse' >> $(MUSE_CFG); \
	echo 'ELPADIR  = ../../elpa' >> $(MUSE_CFG); \
	echo 'ELPADESC = Authoring and publishing tool' >> $(MUSE_CFG);

musecfgclean:
	cd $(MUSE_SRC); \
	$(RM) $(MUSE_CFG)

musebuild:
	cd $(MUSE_SRC); \
	make

museinstall: musecfg musebuild
	cd $(MUSE_SRC); \
	make install

ChangeLog

2009-07-21  Kentaro Ohkouchi  <nanasess@fsm.ne.jp>

	* Makefile: Emacs Muse の設定を追加
	: フォーマットを修正

2009-04-30  Kentaro Ohkouchi  <nanasess@fsm.ne.jp>

	* Makefile (all): target を少し変更
	(buildlib): apelinstall を削除
	(buildall): removed

2009-03-24  Kentaro Ohkouchi  <nanasess@fsm.ne.jp>

	* Makefile: initial version

Cocoa-Emacs のキーバインド

久々に, Cocoa EmacsCVS HEAD にしたら, Preference の設定パネルが custom-mode に変更されていました.

emacs/nextstep/ChangeLog を見ると, 3月14日に Preference Panel は削除された模様.

今まで, Preference Panel でキーバインドを変更していたので, どうやって変更したら良いか解らず, 途方に暮れていましたorz

いろいろ調べてみると, ns-alternate-modifier というのを発見!

こんな感じで幸せになれました

(setq ns-alternate-modifier 'alt)
(setq ns-command-modifier 'meta)