物理の駅 by onsanai

Physics Station → PhSt 質問・疑問・間違いの指摘は、コメントに書くか、直接伝えるときっと良いことがあります。主にWindows or Ubuntu用の記事です

Windows 10でROOT6 (CERN)を動かそう

最終更新: 2020/06/09

仮想環境やリモート環境を使わずに、Windows 10 で直接ROOTバージョン6を使いたい・動かしたい奇特な人のためのドキュメントです。

ROOT6を取り巻く状況

WindowsではROOTの32bit版しか動きません。bellenotが何度も何度も念押ししてるので間違いないです。64bit版が必要な方は、Windows Subsystem for Linux (WSL) でCERN ROOTバージョン6を動かすへ。Pythonを使ってビルドしても、PyRootは動きません。

https://root.cern.ch/downloading-root からダウンロードできる最新版の preview Windows Visual Studio 2019 =ビルド済みバイナリは(ほぼ全ての環境で)動きません。あれはROOT開発者による高度な引っ掛けです。ソースからビルドする必要があります。

ビルドに必要なツール

  • Visual Studio 2019 Community (ProfessionalでもEnterpriseでも可)。インストール時、C++によるデスクトップ開発 にチェックを入れる。
  • Python 32bitバージョン。 当方の環境ではPython 3.7.7Windows x86 web-based installerを使った。
    • ビルド内でPythonコマンドを使うので、PythonへPathを通しておく。
    • ROOTはPyRootのためPython37.lib(Python37.dll)を使ってビルドするので、Pythonも32bitでなければならない(がPyRootは使えない)。
    • Anacondaに含まれる標準ライブラリ(Anaconda3/Library/lib/ 内に含まれる複数の*.lib)はROOTと一部干渉するため使わない(=Anacondaを使わない)。
      Anacondaを使わない場合、ROOTは勝手にROOT内のビルトインライブラリを使ってビルドするので、気にしなくても良い。

ビルドの方法

  • ROOTのソースファイルをスペース文字を含まないディレクトリ下に展開する。
    例: C:\root-6.20.04.source
  • ソースファイルをBOM付きUTF-8に変換する(後述)
  • x86 Native Tools Command Prompt for VS 2019 を開く。
  • build用ディレクトリを作り、移動する。
    例: C:\root_v6.20.04
  • cmakeでビルド用のプロジェクトファイルを生成する。
    cmake -G "Visual Studio 16 2019" -A Win32 -Thost=x64 -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_CXX_STANDARD=14 [ソースを展開したフォルダ]
    出力例は後述
  • ビルドする。
    リリース版なら cmake --build . --config Release
    デバッグ版ならcmake --build . --config Debug
    出力例は後述

ソースファイルをBOM付きUTF-8に変換するPythonスクリプト

日本語版のVisual Studioは、UTF-8 BOM無しを勝手にShift-JISと解釈してコンパイルしようとする。ROOTのソースファイルには、一部UTF-8で書かれた部分があり、これを無理やりShift-JISで解釈しようとしたときにコンパイルエラーが発生する。幸いなことに、ROOTのソースコードはすべてasciiかUTF-8で書かれているので、全ファイルをUTF-8と解釈して、UTF-8 BOM付きに変換する。

以前執筆した変換スクリプトを、ROOT用に書き直した。

pythonでShift-JISやasciiのファイルを一括でUTF-8 with BOMへ変換する - 物理の駅 by onsanai

import chardet
import glob

# 探索する拡張子リスト
extensions = ["cpp", "hpp", "c", "h", "cxx", "hxx"]


def check(filename):
    # バイナリで開く
    with open(filename, 'rb') as f:
        b = f.read()
    # 文字コードを検出(Shift-JISへの精度は高くない)
    det_chardet = chardet.detect(b)

    # UTF-8 with BOM以外の場合はprint
    if det_chardet["encoding"] != "UTF-8-SIG" and det_chardet["encoding"] != None:
        print(det_chardet, filename)

    # ascii100%のコードをUTF-8 with BOMへ変換
    if det_chardet["encoding"] == "ascii" and det_chardet["confidence"] == 1.0:
        with open(filename) as f:
            contents = f.read()
        with open(filename, "w", encoding="utf_8_sig") as f:
            f.write(contents)
        print("ascii -> UTF-8-SIG")
    elif det_chardet["encoding"] != "UTF-8-SIG" and det_chardet["encoding"] != None:
        with open(filename, "r", encoding="utf_8") as f:
            contents = f.read()
        with open(filename, "w", encoding="utf_8_sig") as f:
            f.write(contents)
        print("UTF-8 -> UTF-8-SIG")

    return det_chardet["encoding"]


