Gauche:NSIS

Gauche:NSIS

NSISはnullsoftによるWindowsインストーラコンパイラ。

http://nsis.sourceforge.net/

方針

NSISのインストールディレクトリをPATHに追加

 export PATH=/cygdrive/c/Program\ Files/NSIS:$PATH
 
 which makensis.exe
 /cygdrive/c/Program\ Files/NSIS/makensis.exe

which makensis.exeが正常に実行できるようにする。

Gauche-mingwのビルド

CVS版Gaucheで以下を実行。

 ./DIST mingw

../Gauche-mingw-dist配下にGauche-mingw-<version>.zipとGaucheディレクトリが出来る。

NSISのインストールディレクトリがPATHに含まれているならここでGauche-win32-<version>.exeまで生成できる。

NSISスクリプトテンプレート

setup.nsi.inからsetup.nsiを生成する。

setup.nsi.inには以下を記述した。

デスクトップへのショートカット登録

postセクションに以下を追加。

    SetOutPath $SMPROGRAMS\$StartMenuGroup
    CreateShortCut "$DESKTOP\$(^Name).lnk" "$INSTDIR\bin\gosh.exe" "" "$INSTDIR\gauche-logo.ico"

スタートメニューへの登録

    CreateShortCut "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" "$INSTDIR\bin\gosh.exe" "" "$INSTDIR\gauche-logo.ico"
    CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" $INSTDIR\uninstall.exe

拡張子.scmをgosh.exeに関連付ける

    # .scm registration
    WriteRegStr HKCR ".scm" "" "Scheme.script"
    WriteRegStr HKCR "Scheme.script" "" "Scheme Script"
    WriteRegStr HKCR "Scheme.script\shell" "" "open"
    WriteRegStr HKCR "Scheme.script\DefaultIcon" "" "$INSTDIR\gauche-logo.ico"
    WriteRegStr HKCR "Scheme.script\shell\open\command" "" '$INSTDIR\bin\gosh.exe "%1"'

アンインストールでのショートカット削除

un.postセクションに以下を追加。

    Delete /REBOOTOK "$DESKTOP\$(^Name).lnk"
    Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk"
    Delete /REBOOTOK "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk"

アンインストールでの関連付け削除

un.postセクションに以下を追加。

    DeleteRegKey HKCR ".scm"
    DeleteRegKey HKCR "Scheme.script"

Gaucheのバージョン埋め込み

setup.nsi.inに以下を記述。

 !define VERSION ##(include (*current-version*))

##(include (*current-version*))の部分がfile-list.scmの第3引数で置き換えられる。

../Gauche-mingw-dist/Gauche配下のファイル一覧を得る

Mainセクションに以下を記述。この記述はfile-list.scmで得たファイル一覧と置き換えられる。

 ##(include (install-files))

実際にはこんな感じ。

    SetOutPath $INSTDIR
    File ..\..\..\Gauche-mingw-dist\Gauche\COPYING
    SetOutPath $INSTDIR\bin
    File ..\..\..\Gauche-mingw-dist\Gauche\bin\gauche-cesconv.exe
    File ..\..\..\Gauche-mingw-dist\Gauche\bin\gauche-config.exe
    File ..\..\..\Gauche-mingw-dist\Gauche\bin\gauche-install.exe
    File ..\..\..\Gauche-mingw-dist\Gauche\bin\gauche-package.exe

以下略。

アンインストールでのファイル削除

un.Mainセクションに以下を記述。これもfile-list.scmで得たファイル一覧と置き換えられる。

 ##(include (delete-files))

実際にはこんな感じ。

    Delete /REBOOTOK $INSTDIR\COPYING
    Delete /REBOOTOK $INSTDIR\bin\gauche-cesconv.exe
    Delete /REBOOTOK $INSTDIR\bin\gauche-config.exe
    Delete /REBOOTOK $INSTDIR\bin\gauche-install.exe
    Delete /REBOOTOK $INSTDIR\bin\gauche-package.exe
    Delete /REBOOTOK $INSTDIR\bin\gosh.exe
    Delete /REBOOTOK $INSTDIR\bin\libgauche.dll
    Delete /REBOOTOK $INSTDIR\bin\mingwm10.dll
    Delete /REBOOTOK $INSTDIR\lib\gauche\0.8.13\i686-pc-mingw32\auxsys.dll

以下略。

スクリプトジェネレータ

