Hatena::ブログ(Diary)

アセトアミノフェンの気ままな日常

2016-09-19

LaTeX パッケージ作者もオプションには空白を含めないほうがよい話

前回の記事に関連したタレコミが。

\begin{filecontents}{test3.sty}
\DeclareOption{foo}{\typeout{*** FOO OPTION ***}}
\DeclareOption{bar}{\typeout{*** BAR OPTION ***}}
\DeclareOption{baz}{\typeout{*** BAZ OPTION ***}}
\DeclareOption{qux}{\typeout{*** QUX OPTION ***}}
\ExecuteOptions{foo, bar}
\ProcessOptions\relax
\end{filecontents}

\documentclass{article}
\usepackage[baz, qux]{test3}
\begin{document}
a
\end{document}

パッケージが既定で foo と bar を実行し(パッケージ内で作者が \ExecuteOptions で指定)、さらにユーザが baz と qux を指定する(\usepackage のオプション)ので、全部で四つのメッセージが出そうである。ところが

*** FOO OPTION ***
*** BAZ OPTION ***
*** QUX OPTION ***

あれ、BAR が出ない! という話。\usepackage はコンマの周りに空白があってもよいのに、\ExecuteOptions はダメ、というトラップだそうだ。

LaTeX team も「20年経って今頃なんでこんなに…?」と戸惑っていました…次回全部(これで3つめ?)直すらしい。

2016-09-17

LaTeX パッケージの読込時オプションには空白を含めないほうがよい話

昨日までのアレな話とは別件で:LaTeX team からいただいた情報をひとつ。

「パッケージ読込時に “,” 区切り周囲にスペースを入れると Option clash する例」が最近発覚したらしい。以下の例示ソースで再現可能*1

\documentclass{article}
\usepackage[a, b, c]{foo}
\usepackage[a ]{foo}
\stop
! LaTeX Error: Option clash for package foo.

同じパッケージが 2 回以上使われそうになった場合、本来ならば「2回目のオプションたちが1回目のオプションたちの部分集合であればスルー、もし増えていたら Option clash エラー」となるべきところ、上記ソースでは空白がおかしな作用をして、部分集合になっているのに clash している。これも次回リリースで直すつもりらしい。

