2021年02月19日

Ubuntu上でWindows用clangをカナディアンクロスビルドする

Binutils や GCC は、Ubuntu 上で Windows で動作する、組み込み向け(RISC-V など)のコンパイラツールチェーンを簡単にビルドできます(カナディアンクロスビルド)。configure の際に --target=riscv64-unknown-elf --host=x86_64-w64-mingw32 --build=x86_64-pc-linux-gnu を指定するだけで、後は基本的にネイティブと同じです。この時、Ubuntu 上(x86_64-pc-linux-gnu)で動作するクロスの x86_64-w64-mingw32-gcc(g++)でビルドが行われるという仕組みです。

Clang の場合、CMake でどのように設定すれば良いのかとか、Windows バイナリを生成可能な clang が Ubuntu 上に見当たらなかった(clang をビルドするには、MinGW gcc ではなく、clang が必要)などの理由により、これまでは VisualStudio を使って Windows 上でビルドしていました。

今回、以下の記事で llvm-mingw の存在を知り、無事カナディアンクロスビルドに成功しました。



参考記事
libclang/libLLVM を Windows(MinGW) 向けに llvm-mingw でクロスコンパイルするメモ(10.0.0 or later)

clang をクロスビルドする際には、llvm-tblgen と clang-tblgen が必要なので、一度 Linux 向けに clang をビルドします。環境構築の方法は、この過去記事を参照してください。

Ubuntu 18.04 LTSで最新のClang12をビルドする方法

ビルド環境は Ubuntu 18.04 LTS です。

今回は build_linux で Linux 用をビルドして install_linux にインストール。build_mingw で Windows 用をビルドして install_mingw にインストールします。
~/work/test/clang_canadian_cross_build$ git clone https://github.com/llvm/llvm-project.git
$ cd llvm-project/
$ git log -1
commit df2940aa85f0265c5f718cb23546404246667b99 (HEAD -> main, origin/main, origin/HEAD)
Author: Vitaly Buka 
Date:   Thu Feb 18 17:22:32 2021 -0800

    [android] Fix testing adb call
    
    Looks like some debug leftover which force another retry.
$ cd ..

$ mkdir build_linux build_mingw install_linux install_mingw
1 回目の clang のビルドです。今回は libc や libcompiler_rt はビルドしないので、テストはあまり意味が無いのですが、一応動かしました。clang-tblgen などはインストールされないので、手動で cp しています。
$ mkdir build_linux build_mingw install_linux install_mingw
$ cd build_linux/
$ cmake -DLLVM_ENABLE_PROJECTS="clang;lld" -G "Unix Makefiles" ../llvm-project/llvm -DLLVM_ENABLE_ASSERTIONS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../install_linux -DLLVM_TARGETS_TO_BUILD="RISCV" -DLLVM_DEFAULT_TARGET_TRIPLE=riscv64-unknown-elf -DLLVM_BUILD_EXAMPLES=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DBUILD_SHARED_LIBS=OFF -DLLVM_OPTIMIZED_TABLEGEN=ON -DLLVM_ENABLE_LIBXML2=OFF
$ make -j64
$ make check-all -j64
Failed Tests (5):
  Clang :: CodeGen/sanitize-coverage-old-pm.c
  Clang :: Driver/as-options.s
  Clang :: Driver/clang-s-opts.s
  Clang :: Driver/lto.c
  LLVM :: DebugInfo/Generic/missing-abstract-variable.ll


Testing Time: 92.52s
  Unsupported      : 28953
  Passed           : 43158
  Expectedly Failed:    63
  Failed           :     5

