KiCadでのレイヤーの使い方。

自分でもあやふやだったので、公式のドキュメントから抜粋して和訳。

レイヤと言うのはグラフィックエディタとは異なり、実際の基板製造のための「層」のことです。基板とはプリプレグと呼ばれるグラスファイバーとエポキシを混合したプラスチック層と、銅箔を利用した配線層、レジストと呼ばれる絶縁素材の層、シルクと呼ばれるマークや文字の層からなっていて、基本的にpcbnewなどの基板エディタはプリプレグ以外の層をそれぞれデザインしていきます。
よくある基板は1.6mm厚で、2層だと1.0mmや1.2mm、6層だと1.8mmというのもあります。ここでいう2層とか4層、6層は銅の配線層のことです。

[抜粋和訳はじまり]
5. レイヤー
5.1 イントロダクション
Pcbnewは50の異なるレイヤで作業できる:
  • 配線のための1から32層までのカッパー(銅箔)レイヤー
  • 用途固定の14のテクニカルレイヤー:
    • 12のペアレイヤー(Front/Back): Adhesive()、Solder Paste()、Silk Screen()、Solder Mask()、Courtyard()、Fabrication()
    • 2つの独立したレイヤー: Edge Cuts()、Margin()
  • 好きなように利用できる4つの補助レイヤー: Comments()、E.C.O.1()、E.C.O.2()、Drawings()
5.2 レイヤーのセットアップ
(略)

5.3 レイヤーの解説
5.3.1 カッパーレイヤー
(略)
5.3.2 ペアレイヤー
12のテクニカルレイヤーがペアになっている:1つはフロント(前面/部品面)、1つはバック(背面/はんだ面)。これらは名前の後の"F"または"B"のプレフィクスで識別できる。これらのレイヤーのうちのフットプリントを構成する要素(パッド、描線、テキスト)は、フットプリントをひっくり返されたときには自動的に対となるレイヤーに反転移動される。
テクニカルレイヤーのペアーは次の通り:
  • Adhesive (接着剤)(F.Adhes and B.Adhes)
    These are used in the application of adhesive to stick SMD components to the circuit board, generally before wave soldering.
    一般的にウェーブソルダリング(はんだ槽内でのスルーホール部品のはんだ付け)の前に、回路基板に面実装部品を突き刺して固定するための接着剤を指定するために利用される。(スルーホールには通常面実装部品は使用しないので意味不明。スルーホール部品でも面実装部品でも大きいものはボンドを使用してリフロー前に仮固定することがあるので、SMDという単語は余計。)
  • Solder Paste (はんだペースト)(F.Paste and B.Paste)
    Used to produce a mask to allow solder paste to be placed on the pads of surface mount components, generally before reflow soldering. Usually only surface mount pads occupy these layers.
    一般的にリフローソルダリング(リフローはんだ付け)の前に、面実装部品のパッドにソルダーペーストを塗布するためのマスクを生成するのに使用される。(ソルダーペーストの塗布は、0.1〜0.2mm厚程度のステンレス製メタルマスクを基板上に置いてスキージーでペーストを塗布するシルクスクリーン印刷に似た工程である)
  • Silk Screen (シルクスクリーン)(F.SilkS and B.SilkS)
    They are the layers where the drawings of the components appear. That’s where you draw things like component polarity, first pin indicator, reference for mounting, …
    部品の位置を示す描画を行うためのレイヤー。部品の極性や、1番ピンの位置、実装のためのリファレンスなどを描画する。(通常ではシルクと省略されることが多い。発音的には絹のシルクではなく、ク↑ラブ的な感じ)
  • Solder Mask (はんだマスク)(F.Mask and B.Mask)
    These define the solder masks. All pads should appear on one of these layers (SMT) or both (for through hole) to prevent the varnish from covering the pads.
    ソルダーマスクを定義する。すべてのパッドはFかBのどちらか(面実装)あるいは両方(スルーホール)のレイヤーになければならない。
  • Courtyard (中庭)(F.CrtYd and B.CrtYd)
    Used to show how much space a component physically takes on the PCB.
    部品が基板上で物理的に専有するスペースを表示するために使用される。(JEITA ET-7501では「部品本体とランドパターとを組み合わせた境界の周囲に、電気的及び機械的な最小クリアランス領域(製造許容領域)を加えた長方形領域」となっている)
  • Fabrication (製作)(F.Fab and B.Fab)
    Footprint assembly (?).
    フットプリントの実装(?)
5.3.3 独立したテクニカルレイヤー
(略)
5.3.4 一般用途レイヤー
これらのレイヤーはどんな使い方をしてもよい。実装方法を指示するテキストやワイヤリング、組立図、実装やマシニング用ファイルの生成用途などなど。レイヤーの名前は以下の通り:
  • Comments
  • E.C.O.1
  • E.C.O.2
  • Drawings
