Сборка с 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"

Вот некоторая справочная информация:

Кажется, в данный момент вам нужно обойти много автоматических проверок 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.

  1. Загрузите и установите ОБА установщики Windows Clang/llvm с http://releases.llvm.org/download.html. Вам не нужно добавлять их в путь, так как позже мы явно укажем путь.
  2. Создать папку с CMakeLists.txtи откройте что в VS через Open Folder Диалог.
  3. в CMake меню, выберите Change CMake Settings > CMakeLists.txt, Это создаст CMakeSettings.json содержит настройки для всех конфигураций сборки.
  4. Укажите пути к компиляторам 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

Протестировано с:

Clang 16.0.4, Ninja 1.11.1 , Powershell 7.3.4 и CMake 3.26.

Другие вопросы по тегам