Сборка с CMake, Ninja и Clang на Windows
Уважаемые коллеги по C++,
после того, как я некоторое время использовал набор инструментов Visual Studio для сборки на окнах, я решил попробовать Clang 5.
Я установил двоичные файлы LLVM 5.0.0, среду сборки Ninja, VS 2017 Tools и CMake 3.9.3. Конечная цель состоит в том, чтобы иметь возможность компилировать приложения C и C++ для Windows, используя VS Code с интеграцией CMake в качестве "IDE" и Clang с LLD в качестве компилятора и компоновщика.
Компиляция и выполнение простой программы работали отлично ( скриншот соответствующей истории терминала). Clang автоматически обнаружил стандартную библиотеку lib для Windows в каталогах VS Tools и выдал исполняемый файл.
Следующим шагом была настройка простой сборки с помощью Ninja ( скриншот файла ninja.build и истории терминала). Процесс сборки работал, как и ожидалось, и создал рабочий исполняемый файл, как и раньше.
Проблемы начались, когда я начал интегрировать CMake в процесс. Я ожидаю, что CMake создаст файл сборки ninja и запустит его, правильно? Я попробовал следующий файл CMakeLists
cmake_minimum_required(VERSION 3.9)
project(Test)
add_executable(Test main.c)
и называется CMake с cmake -G Ninja
, Получившийся результат был разочаровывающим, и я не понимаю достаточно, чтобы решить, соответственно, решить проблему самостоятельно.
-- The C compiler identification is Clang 5.0.0
-- The CXX compiler identification is Clang 5.0.0
-- Check for working C compiler: C:/Meine_Programme/LLVM/bin/clang.exe
-- Check for working C compiler: C:/Meine_Programme/LLVM/bin/clang.exe -- broken
CMake Error at C:/Meine_Programme/CMake/share/cmake-3.9/Modules/CMakeTestCCompiler.cmake:51 (message):
The C compiler "C:/Meine_Programme/LLVM/bin/clang.exe" is not able to
compile a simple test program.
It fails with the following output:
Change Dir: D:/Dateien/Downloads/Test/CMakeFiles/CMakeTmp
Run Build Command:"C:/Meine_Programme/Ninja_Build/ninja.exe" "cmTC_eeb5c"
[1/2] Building C object CMakeFiles\cmTC_eeb5c.dir\testCCompiler.c.obj
FAILED: CMakeFiles/cmTC_eeb5c.dir/testCCompiler.c.obj
C:\Meine_Programme\LLVM\bin\clang.exe /nologo /DWIN32 /D_WINDOWS /W3 /MDd
/Zi /Ob0 /Od /RTC1 /showIncludes
/FoCMakeFiles\cmTC_eeb5c.dir\testCCompiler.c.obj
/FdCMakeFiles\cmTC_eeb5c.dir\ -c testCCompiler.c
clang.exe: error: no such file or directory: '/nologo'
clang.exe: error: no such file or directory: '/DWIN32'
clang.exe: error: no such file or directory: '/D_WINDOWS'
clang.exe: error: no such file or directory: '/W3'
clang.exe: error: no such file or directory: '/MDd'
clang.exe: error: no such file or directory: '/Zi'
clang.exe: error: no such file or directory: '/Ob0'
clang.exe: error: no such file or directory: '/Od'
clang.exe: error: no such file or directory: '/RTC1'
clang.exe: error: no such file or directory: '/showIncludes'
clang.exe: error: no such file or directory:
'/FoCMakeFiles\cmTC_eeb5c.dir\testCCompiler.c.obj'
clang.exe: error: no such file or directory:
'/FdCMakeFiles\cmTC_eeb5c.dir\'
ninja: build stopped: subcommand failed.
CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
CMakeLists.txt:3 (project)
-- Configuring incomplete, errors occurred!
See also "D:/Dateien/Downloads/Test/CMakeFiles/CMakeOutput.log".
See also "D:/Dateien/Downloads/Test/CMakeFiles/CMakeError.log".
Я предполагаю, что проблема связана с вызовом CMake clang с опциями стиля VS с использованием косой черты, а не с минусом, как требует clang.
Спасибо за помощь, ребята, я ценю это:-)
Просто оставьте мне комментарий, если вам нужна дополнительная информация.
Ответ на пост Флориан
Я попробовал команду Florians, но пропустил путь к ниндзя для более короткой записи, и оказалось, что он работает просто отлично.
cmake -E env LDFLAGS="-fuse-ld=lld" cmake -H. -G Ninja -Bbuild -DCMAKE_C_COMPILER:PATH="C:\MeineProgramme\LLVM\bin\clang.exe" -DCMAKE_CXX_COMPILER:PATH="C:\MeineProgramme\LLVM\bin\clang++.exe" -DCMAKE_C_COMPILER_ID="Clang" -DCMAKE_CXX_COMPILER_ID="Clang" -DCMAKE_SYSTEM_NAME="Generic"
CMake создал файл сборки для ниндзя.
Я побежал ninja all
построить исполняемый файл как Test
, Я переименовал его в Test.exe
и программа выполнена счастливо. Пока что... успехов!!! Но гораздо сложнее, чем я ожидал.
4 ответа
Наконец-то я нашел способ использовать мои любимые инструменты так, чтобы мне было удобно. Она не идеальна, но работает лучше, чем подход Florians, с установкой имени системы на Generic (которое я использую уже некоторое время)
Сначала я настроил VS Code для использования терминала разработчиков VS в качестве стандартного терминала. Я сделал это, добавив следующую строку в настройки кода VS
"terminal.integrated.shell.windows": "C:\\MeineProgramme\\Visual_Studio\\2017\\BuildTools\\Common7\\Tools\\LaunchDevCmd.bat"
После запуска терминала в VS Code мне нужно вызвать соответствующий пакетный файл, который устанавливает необходимые переменные среды (в моем случае vcvars64.bat
). Их можно найти в
C:\MeineProgramme\Visual_Studio\2017\BuildTools\VC\Auxiliary\Build
После перехода в каталог сборки я запускаю CMake со следующими параметрами
cmake .. -G Ninja -DCMAKE_CXX_COMPILER:PATH="C:\MeineProgramme\LLVM\bin\clang-cl.exe" -DCMAKE_LINKER:PATH="C:\MeineProgramme\LLVM\bin\lld-link.exe"
это побуждает CMake использовать все мои установленные инструменты LLVM. Не только clang
а также lld
(убедитесь, что вы используете lld-link, которая поддерживает параметры во главе с /
), но также llvm-ar
а также llvm-ranlib
, Единственный используемый инструмент сборки MS - это компилятор ресурсов, который я сейчас не использую.
Пока успех, я думаю.
Не стесняйтесь обращаться ко мне или комментировать ниже, если у вас есть дополнительные вопросы.
Вдохновленный постом в блоге "Способы компиляции с Clang в Windows" от @Unspongeful, и после некоторого расширенного тестирования у меня сработала следующая командная строка (и да, это одна большая команда, которую я только что разделил на несколько строк для лучшей читабельности):
> cmake -E env LDFLAGS="-fuse-ld=lld-link" PATH="<path\to\ninja>"
cmake -H. -G Ninja -Bbuild
-DCMAKE_C_COMPILER:PATH="%ProgramFiles(x86)%\LLVM\bin\clang.exe"
-DCMAKE_CXX_COMPILER:PATH="%ProgramFiles(x86)%\LLVM\bin\clang.exe"
-DCMAKE_C_COMPILER_ID="Clang"
-DCMAKE_CXX_COMPILER_ID="Clang"
-DCMAKE_SYSTEM_NAME="Generic"
Вот некоторая справочная информация:
Я ввел ваши флаги компоновщика с
LDFLAGS
переменная окруженияСм. Раздел Передача параметров компилятора cmake.
Я уменьшил
PATH
переменная окружения, чтобы просто указать, гдеninja
находится, потому что CMake выбирал мойMinGW
набор инструментов (который я не хотел включать в процесс сборки)Связано с переменной среды, используемой CMake для обнаружения инструментов компилятора Visual C++ для ниндзя
Определение идентификаторов компилятора "обходит проверку на работоспособность тестов компилятора и базовых данных компилятора"
Смотри устаревшее, но иногда полезное
CMakeForceCompiler
модульИ я поставил
CMAKE_SYSTEM_NAME
вGeneric
чтобы избежать добавления каких-либо дополнительных платформенных флагов компилятора / компоновщика, добавленных CMakeСм. Как частично отключить проверку пользовательского компилятора cmake C/C++
Кажется, в данный момент вам нужно обойти много автоматических проверок CMake, чтобы заставить его работать. Поэтому, возможно, свяжитесь с командой CMake или поднимите вопрос, чтобы официально поддержать этот сценарий.
И последняя часть с Generic
Система, вероятно, не лучший выбор, потому что она будет пропускать специфические настройки Windows, такие как .exe
суффикс.
Но это было единственное созвездие, которое действительно работало:
-- The C compiler identification is Clang
-- The CXX compiler identification is Clang
-- Check for working C compiler: C:/Program Files (x86)/LLVM/bin/clang.exe
-- Check for working C compiler: C:/Program Files (x86)/LLVM/bin/clang.exe -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: C:/Program Files (x86)/LLVM/bin/clang.exe
-- Check for working CXX compiler: C:/Program Files (x86)/LLVM/bin/clang.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: build
Я столкнулся с подобными проблемами при попытке использовать clang cmake и msvc 2017 вместе. По крайней мере, для очень простого тестового проекта я смог запустить все, но я довольно новичок в этом, так что, возможно, мое решение не решит ваши проблемы.
Тем не мение. Насколько я знаю, вы должны использовать clang-cl.exe
скорее, чем clang.exe
с VS. Тем не менее, сборка все еще не удалась для меня в конфигурациях x86 из-за некоторых проблем компоновщика относительно несовместимости библиотек x86 и x64.
Итак, вот мое решение для получения конфигураций x64 и x86, построенных в VS 2017.
- Загрузите и установите ОБА установщики Windows Clang/llvm с http://releases.llvm.org/download.html. Вам не нужно добавлять их в путь, так как позже мы явно укажем путь.
- Создать папку с
CMakeLists.txt
и откройте что в VS черезOpen Folder
Диалог. - в
CMake
меню, выберитеChange CMake Settings > CMakeLists.txt
, Это создастCMakeSettings.json
содержит настройки для всех конфигураций сборки. Укажите пути к компиляторам x64/x86 cmake в
cmakeCommandArgs
для всех конфигураций. Моя выглядит так:{ // See https://go.microsoft.com//fwlink//?linkid=834763 for more information about this file. "configurations": [ { "name": "x86-Debug", "generator": "Ninja", "configurationType": "Debug", "inheritEnvironments": [ "msvc_x86" ], "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", "cmakeCommandArgs": "-D CMAKE_CXX_COMPILER=D:/windows/LLVM5_x86/bin/clang-cl.exe", "buildCommandArgs": "-v", "ctestCommandArgs": "" }, { "name": "x86-Release", "generator": "Ninja", "configurationType": "RelWithDebInfo", "inheritEnvironments": [ "msvc_x86" ], "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", "cmakeCommandArgs": "-D CMAKE_CXX_COMPILER=D:/windows/LLVM5_x86/bin/clang-cl.exe", "buildCommandArgs": "-v", "ctestCommandArgs": "" }, { "name": "x64-Debug", "generator": "Ninja", "configurationType": "Debug", "inheritEnvironments": [ "msvc_x64" ], "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", "cmakeCommandArgs": "-D CMAKE_CXX_COMPILER=D:/windows/LLVM5/bin/clang-cl.exe", "buildCommandArgs": "-v", "ctestCommandArgs": "" }, { "name": "x64-Release", "generator": "Ninja", "configurationType": "RelWithDebInfo", "inheritEnvironments": [ "msvc_x64" ], "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", "cmakeCommandArgs": "-D CMAKE_CXX_COMPILER=D:/windows/LLVM5/bin/clang-cl.exe", "buildCommandArgs": "-v", "ctestCommandArgs": "" } ]
}
Теперь вы сможете без проблем создавать конфигурации как x64, так и x86.
Это старый вопрос, но...
Что касается использования их текущих версий clang, ninja и cmake, если вы создаете непосредственно в терминале, вы можете использовать это в Powershell:
cmake -B build -S . -DCMAKE_CXX_COMPILER:FILEPATH="C:/Program Files/LLVM/bin/clang.exe" -DCMAKE_C_COMPILER:FILEPATH="C:/Program Files/LLVM/bin/clang.exe" -DCMAKE_LINKER:FILEPATH="C:/Program Files/LLVM/bin/lld-link.exe" -G"Ninja" -DCMAKE_EXPORT_COMPILE_COMMANDS=1
Вам не нужно указывать какие-либо флаги илиCMAKE_<LANG>_COMPILER_ID