web-dev-qa-db-ja.com

Windowsに埋め込まれたARMのclangでクロスコンパイルするようにCMakeを設定する方法は?

ARM Cortex A5 CPUのClangを使用してC++プロジェクトをクロスコンパイルするために忍者メイクファイルを生成しようとしています。CMake用のツールチェーンファイルを作成しましたが、エラーまたは何か不足しているようです以下のツールチェーンファイルでCMakeを呼び出すと、次のエラーが発生します。

CMakeコマンド:

cmake -DCMAKE_TOOLCHAIN_FILE = "..\Src\Build\Toolchain-clang-arm.cmake" -GNinja ..\Src \

出力:

-Cコンパイラの識別はClang 7.0.0ですC:/Users/user/scoop/apps/cmake/3.13.4/share/cmake-3.13/Modules/CMakeDetermineCompilerId.cmake:802でのCMakeエラー(メッセージ):The Clangコンパイラツール

「C:/ Program Files/LLVM/bin/clang.exe」

mSVC ABIをターゲットにしていますが、GNUのようなコマンドラインインターフェイスを備えています。これはサポートされていません。代わりに「clang-cl」を使用してください。環境で 'CC = clang-cl'を設定する。さらに、MSVCコマンドライン環境を使用します。呼び出しスタック(最新の呼び出しが最初):
C:/Users/user/scoop/apps/cmake/3.13.4/share/cmake-3.13/Modules/CMakeDetermineCCompiler.cmake:113(CMAKE_DIAGNOSE_UNSUPPORTED_CLANG)CMakeLists.txt:2(PROJECT)

-設定が不完全で、エラーが発生しました!

CMakeツールチェーンファイル(Toolchain-clang-arm.cmake):

set(CMAKE_CROSSCOMPILING TRUE)
SET(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)

# Clang target triple
SET(TARGET armv7-none-eabi)

# specify the cross compiler
SET(CMAKE_C_COMPILER_TARGET ${TARGET})
SET(CMAKE_C_COMPILER clang)
SET(CMAKE_CXX_COMPILER_TARGET ${TARGET})
SET(CMAKE_CXX_COMPILER clang++)
SET(CMAKE_ASM_COMPILER_TARGET ${TARGET})
SET(CMAKE_ASM_COMPILER clang)

# C/C++ toolchain
SET(TOOLCHAIN "C:/Program Files (x86)/GNU Tools ARM Embedded/7 2018-q2-update")
SET(CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN ${TOOLCHAIN})
SET(CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN ${TOOLCHAIN})

# specify compiler flags
SET(Arch_FLAGS "-target armv7-none-eabi -mcpu=cortex-a5")
SET(CMAKE_C_FLAGS "-Wall -Wextra ${Arch_FLAGS}" CACHE STRING "Common flags for C compiler")
SET(CMAKE_CXX_FLAGS "-Wall -Wextra -std=c++11 -fno-exceptions -fno-threadsafe-statics ${Arch_FLAGS}" CACHE STRING "Common flags for C++ compiler")

ツールチェーンファイルを作成するために、ネットから CMake および Clang のドキュメントといくつかの ランダムリンク を使用しました。プロジェクト全体がARM GCC for Windowsで正常にコンパイルされるため、ツールチェーンファイルが唯一の欠けているパズルのピースのようです。

