このブログは、旧・はてなダイアリー「檜山正幸のキマイラ飼育記 メモ編」(http://d.hatena.ne.jp/m-hiyama-memo/)のデータを移行・保存したものであり、今後(2019年1月以降)更新の予定はありません。

今後の更新は、新しいブログ http://m-hiyama-memo.hatenablog.com/ で行います。

Clingビルド 失敗の記録

LLVM/CLang上のC++インタプリタ Cling

Windows上のビルドはダメだった。いまいましいコマンドラインは:


$ cmake --build . --config Release --target clang

.... # この間、2時間弱

[100%] Linking CXX executable ../../../../bin/clang.exe

out of memory allocating 3424134 bytes
collect2.exe: error: ld returned 1 exit status
make[3]: *** [bin/clang.exe] Error 1
make[3]: *** Deleting file `bin/clang.exe'
make[2]: *** [tools/clang/tools/driver/CMakeFiles/clang.dir/all] Error 2
make[1]: *** [tools/clang/tools/driver/CMakeFiles/clang.dir/rule] Error 2
make: *** [clang] Error 2

$

前提となる状況

MSVC Community と tdm-gcc - 檜山正幸のキマイラ飼育記 メモ編 のように、MSVC CommunityとTDM-GCCが入っている。

C:/Progaram Files (x86)/Microsoft Visual Studio 14.0/VC/bin/ にはパスが通ってない(メニューからGUIを起動するので)、C:/Installed/TDM-GCC-64/bin/ はWindowsのレベルではPATHの先頭に入っている。

bashは、Mingw-w64/MSYS2 を入れなくても Git for Windows で間に合うみたい - 檜山正幸のキマイラ飼育記 で書いたように、git-bashを使っている。Git for Windowsが提供するgit関連コマンド以外は、古いMSYS/MinGWの(Mingw-w64/MSYS2ではない)コマンドが呼ばれる。

bashとmakeの問題点

git-bashからmakeを呼ぶと、次のようなことになる(オレンジと赤色は檜山が付けた、黄色は「はてな」の自動)。


$ bash --version
GNU bash, version 4.3.42(2)-release (x86_64-pc-msys)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

hiyama@TP-X220-HIYAMA ~
$ make --version
0 [main] make 55772 stdio_init: couldn't make stderr distinct from stdout
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for i686-pc-msys

$

mingw32-makeなら問題ない。


$ /c/Installed/TDM-GCC-64/bin/mingw32-make.exe --version
GNU Make 3.82.90
Built for i686-pc-mingw32
Copyright (C) 1988-2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

$

古いbashならどっちも問題ない。


$ bash --version
GNU bash, version 3.1.17(1)-release (i686-pc-msys)
Copyright (C) 2005 Free Software Foundation, Inc.

$ make --version
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for i686-pc-msys

$ /c/Installed/TDM-GCC-64/bin/mingw32-make.exe --version
GNU Make 3.82.90
Built for i686-pc-mingw32
Copyright (C) 1988-2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

$

これがあるので、古いbash v. 3.1.17を使った。

情報源と発端

バイナリは、

にあるはずだが、Not Found。しょうがないのでビルドすることに。ビルド・インストラクションは、

configure and make方式

build script https://raw.githubusercontent.com/karies/cling-all-in-one/master/clone.sh を修正してビルドを試みる。autoconfを使ってconfigure and makeする。clone.shって名前だが、ふさわしくないので、build.sh にした。

. ./build.shして、bash関数を実行することにしたが、initial関数は手動で次を実行するのと変わりない。/c/Installed/Cling/ の下に必要なもの一式を配置。

it clone http://root.cern.ch/git/llvm.git src
cd src
git checkout cling-patches
cd tools
git clone http://root.cern.ch/git/cling.git
git clone http://root.cern.ch/git/clang.git
cd clang
git checkout cling-patches
cd ..

なお、Windowsでは、bashのプロセス置換がうまく動かない模様。python呼ぶところは手動で行って、値は直書きした。

# which is not ideal, see http://stackoverflow.com/a/677212/1392758
python=`which python`
if type python2 > /dev/null 2>&1; then
    python=`which python2`
fi

# bash process substitution does not work.
# 
# cores=`$python <(cat <<EOF
# import multiprocessing
# print (multiprocessing.cpu_count())
# EOF
# )`

cores=4
echo Using $cores cores.

さて、問題はconfigure。自システムを認識できいない。


$ configure

# ... 省略

config.guess timestamp = 2011-08-20

uname -m = x86_64
uname -r = 2.3.0(0.290/5/3)
uname -s = MSYS_NT-6.1
uname -v = 2015-09-16 19:07

/usr/bin/uname -p = unknown
/bin/uname -X =

hostinfo =
/bin/universe =
/usr/bin/arch -k =
/bin/arch = x86_64
/usr/bin/oslevel =
/usr/convex/getsysinfo =

UNAME_MACHINE = x86_64
UNAME_RELEASE = 2.3.0(0.290/5/3)
UNAME_SYSTEM = MSYS_NT-6.1
UNAME_VERSION = 2015-09-16 19:07
configure: error: cannot guess build type; you must specify one

$

c:/Installed/Cling/src/autoconf/ の下のcofig.guessを修正する。

    *:MINGW*:*)
	echo ${UNAME_MACHINE}-pc-mingw32
	exit ;;
    *:MSYS*:*)
	echo ${UNAME_MACHINE}-pc-msys
	exit ;;

