Как настроить CMake для кросс-компиляции с Clang для ARM, встроенного в Windows? - PullRequest
0 голосов
/ 05 февраля 2019

Я пытаюсь сгенерировать make-файлы Ninja для кросс-компиляции проекта C ++ с Clang для процессора ARM Cortex A5.Я создал файл цепочки инструментов для CMake, но кажется, что произошла ошибка или что-то отсутствует, но я не могу найти.При вызове CMake с файлом инструментария ниже я получаю следующую ошибку:

Команда CMake:

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

Вывод:

- Идентификатор компилятора C - Clang 7.0.0 Ошибка CMake в C: /Users/user/scoop/apps/cmake/3.13.4/share/cmake-3.13/Modules/CMakeDetermineCompilerId.cmake: 802 (сообщение): инструмент компилятора Clang

"C: / Program Files / LLVM / bin / clang.exe "

предназначена для ABI MSVC, но имеет интерфейс командной строки, подобный 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.t:(ПРОЕКТ)

- Конфигурирование неполное, произошли ошибки!

Файл CMake toolchain (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 для Windows, поэтому файл цепочки инструментов, кажется, является единственным недостающим фрагментом головоломки.

EDIT

Я пытался обойтиКомпилятор CMake проверяет принудительно.Я заменяю строки на SET (CMAKE_C_COMPILER clang), SET (CMAKE_CXX_COMPILER clang ++) и т. Д. На:

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

Ошибка остается прежней.

EDIT

Я могу успешно скомпилировать пример hello world с помощью clang -target arm-none-eabi.Таким образом, проблема, кажется, в CMake.Я создал ошибку в трекере проблем CMake.

Версии инструментов:

  • clang версия 7.0.0 (tags / RELEASE_700 /окончательный вариант)
  • cmake версия 3.13.4

Ответы [ 2 ]

0 голосов
/ 10 апреля 2019

Вот альтернативный ответ, который использует CMake для кросс-компиляции для встроенного ARM с использованием цепочки инструментов GCC, а не clang, а также использует простой старый make, а не Ninja.Я знаю, что это не дает прямого ответа на вопрос, но это очень разумная альтернатива для встроенного ARM, и многие из используемых в настоящее время инструментальных цепочек поставщиков на основе Eclipse основаны на GCC, а не на LLVM / clang.

Сначала установите последний набор инструментов «GNU MCU Eclipse ARM Embedded GCC» из https://github.com/gnu-mcu-eclipse/arm-none-eabi-gcc/releases (ПРИМЕЧАНИЕ: нет установщика, просто разархивируйте его в нужное место).

Затем установите последнюю версию MSYS2 / MinGW с помощьюУстановщик доступен по адресу https://www.msys2.org/.

. По какой-то причине установка MSYS2 по умолчанию не включает make.Итак, после использования pacman для обновления пакетов по умолчанию в соответствии с инструкциями по установке, выполните команду «pacman -S make» для установки make.

В MSYS2 доступна сборка cmake.Тем не менее, он не включает генераторы для MSYS или MinGW (не знаю почему), а также (или из-за), кажется, возникают проблемы с поиском внешнего набора инструментов GCC, даже если полные пути явно указаны в командной строке или в файле набора инструментов,Таким образом, это решение использует встроенную сборку Windows CMake, доступную по https://cmake.org/download/,, а НЕ сборку MSYS2 cmake.

По умолчанию оболочка MSYS НЕ наследует среду Windows, поэтому встроенная WindowsCMake не будет находиться на пути оболочки MSYS.Простое решение - указать полный путь к cmake в командной строке.В моем случае у меня есть набор инструментов для кросс-компиляции GCC в C: / GNU MCU Eclipse / ARM Embedded GCC / 8.2.1-1.4-20190214-0604.Таким образом, полная команда для 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" ../

Здесь команда выполняется из каталога сборки на один уровень ниже корня проекта, а каталог cmake одноуровневого типа содержит указанный файл цепочки инструментов.Обратите внимание, обратная косая черта необходима для экранирования любых пробелов в пути к cmake.exe, но НЕ используется в путях, указанных в кавычках, передаваемых в качестве аргумента cmake.

Вы также можете запустить cmake и сделать правую из простой старой Windowsкомандной строки (cmd.exe), если каталоги cmake и msys bin включены в путь Windows.В этом случае нет необходимости указывать полный путь к cmake.Однако PowerShell не добился успеха.

0 голосов
/ 10 апреля 2019

На мой вопрос был дан ответ на мой отчет об ошибках, но я добавляю ответ, чтобы вся информация была в одном месте для дальнейшего использования.

Короче говоря: В настоящее время CMake не поддерживает использование интерфейса командной строки clang / clang ++, если вы устанавливаете Clang из llvm.org .Если вы хотите использовать интерфейс clang / clang ++ (который необходим для кросс-компиляции для ARM), вам нужно установить Clang через msys2 .

Подробнее

Clang в Windows имеет два различных интерфейса командной строки:

  • clang / clang ++ интерфейс по умолчанию, который пытается быть совместимым с GCCs gcc / g ++ и предназначается для GNUABI
  • clang-cl , который пытается быть совместимым с компилятором Microsoft Visual C ++ cl.exe и предназначается для MSVC ABI

для кросс-компиляции дляARM вам нужен интерфейс clang / clang ++.Проблема в том, что CMake поддерживает разные интерфейсы в зависимости от того, как вы установили Clang (см. bug в трекере проблем CMake для более подробной информации):

  • Если вы устанавливаете Clang из llvm.org CMake поддерживает только интерфейс clang-cl.
  • Если вы устанавливаете Clang через msys2 CMake поддерживает интерфейс clang / clang ++.

Итак, вот что я сделал:

  1. Установка msys2
  2. Установка Clang и CMake с pacman .В msys2 есть два пакета clang, версия mingw32 и mingw64.Я использовал пакет mingw64 (mingw-w64-x86_64-clang).
  3. Запустите оболочку mingw64, запустите CMake и соберите оттуда.

Файл набора инструментов

Были две проблемы с моим исходным файлом toolchain, которые я долго исправлял.Поэтому я надеюсь, что это сэкономит время другим:

  1. Целевая тройка (например, arm-none-eabi) должна точно соответствовать префиксу binutils GCC .Префикс моего binutils был arm-none-eabi (например, arm-none-eabi-ar), поэтому мне пришлось соответствующим образом изменить целевую тройку.
  2. CMAKE_TRY_COMPILE_TARGET_TYPE необходимо изменить на STATIC_LIBRARYчтобы CMake не запускал компоновщик во время проверки компиляции.

Вот последний файл цепочки инструментов, который я использовал (вы также можете найти хороший пример файла цепочки инструментов в этом репозитории GitHub):

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)
...