[〜#〜]編集[〜#〜]

コンパイラーを強制して、CMakeコンパイラーのチェックを回避しようとしました。行をSET(CMAKE_C_COMPILER clang)、SET(CMAKE_CXX_COMPILER clang ++)などに置き換えます。

CMAKE_FORCE_C_COMPILER(clang Clang)
CMAKE_FORCE_CXX_COMPILER(clang++ Clang)

エラーは同じままです。

[〜#〜]編集[〜#〜]

Clang -target arm-none-eabiでhello worldの例を正常にコンパイルできます。したがって、問題はCMakeにあるようです。 CMakeの課題追跡で bug を作成しました。

ツールバージョン:

  • clangバージョン7.0.0(tags/RELEASE_700/final)
  • cmakeバージョン3.13.4
7
S. Marti

私の質問は reply を介してバグレポートに回答されましたが、すべての情報を1か所にまとめて参照できるように、ここに回答を追加しました。

要するに:現在、CMakeは llvm.org からClangをインストールする場合、clang/clang ++コマンドラインインターフェイスの使用をサポートしていません。 。 clang/clang ++インターフェース(ARMのクロスコンパイルに必要)を使用する場合は、 msys2 を使用してClangをインストールする必要があります。

詳細

WindowsのClangには、2つの異なるコマンドラインインターフェイスがあります。

  • clang/clang ++ GCCのgcc/g ++との互換性を試み、GNU ABIをターゲットとするデフォルトのインターフェース
  • clang-cl Microsofts Visual C++コンパイラcl.exeとの互換性を試み、MSVC ABIをターゲットにします

ARMのクロスコンパイルを行うには、clang/clang ++インターフェイスが必要です。問題は、CMakeがClangのインストール方法に応じて異なるインターフェイスをサポートすることです( bug 詳細については、CMakeの課題トラッカー):

  • llvm.org からClangをインストールする場合、CMakeはclang-clインターフェースのみをサポートします。
  • msys2 を介してClangをインストールする場合、CMakeはclang/clang ++インターフェースをサポートします。

だからここに私がやったことがあります:

  1. インストール msys2
  2. ClangとCMakeを pacman でインストールします。 msys2には、mingw32バージョンとmingw64バージョンの2つのclangパッケージがあります。私はmingw64パッケージ(mingw-w64-x86_64-clang)を使用しました。
  3. Mingw64シェルを起動してCMakeを実行し、そこからビルドします。

ツールチェーンファイル

元のツールチェーンファイルに2つの問題があり、修正に長い時間がかかりました。だから私はこれが他の人の時間を節約することを願っています:

  1. ターゲットトリプル (たとえば、arm-none-eabi)は、GCC binutilsのプレフィックスと正確に一致する必要があります。私のbinutilsのプレフィックスはarm-none-eabi(例:arm-none-eabi-ar)だったので、それに応じてターゲットトリプルを変更する必要がありました。
  2. CMAKE_TRY_COMPILE_TARGET_TYPE は、コンパイルチェック中にCMakeがリンカーを実行しないようにするために、STATIC_LIBRARYに変更する必要があります。

これが私が使用した最後のツールチェーンファイルです(ツールチェーンファイルの良い例は、この GitHub repo )にもあります)。

cmake_minimum_required(VERSION 3.13)

set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR ARM)

if(DEFINED ENV{GCC_ARM_TOOLCHAIN})
    set(GCC_ARM_TOOLCHAIN $ENV{GCC_ARM_TOOLCHAIN})
else()
    set(GCC_ARM_TOOLCHAIN "C:/Users/user/tools/gcc-arm-none-eabi-7-2018-q2-update-win32")
endif()

LIST(APPEND CMAKE_PROGRAM_PATH ${GCC_ARM_TOOLCHAIN})

# Specify the cross compiler
# The target triple needs to match the prefix of the binutils exactly
# (e.g. CMake looks for arm-none-eabi-ar)
set(CLANG_TARGET_TRIPLE arm-none-eabi)
set(GCC_ARM_TOOLCHAIN_PREFIX ${CLANG_CLANG_TARGET_TRIPLE})
set(CMAKE_C_COMPILER clang)
set(CMAKE_C_COMPILER_TARGET ${CLANG_TARGET_TRIPLE})
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_CXX_COMPILER_TARGET ${CLANG_TARGET_TRIPLE})
set(CMAKE_ASM_COMPILER clang)
set(CMAKE_ASM_COMPILER_TARGET ${CLANG_TARGET_TRIPLE})

# Don't run the linker on compiler check
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