[抜粋和訳おわり]


…だそうなので、5.3.4の説明によればこれら4つのレイヤーを使って、寸法図や中心線、補助線などをいれ、最終的に外形図などを出力するときに印刷すべきもの(寸法図やキリなどの指示)と印刷しないもの(中心線、補助線)を別レイヤーにするのがよいと思われます。

ということを考えて、自分的利用分類を以下のようにしました。
  • Comments コメント、高さ方向クリアランスの計算根拠とかいろいろ
  • E.C.O.1 寸法線、寸法補助線、引出線
  • E.C.O.2 基板製造及び実装指示におけるコメント
  • Drawings 中心線、基準線、ピッチ線など
  • Adhesive (接着剤)(F.Adhes and B.Adhes)
    実装時、基板を移動させたりリフロー炉での加熱中に動いたり落ちたりしないよう、回路基板に部品を固定するための接着剤塗布の場所を指定するために使用する。
  • Courtyard (中庭)(F.CrtYd and B.CrtYd)
    部品が基板上で占有するスペースを描く層。他の部品との干渉を避けたり、実装のためのスペース(自動実装でも手実装でも必要な余裕)を確保したりするのに使用する。(JEITA ET-7501では「部品本体とランドパターとを組み合わせた境界の周囲に、電気的及び機械的な最小クリアランス領域(製造許容領域)を加えた長方形領域」となっている)
  • Fabrication (製作)(F.Fab and B.Fab)
    部品の実際の外形を描く層。部品外形。
    基板上には表示されず、基板エディタ上でのみ利用される。

ということは、FabとCrtYdではFabのほうが外側(フットプリントシンボルでは最外周)で、その内側にシルク、さらにCrtYd(部品外形)がくるということですね。

SyncTeX対応のPDFビューワ。

TeX WikiのSyncTeXのページに対応ビューワがまとめられています。

このうちWindowsで利用できるのは、
  • TeXworks - TeX Live付属の統合環境。
    ただし、キーワードの補完などはなく編集機能としては貧弱。
  • TeXstudio - TeX統合環境。
    ただ、upLaTeXを指定しているのにXeLaTeXを使ってくれたりして、なかなかままならない。たぶん、自分の使い方がタコい。
  • SumatraPDF - ちょっと前までNeovimと組み合わせて使おうと躍起になっていたPDFビューワ。
    軽くていいのだけれど、Neovimと組み合わせたときに inverse search がうまくいかない。Neovim側の --remote-* オプションが削除されてしまったため、neovim-remoteモジュールを利用する必要があるが、それでも完璧にはいかず、Windows環境はサポートしない(できない)、とのこと。gVimは --remote-*引数を受け取るのでパーフェクトに動く。また、Visual Studio Codeとの組み合わせもうまくいかない。
  • Okular - KDEベースのPDFビューワ。
    PDF、DVI、PSファイルも表示できる。ただし、WindowsでのインストールはChocolateyを利用する以外の方法はなさそう。Cygwin版もあるが、パス名の解釈の関係かドラッグ&ドロップができないため、実質使えない。
  • Visual Studio Code - Microsoftの提供するエディタ。
    PDFビューワも組み込まれているようで、LaTeX-Workshopをインストールして内蔵ビューワで表示した場合にはSyncTeXが有効になる。

その他のPDFビューワでも、SkimはMacOS専用、Evince (Gnomeベース)はMSYS2上での利用は可能のようだがWindowsネイティブはなし (どうもあるっぽいけれど、ftpサーバへのリンクが切れていて、win32バイナリのディレクトリにevinceはない)、zathuraはWindows版はなし、という感じで、現状でWindows環境でのスタンドアロンのPDFビューワとしてはSumatraPDFかOkularのみ、という状況です。

また、エディタと一緒になった環境ではVisual Studio Codeがかなりいい感じで、内蔵ビューワとの連携もしっかりできているので、設定さえできればサクサク使えそうです。ただ、場合によってはダンマリ状態になることもあり、またタイプセットに失敗してもどこでどう失敗したのかログ表示もヒントもないため、けっこう設定が大変です。

SumatraPDFはNeovimとの組み合わせが今ひとつ。外部からカーソルをジャンプさせる (SyncTeX) コマンドを送り込む際に、どうもSumatraPDF側でおかしなことになっている感じです。Neovim以外ではVS Codeでも試してみましたがうまくいきませんでした。gVimやNotepad++などでは問題はありません。なので、Neovimを使いたい、という場合には現状では選択肢からは外れます。

OkularはインストールするのにChocolateyが必要なのがいやらしい感じ。Okularを使うだけのために別のパッケージ管理ソフトをインストールするのはちょっとためらわれます。が、Okularはいじってみた感じでは軽くて使いやすそうだし、DVIファイルを表示する機能もあるようなので、もう少し見てみましょう。