\def\@if@pti@ns#1#2{%
  \let\reserved@a\@firstoftwo
  \edef\reserved@b{\zap@space#2 \@empty}%       <- new
 \@for\reserved@b:=\reserved@b\do{%             <- changed
   \ifx\reserved@b\@empty
   \else
     \expandafter\in@\expandafter{\expandafter,\reserved@b,}{,#1,}%
     \ifin@
     \else
       \let\reserved@a\@secondoftwo
     \fi
   \fi
 }%
 \reserved@a}

ついついやってしまいがちな「空白」。特にオプションを多数指定する場合、コード上は改行して書くことも多いだろう:

\usepackage[dvipdfmx,%
 bookmarks=true,%
 bookmarksnumbered=true,%
 colorlinks=true,%
 setpagesize=false,%
 pdftitle={LaTeX研修課程},%
 pdfauthor={ななしのごんべぇ},%
 pdfsubject={hyperref入門・演習},%
 pdfkeywords={TeX; dvipdfmx; hyperref; color;}]{hyperref}

最後の % を書く習慣は付けておくと無難、ということかもしれない。オプション周りにいろいろ潜んでいたことがわかって怖い 3 日間だった。 → もうひとつ…

*1:これは一般化した記述であるが、たとえば foo → graphicx、a → dvipdfmx、b → dvips、c → dvipsone 等と置き換えてみるとよいだろう。

2016-09-16

存在するはずの LaTeX パッケージのオプションがなぜか未定義?(続き)

もう少し昨日のアレについて補足しておく。

昨日述べたとおり

% NG
\begin{filecontents}{test1.sty}
\DeclareOption{loadxspace}{\relax}
\ProcessOptions
\AtEndOfPackage{\RequirePackage{xspace}}
\end{filecontents}
\documentclass{article}
\usepackage[loadxspace]{test1}
\begin{document}
\end{document}

はエラーになる。しかし

% OK
\begin{filecontents}{test0.sty}
\DeclareOption{loadxspace}{\AtEndOfPackage{\RequirePackage{xspace}}}
\ProcessOptions
\end{filecontents}
\documentclass{article}
\usepackage[loadxspace]{test0}
\begin{document}
\end{document}

は正常に通る。これは特に不思議なことではないし、この OK な書式を各種パッケージがあちこちで使っている例も見つかる。

最初の NG になるケースについてもう少し厳密にいうと

パッケージ内で \ProcessOptions した後に、\AtEndOfPackage{\RequirePackage{hoge}} されることが現状「未考慮」である

ということなのだと思う。そもそも、\DeclareOption 以外の場所で \AtEndOfPackage を発行する必要性がほとんど生じない(自分でパッケージの末尾に書けば済む場合がほとんど)なので、それでもよいということなのだろう。

この現状「未考慮」とおぼしきものを大丈夫にしようとすると

  • コレ (Gist: 20160916-AtEndOfPackage-RequirePackage-test.tex)

みたいな感じになる。

ちなみに

もうひとつアレな挙動がある。

この回答では、\AtEndOfPackage{\RequirePackage{hoge}} とするのが workaround とされている。そうすることで、「親パッケージ読み込みが完全に終了したあとに、子パッケージを読み込む」ということが可能になるのである。というわけで、上の

自分でパッケージの末尾に書けば済む場合がほとんど

は必ずしも成り立たないのである。

で、この TeX.SX のソースと今回僕が発見したアレな挙動の合わせ技で、こんな変なことが起きる。これはヤバい…

\documentclass{article}

\begin{filecontents}{test0.sty}
\DeclareOption{FOO}{\typeout{*** FOO OPTION ***}}
\ProcessOptions\relax
\RequirePackage{test1}
%\AtEndOfPackage{\RequirePackage{test1}} % <= "workaround" proposed in TeX.SX
\end{filecontents}

\begin{filecontents}{test1.sty}
\RequirePackage{test0}
\end{filecontents}

\usepackage[FOO]{test0}

\begin{document}

\end{document}

つまり、二つのパッケージが互いに相手を必要としている場合である。

\ProcessOptions よりあとに、オプション実装を持たない子パッケージを読み込むと、どうやっても(素朴に \RequirePackage しても TeX.SX 的な workaround をしても)エラーが出る

というアレすぎる挙動になる*1\RequirePackage\ProcessOptions よりあとに書いてはダメ、というのはさすがにアレすぎないだろうか…

追記:問題発覚

当初 Gist に置いたコードだと、別の問題が発生してしまった:

\documentclass{article}
\usepackage[dvips]{geometry}
\begin{document}
\end{document}

これを処理したときに

! LaTeX Error: Unknown option `dvips' for package `geometry'.

が出てしまう。keyval を使うパッケージでは内部でこのエラーを出さないようにするハンドリングを独自で持っていて、それと衝突してしまうらしい…

→ というわけで改良版 (2016-09-16 17:42 GMT+09:00)

もうひとつ不自然な挙動があったそうです

上記の件を報告したところ、今度は LaTeX team から最近発覚した(全く別の)問題について教えていただきました → こちら

*1:ちなみに、このケースに対する正しい workaround は「test0.sty のなかで \RequirePackage{test1} を \ProcessOptions より前に持ってくる」である。

2016-09-15

存在するはずの LaTeX パッケージのオプションがなぜか未定義?

以下の LaTeX ソースを処理してみる*1

\begin{filecontents}{test.sty}
\DeclareOption{TEST}{\typeout{*** TEST OPTION ***}}
\ProcessOptions
\AtEndOfPackage{\RequirePackage{xspace}} % !!!
\end{filecontents}
\documentclass{article}
\usepackage[TEST]{test}
\begin{document}
\end{document}

この !!! を付けた行で呼び出すパッケージによって、これがエラーになったりエラーにならなかったりする。エラーというのは

! LaTeX Error: Unknown option `TEST' for package `test'.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...                                              
                                                  
l.8 \begin
          {document}
? 

というもの。LaTeX の required に含まれるパッケージ群 (graphics, tools) の中で、適当に試してみると、以下は OK なもの:

  • longtable
  • multicol
  • varioref
  • color
  • graphicx

以下は NG なもの:

  • alltt
  • array
  • enumerate
  • ftnright
  • hhline
  • somedefs
  • theorem
  • xspace

この違いはなんでしょう?

どうやら、正解は「呼び出されたパッケージに何らかのオプションが実装されているかどうか」らしい。オプション実装なしのパッケージでは初期化されていなくて、出てくるエラーが不可解になっているということ…!?

追記:latex.ltx を読んでみる

[1] エラー本体は \@unknownoptionerror という名前。
[2] これは \@@unprocessedoptions の中で使われている。
[3] 実際の呼び出しは \@onefilewithoptions で行われる。

    \let\@unprocessedoptions\@@unprocessedoptions % <= ここでコピーされる
    \csname\@currname.\@currext-h@@k\endcsname % <= これに注目!
    \expandafter\let\csname\@currname.\@currext-h@@k\endcsname
              \@undefined
    \@unprocessedoptions % <= ここで使われる

一見そのままだと常にエラーになりそう…だがまだ続きがあって、もし「いま読んでいるパッケージ」にオプションが実装されていれば話は別になる。
[4] \ProcessOptions の下請け \@process@pti@ns がエラーを抑制する。

  \AtEndOfPackage{\let\@unprocessedoptions\relax}

ここで使われている \AtEndOfPackage の引数は

    \csname\@currname.\@currext-h@@k\endcsname

のタイミングで実行されることに注目。
[5] 上記の説明は、呼び出し元のパッケージだけでなく呼び出された側のパッケージでも起きる。このため、\AtEndOfPackage のなかで呼び出されたパッケージが「エラー抑制」をしなかった(= \ProcessOptions が使われていなかった)場合、呼び出し元のパッケージに波及してエラーを吐いてしまうようだ…。

理由までは分かる、でも単に「想定外」な気もしているし、実際に改善する方法もこれといって思いつかないのでアレ、という話です、ハイ。 → こっそり

*1:簡略化のため filecontents 環境を使っているが、これは「環境内の命令を test.sty というファイルに保存して同じディレクトリに置く」というのと同じである。

2016-08-26

TeX Live (win32) をビルドしてみる実験(3)

1. 本日 (2016-08-26) でメインブログが2周年です。ブログの開設は、大学院入試を受験終了した当日の夕方に行いましたのではっきり記憶にありますが、早いものです。お読みいただきありがとうございます☃
2. 昨日 (2016-08-25)、所属専攻の修士論文中間審査会で無事(?)発表終了しました。あと半年で最終審査会ですので精進します。

第1回第2回に続き、今度も win32 バイナリのビルドに挑戦する。最難関と思われる XeTeX (xetex.dll) のビルドが幸いにも通ったので、その手順を書いておく。

XeTeX のビルド手順

XeTeX のソースは、w32tex-src のなかの ktx ではなく xtx のほうに入っている。(いまだに ktx と xtx の違いがわからない…)

[A] kpathsea のビルド

まずは kpathsea のビルド。

> cd w32tex-src
> cd xtx\texk\kpathsea
> make

これで libkpathsea.lib ができる。

[B] web2c のビルド

次いで、web2c のビルドに移る。天下り的だが、w32tex-src\xtx\texk\web2c に texmf.cnf を置いておくと後で滞らないらしい。

> cd ..
> cd web2c
> make

途中で、第1回でお馴染のエラーが出て止まる:

cl -DICUFORXeTeX=1 -DHAVE_CONFIG_H=1 -DNO_KPSE_DLL=1 -DXETEX_OTHER=1 -I. -I../..
/libs/fontconfig -I../../libs/freetype/include -I. -I.. -I./..  -I../../libs/lib
png -Ilualibs/lua52 -Ilualibs -I -I/.. -nologo -O2 -MT -wd4819 -DWIN32=1 -D_CRT_
SECURE_NO_DEPRECATE=1 -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_OBSOLETE_NO_DEPRECATE -
D_SECURE_SCL=0 -DNO_KPSE_DLL=1 -DLUA_BUILD_AS_DLL=1 -I. -I.. -Isynctexdir -Ilibm
d5 -DLUA_COMPAT_MODULE=1 -I. -I.. -I../../libs -I../../libs/poppler/poppler-src
-I../../libs/poppler/poppler-src/poppler -I../../libs/poppler/poppler-src/fofi -
I../../libs/poppler/poppler-src/goo -I../../libs/libpng -I../../libs/zlib -I../.
./libs/icu-src/source/common/unicode -I../../libs/icu-src/source/common -I../../
libs/icu-src/source/layout -I../../libs/icu-src/source -DLE_USE_CMEMORY -I. -I..
 -DGRAPHITE2_STATIC=1 -I../../libs/graphite2-src/include -I../../libs/graphite2-
src/include/graphite2 -D__HP_cc=1 -I../../libs/harfbuzz/harfbuzz-src/src -c ctan
gle.c
ctangle.c
./cwebdir/ctang-w2c.ch(132) : fatal error C1083: Cannot open include file: 'cweb
.h': No such file or directory
make: *** [ctangle.obj] Error 2

というわけで、やっぱり

> make cweb

として cweb.h を“発生”させて

cl -nologo -O2 -MT -wd4819 -DWIN32=1 -D_CRT_SECURE_NO_DEPRECATE=1 -D_CRT_NONSTDC
_NO_DEPRECATE -D_CRT_OBSOLETE_NO_DEPRECATE -D_SECURE_SCL=0 -DNO_KPSE_DLL=1 -DLUA
_BUILD_AS_DLL=1 -I. -I.. -Isynctexdir -Ilibmd5 -DLUA_COMPAT_MODULE=1 -I. -I.. -I
../../libs -I../../libs/poppler/poppler-src -I../../libs/poppler/poppler-src/pop
pler -I../../libs/poppler/poppler-src/fofi -I../../libs/poppler/poppler-src/goo
-I../../libs/libpng -I../../libs/zlib -I../../libs/icu-src/source/common/unicode
 -I../../libs/icu-src/source/common -I../../libs/icu-src/source/layout -I../../l
ibs/icu-src/source -DLE_USE_CMEMORY -I. -I.. -DGRAPHITE2_STATIC=1 -I../../libs/g
raphite2-src/include -I../../libs/graphite2-src/include/graphite2 -D__HP_cc=1 -I
../../libs/harfbuzz/harfbuzz-src/src -I../../libs/libpng -Ilualibs/lua52 -Iluali
bs -I -I/.. -link /SUBSYSTEM:CONSOLE  cweb.c lib/lib.lib ../kpathsea/libkpathsea
.lib wsock32.lib user32.lib advapi32.lib shell32.lib  -o cweb
cl : Command line error D8003 : missing source filename
make: *** [cweb] Error 2

再度 make する。

> make

今度は以下のエラーで止まってしまった…

make[1]: Entering directory `/path/to/w32tex-src/xtx/texk/web2c/web2c'
cl -DHAVE_CONFIG_H -D__STDC_VERSION__=199901L -DWIN32=1 -DYY_NO_UNISTD_H=1 -D_CR
T_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_OBSOLETE_NO_DEPRECATE -
DNO_KPSE_DLL=1 -I. -I. -I../.. -I../.. -I.. -I.. -I./..  -nologo -O2 -MT -wd4819
 -DWIN32=1 -D_CRT_SECURE_NO_DEPRECATE=1 -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_OBSOL
ETE_NO_DEPRECATE -D_SECURE_SCL=0 -DNO_KPSE_DLL=1 -DLUA_BUILD_AS_DLL=1 -I. -I.. -
Isynctexdir -Ilibmd5 -DLUA_COMPAT_MODULE=1 -I. -I.. -I../../libs -I../../libs/po
ppler/poppler-src -I../../libs/poppler/poppler-src/poppler -I../../libs/poppler/
poppler-src/fofi -I../../libs/poppler/poppler-src/goo -I../../libs/libpng -I../.
./libs/zlib -I../../libs/icu-src/source/common/unicode -I../../libs/icu-src/sour
ce/common -I../../libs/icu-src/source/layout -I../../libs/icu-src/source -DLE_US
E_CMEMORY -I. -I.. -DGRAPHITE2_STATIC=1 -I../../libs/graphite2-src/include -I../
../libs/graphite2-src/include/graphite2 -D__HP_cc=1 -I../../libs/harfbuzz/harfbu
zz-src/src -c fixwrites.c
fixwrites.c
make[1]: *** No rule to make target `../../make/paths.mk', needed by `../../kpat
hsea/libkpathsea.lib'.  Stop.
make[1]: Leaving directory `/path/to/w32tex-src/xtx/texk/web2c/web2c'
make: *** [web2c/fixwrites.exe] Error 2

xtx\texk\make\paths.mk というファイルは、どうやら W32TeX の昔のソースアーカイブには入っていたらしいが、最新のアーカイブには入っていない。とりあえず、xtx\texk\web2c\web2c の Makefile をいじって逃げることにした。

$(kpathsea): $(kpathsea_srcdir)/*.c $(kpathsea_srcdir)/*.h \
	     $(kpathsea_srcdir)/texmf.cnf $(top_srcdir)/../make/paths.mk
	cd $(kpathsea_dir) && $(MAKE) $(makeargs)

という3行を探し、$(top_srcdir)/../make/paths.mkをコメントアウト。

$(kpathsea): $(kpathsea_srcdir)/*.c $(kpathsea_srcdir)/*.h \
	     $(kpathsea_srcdir)/texmf.cnf #$(top_srcdir)/../make/paths.mk
	cd $(kpathsea_dir) && $(MAKE) $(makeargs)

これで、改めて make すると

make[1]: Entering directory `/path/to/w32tex-src/xtx/texk/web2c/web2c'
cl -Fefixwrites.exe fixwrites.obj setargv.obj ../lib/lib.lib ../../kpathsea/libkpathsea.lib user32.lib advapi32.lib shell32.lib  -link /SUBSYSTEM:CONSOLE /MANIFEST
Microsoft (R) Incremental Linker Version 12.00.40629.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:fixwrites.exe 
/SUBSYSTEM:CONSOLE 
C:/MinGW/msys/1.0/MANIFEST 
fixwrites.obj 
setargv.obj 
../lib/lib.lib 
../../kpathsea/libkpathsea.lib 
user32.lib 
advapi32.lib 
shell32.lib 
LINK : fatal error LNK1181: cannot open input file 'C:/MinGW/msys/1.0/MANIFEST.obj'
make[1]: Leaving directory `/path/to/w32tex-src/xtx/texk/web2c/web2c'

えーっ! なんか /MANIFEST オプションが機能しない… MSYS1.0 を使っているせいなのか、設定がわるいのか…

ひとまず /MANIFEST オプションを諦めることにした。つまり、Makefile

DEBFLAGS = /MANIFEST

という行を探してコメントアウト。

DEBFLAGS = #/MANIFEST

このあと改めて make すると、make は最後まで到達せずにストップしてしまう:

make: *** No rule to make target `luatexdir/font/*.c', needed by `luatexdir/libl
uatex.lib'.  Stop.

とはいえ、この時点で

  • ctangleboot.exe
  • ctangle.exe
  • tie.exe
  • tangleboot.exe
  • tangle.exe
  • otangle.exe

という「XeTeX のビルドに必要なソースをつなぎあわせたりするツール」が出来上がっているので、御の字である。追加として、まだ一部 xtx\texk\web2c\web2c\makecpool.exe なども必要になるようなので

> cd web2c
> make

としてビルドしておこう。

[C] libs のビルド

次に、libs をビルドする。たくさんあるが順番に:

> cd w32tex-src\xtx\libs
> cd zlib
> nmake
> cd ..
> cd libpng
> nmake
> cd ..
> cd freetype
> make
> cd ..
> cd fontconfig
> cd src
> nmake
> cd ..
> cd ..
> cd expat\lib
> nmake
> cd ..\..
> cd fontconfig
> sh mkall.sh

僕の環境では、この fontconfig のビルドの際にやっぱり /MANIFEST オプションが変だったので、mkall.sh の中身を読んで、登録されている各ディレクトリにある Makefile を編集した:

DBG=-link /manifest

という行を

DBG=-link #/manifest

にコメントアウト。このあと mkall.sh を実行すると、fc-cache.exe や fc-cat.exe などがビルドできた。

気を取り直して次へ:

> cd ..
> cd poppler\poppler-src
> make

これがまたよくわからないことにエラーが出てしまった:

cl -GR -EHsc -MT -O2 -nologo -wd4819 -DWIN32=1 -DHAVE_CONFIG_H=1 -D_CRT_SECURE_N
O_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_OBSOLETE_NO_DEPRECATE -D_SECURE_S
CL=0 -Dpopen=win32_popen -Dpclose=win32_pclose -I.. -I../goo -I../fofi -I../popp
ler -I../../../libpng -I../../../zlib -I../../../cairo/cairo-src/src -c -Tp../po
ppler/Annot.cc
Annot.cc
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\INCLUDE\xtgmath.h(188) :
error C2039: 'max' : is not a member of 'std'
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\INCLUDE\xtgmath.h(189) :
error C2039: 'min' : is not a member of 'std'
make[1]: *** [../poppler/Annot.obj] Error 2
make[1]: Leaving directory `/path/to/w32tex-src/xtx/libs/popple
r/poppler-src/poppler'
make: *** [poppler/Annot.obj] Error 2

この手のエラーはよくわからないが、どうやらこの辺が関係しているらしい。正しい対処法がよくわからないが、一例として以下のようにする:

(1) config.h の冒頭に

#include <algorithm>

を足す。
(2) Linearization.cc、MarkedContentOutputDev.cc、StructElement.cc、StructTreeRoot.cc、Sound.cc の5つのファイルの冒頭に

#include <config.h>

を足す。

これで改めて make すると、どうにか libpoppler.lib が生成。

諦めずに次へ進もう:

> cd ..\..
> cd graphite2-src\src
> make
> cd ..\..
> cd teckit
> make
> cd ..
> cd icu-src

この ICU ライブラリのビルドがヤバい。ただ、非常にありがたいことに、ここに角藤さんの README.kakuto を発見。日本語で手とり足とりかかれているので、これに従ってビルドする。

> cd source
> cd common
> make && make install
> cd ..
> cd i18n
> make && make install
> cd ..
> cd io
> make && make install
> cd ..
> cd stubdata
> make && make install
> cd ..
> cd tools
> cd toolutil
> make && make install
> cd ..
> cd gencfu
> make && make install
> cd ..
> cd gencnval
> make && make install
> cd ..
> cd gennorm2
> make && make install
> cd ..
> cd genrb
> make && make install
> cd ..
> cd gensprep
> make && make install
> cd ..
> cd gentest
> make && make install
> cd ..
> cd icupkg
> make && make install
> cd ..
> cd makeconv
> make && make install
> cd ..
> cd pkgdata
> make && make install
> cd ..
> cd genbrk
> make && make install
> cd ..
> cd gendict
> make && make install
> cd ..
> cd ..

注意:この時点で icu-src\bin フォルダを見ると、ダミーの小さな icudt57.dll ファイルが見つかるが、これはあとで上書きされるまで意味のないものである。

> cd data

このディレクトリに makedata.mak というファイルが見つかる。その中には、角藤さんのビルド環境で書かれたと推察される

ICUMAKE=c:\usr\work\edrive\w32texsrc\xtx\libs\icu-src\source\data
CFG=x86\Release

という行が見つかる。これを、自分の環境に合わせて書き換える(カレントなので . で良さそうに思えるが、これはダメだった…)。たとえば

ICUMAKE=C:\Users\ユーザ名\Desktop\w32tex-src\xtx\libs\icu-src\source\data
CFG=x86\Release

と書き換えてから

> nmake -f makedata.mak

を実行すると、先ほど見た icudt57.dll のファイルサイズが大きくなって、いかにも本物らしくなる。icu-src\lib ディレクトリには

  • icudt.lib
  • icuinputoutput.lib
  • icuinternational.lib
  • icutoolutil.lib
  • icuucommon.lib

の5個ができた。これにて完了。ふう…

あと一息:

> cd ..\..\..
> cd harfbuzz\harfbuzz-src\src
> make

これで、必要なライブラリがビルドできる。

[D] 再び web2c へ:xetex.dll のビルド
> cd w32tex-src\xtx\texk\web2c
> make xetex.dll

最後の最後にエラーが出るorz…

cl -LD -Fexetex.dll xetexini.obj xetex0.obj xetexextra.obj trans.obj XeTeX_ext.obj xetex-pool.obj synctex-xe.obj XeTeXFontMgr_FC.obj hz.obj XeTeXFontMgr.obj XeTeXLayoutInterface.obj XeTeXFontInst.obj XeTeXOTMath.obj pdfimage.obj bmpimage.obj jpegimage.obj mfileio.obj numbers.obj pngimage.obj XeTeX_pic.obj \
           libmd5/md5.obj \
            lib/lib.lib ../kpathsea/libkpathsea.lib wsock32.lib user32.lib advapi32.lib shell32.lib ../../libs/icu-src/lib/icuucommon.lib ../../libs/icu-src/lib/icudt.lib ../../libs/teckit/lib/libTECkit.lib ../../libs/freetype/objs/freetype.lib ../../libs/fontconfig/src/libfontconfig.lib ../../libs/expat/lib/libexpat.lib ../../libs/libpng/libpng.lib ../../libs/poppler/poppler-src/libpoppler.lib ../../libs/zlib/libz.lib ../../libs/graphite2-src/lib/graphite2.lib ../../libs/harfbuzz/harfbuzz-src/src/harfbuzz.lib \
           -link /SUBSYSTEM:CONSOLE /STACK:0x280000 
Microsoft (R) Incremental Linker Version 12.00.40629.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/dll 
/implib:xetex.lib 
/out:xetex.dll 
/SUBSYSTEM:CONSOLE 
/STACK:0x280000 
xetexini.obj 
xetex0.obj 
xetexextra.obj 
trans.obj 
XeTeX_ext.obj 
xetex-pool.obj 
synctex-xe.obj 
XeTeXFontMgr_FC.obj 
hz.obj 
XeTeXFontMgr.obj 
XeTeXLayoutInterface.obj 
XeTeXFontInst.obj 
XeTeXOTMath.obj 
pdfimage.obj 
bmpimage.obj 
jpegimage.obj 
mfileio.obj 
numbers.obj 
pngimage.obj 
XeTeX_pic.obj 
libmd5/md5.obj 
lib/lib.lib 
../kpathsea/libkpathsea.lib 
wsock32.lib 
user32.lib 
advapi32.lib 
shell32.lib 
../../libs/icu-src/lib/icuucommon.lib 
../../libs/icu-src/lib/icudt.lib 
../../libs/teckit/lib/libTECkit.lib 
../../libs/freetype/objs/freetype.lib 
../../libs/fontconfig/src/libfontconfig.lib 
../../libs/expat/lib/libexpat.lib 
../../libs/libpng/libpng.lib 
../../libs/poppler/poppler-src/libpoppler.lib 
../../libs/zlib/libz.lib 
../../libs/graphite2-src/lib/graphite2.lib 
../../libs/harfbuzz/harfbuzz-src/src/harfbuzz.lib 
   Creating library xetex.lib and object xetex.exp
harfbuzz.lib(hb-uniscribe.obj) : error LNK2019: unresolved external symbol __imp__CreateFontIndirectW@4 referenced in function __hb_uniscribe_shaper_font_data_create
harfbuzz.lib(hb-directwrite.obj) : error LNK2001: unresolved external symbol __imp__CreateFontIndirectW@4
harfbuzz.lib(hb-uniscribe.obj) : error LNK2019: unresolved external symbol __imp__DeleteObject@4 referenced in function "bool __cdecl hb_uniscribe_shaper_font_data_ensure(struct hb_font_t *)" (?hb_uniscribe_shaper_font_data_ensure@@YA_NPAUhb_font_t@@@Z)
harfbuzz.lib(hb-directwrite.obj) : error LNK2001: unresolved external symbol __imp__DeleteObject@4
harfbuzz.lib(hb-uniscribe.obj) : error LNK2019: unresolved external symbol __imp__AddFontMemResourceEx@16 referenced in function "bool __cdecl hb_uniscribe_shaper_face_data_ensure(struct hb_face_t *)" (?hb_uniscribe_shaper_face_data_ensure@@YA_NPAUhb_face_t@@@Z)
harfbuzz.lib(hb-directwrite.obj) : error LNK2001: unresolved external symbol __imp__AddFontMemResourceEx@16
harfbuzz.lib(hb-uniscribe.obj) : error LNK2019: unresolved external symbol __imp__RemoveFontMemResourceEx@4 referenced in function "bool __cdecl hb_uniscribe_shaper_face_data_ensure(struct hb_face_t *)" (?hb_uniscribe_shaper_face_data_ensure@@YA_NPAUhb_face_t@@@Z)
harfbuzz.lib(hb-directwrite.obj) : error LNK2001: unresolved external symbol __imp__RemoveFontMemResourceEx@4
harfbuzz.lib(hb-uniscribe.obj) : error LNK2019: unresolved external symbol __imp__SelectObject@8 referenced in function __hb_uniscribe_shaper_font_data_create
harfbuzz.lib(hb-directwrite.obj) : error LNK2001: unresolved external symbol __imp__SelectObject@8
harfbuzz.lib(hb-uniscribe.obj) : error LNK2019: unresolved external symbol _ScriptFreeCache@4 referenced in function "bool __cdecl hb_uniscribe_shaper_font_data_ensure(struct hb_font_t *)" (?hb_uniscribe_shaper_font_data_ensure@@YA_NPAUhb_font_t@@@Z)
harfbuzz.lib(hb-uniscribe.obj) : error LNK2019: unresolved external symbol _ScriptItemize@28 referenced in function "long __stdcall hb_ScriptItemizeOpenType(wchar_t const *,int,int,struct tag_SCRIPT_CONTROL const *,struct tag_SCRIPT_STATE const *,struct tag_SCRIPT_ITEM *,unsigned long *,int *)" (?hb_ScriptItemizeOpenType@@YGJPB_WHHPBUtag_SCRIPT_CONTROL@@PBUtag_SCRIPT_STATE@@PAUtag_SCRIPT_ITEM@@PAKPAH@Z)
harfbuzz.lib(hb-uniscribe.obj) : error LNK2019: unresolved external symbol _ScriptShape@40 referenced in function "long __stdcall hb_ScriptShapeOpenType(struct HDC__ *,void * *,struct tag_SCRIPT_ANALYSIS *,unsigned long,unsigned long,int *,struct textrange_properties * *,int,wchar_t const *,int,int,unsigned short *,struct script_charprop *,unsigned short *,struct script_glyphprop *,int *)" (?hb_ScriptShapeOpenType@@YGJPAUHDC__@@PAPAXPAUtag_SCRIPT_ANALYSIS@@KKPAHPAPAUtextrange_properties@@HPB_WHHPAGPAUscript_charprop@@6PAUscript_glyphprop@@3@Z)
harfbuzz.lib(hb-uniscribe.obj) : error LNK2019: unresolved external symbol _ScriptPlace@36 referenced in function "long __stdcall hb_ScriptPlaceOpenType(struct HDC__ *,void * *,struct tag_SCRIPT_ANALYSIS *,unsigned long,unsigned long,int *,struct textrange_properties * *,int,wchar_t const *,unsigned short *,struct script_charprop *,int,unsigned short const *,struct script_glyphprop const *,int,int *,struct tagGOFFSET *,struct _ABC *)" (?hb_ScriptPlaceOpenType@@YGJPAUHDC__@@PAPAXPAUtag_SCRIPT_ANALYSIS@@KKPAHPAPAUtextrange_properties@@HPB_WPAGPAUscript_charprop@@HPBGPBUscript_glyphprop@@H3PAUtagGOFFSET@@PAU_ABC@@@Z)
harfbuzz.lib(hb-uniscribe.obj) : error LNK2019: unresolved external symbol __imp__UuidCreate@4 referenced in function "void __cdecl _hb_generate_unique_face_name(wchar_t *,unsigned int *)" (?_hb_generate_unique_face_name@@YAXPA_WPAI@Z)
harfbuzz.lib(hb-directwrite.obj) : error LNK2001: unresolved external symbol __imp__UuidCreate@4
harfbuzz.lib(hb-directwrite.obj) : error LNK2019: unresolved external symbol __imp__DWriteCreateFactory@12 referenced in function __hb_directwrite_shape
xetex.dll : fatal error LNK1120: 11 unresolved externals

よくわからない…が、ググってそれっぽいエラーの対処法を探してどうにかたどり着いたのが、Makefile のなかの

xetex.dll: $(xetex_ot_layout_o) $(xetex_o) $(xetex_images_o) $(xetexlibs) libmd5/md5.obj
	$(CC) -LD -Fe$@ $(xetex_o) $(xetex_ot_layout_o) $(xetex_images_o) \
           libmd5/md5.obj \
           $(socketlibs) $(LOADLIBES) $(xetexlibs) $(FRAMEWORKS) \
           $(LDFLAGSXX) $(LKDEBUG)

に gdi32.lib Rpcrt4.lib usp10.lib Dwrite.lib を追加して

xetex.dll: $(xetex_ot_layout_o) $(xetex_o) $(xetex_images_o) $(xetexlibs) libmd5/md5.obj
	$(CC) -LD -Fe$@ $(xetex_o) $(xetex_ot_layout_o) $(xetex_images_o) \
           libmd5/md5.obj \
           $(socketlibs) $(LOADLIBES) gdi32.lib Rpcrt4.lib usp10.lib Dwrite.lib $(xetexlibs) $(FRAMEWORKS) \
           $(LDFLAGSXX) $(LKDEBUG)

とすることで、なんと xetex.dll が無事生成した。ちゃんと動作確認して手元では動いたので正直驚いている。自信ないが…