これで、x86_64-pc-msys というシステム名が得られるが、その後が続かない。あきらめて、x86_64-pc-mingw32 となるようにして実行。


configure: WARNING: --enable-bindings=ocaml specified, but ctypes is not installed
configure: WARNING: --enable-bindings=ocaml specified, but OUnit 2 is not installed. Tests will not run
configure: error: Prequisites for bindings not satisfied. Fix them or use configure --disable-bindings.

c:/Installed/Cling/src/bindings/ を見ると、go/, ocaml/, python/ がある。これがバインディングらしい。バインディングを諦めて、configureのオプションを次のようにする。--disable-bindings 追加。

../src/configure --disable-bindings --enable-cxx11 --disable-compiler-version-checks --with-python=$python --enable-targets=host --prefix=$INSTDIR

これでconfigureが実行できて、c:/Installed/Cling/obj/ の下にファイル群一式ができる。


$ cd obj/

$ ls
./ config.status* lib/ Makefile.config unittests/
../ docs/ llvm.spec projects/ utils/
bindings/ examples/ Makefile test/
config.log include/ Makefile.common tools/

$

make!


$ make

#
# ... 何時間か
#

llvm[4]: Building Debug+Asserts Archive Library libclangLex.a
make[4]: Leaving directory `/c/Installed/Cling/obj/tools/clang/lib/Lex'
make[4]: Entering directory `/c/Installed/Cling/obj/tools/clang/lib/Parse'
llvm[4]: Compiling ParseAST.cpp for Debug+Asserts build
llvm[4]: Compiling ParseCXXInlineMethods.cpp for Debug+Asserts build
llvm[4]: Compiling ParseDecl.cpp for Debug+Asserts build
llvm[4]: Compiling ParseDeclCXX.cpp for Debug+Asserts build
llvm[4]: Compiling ParseExpr.cpp for Debug+Asserts build
llvm[4]: Compiling ParseExprCXX.cpp for Debug+Asserts build
llvm[4]: Compiling ParseInit.cpp for Debug+Asserts build
llvm[4]: Compiling ParseObjc.cpp for Debug+Asserts build
llvm[4]: Compiling ParseOpenMP.cpp for Debug+Asserts build
llvm[4]: Compiling ParsePragma.cpp for Debug+Asserts build
llvm[4]: Compiling ParseStmt.cpp for Debug+Asserts build
llvm[4]: Compiling ParseStmtAsm.cpp for Debug+Asserts build
llvm[4]: Compiling ParseTemplate.cpp for Debug+Asserts build
llvm[4]: Compiling ParseTentative.cpp for Debug+Asserts build
llvm[4]: Compiling Parser.cpp for Debug+Asserts build
llvm[4]: Building Debug+Asserts Archive Library libclangParse.a
make[4]: Leaving directory `/c/Installed/Cling/obj/tools/clang/lib/Parse'
make[4]: Entering directory `/c/Installed/Cling/obj/tools/clang/lib/AST'
llvm[4]: Compiling APValue.cpp for Debug+Asserts build
llvm[4]: Compiling ASTConsumer.cpp for Debug+Asserts build
llvm[4]: Compiling ASTContext.cpp for Debug+Asserts build
C:/Installed/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/5.1.0/../../../../x86_
64-w64-mingw32/bin/as.exe: C:/Installed/Cling/obj/tools/clang/lib/AST/Debug+Asse
rts/ASTContext.o: too many sections (35209)
C:\Users\hiyama\AppData\Local\Temp\cc7xvoLc.s: Assembler messages:
C:\Users\hiyama\AppData\Local\Temp\cc7xvoLc.s: Fatal error: can't write C:/Insta
lled/Cling/obj/tools/clang/lib/AST/Debug+Asserts/ASTContext.o: File too big
C:/Installed/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/5.1.0/../../../../x86_
64-w64-mingw32/bin/as.exe: C:/Installed/Cling/obj/tools/clang/lib/AST/Debug+Asse
rts/ASTContext.o: too many sections (35209)
C:\Users\hiyama\AppData\Local\Temp\cc7xvoLc.s: Fatal error: can't close C:/Insta
lled/Cling/obj/tools/clang/lib/AST/Debug+Asserts/ASTContext.o: File too big
make[4]: *** [/cygdrive/c/Installed/Cling/obj/tools/clang/lib/AST/Debug+Asserts/
ASTContext.o] Error 1
make[4]: Leaving directory `/c/Installed/Cling/obj/tools/clang/lib/AST'
make[3]: *** [AST/.makeall] Error 2
make[3]: Leaving directory `/c/Installed/Cling/obj/tools/clang/lib'
make[2]: *** [all] Error 1
make[2]: Leaving directory `/c/Installed/Cling/obj/tools/clang'
make[1]: *** [clang/.makeall] Error 2
make[1]: Leaving directory `/c/Installed/Cling/obj/tools'
make: *** [all] Error 1