Inverse Search between LATEX Editors and Okularにあるように、標準ではエディタとしてKateが指定されています。

さらにOkularのEditorの設定を見ると、ファイル名は "%f"、行番号は "%l"、桁番号は "%c" で指定できるようです。なので、エディタによって違いますが以下のように設定すれば、Shift+マウス左クリックでカーソル位置に飛ぶはずです。

  • 秀丸エディタの場合:
    "c:\Program Files\Hidemaru\Hidemaru.exe" /j %l,%c %f
  • Visual Studio Codeの場合:
    code -g %f:%l:%c
  • Notepad++の場合:
    "c:\Program Files\Notepad++\notepad++.exe" -n%l -c%c %f

ところがどうしたわけか、どうやっても動きません。
synctexのファイル拡張子も、*.synctex.gz、*.synctex (非圧縮)、*.pdfsync (上記ページに書いてあったもの)と試しましたが、ダメなようです。ということで、選択肢はSumatraPDFかOkularと書いたのですが、スタンドアロンのPDFビューワは現実的にはSumatraPDFしか選択肢がない、ということになりました。

LaTeXでプログラムコードを扱う。

プログラムコードをLaTeXで扱うにはlistings環境を使いますが、日本語のコメントなどに関してはうまく扱えないことがあるようで、それを修正してくれる jlisting.sty も併用します。

ところでWEB上での jlisting.sty のインストール方法は、直接TeX Liveの texmf-dist ディレクトリに置くような書き方をしているものが多いですが、本来ローカルなstyファイルなどは texmf-local に置くべきものです。なんでローカルなファイルをdist (本来はdistribution すなわち配布物)に置こうとするかな。

インストール方法は以下の通り。

  1. jlisting.styはmyTeXpertからダウンロードできます。
  2. BZ2形式で圧縮されているので7zipなどで展開してから、出てきた jlisting.sty ファイルを C:\texlive\texmf-local\tex\latex\local\listings ディレクトリに置きます。
    C:\texlive\texmf-local\tex\latex\local までのディレクトリはありますので、そこに listings ディレクトリを作成してその中にコピーまたは移動します。
  3. 管理者モードのコマンドプロンプトなどから mktexlsr c:\texlive\tekmf-local を実行します。

LaTeX Workshopを使ってみる。

LaTeX Workshopというのがあるようです。

  • Build LaTeX (including BibTeX) to PDF automatically on save.
  • View PDF on-the-fly (in VS Code or browser).
  • Direct and reverse SyncTeX. Click to jump between location in .tex source and PDF and vice versa.
  • Intellisense, including completions for bibliography keys (\cite{}) and labels (\ref{}).
  • Syntax highlighting (colorized code) for .tex / .bib files and more.
  • LaTeX log parser, with errors and warnings in LaTeX build automatically reported in VS Code.
  • Real-time linting of LaTeX with ChkTeX to pick up common LaTeX issues as you type.
    • Code Actions (automatic fixes) are offered for many issues found by ChkTeX.

え、これもしかしてTeXstudioいらなくない?

ということでLaTeX Workshopをインストールして使ってみます。

BloggerでMathjaxを使ってみる。

やっぱり数式を書くならLaTeXが一番美しく書けますね。実は太陽の重力はどれくらいなんだろうとふと考えたのがこのエントリを書くきっかけ。
BloggerでMathJaxを使ってTeXっぽく数式を入れる方法を参照させていただきました。

で、Wikipediaの重力加速度より、

球対称な天体を考え、自転の影響を考えない場合には、天体の質量を M、半径を R とすると、地表付近での重力加速度の大きさは、万有引力の法則から万有引力定数を G として

$$g=\frac{GM}{R^2}$$

と表すことができる。半径方向の単位ベクトルを\(e_r\)とすれば

$$g=-\frac{GM}{R^2}e_r$$

と表される。自転による遠心力を考慮すれば、自転の角速度を\(\omega = \omega e_z\)として

$$g=-\left(\frac{GM}{R^2}-R\omega^2\right)e_r-R\omega^2e_z \sin \phi$$

となる。ここで\(\phi\)は観測点の緯度である。重力加速度の大きさは緯度によって変化し、赤道で最も小さく、極で最も大きい。また、その方向も球の中心からずれる。

だそうです。
地球の場合には、Particle Data GroupのデータASTROPHYSICAL CONSTANTS AND PARAMETERSによれば、地球の質量は\(5.9724(3)×10^{24}\)kg(ただし(3)は3の循環小数)、半径(nominal Earth equatorial radius)は\(6.3781×10^6\)m、万有引力定数は\(6.67408(31)×10^{−11}\)m3 kg−1 s−2ということなので、自転を考えなければ\(9.79851528...\)m/s2となります。
公式には地球の重力加速度は\(9.80665\)m/s2なので、ほんのちょっと違いますが、およその値としてはかまわないでしょう。

