ラベル Cygwin の投稿を表示しています。 すべての投稿を表示
ラベル Cygwin の投稿を表示しています。 すべての投稿を表示

2013-11-17

コマンドのハードコーディングを回避する仕組み

/bin/sh決め打ちとかそういうのを回避するために使う。こういうの、他の人も色々書いてる気がするけど。

(defvar alternate-program-table
  (make-hash-table :test 'equal))

(defmacro define-alternate-program (program alt)
  `(puthash ,program ,alt alternate-program-table))

(defun alternate-program (program)
  (gethash program alternate-program-table))

(defadvice start-process (around kludge-for-hard-coding (name buffer program &rest program-args) activate)
  (let* ((alternate (alternate-program program))
         (program (or (if (consp alternate) (car alternate) alternate) program))
         (program-args (if (consp alternate) (append (cdr alternate) program-args) program-args)))
    ad-do-it))

こういう感じに使う。

(defmacro when-windows (&rest body)
  `(if-windows (progn ,@body)))

(when-windows
  (define-alternate-program "/bin/sh" '("fakecygpty" "/bin/sh")))

Cygwin環境とfakecygptyがちゃんとあれば、term.elのansi-termとかがWindowsでもきちんと動作するように。

2012-08-25

OCamlSpotterを強引に使うための設定

CygwinでビルドしたOCaml 4.00.0と、それを使ってビルドしたOCamlSpotter(bf0060bc031f)と、non-Cygwin Emacs 23.2を併用するためのkluge。CygwinでのパスとWindowsのパスの表現の違いによる問題を解決するものなので、MinGW版のOCamlならこういう設定は不要のはず。多分素直に使える。

.emacsの(require 'ocamlspot)以降に

(defun cygpath (args)
  (let* ((command (with-output-to-string
                    (princ "cygpath")
                    (mapc (lambda (x) (princ " ") (princ x)) args)))
         (result (shell-command-to-string command)))
    (replace-regexp-in-string "\n$" "" result)))

(defun ocamlspot-query-string-at-cursor ()
  (let ((file-name (cygpath `(-u ,(prin1-to-string (buffer-file-name))))))
    (setq ad-return-value
          (format "%s:l%dc%d"
                  file-name
                  (ocamlspot-lines-of-point)
                  (ocamlspot-bytes-of-line-to-point)))))

(defun ocamlspot-find-file-existing (path)
  (let ((path (cygpath `(-w ,path))))
    (if (file-exists-p path)
        (find-file-other-window path)
      (ocamlspot-message-add (format "ERROR: source file %s was not found" path))
      nil)))

で取り敢えず動くと思う。良く分からなかったりちゃんと動かなかったら諦めた方が吉。

やってて思ったけど、素直に仮想マシンにLinuxなりをインストールした方が苦労が少なそう。でもこのPCメモリそんな積んでないから厳しい。

2012-08-17

Caml modeの設定

Caml modeの設定も。

(autoload 'caml-mode "caml" "Major mode for editing OCaml code." t)
(autoload 'run-caml "inf-caml" "Run an inferior OCaml process." t)
(autoload 'camldebug "camldebug" "Run ocamldebug on program." t)

(setq inferior-caml-program
      (if-windows "sh -c ocaml" "ocaml")
      auto-mode-alist
      (cons '("\\.ml[iylp]?$" . caml-mode) auto-mode-alist)
      interpreter-mode-alist
      `(("ocamlrun" . caml-mode)
        ("ocaml" . caml-mode)
        ,@interpreter-mode-alist)
      process-coding-system-alist
      (cons (if-windows '("^sh$" utf-8 . utf-8)
                        '("ocaml" utf-8 . utf-8))
            process-coding-system-alist))

;; If "ocamlc -where" is called, OCaml built with Cygwin returns a Cygwin-style
;; path. Caml mode on non-Cygwin Emacs can't handle it.
(when-windows
  (setq ocaml-lib-path '("C:/Cygwin/usr/local/ocaml-4.00.0/lib/ocaml")))

(add-hook 'caml-mode-hook 'viper-mode)

(if window-system
    (require 'caml-font))

inferior-caml-program"sh -c ocaml"にしているのは、OCamlのインストール先の都合上。/usr/local/ocaml-4.00.0以下にインストールして、/usr/local/binなどに各ファイルのシンボリックリンクを張っているんだけど、CygwinをリンクしてないEmacsだとシンボリックリンクを辿れないし、パスを追加したりとかは色々面倒なので。

shのprocess coding systemをここで指定しているのは格好悪いかも。どうせCygwinは1.7以降UTF-8前提なんだし、別の所で堂々と設定したほうが良いかもしれない。

2012-08-11

OMakeをビルドするときの問題

OMake 0.9.8.6をCygwinでビルドするとき、

  • 依存しているライブラリが正常に検出されない
  • OCaml 4.00.0でビルドすると警告が原因でビルドに失敗する

という問題があったので、解決方法を記録しておく。

依存するライブラリが検出されない問題について。OMakeでは、自身をビルドするとき、ncursesなどのライブラリの検出にCheckLibという関数を利用している。このCheckLibの実体は、lib/configure/Configure.omで定義されている、CheckCLibという関数なんだけど、ここでライブラリの指定をLDFLAGSではなく、CFLAGSでしている。

public.CheckCLib(libs, funs) =
    CFLAGS += $(addprefix -l, $(libs))

    return $(TryLinkC $"""
#ifdef __cplusplus
extern "C"
#endif
#pragma warning( disable : 4100 )
/* Override any gcc2 internal prototype to avoid an error.  */
$(add-wrapper $(nl)extern char , $'();', $(funs))
int main(int argc, char **argv) {
    /* Usage */
$(add-wrapper $(nl)    , $'();', $(funs))
    return 0;
}
""")

これによって、gccに渡される-lオプションがCFLAGSの位置にきてしまい、ライブラリを検出するときのリンクに失敗する。

なので、

--- ../omake-0.9.8.6-/lib/configure/Configure.om        2012-08-11 15:05:41.265625000 +0900
+++ lib/configure/Configure.om  2012-08-11 16:12:42.359375000 +0900
@@ -266,7 +266,8 @@
 # \end{doc}
 #
 public.CheckCLib(libs, funs) =
-    CFLAGS += $(addprefix -l, $(libs))
+    # CFLAGS += $(addprefix -l, $(libs))
+    LDFLAGS += $(addprefix -l, $(libs))

     return $(TryLinkC $"""
 #ifdef __cplusplus

のように修正すれば、正常にライブラリが検出されるようになる。

ちなみに、FAM(OMakeの-Pオプションを利用するために必要)のためにCygwinのパッケージに収録されているGaminをインストールした場合、ビルドに失敗してしまう。

- build src/main omake.opt
+ ocamlopt.opt -warn-error A -w Aekr-29z -I . -I ../libmojave -I ../util -I ../magic -I ../ast -I ../ir -I ../env -I ../exec -I ../eval -I ../shell -I ../build -I ../builtin -o omake.opt unix.cmxa ../libmojave/lm.cmxa ../util/util.cmxa ../magic/magic.cmxa ../ast/ast.cmxa ../ir/ir.cmxa ../env/env.cmxa ../exec/exec.cmxa ../eval/eval.cmxa ../shell/shell.cmxa ../build/build.cmxa ../builtin/builtin.cmxa omake_shell.cmx omake_main.cmx ../clib/clib.a -cclib -lfam
** Cannot resolve symbols for ../clib/clib.a(lm_notify.o):
 _FAMErrno
 _FamErrlist
File "caml_startup", line 1:===============================    ] 01189 / 01242
Error: Error during linking
*** omake: 1189/1242 targets are up to date
*** omake: failed (4 min 47.47 sec, 234/234 scans, 357/519 rules, 801/2398 digests)
*** omake: targets were not rebuilt because of errors:
   src/main/omake.opt

DLL特有の名前修飾が原因と思われるものの、関数のシンボルは正常に解決できているようで、詳しい原因は分からなかった。GaminのDLLをGNU ldのruntime pseudo relocations機能を使ってビルドすれば良いのかもしれないが、そちらのビルドにも行き詰まったので、今回は手を引くことにした。

次に、警告が原因でビルドに失敗する問題について。参考資料によると、OCaml 3.12で厳し目に警告を出すようになったことが原因らしい。

コンパイラに渡すフラグをOMakefileで指定しているので、

--- ../omake-0.9.8.6-/OMakefile 2012-08-11 15:05:41.484375000 +0900
+++ OMakefile   2012-08-11 17:41:35.703125000 +0900
@@ -57,7 +57,7 @@
 #
 # OCaml options
 #
-OCAMLFLAGS[] += -w Ae$(if $(OCAML_ACCEPTS_Z_WARNING), z)
+OCAMLFLAGS[] += -w Aekr-29$(if $(OCAML_ACCEPTS_Z_WARNING), z)
 if $(THREADS_ENABLED)
     OCAMLFLAGS += -thread
     export

といった感じで、特定の警告は無視することにすれば良い。

以上。以下は参考資料。

2012-03-28

Chicken Schemeのビルド

WindowsでChicken Schemeをビルドするには、CygwinMinGWのどちらかのgccを使う。Visual Studioはサポートされていない。MinGWを使ってビルドする場合はMSYSは必須ではないけど、いずれにせよGNU makeは必要。以下の例はCygwinを使っている場合。

makeのマクロによって、どういった感じでビルドするか設定をする仕組み。どんなオプションがあるかはREADMEに書いてある。

% tar xf chicken-4.7.0
% cd chicken-4.7.0
% make PLATFORM=cygwin
% !! install

インストールする場所を指定しないと/usr/localにインストールされる。指定する場合はmake PLATFORM=cygwin PREFIX=/opt/chicken-4.7.0といった感じでPREFIXという名前のマクロを指定する。

2009-03-20

Ikarus Schemeのインストール

Cygwin 1.7.0-43にIkarus Schemeをインストールする。

Ikarusは多倍長整数の計算にGMPを使うので、ない場合はインストール。GMPはGCC 4も使っているので、GCC 4がインストールされている環境にはある。今回はGCC 4.3.3でコンパイルしたのでインストールは省略。

FFIを使うために、libffiのインストール。

$ tar xfz libffi-3.0.8.tar.gz
$ cd libffi-3.0.8
$ ./configure
$ make
$ make install

libffi 3.0.8時点での標準では、libffiのヘッダが、PREFIX/includeではなくて、PREFIX/lib/libffi-version/includeにインストールされることに注意。これを忘れていると、Ikarusのconfigureでffi.hが見付からずにエラーになる。

Ikarusのインストール。今回はリポジトリの最新版をチェックアウトしてビルドするので、AutoconfAutomakeが必要なのに注意。それと、IkarusはBazaarでバージョン管理されているので、チェックアウトにはBazaarが必要。ないときはCygwinのインストーラからインストールする。公式のWindowsバイナリではシンボリックリンクが張れないので、チェックアウトに失敗する。

$ bzr co --lightweight http://www.cs.indiana.edu/~aghuloum/ikarus.dev
$ cd ikarus.dev
$ CPPFLAGS=-I/usr/local/lib/libffi-3.0.8/include ./configure
$ make
$ make install

2009-03-19

Cygwin 1.7.0でGCC 4.3.3をビルドするときの注意点

Cygwin 1.7.0-43上でGCC 4.3.3をビルドしたところ、libibertyのコンパイル中にエラーが発生。

../../../gcc-4.3.3/libiberty/strsignal.c:408: error: conflicting types for 'strsignal'
/usr/include/string.h:79: error: previous declaration of 'strsignal' was here

とのこと。どうやら、Cygwinのstring.hと、GCCのlibiberty/strsignal.cとで、strsignalの型に食い違いがあるらしい。

それぞれを比べてみると、

/* string.h */
char  *_EXFUN(strsignal, (int __signo));
...

/* libiberty/strsignal.c */
const char *
strsignal (int signo)
{
  ...

確かに違う。でも、libiberty/strsignal.cのstrsignalの定義は、#ifndef HAVE_STRSIGNALで囲まれている。Cygwinのlibcにstrsignalがあるなら、定義部分はコンパイルされないので、こんなエラーは出ないはず。何故だ。というわけで、色々調べた。

とりあえず宣言と定義の食い違いについて。POSIXに準拠するために、strsignalの戻り値の型をconst char*からchar*に修正する動きがあって、Cygwinのstring.hはリビジョン1.22、GCCのlibiberty/strsignal.cはtrunkのリビジョン136949で修正された。なんだけど、Cygwin 1.7.0-43のstring.hではこの修正がされているのに対して、既に別のブランチになっていたGCC 4.3.3のlibiberty/strsignal.cでは、戻り値の型がconst char*のままなので、食い違いが起きた。

次に本題、HAVE_STRSIGNALマクロについて。結論から。以前はCygwinのライブラリをビルドするのに、libibertyの関数を使っていたので、強制的にconfigureのチェックを外していたらしい。ちくしょー、妙なkluge仕掛けてんじゃねー、とか思わないでもないけど、必要だった時期があったんだろうから仕方がないか。疲れた。

2009-03-18

Cygwinでライブラリをビルドするときの注意点

CygwinGMPをビルドしたんだけど、スタティックライブラリはできているのに、DLLがない。はて? と思ってconfigure.inを調べたところ、Cygwinでは--enable-sharedと--enable-staticが排他的な関係になっていた。gmp.hの内容がそれぞれで違ってくるからだそうだ。

言われてみれば、WindowsのDLLでは、関数をエクスポートやインポートするときに、修飾子を使ったりするんだったっけ。納得。

2007-11-17

Cygwin環境へのBiglooのインストールにおける注意点

自分向けに注意点。

  1. アーカイブはCygwinのtarで展開する
  2. GCC 3.xでコンパイルする場合、configure--cflags=-fno-reorder-blocksを必ず渡す

1について。Biglooのアーカイブにはシンボリックリンクが入っている。シンボリックリンクを良きに計らってくれるWindowsのアーカイバなどというものは存在しないので、Cygwinのtarなどを使って展開する。シンボリックリンクの存在を忘れていて、見事なまでに嵌った。

2はGCC3系列のバグだそうだ。これを忘れたままコンパイルしたら、見事にコンパイラがシンボルを参照できなくなって大量のエラーと共にコンパイルに失敗した。INSTALLの一番最初に書いてるのに見落としている辺り、いかに自分がこの手の注意を読み飛ばしているかが知れる。