# Specify compiler flags
set(Arch_FLAGS "-mcpu=cortex-a5 -mthumb -mfpu=neon-vfpv4 -mfloat-abi=hard -mno-unaligned-access")
set(CMAKE_C_FLAGS "-Wall ${Arch_FLAGS}" CACHE STRING "Common flags for C compiler")
set(CMAKE_CXX_FLAGS "-Wall -std=c++17 -fno-exceptions -fno-rtti -fno-threadsafe-statics ${Arch_FLAGS}" CACHE STRING "Common flags for C++ compiler")
set(CMAKE_ASM_FLAGS "-Wall ${Arch_FLAGS} -x assembler-with-cpp" CACHE STRING "Common flags for assembler")
set(CMAKE_EXE_LINKER_FLAGS "-nostartfiles -Wl,-Map,kernel.map,--gc-sections -Fuse-linker-plugin -Wl,--use-blx --specs=nano.specs --specs=nosys.specs" CACHE STRING "")

# C/C++ toolchain
set(GCC_ARM_SYSROOT "${GCC_ARM_TOOLCHAIN}/${GCC_ARM_TOOLCHAIN_PREFIX}")
# set(CMAKE_SYSROOT ${GCC_ARM_SYSROOT})
set(CMAKE_FIND_ROOT_PATH ${GCC_ARM_SYSROOT})

# Search for programs in the build Host directories
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# For libraries and headers in the target directories
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
2
S. Marti

ここでは、CMakeを使用して、組み込みのARMをclangではなくGCCツールチェーンを使用してクロスコンパイルし、忍者ではなくプレーンな古いmakeを使用しています。これは直接に答えないことを知っています。質問ですが、組み込みARMの非常に合理的な代替手段であり、現在使用しているEclipseベースのベンダーツールチェーンの多くは、LLVM/clangではなくGCCに基づいています。

最初に から最新の「GNU MCU Eclipse ARM Embedded GCC "ツールチェーン」をインストールしますhttps://github.com/gnu-mcu-Eclipse/arm-none- eabi-gcc/releases (注:インストーラーはなく、必要な場所に解凍するだけです)。

次に、 https://www.msys2.org/ にあるインストーラーを使用して最新のMSYS2/MinGWをインストールします。

何らかの理由で、MSYS2のデフォルトのインストールにはmakeが含まれていません。そのため、インストール手順に従ってpacmanを使用してデフォルトパッケージを更新した後、「pacman -S make」を実行してmakeをインストールします。

MSYS2内で利用可能なcmakeビルドがあります。ただし、MSYSまたはMinGWのジェネレーターは含まれていません(理由がわからない)。また、フルパスがコマンドラインまたはツールチェーンファイルで明示的に指定されている場合でも、外部GCCツールチェーンの検索に問題があるようです(またはそのため)。 。したがって、このソリューションでは、 https://cmake.org/download/ で入手可能なCMakeのネイティブウィンドウビルドを使用し、cmakeのMSYS2ビルドは使用しません。

デフォルトでは、MSYSシェルはWindows環境を継承しないため、ネイティブのWindows CMakeはMSYSシェルパス上にありません。簡単な解決策は、コマンドラインでcmakeへのフルパスを指定することです。私の場合、C:/ GNU MCU Eclipse/ARM Embedded GCC/8.2.1-1.4-20190214-0604にGCCクロスコンパイラツールチェーンがあります。したがって、cmakeの完全なコマンドは次のようになります。

/c/Program\ Files/CMake/bin/cmake.exe -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm-none-eabi.cmake "-DTOOLCHAIN_PREFIX=C:/GNU MCU Eclipse/ARM Embedded GCC/8.2.1-1.4-20190214-0604" -G "MSYS Makefiles" ../

ここでは、コマンドはプロジェクトルートから1レベル下のビルドディレクトリから実行され、兄弟のcmakeディレクトリには指定されたツールチェーンファイルが含まれています。バックスラッシュは、cmake.exeへのパス内のスペースをエスケープするために必要ですが、cmakeへの引数として渡される引用符付きパスでは使用されません。

Cmakeを実行して、Windowsパス上のcmakeとmsys binの両方のディレクトリにある限り、通常のWindowsコマンドライン(cmd.exe)から直接作成することもできます。その場合、cmakeへのフルパスを指定する必要はありません。ただし、PowerShellでは成功しません。

1
AngCaruso