そして肝心の太陽です。
Wikipediaによれば、太陽は質量\(1.9891×10^30\)kg、半径\(6.96×10^8\)mですから、自転を考えなければおよそ\(274.05\)m/s2となります。つまり地球の28倍です。
そしてそんな太陽からの脱出速度は617.7 km/s。地球からの脱出速度は11.186 km/sですから、地球の55倍の速度が必要となり、太陽の重力圏に捕まったらものすごい勢いで太陽に落ちていくんだよ、ということになります。
ちなみに音速のマッハでいえば、マッハ1は340 m/sですから、地球からの脱出にはマッハ33、太陽からの脱出にはマッハ1817と、もう想像することも困難な数字になってきます。時速になおせばマッハ1=1225 km/hとなります。
参考までに成田-サンフランシスコの距離は8236 km、マッハ1なら7.3時間、マッハ33なら0.22時間=13分30秒、マッハ1817なら14.5秒…というとんでもない速度ということになります。

なんというか、天文学ではほんとに天文学的な数字を扱うんだなぁ。

もうちょっとicsをいじってみる。

PyPiでicalendarというのを見つけてちょっといじってみたんだけれど、icalendarは今ひとつドキュメントが足りてないのと、「テストコードがあるから使用方法はそっちを見てね」的な感じだけどカバーしきれていない感じなのとで、やっぱりicsをもうちょっといじってみることにしました。

さて、GoogleカレンダーのエクスポートをCSVにする。では浅瀬でパシャパシャやってただけなので、もうちょっと深いところまでいってみましょう。

GoogleカレンダーのエクスポートをCSVにする。

Android端末を使っている関係で、Googleカレンダーを使用してスケジュール管理しているわけですが、これをエクスポートするとiCalendar形式のファイルになります。
iCalendar形式はxmlでもCSVでもなくて、
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:<ちよすけのメールアドレス>
X-WR-TIMEZONE:Asia/Tokyo
BEGIN:VTIMEZONE
TZID:Asia/Tokyo
X-LIC-LOCATION:Asia/Tokyo
BEGIN:STANDARD
TZOFFSETFROM:+0900
TZOFFSETTO:+0900
こんな感じにフィールド名:値という形式になっています。

これを容易に扱えるようにするには、「何かと都合のいい」CSV(カンマ区切り形式)が便利ですから、ぜひとも変換したい。

そしてこういうテキストを扱うのに適しているのは、昔ならsedやawk、perlなどでしたが、pythonでやればオブジェクト指向的にぱっぱと処理できるではないか、と思ったのでやってみました。

python2でもpython3でもどちらでもいいんですが、新しいことをやるのにはpython3のほうがいいです。

そして、iCalendar形式をpythonで扱うためのライブラリがすでにありました。
PyPi(ぱいぱい)よりicsです。

===
Ics.py is a pythonic and easy iCalendar library. It’s goals are to read and write ics data in a developer friendly way.
===

Windowsのpython3ではpipが標準で同梱されているので、コマンドプロンプトまたはPowerShellを開いて
pip install ics
でインストールできます。

そこでIdleを起動してちょっといじってみました。
まず、Googleカレンダーからエクスポートしたスケジュールデータはzipファイルに入っていますから、これを解凍し、さらに利用しやすいように名前を変更します。ここではchiyo.icsにしました。
まずはカレントディレクトリを移動します。chiyo.icsは/Users/chiyoに置いてあるとします。

>>> import os
>>> os.getcwd()
'C:\\Program Files\\Python36'
>>> os.chdir('/Users/chiyo')
>>> os.getcwd()
'C:\\Users\\chiyo'

pythonではパス区切りに '/' も使えるんですね。
では早速chiyo.icsを読み込んでみます。

>>> import ics
>>> f = open('chiyo.ics', 'r')
>>> c=ics.Calendar(f.read())
Traceback (most recent call last):
  File "", line 1, in 
    c=ics.Calendar(f.read())
UnicodeDecodeError: 'cp932' codec can't decode byte 0x86 in position 770: illegal multibyte sequence
>>> f
<_io.TextIOWrapper name='chiyo.ics' mode='r' encoding='cp932'>
>>> f.encoding
'cp932'

エンコードが違いますと怒られました。なんでデフォルトのファイルエンコーディングがcp932なんですかね。Windowsシステムの設定を参照してるんでしょうけど…。
そこで、標準ライブラリのcodecsを使用します。

>>> import codecs
>>> f=codecs.open('chiyo.ics', 'r', 'utf-8')
>>> c=ics.Calendar(f.read())
>>> c
<Calendar with 1588 events>

読み込めました。