アセンブラ C:/Installed/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/5.1.0/../../../../x86_64-w64-mingw32/bin/as.exe からのメッセージ:

C:/Installed/Cling/obj/tools/clang/lib/AST/Debug+Asserts/ASTContext.o:
too many sections (35209)

C:\Users\hiyama\AppData\Local\Temp\cc7xvoLc.s: Fatal error:
can't write C:/Installed/Cling/obj/tools/clang/lib/AST/Debug+Asserts/ASTContext.o:
File too big

量的に無理だってことか。

CMake と Visual C++

https://root.cern.ch/cling-build-instructionsWindowsならCMake使え、みたいなことが書いてある。CMakeはchocoで入れた。


# 管理者権限で
PS> choco install cmake

c:/Program Files (x86)/CMake/bin/ にインストールされるが、パスは通らないので、自分でパス設定。chocoの難点は、後で自分でやる作業があるかないかワカランことだ。


PS> cmake --version
cmake version 3.3.0

CMake suite maintained and supported by Kitware (kitware.com/cmake).

PS>

https://root.cern.ch/cling-build-instructions に従って


$ mkdir build
$ cd build
$ cmake -DCMAKE_INSTALL_PREFIX=/c/Installed/Cling ../src

とすると、CMakeはMSVC(c:/Program Files/Microsoft Visual Studio 14.0/)を探して、MSVC用のビルド環境を作る。

cmake --build . --config Release --target clang すると、けっこうな時間(でも、gccより全然速かった、gccは2時間弱だもん)がかかった後で、

48 個の警告
11 エラー

経過時間 00:37:34.29

途中で、次のような致命的そうなエラーもあったし。


(ClCompile ターゲット) ->
c:\installed\cling\src\tools\clang\lib\ast\astcontext.cpp(334): fatal error C
1001: コンパイラで内部エラーが発生しました。 [C:\Installed\Cling\build\tools\cla
ng\lib\AST\clangAS
T.vcxproj]
cl : コマンド ライン error D8040: 子プロセスの作成中または更新中にエラーが発生
しました。 [C:\Installed\Cling\bu
ild\tools\clang\lib\AST\clangAST.vcxproj]