;; -*- coding: utf-8 -*-
;;  Copyright (c) 2008 ENDO Yasuyuki, All rights reserved. 
;;  Copyright (c) 2008 Kahua Project, All rights reserved. 
;;  See COPYING for terms and conditions of using this software 

(use file.util)
(use srfi-1)
(use srfi-13)
(use gauche.parameter)
(use gauche.parseopt)
(use text.tree)

(define *instdir* "$INSTDIR")
(define *ignore-path* "CVS")
(define *target-prefix* "    SetOutPath ")
(define *install-prefix* "    File ")
(define *delete-prefix* "    Delete /REBOOTOK ")
(define *cr-lf* "\r\n")
(define *path-separater* "\\")
(define *root-path* (make-parameter #f))
(define *file-list* (make-parameter #f))
(define *current-version* (make-parameter #f))

(define (replace-inst prefix path)
  (regexp-replace (string->regexp prefix)
          path *instdir*))

(define (file-list path)
  (directory-fold
   path cons '()
   :lister (lambda (path seed)
             (receive (d f)
                      (directory-list2 path :add-path? #t :children? #t)
                      (values d
                              (cons (cons path f) seed))))))

(define (initialize path version)
  (begin0
   (*root-path* path)
   (*current-version* version)
   (*file-list*
    (reverse
     (filter
      (lambda (ls) (and (pair? (cdr ls))
                        (not (string-contains (car ls) *ignore-path*))))
      (file-list (*root-path*)))))))

(define (inst-str ls)
  (cons
   #`",|*target-prefix*|,(change-path (replace-inst (*root-path*) (car ls))),|*cr-lf*|"
   (map change-path
        (map
         (lambda (s) #`",|*install-prefix*|,|s|,|*cr-lf*|")
        (cdr ls)))))

(define (del-str ls)
  (map
   (lambda (s) #`",|*delete-prefix*|,(change-path (replace-inst (*root-path*) s)),|*cr-lf*|")
   (cdr ls)))

(define (install-files)
  (map inst-str (*file-list*)))

(define (delete-files)
  (map del-str (*file-list*)))

(define (include line)
  (or
   (and-let* ((match (#/^(.*)##\(include (.*)\)(.*\r\n)$/ line))
              (exp (call-with-input-string (match 2) (cut read <>))))
             (list (match 1) (eval exp (current-module)) (match 3)))
   line))

(define (include-all lis)
  (map include lis))

(define (change-path str)
  (string-join (string-split str #\/) *path-separater*))

(define (read-line-crlf file)
  (let1 line (read-line file)
        (if (eof-object? line) line
            #`",|line|,|*cr-lf*|")))

(define (main args)
  (if (> (length args) 3)
      (let* ((path (cadr args))
             (in (caddr args))
             (version (cadddr args))
             (out (path-sans-extension in))
             (lines (file->list read-line-crlf in)))
        (if (file-exists? path)
            (begin
              (initialize path version)
              (call-with-output-file out
                (cut write-tree (include-all lines) <>)))
            (print "Path not exists: " path))
        0)
      (print "Usage: gosh " (car args) " <dist-path> <template-file> <gauche-version>")))

NSISスクリプトの生成

file-list.scmを実行するMakefileを書いた。

setup.nsi: setup.nsi.in
        gosh ./file-list.scm ../../../Gauche-mingw-dist/Gauche setup.nsi.in `cat ../../VERSION`

winnt/nsisでmakeを実行するとsetup.nsiが生成される。

NSISのインストールディレクトリがPATHに含まれているなら、Gauche-win32-<version>.exeも生成される。

NSISによるコンパイル

NSISのインストールディレクトリがPATHに含まれていないときは手動でコンパイルする。

インストーラー実行

Gauche-win32-<version>.exeを実行するとMinGW版GaucheがC:\Program Files\Gaucheにインストールされる。

今後の課題

日本語版以外のWindowsへGauche-win32-<version>.exeをインストールしたときの挙動?

どなたかテストお願いします。

Gaucheboxへの発展

これはGaucheのソースツリーの中ではなくて別途プロジェクトを立てたほうがヨサゲ。 →Gauche:Gauchebox

PATHの追加

NSISでもけっこう面倒。 WindowsのインストーラでPATHを設定するものは稀。

コメント

Post a comment

Name:


Last modified : 2012/02/23 03:15:50 UTC