Windows Itanium アプリケーションのビルド方法。

はじめに

このドキュメントには、Windows Itanium ツールチェーンの作成方法に関する情報が含まれています。

Windows Itanium を使用すると、MS VS CRT 上に Itanium C++ ABI アプリケーションを配置できます。この環境では、Windows SDK ヘッダーを直接使用でき、追加のヘッダーやランタイム機構(mingw などで使用されるもの)は必要ありません。

Windows Itanium スタック

  • Itanium C++ abi を使用します。

  • libc++。

  • libc++-abi。

  • libunwind。

  • MS VS CRT。

  • MS Windows SDK インクルードヘッダーと互換性があります。

  • COFF/PE ファイル形式。

  • LLD

注: compiler-rt は使用されません。この機能は MS VCRT によって提供されます。

前提条件

  • MS SDK は MS Visual Studio の一部としてインストールされます。

  • windows-itanium トリプルをサポートする Clang。

  • -autoimport スイッチをサポートする COFF LLD。

既知の問題

SJLJ 例外(“-fsjlj-exceptions”)のみが現在サポートされているモデルです。

link.exe(MSリンカ)は、現在正しくリンクするために必要な自動インポートをサポートしていないため、適切ではありません。ただし、この制限が解除されれば、link.exe の使用に関するその他の既知の問題はありません。

現在、Windows Itanium 用の実用的な Windows コンパイラドライバがありません。妥当な回避策として、windows-msvc デフォルトターゲットで clang をビルドし、トリプルを「-Xclang -triple -Xclang x86_64-unknown-windows-itanium」などで上書きします。リンカは「-fuse-ld=lld」で指定できます。