cはiCalendarのBEGIN:VEVENTからEND:VEVENTに囲まれたそれぞれのスケジュールデータを保持していて、引数で指定できます。

>>> c.events[5]
<Event '岡山出張' begin:2008-12-10T00:00:00+00:00 end:2008-12-12T00:00:00+00:00>
>>> 

という感じ。

表示されているのはSUMMARY、DTSTART、DTENDの3つのフィールドだけですが、フィールドには他にもLOCATION、DESCRIPTIONなどがあります。
これらはそれぞれ、Calendar.name、Calendar.begin、Calendar.end、Calendar.location、Calendar.descriptionになります。

なので、プログラムとしてはc.events[]の添字を1から最大数まで増やしながら、上記のそれぞれのメンバを書き出すだけになります。

>>> for i in range(1, 100):
 print (c.events[i].begin, c.events[i].end, c.events[i].name, c.events[i].location, c.events[i].description, sep=',')

2008-12-10T00:00:00+00:00,2008-12-12T00:00:00+00:00,岡山出張,,

実際にはこんな風にどんどん出力されます。
日付形式とかちょっとアレな感じですが、これで出力できそうです。エンコーディングの問題があったので、出力用のファイルもcodecs.open()で開きます。

>>> fout=codecs.open('chiyo.out', 'w', encoding='utf-8')
>>> for i in range(1, 1588):
 print (c.events[i].begin, c.events[i].end, c.events[i].name, c.events[i].location, c.events[i].description, sep=',', file=fout)
 
>>> 

これでファイル 'chiyo.out' に出力できました。

実際には、どうもエンコーディングの違うフィールドがあるようで、データの一部が文字化けしてたりしましたが、一応目的は達成できました。
この文字化けはもしかしたらAndroidで使ってるカレンダーツールが悪さしているかもしれません。ちょっと注意してみましょう。

もうちょっとicsをいじってみる。 に続く。

コマンドプロンプトでの入力補完。

管理者モードのコマンドプロンプトでプロンプトを変える。AutoRun の設定をするときに regedit を開いたわけですが、HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processorキーには他に CompletionChar というキーがあります。うちではこの値は 0x40 になっています。

この CompletionChar はファイル名の補完機能の設定で、たとえばカレントディレクトリにabc.txtcde.txtxyz.txtがあったとき、a<TAB>と押せば abc.txt が補完され、x<TAB>と押せば xyz.txt が補完されます。

キーにはこのCompletionCharの他に、PathCompletionCharというのもあります。どちらもデフォルト値は 0x09 (TAB) に設定されているようです。が、自分のところでは両方ともに 0x40 です。なんで 0x40 なのかわかりません。上記のページでは 0x40 は "key" となっていて、詳しい説明がありません。が、動作としてはTABキーで補完してくれるので気にしないようにします。

ところで、CMD.EXEの補完機能は結構貧弱ですが、これをbash的な行編集機能にするためのClinkというアプリケーションがあるようです。

===
Clink combines the native Windows shell cmd.exe with the powerful command line editing features of the GNU Readline library, which provides rich completion, history, and line-editing capabilities. Readline is best known for its use in the well-known Unix shell Bash, the standard shell for Mac OS X and many Linux distributions.
===

ということで、CMD.EXEがかなりいい感じになるようです。
ClinkはインストーラーでインストールするとAutoRun値を書き換えてしまうようなので、ZIP形式をダウンロードして c:\Apps ディレクトリに配置します。

次に、前記事で書いた cmdrc.bat の最終行に次の行を加えます。
c:\Apps\clink_0.4.9\clink_x64.exe inject

ただ…せっかく指定したコマンドプロンプトのエスケープシーケンス (色) が消えてしまいました。すごく残念。なにかやりようはないかしら。でも、CTRL-Dでコマンドプロンプトを閉じることができるのは素晴らしいです。

結局cmdrc.batを以下のように変更しました。

@echo off
doskey /macrofile=%userprofile%\cmd.rc

c:\Apps\clink_0.4.9\clink_x64.exe inject

openfiles > NUL 2>&1