# エンコードリスト
encodings = {}

for extension in extensions:
    # cd以下全部を再帰的に探索
    files = glob.glob(f"**/*.{extension}", recursive=True)
    for filename in files:
        # パッケージフォルダ内は無視する
        if "\\packages\\" in filename:
            continue
        det_encoding = check(filename)
        # 検出したエンコードリストを辞書型で集計する
        if det_encoding not in encodings:
            encodings[det_encoding] = 1
        else:
            encodings[det_encoding] += 1
    print()

# 集計結果
print(encodings)

root-6.20.04 の場合、上記スクリプトの標準出力の最後の行は以下のようになるはず

{'ascii': 13010, 'utf-8': 34, 'Windows-1252': 18, 'TIS-620': 1, None: 133, 'ISO-8859-1': 15}

cmakeの出力例

Enabled support for のくだりが完全に一致していることを確認してほしい。

-- The C compiler identification is MSVC 19.26.28806.0
-- The CXX compiler identification is MSVC 19.26.28806.0
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Tools/MSVC/14.26.28801/bin/Hostx64/x86/cl.exe
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Tools/MSVC/14.26.28801/bin/Hostx64/x86/cl.exe - works

中略

-- Enabled support for:  asimage builtin_afterimage builtin_clang builtin_freetype builtin_ftgl builtin_gl2ps builtin_glew builtin_llvm builtin_lz4 builtin_lzma builtin_pcre builtin_xxhash builtin_zlib builtin_zstd clad exceptions gdml http mlp opengl pyroot webgui root7 shared spectrum
-- Configuring done
-- Generating done
-- Build files have been written to: PATH/root_build

cmake --buildの出力例

マルチスレッドでビルドするものの、8コア16スレッドのパソコンで42分かかった。0 エラー でなければどこかで失敗している。警告の数はReleaseかDebugかで若干変化する。

.NET Framework 向け Microsoft (R) Build Engine バージョン 16.6.0+5ff7b0c9e
Copyright (C) Microsoft Corporation.All rights reserved.

2020/06/10 10:37:19 にビルドを開始しました。

中略

    228 個の警告
    0 エラー

経過時間 00:42:06.39

参考文献

ビルドオプション一覧
https://root.cern.ch/building-root

bellenotによるWindows10でコンパイルする方法
https://root-forum.cern.ch/t/run-root-6-19-02-on-windows-10/38529/14

ROOTコミュニティでの報告
https://root-forum.cern.ch/t/building-and-executing-root6-on-windows-with-vs2019/39864

これまでの経緯

最終更新: 2019/04/10

bellenot氏曰く、Windows (Visual Studio 2019のcl.exe)でROOT6が動く(コンパイルできる)らしい。だが私の環境では動かなかった。

最終更新: 2018/10/29

Windows用のROOT6はプレビュー版がリリースされています。これは、Visual Studio 2017が必須です。無料のCommunity版でも良い。しかし、Visual StudioC++コンパイラーのバグにより、現状プレビュー版ROOT6用は正常に動きません。

https://root-forum.cern.ch/t/assertion-failed-occurred-when-executing-compiled-exe-with-visual-studio-2017/31013

ROOTのインストール方法の日本語訳

書いておくけど、全く役に立たないので無視でいいよ。

https://root.cern.ch/downloading-root

僕の流儀はZIPからインストールなのでそちらだけ。

伝統的な変種(筆者注: 変種ってどう訳すの?)。7zip(筆者注: おすすめなので入れておくべし)などで解凍する。ROOTはMicrosoft Visual Studioコマンドプロンプト(スタートメニューのプログラムのVisual Studio 2017 VS 2017 用)から始める。ROOTを C:\root にインストールしたとき、ROOTを使う前に必要な環境変数をセットアップするために C:\root\bin\thisroot.bat を実行せよ。

重要なインストール手法

  • システムにインストールされたのと完全に同じバージョンのVisual Studioでビルドされた(筆者注: 今回はVS2017)バイナリをダウンロードする必要がある。
  • ブランク文字を含む(筆者注: 日本語のパスを含む)ディレクトリにZIPを解凍してはならない。
  • パフォーマンスが重要な場合(筆者注: 基本的に必要である)は、リリース版を入手せよ。
  • コードをデバッグ(筆者注: ここでのデバッグは、ROOTそのもののデバッグを意味する。コードがコンパイルできないなどの問題の多くは、ROOTではなく君が書いたコードにバグがある)する場合、ROOTのデバッグ用ビルドが必要。マイクロソフトの制限のため、リリース版とデバッグ版を混在はできない。