Itanium C++ ABI では、オブジェクトの最初のメンバーはクラスの vtable へのポインタです。vtable は多くの場合、キー関数とともにオブジェクトファイルに出力され、dllimport とマークされたクラスの場合はインポートする必要があります。ポインタはグローバルに一意である必要があります。残念ながら、COFF/PE ファイル形式は、別の DLL からのランタイムアドレスをこのポインタに格納するメカニズムを提供していません(ランタイムアドレスは IAT にパッチされますが)。そのため、コンパイラは、IAT パッチの後、vtable ポインタを使用する可能性のあるものよりも前に実行されるコードを生成し、vtable ポインタを IAT からのアドレスに設定する必要があります。typeinto オブジェクトからの __cxxabiv1::__class_type_info の vtable への参照という特別なケースでは、コンパイラで使用できる宣言がないため、これは行えません。プログラムをリンクできるようにするために、現在、LLD の -auto-import スイッチに依存して、__cxxabiv1::__class_type_info ポインタへの参照を自動的にインポートしています(関連する議論については、https://reviews.llvm.org/D43184 を参照してください)。これにより、リンクが可能になります。しかし、そのようなフィールドを実際に使用するコードは機能しません。これらのフィールドはランタイム時に修正されないためです。_pei386_runtime_relocator は、mingw に使用される自動インポートスキームのランタイムコンポーネントを処理し、https://reviews.llvm.org/D43184https://reviews.llvm.org/D89518 のコメントを参照してください。

ツールチェーンの構築

手順は次のとおりです。

# Windows Itanium をサポートする LLVM ツールチェーンをビルドします。# 手順 1. のツールチェーンを使用して、libc++、libc++abi、および libunwind をビルドします。

Linux からクロスコンパイルすることも可能です。

手順 2. のライブラリをビルドする1つの方法は、「スタンドアロン」でビルドすることです。スタンドアロンビルドは、LLVMツリーの残りの部分を含みません。手順は次のとおりです。

  • cd build-dir

  • cmake -DLLVM_PATH=<llvm チェックアウトへのパス 例: /llvm-project/> -DCMAKE_INSTALL_PREFIX=<インストールパス> <その他のオプション> <プロジェクトへのパス 例: /llvm-project/libcxxabi>

  • <make プログラム 例: ninja>

  • <make プログラム> install

スタンドアロンビルドの詳細については、それぞれのライブラリのビルドドキュメントを参照してください。次のセクションでは、スタンドアロンビルドを使用してライブラリをビルドおよびインストールするために必要な重要なオプションと変更について説明します。これは、libunwind と ibc++ を DLL としてビルドし、libc++abi を libc++ に静的にリンクすることを前提としています。他のビルド構成も可能ですが、ここでは説明しません。

一般的な CMake 構成オプション

  • -D_LIBCPP_ABI_FORCE_ITANIUM'

Itanium C++ ABI が使用されていることを libc++ ヘッダーに伝えます。

  • -DCMAKE_C_FLAGS="-lmsvcrt -llegacy_stdio_definitions -D_NO_CRT_STDIO_INLINE"

MS VS CRT から削除された stdio 定義を含む CRT 定義を提供します。legacy_stdio_definitions.ib から同じシンボルが取り込まれると、複数定義エラーが発生するため、stdio 関数をインラインで宣言したくありません。

  • -DCMAKE_INSTALL_PREFIX=<インストールパス>

ライブラリとヘッダーをインストールする場所。

libunwind のビルド

  • -DLIBUNWIND_ENABLE_SHARED=ON

  • -DLIBUNWIND_ENABLE_STATIC=OFF

libunwind は DLL としてビルドできます。他のプロジェクトには依存しません。

  • -DLIBUNWIND_USE_COMPILER_RT=OFF

MS ランタイムを使用します。

GNU固有のライブラリをリンク行に追加しないように、CMakeファイルを編集する必要があります。

libc++abi のビルド

  • -DLIBCXXABI_ENABLE_SHARED=OFF

  • -DLIBCXXABI_ENABLE_STATIC=ON

  • -DLIBCXX_ENABLE_SHARED=ON'

  • -DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=ON

libc++abi と libc++ 間のシンボル依存関係を解消するために、libc++abi を静的ライブラリとしてビルドし、それを libc++ DLL に静的にリンクします。これには、最終的な libc++ DLL を作成する際に必要になる可視性マクロ(dllexport/import に展開される)が確実に展開されるように CMake ファイルを設定する必要があります。https://reviews.llvm.org/D90021 を参照してください。

  • -DLIBCXXABI_LIBCXX_INCLUDES=<libcxx>/includeへのパス

libc++ ヘッダーを見つける場所

libc++ のビルド

  • -DLIBCXX_ENABLE_SHARED=ON

  • -DLIBCXX_ENABLE_STATIC=OFF

libc++ を DLL としてビルドし、libc++abi を静的にリンクします。

  • -DLIBCXX_INSTALL_HEADERS=ON

ヘッダーをインストールします。

  • -DLIBCXX_USE_COMPILER_RT=OFF

MS ランタイムを使用します。

  • -DLIBCXX_HAS_WIN32_THREAD_API=ON

Windows Itanium は WIN32 上の POSIX ライクなレイヤーを提供しません。

  • -DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=ON

  • -DLIBCXX_CXX_ABI=libcxxabi

  • -DLIBCXX_CXX_ABI_INCLUDE_PATHS=<libcxxabi ソースパス>/include

  • -DLIBCXX_CXX_ABI_LIBRARY_PATH=<libcxxabi ビルドパス>/lib

前にビルドした静的 libc++abi ライブラリを使用します。

  • -DLIBCXX_NO_VCRUNTIME=ON

VC ランタイムへの依存関係を削除します - C++ ランタイムは libc++abi によって提供される必要があります。

  • -DCMAKE_C_FLAGS=<インストール済みのunwind.libへのパス>

libcxxabi に対して静的にリンクしているため、libcxxabi オブジェクトからの unwind 参照を解決するために、unwind インポートライブラリにリンクする必要があります。

  • -DCMAKE_C_FLAGS+=' -UCLOCK_REALTIME'

MS が提供していない sys/time のインクルードを防ぎます。

注記

ビルドレシピの例はこちらにあります。https://reviews.llvm.org/D88124