どうやら、自分の環境では、MSVCでClingを作るのは無理っぽい。しかし、Clang(Clingのベース)をMSVCで作ったという報告もあるなー。どこをどうすればいいのか?

CMake と TDM-GCC

これはミスをやらかした。TDM-GCCのbinをパスの先頭に入れていたから、gcc, g++でTDMが呼ばれると思っていたがオオマチガイ。bashは、自分が必要とするパスである /usr/local/bin /usr/bin /bin を起動時に先頭に付ける。よって、古い /usr/bin/gcc などが呼ばれる。事前に、gcc, g++, makeなどはどれが呼ばれるかを確認する必要がある。

結論を言えば、このミスがビルド失敗の原因ではなくて、最後の最後でリンカー(ld.exe)が動かないこと。

CMakeにTDM-GCCを使わせるには、gcc, g++としてTDMが呼ばれることを確認した上で、


$ mkdir build2
$ cd build2
$ cmake -G "MSYS Makefiles" -DCMAKE_INSTALL_PREFIX=/c/Installed/Cling ../src

-Gオプションがジェネレーター指定。このコマンドラインで、CMakeがconfigureと同じようなことをする。ここは特に問題なし。


$ cmake --build . --config Release --target clang

# ...

[100%] Built target clangFrontend
Scanning dependencies of target clang
[100%] Building CXX object tools/clang/tools/driver/CMakeFiles/clang.dir/driver.
cpp.obj
[100%] Building CXX object tools/clang/tools/driver/CMakeFiles/clang.dir/cc1_mai
n.cpp.obj
[100%] Building CXX object tools/clang/tools/driver/CMakeFiles/clang.dir/cc1as_m
ain.cpp.obj
[100%] Linking CXX executable ../../../../bin/clang.exe

out of memory allocating 3424134 bytes
collect2.exe: error: ld returned 1 exit status
make[3]: *** [bin/clang.exe] Error 1
make[3]: *** Deleting file `bin/clang.exe'
make[2]: *** [tools/clang/tools/driver/CMakeFiles/clang.dir/all] Error 2
make[1]: *** [tools/clang/tools/driver/CMakeFiles/clang.dir/rule] Error 2
make: *** [clang] Error 2

$

Linking CXX executable ../../../../bin/clang.exe における out of memory allocating 3424134 bytes が問題。

悪あがき 1 物理メモリ

物理メモリが足りないかと思って、他のアプリケーションをすべて終了してやったがダメ。タスクマネージャーでメモリ使用を監視していたが、そんなにむちゃくちゃにメモリを使うわけでもない。

悪あがき 2 ld.exeを修正

http://stackoverflow.com/questions/11979482/why-is-g-ld-running-out-of-memory にあった方法。

editbin /largeaddressaware ld.exe としてみる。editbinは、c:/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio\ 14.0/VC/bin/editbin にある。bashじゃなくて、PowerShellからやったほうがいい。

editbinしても、バイト数が変わらないので効果ないかも、と思ったが、やっぱりダメだった。

悪あがき 3 -fno-keep-inline-dllexport

これも、http://stackoverflow.com/questions/11979482/why-is-g-ld-running-out-of-memory にあった方法。

オプション -fno-keep-inline-dllexport という記述があったので、g++にこのオプションを付けてみる。変更したファイルは、

  • c:/Installed/Cling/src/tools/clang/CMakeLists.txt
  • c:/Installed/Cling/src/tools/cling/CMakeLists.txt
# Add appropriate flags for GCC
if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-keep-inline-dllexport -fno-common -Woverloaded-virtual -fno-strict-aliasing")
#
# ...

CMAKE_CXX_FLAGSに追加。効果なしだった。


TDM-gccは64ビットコードを吐けるのでそれ自体64ビットと思っていたが、ld.exeは32ビット、なんでだ? gdb.exeなどを除いてコンパイラツールは32ビットで動く。コンパイラツールが64ビットじゃないとダメなんかな?

残念。