if %ERRORLEVEL% == 0 (
  rem 管理者モードの処理
  rem CRIMSON
  rem set PROMPT=$e[38;2;220;20;60m$p# $e[0m
  set PROMPT=$p# 
  set clink.prompt_colour=4
) else (
  rem 通常モードの処理
  rem deepskyblue
  rem set PROMPT=$e[38;2;0;191;255m$p$$ $e[0m
  set PROMPT=$p$$ 
  set clink.prompt_colour=3
)

これだと基本的な16色しか指定できないので、ちょっとつまらないんですが仕方ないですね。

管理者モードのコマンドプロンプトでプロンプトを変える。

コマンドプロンプトの色を変える。では、有無を言わさず自分が開くコマンドプロンプトのプロンプトを変えてしまう方法を書きました。

ところで自分が使用するNetBSDやLinuxやCygwin上では zsh を使用していて、suでrootになったときにはプロンプトを赤色に変更しています。通常のプロンプトはネイビーというかブルー系です。これは、うっかりミスをできるだけ防ぐように、という工夫です。

これを管理者モードのコマンドプロンプトでも実現できないか、と考えるわけです。

コマンドプロンプトの色を変える。

Windowsでコマンドプロンプトを使っていると通常は文字の色が全部白のため、スクロールバックしたときなどにどれがコマンドなのかがわかりにくくなります。

コマンドプロンプトを管理者モードで起動する方法。

「コマンドプロンプト」をタスクバーにピン留めしておいて、コマンドプロンプトを右クリックしてメニューを出して、さらに「コマンドプロンプト」の上で右クリックするともう一つメニューが出ます。



コマンドプロンプトにかぎらず他のアプリもこの方法で管理者モードで起動できます。

スタートメニューの場合には、アイコンを右クリックしてから「その他」を選択すると「管理者として実行」メニューが出ます。

コマンドプロンプトでエイリアスを使う。

Windowsのコマンドプロンプトでは、ドライブごとにカレントディレクトリを記憶している関係なのか、たとえばc:\tempからd:\appsに移動したいときに

c:\temp>cd d:\apps
c:\temp>

などとしても、カレントディレクトリはc:\tempのまま。d:ドライブに移動すると、d:ドライブではd:\appsに移動しているという実装になっています。つまり、カレントディレクトリはドライブごとに管理されています。

コマンドプロンプトの実体であるcmd.exeの組み込みコマンドcd (chdir)では、

cd /?

などとするとヘルプが表示され、その中に/dオプションがあることがわかります。これはドライブも含めて移動するオプションで、

c:\temp>cd /d d:\apps
d:\apps>

とすればカレントドライブもカレントディレクトリも同時に変更され、現在位置が d:\apps になります。

ところでWindows10では doskey というユーティリティがあり、これを使うとUNIX上のシェルのようにエイリアスを使用することができるようになります。

D:\apps>doskey /?
コマンド ラインの編集、Windows コマンドの再呼び出し、マクロの作成を行います。

DOSKEY [/REINSTALL] [/LISTSIZE=サイズ] [/MACROS[:ALL | :実行ファイル名]]
  [/HISTORY] [/INSERT | /OVERSTRIKE] [/EXENAME=実行ファイル名]
  [/MACROFILE=ファイル名][マクロ名=[テキスト]]

  /REINSTALL               Doskey の新しいコピーを組み込みます。
  /LISTSIZE=サイズ         コマンド履歴バッファーのサイズを設定します。
  /MACROS                  すべての Doskey マクロを表示します。
  /MACROS:ALL              Doskey マクロを含むすべての実行可能ファイルの
                           すべての Doskey マクロを表示します。
  /MACROS:実行ファイル名
                           指定した実行可能ファイルのすべての Doskey マクロを
                           表示します。
  /HISTORY                 メモリ内のすべてのコマンドを表示します。
  /INSERT                  入力したテキストが古いテキストに挿入されるように
                           指定します。
  /OVERSTRIKE              入力したテキストが古いテキストを上書きするように
                           指定します。
  /EXENAME=実行ファイル名  実行可能ファイルを指定します。
  /MACROFILE=ファイル名    作成するマクロ ファイル名を指定します。
  マクロ名                 作成するマクロ名を指定します。
  テキスト                 登録するコマンドを指定します。

上下方向キーはコマンドを再度呼び出します。Esc はコマンド ラインをクリア
します。F7 はコマンド履歴を表示します。Alt+F7 はコマンド履歴をクリアします。
F8 はコマンド履歴を検索します。F9 は数字によるコマンドを選択します。
Alt+F10 はマクロ定義をクリアします。

以下は、DOSKEY のマクロ定義で使用する特殊コードです:
$T     コマンド セパレーターです。マクロ中で複数のコマンドを定義できます。
$1-$9  バッチ パラメーターです。バッチ ファイル中の %1-%9 と同じ意味です。
$*     コマンド ライン上のマクロ名に続くテキストで置き換えられるシンボルです。

これを利用してコマンドプロンプトで doskey cd=cd /d $* とすれば、cd の動作が cd /d に展開されるのでドライブも一緒に変更できるようになります。

さらにこれをコマンドプロンプト起動時に自動的に設定するには、regeditを利用して HKEY_CURRENT_USER\Software\Microsoft\Command ProcessorAutoRunというキーを作り、そこに初期設定として実行したい内容を記述したバッチファイルを設定しておきます。

登録するバッチファイルは以下のような感じで作成しておきます。

@echo off
Doskey cd=cd /d $*
Doskey history=doskey /history
Doskey vim="C:\Program Files\Vim\vim.exe" $*

なんて感じで。

また、別なやり方として、ホームディレクトリにDOSKEYマクロファイルを置く方法もあります。ファイル名は cmd.rc で、以下のような内容を記述します。AutoRun には doskey /macrofile=%userprofile%\cmd.rcなどとします。

CD=CD /D $*
H=doskey /history
HISTORY=doskey /history
ALIASES=doskey /macros

こちらのほうが、よりUNIX的な感じがしますね。

よくわからないコマンドプロンプト。

ちょっとCMD.EXEシリーズ。

なにがわからないかというと、空白文字の扱い。

たとえば a.bat という名前で次の内容のファイルを作ります。

@echo %1

これを、a.bat あいうえお_かきくけこ と引数を与えて実行します。 "_" は全角空白に置き換えてください。

すると、 "あいうえお" が返ってきます。つまり全角空白がデリミタ (区切り文字) として処理されています。

次にコマンドプロンプトで直接

set a=あいうえお かきくけこ
echo %a%
あいうえお かきくけこ

今度は全角空白がデリミタではなく文字として扱われています。

これはかなり困った仕様で、バッチファイルに「ファイル名に全角空白文字を含んだファイル」を食わせると、勝手に分解してしまうのです。その結果、「指定されたファイルが見つかりません」エラーになります。全角空白をデリミタとして処理してしまうということを知らないと、なにがおかしいのかまったく見当もつかない状態になります。

これを防ぐにはダブルクォーテーションで文字列を囲うという方法があるのですが、その方法はドラッグ&ドロップでバッチファイルに食わせるときには使えません。つまり自動的には行ってくれません。それを解決するには、引数で与えられたファイル名をバッチファイル内部でダブルクォーテーションで囲い直す、などという処理が必要になってきます。

ところがたちの悪いことに、バッチファイルに「ファイル名に半角空白文字を含んだファイル」をドラッグ&ドロップで食わせると、コマンドプロンプトがバッチファイル内で自動的にダブルクォーテーションで囲ってしまうのです。するとどういうことが起こるかというと、「すでにダブルクォーテーションで囲われている文字列をさらにダブルクォーテーションで囲う」ということになり、結果「ダブルクォーテーションで囲われていない」のと同じ状態になってしまうのです。

それからファイル名に "&" の文字を含んでいるファイルをバッチファイルに食わせると、 "&" 以降を別のコマンドとして実行しようとしますので、これも注意が必要です。

はぁ…。

NeovimをVisual Studio 2017でコンパイルする。

必要要件

  • Windowsのシステムロケールを「英語(米国)」に変更しておく。
  • Git for Windowsをインストールし、パスを通しておく。
  • CMakeをインストールし、パスを通しておく。
  • 必要に応じてPython2、Python3、RubyおよびNode.jsをインストールし、パスを通しておく。特にShougo/dein.vimを使う場合にはPython3は必須となる。
  • gettext0.19.8.1-iconv1.15-shared-64.zipをダウンロードしておく。
  • Neovimインストーラを作成する場合にはNSISをインストールしておく。
パスについては、
setx GITPATH=C:\Program Files\Git\bin;C:\Program Files\Git\usr\bin;C:\Program Files\Git\mingw64\bin
setx CMAKEPATH=C:\Program Files\CMake\bin
setx PATH=%PATH%;%GITPATH%;%CMAKEPATH%
などとしておきます。こうしておくと、Git for Windowsに同梱されているMSYS系のコマンド (cpやpatchなど) が使えるようになります。CygwinやMSYSなどを別途インストールしておく必要はありません。

ビルドオプション

以下の条件でビルドします。
  • x64-Release
  • +iconv、+tui、-acl、-jemalloc
  • 作業は %USERPROFILE%/build ディレクトリで行う。
  • インストール先は c:\Apps\Neovim とする。
  • MSBuild を使うので、作業は「VS2017用 x64 Native Toolsコマンドプロンプト」で行う。(iconvは除く)

準備: libiconvのコンパイル

cd %USERPROFILE%\build
git clone https://github.com/kiyolee/libiconv-win-build
cd libiconv-win-build/build-VS2017-MT
  1. ここにある libiconv.sln をダブルクリックしてVS2017を起動する。
  2. このままビルドすると「Windows SDKバージョンが違う」というエラーが出るので、それぞれのプロジェクトのプロパティから変更する。
  3. 「Release」「x64」を選択してビルドする。

準備: 依存ライブラリのコンパイル

cd %USERPROFILE%\build
git clone https://github.com/neovim/neovim
cd neovim
mkdir .deps
mkdir build
cd .deps
"\Program Files\CMake\bin\CMAKE.exe" -G "Visual Studio 15 2017 Win64" ..\third-party
MSbuild ALL_BUILD.vcxproj /p:Configuration=Release
2018/5/1現在のmasterでは libuv にパッチが追加されたもののパッチできないため、libuv のコンパイルが失敗します。その場合にはなんとか自力で (libuv.vcprojなどを見ながら手動で) コンパイルしておきます。
ここまででツリー構造は以下のようになっているはずです。.deps以下にディレクトリが作られ、依存ライブラリはここにコピーされています。

build -+- neovim -+- .deps -- usr -+- bin
       |          |                +- include
       |          |                +- lib
       |          |
       |          +- build
       |
       +- libiconv-win-build -+- include -- iconv.h
                              +- build-VS2017-MT -- x64 -- Release -+- libiconv.dll
                                                                    +- libiconv.lib
                                                                    +- iconv.exe

ここで、iconvのヘッダファイルとDLLをコピーします。
cd %USERPROFILE%\build\neovim\.deps
copy ..\..\libiconv-win-build\include\iconv.h usr\include
copy ..\..\libiconv-win-build\build-VS2017-MT\x64\Release\iconv.exe usr\bin
copy ..\..\libiconv-win-build\build-VS2017-MT\x64\Release\libiconv.dll usr\bin
copy ..\..\libiconv-win-build\build-VS2017-MT\x64\Release\*.lib usr\lib

また、ダウンロードしてある gettext0.19.8.1-iconv1.15-shared-64.zip を展開して libintl-8.dll を取り出し、usr\bin にコピーしておきます。

準備: cmakeファイルの変更

cmakeが libiconv と libintl を見つけられるようにcmakeファイルを変更します。
--- cmake\FindIconv.cmake.orig Wed Apr 18 18:08:38 2018
+++ cmake\FindIconv.cmake Wed Apr 18 18:05:32 2018
@@ -8,7 +8,7 @@
 include(LibFindMacros)
 
 find_path(ICONV_INCLUDE_DIR NAMES iconv.h)
-find_library(ICONV_LIBRARY NAMES iconv)
+find_library(ICONV_LIBRARY NAMES iconv libiconv libiconv-2)
 
 set(Iconv_PROCESS_INCLUDES ICONV_INCLUDE_DIR)
 if(ICONV_LIBRARY)
--- cmake\FindLibIntl.cmake.orig Wed Apr 18 18:08:28 2018
+++ cmake\FindLibIntl.cmake Wed Apr 18 18:04:29 2018
@@ -27,7 +27,7 @@
 )
 
 find_library(LibIntl_LIBRARY
-    NAMES intl libintl
+    NAMES intl libintl libintl-8
 )
 
 if (LibIntl_INCLUDE_DIR)

パッチは %USERPROFILE%\neovim ディレクトリで行います。上記のdiffを cmake.patch という名前で保存し、
cd %USERPROFILE%\neovim
patch -p0 < cmake.patch
でパッチがあたります。patch コマンドはGit for Windowsに含まれています。

Neovimをビルドする

cd %USERPROFILE%\build\neovim\build
"\Program Files\CMake\bin\CMAKE.exe" -DCMAKE_BUILD_TYPE=RelWithDebInfo -CMAKE_INSTALL_PREFIX=\Apps\Neovim -G "Visual Studio 15 2017 Win64" ..
MSbuild ALL_BUILD.vcxproj /p:Configuration=Release
ConfigurationRelease もしくは RelWithDebInfo を指定します。

Neovimをデプロイする

前の記事ではちまちまコピーしていたのでいっそ cp なんかを使ってスクリプトでも作ろうかと思ったのですが、INSTALL.vcxproj を使います。
cd %USERPROFILE%\build\neovim\build
MSbuild INSTALL.vcxproj /p:Configuration=Release
これで -CMAKE_INSTALL_PREFIX= で指定した場所にデプロイされます。ここでは c:\Apps\Neovim になっています。

Neovimインストーラを作成する

NSIS (Nullsoft Scriptable Install System) を使って、Neovim.exeという形でインストーラを作成できます。NSISはインストールしておけばパスを通す必要はないようです。
cd %USERPROFILE%\build\neovim\build
MSbuild PACKAGE.vcxproj /p:Configuration=Release
これで %USERPROFILE%\buildNeovim.exe が生成されます。 これは-CMAKE_INSTALL_PREFIX= で指定した場所ではなく、c:\Program Files\Neovim にインストールされるようです。
また証明書のついていないインストーラなので、セキュリティポリシーを上げたWindowsではインストールできないかもしれません。

以上で一通りNeovimのビルドは終わりです。
Have a good Neovim life!

Windowsでシンボリックリンクを試してみる。

きっかけは、1つのファイルを別の名前で起動したら違う動きになるようなスクリプトを書く、でした。  busybox なんかでは、同じ実行形式ファイルの名前を、lsにすればlsと同じ、cpとすればcpと同じ動作をするようにしてますが、Pythonスクリプトでそれと同じように argv...