$ make install
$ cp bin/* ../install_linux/bin
適当な所に llvm-mingw をダウンロードして、build_linux と一緒に PATH を通しておきます。msvcrt はもう古いらしく、ucrt の方が良いのかもしれませんが、今回は msvcrt で試しました。
$ cd /home/kmc/Downloads
$ wget https://github.com/mstorsjo/llvm-mingw/releases/download/20201020/llvm-mingw-20201020-msvcrt-ubuntu-18.04.tar.xz
$ tar xvf llvm-mingw-20201020-msvcrt-ubuntu-18.04.tar.xz

$ export LLVM_MINGW_PATH=/home/kmc/Downloads/llvm-mingw-20201020-msvcrt-ubuntu-18.04
$ export INSTALL_LINUX=/home/kmc/work/test/clang_canadian_cross_build/install_linux
$ export PATH=$INSTALL_LINUX/bin:$LLVM_MINGW_PATH/bin:$PATH
ちゃんと PATH が通っているか確認しておきます。
$ x86_64-w64-mingw32-clang -v
clang version 11.0.0 (https://github.com/llvm/llvm-project.git 176249bd6732a8044d457092ed932768724a6f06)
Target: x86_64-w64-windows-gnu
Thread model: posix
InstalledDir: /home/kmc/Downloads/llvm-mingw-20201020-msvcrt-ubuntu-18.04/bin

$ x86_64-w64-mingw32-clang++ -v
clang version 11.0.0 (https://github.com/llvm/llvm-project.git 176249bd6732a8044d457092ed932768724a6f06)
Target: x86_64-w64-windows-gnu
Thread model: posix
InstalledDir: /home/kmc/Downloads/llvm-mingw-20201020-msvcrt-ubuntu-18.04/bin

$ llvm-tblgen --version
LLVM (http://llvm.org/):
  LLVM version 13.0.0git
  Optimized build with assertions.
  Default target: riscv64-unknown-elf
  Host CPU: znver2

$ clang-tblgen --version
LLVM (http://llvm.org/):
  LLVM version 13.0.0git
  Optimized build with assertions.
  Default target: riscv64-unknown-elf
  Host CPU: znver2
バイナリサイズが肥大化してしまう問題がありますが、今回は dll のコピーなどの面倒を避けるために全部 static link します。
$ cd build_mingw
$ cmake -DLLVM_ENABLE_PROJECTS="clang;lld" -G "Unix Makefiles" ../llvm-project/llvm -DCMAKE_CROSSCOMPILING=True -DCMAKE_SYSTEM_NAME=Windows -DLLVM_TABLEGEN=$INSTALL_LINUX/bin/llvm-tblgen -DCLANG_TABLEGEN=$INSTALL_LINUX/bin/clang-tblgen -DLLVM_CONFIG_PATH=$INSTALL_LINUX/bin/llvm-config -DCMAKE_C_COMPILER=x86_64-w64-mingw32-clang -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-clang++ -DCMAKE_RC_COMPILER=x86_64-w64-mingw32-windres -DLLVM_ENABLE_ASSERTIONS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../install_mingw -DLLVM_TARGETS_TO_BUILD="RISCV" -DLLVM_DEFAULT_TARGET_TRIPLE=riscv64-unknown-elf -DLLVM_BUILD_EXAMPLES=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DBUILD_SHARED_LIBS=OFF -DLLVM_OPTIMIZED_TABLEGEN=ON -DLLVM_ENABLE_LIBXML2=OFF -DCMAKE_C_FLAGS="-static" -DCMAKE_CXX_FLAGS="-static"
$ make -j64 && make install
バイナリサイズが 110MB もありますが、とりあえずビルドはできました。
$ du -h ../install_mingw/bin/clang.exe 
110M	../install_mingw/bin/clang.exe
依存 dll も無く、無事に Windows 上で動きました。
dumpbin /dependents y:\work\test\clang_canadian_cross_build\install_mingw\bin\clang.exe
Microsoft (R) COFF/PE Dumper Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file y:\work\test\clang_canadian_cross_build\install_mingw\bin\clang.exe

File Type: EXECUTABLE IMAGE

  Image has the following dependencies:

    KERNEL32.dll
    msvcrt.dll
    SHELL32.dll
    ole32.dll
    ADVAPI32.dll
    VERSION.dll

C:\Users\kmc\test>y:\work\test\clang_canadian_cross_build\install_mingw\bin\clang.exe -v
clang version 13.0.0 (https://github.com/llvm/llvm-project.git df2940aa85f0265c5f718cb23546404246667b99)
Target: riscv64-unknown-unknown-elf
Thread model: posix
InstalledDir: y:\work\test\clang_canadian_cross_build\install_mingw\bin


kmckk at 11:55コメント(0)Clang | 若槻 

コメントする

名前
 
  絵文字
 
 
記事検索
最新コメント
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

QRコード
QRコード