Русский
Русский
English
Статистика
Реклама

Cmake

Перевод История успешного перевода ScreenPlay с QMake на CMake

27.09.2020 16:05:45 | Автор: admin
ScreenPlay это опенсорсное приложение для Windows (а скоро ещё и для Linux и macOS), предназначенное для работы с обоями и виджетами. Оно создано с использованием современных инструментов (C++/Qt/QML), активная работа над ним ведётся с первой половины 2017 года. Код проекта хранится на платформе GitLab.



Автор статьи, перевод которой мы сегодня публикуем, занимается разработкой ScreenPlay. Он столкнулся с рядом проблем, решить которые ему помог переход с QMake на CMake.

QMake и разработка больших проектов


Совместное использование кода в QMake это очень неудобно


При разработке достаточно сложных приложений обычно лучше всего разбивать их на небольшие фрагменты, которыми удобно управлять. Например, если нужно представить приложение в виде основного исполняемого файла, к которому подключаются библиотеки, то, пользуясь QMake, сделать это можно лишь с помощью проекта, основанного на шаблоне subdirs. Это проект, представленный файлом, скажем, с именем MyApp.pro, который содержит запись об используемом шаблоне и список папок проекта:

TEMPLATE = subdirsSUBDIRS = \src/app \  # относительные путиsrc/lib \src/lib2

При таком подходе в нашем распоряжении оказываются несколько подпроектов, в которых нужно организовать совместное использование кода. Для того чтобы сообщить компилятору о том, где именно в других проектах ему нужно искать заголовочные файлы и файлы с исходным кодом, нужно передать линковщику сведения о том, какие именно библиотеки ему требуется подключать, и о том, где искать скомпилированные файлы. В QMake это делается через создание огромных .pri-файлов, которые используются исключительно для описания того, что нужно включить в проект. Это напоминает использование обычных C++-конструкций вида #include <xyz.h>. В результате оказывается, что, например, файл MyProjectName.pri включается в состав MyProjectName.pro. А для исправления проблемы, связанной с относительными путями, нужно добавить текущий абсолютный путь в каждую строку.

Внешние зависимости


Работа с внешними зависимостями, предназначенными для различных операционных систем, сводится, в основном, к копированию путей к соответствующим зависимостям и к вставке их в .pro-файл. Это скучная и утомительная работа, так как у каждой ОС есть, в этом плане, свои особенности. Например, в Linux нет отдельных подпапок debug и release.

CONFIG += ordered убийца производительности компиляции


Ещё один недостаток QMake заключается в периодическом возникновении проблем с компиляцией. Так, если в проекте есть множество подпроектов, которые представляют собой библиотеки, используемые в других подпроектах, то компиляция периодически завершается с ошибкой. Причиной ошибки может быть примерно такая ситуация: библиотека libA зависит от библиотек libB и libC. Но к моменту сборки libA библиотека libC ещё не готова. Обычно проблема исчезает при перекомпиляции проекта. Но то, что такое вообще происходит, указывает на серьёзные проблемы QMake. И эти проблемы не удаётся решить, пользуясь чем-то вроде libA.depends = libB. Вероятно (и, пожалуй, так оно и есть), я что-то делаю не так, но справиться с проблемой не удалось ни мне, ни моим коллегам. Единственный способ решить проблему с порядком сборки библиотек заключается в использовании настройки CONFIG += ordered, но из-за этого, за счёт отказа от параллельной сборки, сильно страдает производительность.

QBS и CMake


Почему QBS проигрывает CMake?


Сообщение о прекращении поддержки QBS (Qt Build System, система сборки Qt) стало для меня настоящим шоком. Я даже был одним из инициаторов попытки это изменить. При использовании QBS применяются приятные синтаксические конструкции, знакомые каждому, кто когда-либо писал QML-код. Не могу сказать того же о CMake, но после того, как я несколько месяцев поработал с этой системой сборки проектов, я могу с уверенностью заявить о том, что переход на неё с QBS был правильным решением, и о том, что я продолжу пользоваться CMake.

CMake, хотя и имеет некоторые недостатки синтаксического плана, работает надёжно. А проблемы QBS больше относятся к сфере политики, чем к технической стороне вопроса.

Это один из основных факторов, заставляющих программистов, недовольных размером Qt (и в плане количества строк кода, и в плане размера библиотеки), искать альтернативу. Кроме того, многим крайне не нравится MOC. Это метаобъектный компилятор, который преобразует C++-код, написанный с использованием Qt, в обычный C++. Благодаря этому компилятору можно, например, пользоваться удобными конструкциями, вроде тех, которые позволяют работать с сигналами.

Альтернативы QBS


В нашем распоряжении, помимо QBS, имеются такие системы сборки проектов, как build2, CMake, Meson, SCons. Они, за пределами экосистемы Qt, используются во многих проектах.

Плохая поддержка QBS в IDE


Насколько мне известно, единственной IDE, поддерживающей QBS, является QtCreator.

Блестящий союз vcpkg и CMake


Помните, как выше я возмущался проблемами с внешними зависимостями? Поэтому неудивительно то, сколько положительных эмоций у меня вызвал диспетчер пакетов vcpkg. Для установки зависимости достаточно одной команды! Полагаю, vcpkg может пригодиться любому C++-программисту.

О кажущейся непривлекательности синтаксиса CMake


Если судить о CMake по первой десятке ссылок найденных Google, то может показаться, что в этой системе используются весьма непривлекательные синтаксические конструкции. Но проблема тут в том, что Google выводит первыми старые материалы о CMake со Stack Overflow, датированные 2008 годом. Тут же попадаются и ссылки на старую документацию к версии CMake 2.8. Синтаксические конструкции, используемые при работе с CMake, могут быть очень даже симпатичными. Дело в том, что применение CMake предусматривает, в основном, использование конструкций, показанных ниже (это сокращённый вариант файла CMakeList.txt из проекта ScreenPlay).

# Проверка минимальных требованийcmake_minimum_required(VERSION 3.16.0)# Указание имени проекта. Оно потом будет использовано для именования# исполняемых файлов и для весьма полезного ${PROJECT_NAME}project(ScreenPlay)# Некоторые настройки Qt, касающиеся ресурсов и MOCset(CMAKE_AUTORCC ON)set(CMAKE_AUTOMOC ON)# Это - лишь синтаксический сахар. Тут создаётся переменная src,# содержащая список строк. Всё это потом будет использоваться в add_executableset(src main.cppapp.cpp# Тут кое-что пропустимsrc/util.cppsrc/create.cpp)set(headers app.hsrc/globalvariables.h# И тут кое-что пропустимsrc/util.hsrc/create.h)# Макрос Qt для больших ресурсов наподобие шрифтовqt5_add_big_resources(resources resources.qrc)# Предлагаем CMake скомпилировать qml в C++ в режиме release# ради повышения производительности!if(CMAKE_BUILD_TYPE STREQUAL "Debug")set(qml qml.qrc)else()qtquick_compiler_add_resources(qml qml.qrc )endif()# Предлагаем CMake найти эти библиотеки. Ранее мы, рассчитывая на это, настроили CMAKE_TOOLCHAIN_FILE# и нам больше не нужно вручную редактировать относительные пути!find_package(Qt5COMPONENTS QuickQuickCompilerWidgetsGuiWebEngineREQUIRED)# Внешние библиотеки vcpkgfind_package(ZLIB REQUIRED)find_package(OpenSSL REQUIRED)find_package(libzippp CONFIG REQUIRED)find_package(nlohmann_json CONFIG REQUIRED)# У CMake есть две основные команды:# add_executable для создания исполняемых файлов# add_library для создания библиотекadd_executable(${PROJECT_NAME} ${src} ${headers} ${resources} ${qml})# Пользовательское свойство для отключения окна консоли в Windows# https://stackoverflow.com/questions/8249028/how-do-i-keep-my-qt-c-program-from-opening-a-console-in-windowsset_property(TARGET ${PROJECT_NAME} PROPERTY WIN32_EXECUTABLE true)# Предлагаем компилятору найти указанные зависимости. Чаще всего имя# библиотеки можно узнать у vcpkg. В противном случае можно поискать# dll/lib/so/dynlib в vcpkg/installed# Если нужны зависимости внутри структуры проекта, можно# просто добавить project(MyLib) к target_link_libraries.# Никаких путей и ничего другого указывать не нужно.target_link_libraries(${PROJECT_NAME}PRIVATEQt5::QuickQt5::GuiQt5::WidgetsQt5::CoreQt5::WebEnginenlohmann_json::nlohmann_jsonlibzippp::libzipppScreenPlaySDKQTBreakpadplugin)# Предлагаем CMake скопировать этот файл в директорию build в том случае, если он изменился.# ${CMAKE_BINARY_DIR} - это директория build!file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/bin/assets/fonts)configure_file(assets/fonts/NotoSansCJKkr-Regular.otf ${CMAKE_BINARY_DIR}/bin/assets/fonts COPYONLY)

Ninja ускоряет CMake


Роль CMake заключается лишь в том, чтобы генерировать инструкции для выбранной разработчиком системы сборки проектов. Это может оказаться огромным плюсом при работе с людьми, которые пользуются не Qt Creator, а Visual Studio. При использовании CMake можно (и нужно) выбрать Ninja в качестве системы сборки, используемой по умолчанию. Компиляция проектов с применением связки CMake+Ninja это очень приятно. И то и другое можно найти в наборе инструментов Qt Maintenance. Кроме прочего, эти инструменты очень быстро обрабатывают изменения при итеративном подходе к разработке. На самом деле, всё работает так быстро, что при использовании Godot со SCons мне очень хочется и тут пользоваться CMake.

Vcpkg позволяет CMake проявить себя во всей красе


Управление зависимостями в C++-проектах это непростая задача. Для её решения многие проекты даже размещают в своих Git-репозиториях необходимые DLL. А это плохо, так как из-за этого неоправданно увеличиваются размеры репозиториев (Git LFS мы тут не касаемся). Недостаток vcpkg заключается лишь в том, что этот диспетчер пакетов поддерживает лишь одну глобальную версию некоего пакета (то есть, приходится самостоятельно устанавливать разные версии vcpkg, но это нечто вроде хака, да и нужно это редко). Правда, в планах развития проекта можно увидеть то, что он идёт в правильном направлении.

Для установки пакетов используется такая команда:

vcpkg install crashpad

Мы, при работе над ScreenPlay, просто создали скрипты install_dependencies_windows.bat и install_dependencies_linux_mac.sh для клонирования репозитория vcpkg, для его сборки и установки всех наших зависимостей. При работе с Qt Creator необходимо записывать в CMAKE_TOOLCHAIN_FILE относительный путь к vcpkg. Кроме того, vcpkg нужно сообщить о том, какую ОС и какую архитектуру мы используем.

# Настройка QtCreator. Extras -> Tools -> Kits -> -> CMake Configuration. Туда надо добавить следующее:CMAKE_TOOLCHAIN_FILE:STRING=%{CurrentProject:Path}/Common/vcpkg/scripts/buildsystems/vcpkg.CMakeVCPKG_TARGET_TRIPLET:STRING=x64-windows

Нужно установить ещё какую-нибудь библиотеку? Для этого достаточно воспользоваться командой вида vcpkg install myLibToInstall.

Итоги


У подхода, когда пользуются всем самым новым и популярным, есть свои плюсы. Но что делать, например, когда системы сборки с большим потенциалом, вроде QBS, вдруг оказываются на обочине? В конечном счёте, разработчик сам принимает решения о том, чем ему пользоваться в его проектах. Именно поэтому я решил перевести свой проект на CMake. И, надо сказать, это было правильное решение. Сегодня, в 2020 году, CMake смотрится очень даже хорошо.

Пользуетесь ли вы CMake и vcpkg?



Подробнее..

Из песочницы Использование GitHub Actions с C и CMake

24.06.2020 14:16:49 | Автор: admin

Привет, Хабр! Предлагаю вашему вниманию перевод статьи "Using GitHub Actions with C++ and CMake" о сборке проекта на C++ с использованием GitHub Actions и CMake автора Кристиана Адама.


Использование GitHub Actions с C++ и CMake


В этом посте я хочу показать файл конфигурации GitHub Actions для проекта C++, использующего CMake.


GitHub Actions это предоставляемая GitHub инфраструктура CI/CD. Сейчас GitHub Actions предлагает следующие виртуальные машины (runners):


Виртуальное окружение Имя рабочего процесса YAML
Windows Server 2019 windows-latest
Ubuntu 18.04 ubuntu-latest or ubuntu-18.04
Ubuntu 16.04 ubuntu-16.04
macOS Catalina 10.15 macos-latest

Каждая виртуальная машина имеет одинаковые доступные аппаратные ресурсы:


  • 2х ядерное CPU
  • 7 Гб оперативной памяти
  • 14 Гб на диске SSD

Каждое задание рабочего процесса может выполняться до 6 часов.


К сожалению, когда я включил GitHub Actions в проекте C++, мне предложили такой рабочий процесс:


./configuremakemake checkmake distcheck

Это немного не то, что можно использовать с CMake.


Hello World


Я хочу собрать традиционное тестовое приложение C++:


#include <iostream>int main(){  std::cout << "Hello world\n";}

Со следующим проектом CMake:


cmake_minimum_required(VERSION 3.16)project(main)add_executable(main main.cpp)install(TARGETS main)enable_testing()add_test(NAME main COMMAND main)

TL;DR смотрите проект на GitHub.


Матрица сборки


Я начал со следующей матрицы сборки:


name: CMake Build Matrixon: [push]jobs:  build:    name: ${{ matrix.config.name }}    runs-on: ${{ matrix.config.os }}    strategy:      fail-fast: false      matrix:        config:        - {            name: "Windows Latest MSVC", artifact: "Windows-MSVC.tar.xz",            os: windows-latest,            build_type: "Release", cc: "cl", cxx: "cl",            environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat"          }        - {            name: "Windows Latest MinGW", artifact: "Windows-MinGW.tar.xz",            os: windows-latest,            build_type: "Release", cc: "gcc", cxx: "g++"          }        - {            name: "Ubuntu Latest GCC", artifact: "Linux.tar.xz",            os: ubuntu-latest,            build_type: "Release", cc: "gcc", cxx: "g++"          }        - {            name: "macOS Latest Clang", artifact: "macOS.tar.xz",            os: macos-latest,            build_type: "Release", cc: "clang", cxx: "clang++"          }

Свежие CMake и Ninja


На странице установленного ПО виртуальных машин мы видим, что CMake есть везде, но в разных версиях:


Виртуальное окружение Версия CMake
Windows Server 2019 3.16.0
Ubuntu 18.04 3.12.4
macOS Catalina 10.15 3.15.5

Это значит, что нужно будет ограничить минимальную версию CMake до 3.12 или обновить CMake.


CMake 3.16 поддерживает прекомпиляцию заголовков и Unity Builds, которые помогают сократить время сборки.


Поскольку у CMake и Ninja есть репозитории на GitHub, я решил скачать нужные релизы с GitHub.


Для написания скрипта я использовал CMake, потому что виртуальные машины по умолчанию используют свойственный им язык скриптов (bash для Linux и powershell для Windows). CMake умеет выполнять процессы, загружать файлы, извлекать архивы и делать еще много полезных вещей.


- name: Download Ninja and CMake  id: cmake_and_ninja  shell: cmake -P {0}  run: |    set(ninja_version "1.9.0")    set(cmake_version "3.16.2")    message(STATUS "Using host CMake version: ${CMAKE_VERSION}")    if ("${{ runner.os }}" STREQUAL "Windows")      set(ninja_suffix "win.zip")      set(cmake_suffix "win64-x64.zip")      set(cmake_dir "cmake-${cmake_version}-win64-x64/bin")    elseif ("${{ runner.os }}" STREQUAL "Linux")      set(ninja_suffix "linux.zip")      set(cmake_suffix "Linux-x86_64.tar.gz")      set(cmake_dir "cmake-${cmake_version}-Linux-x86_64/bin")    elseif ("${{ runner.os }}" STREQUAL "macOS")      set(ninja_suffix "mac.zip")      set(cmake_suffix "Darwin-x86_64.tar.gz")      set(cmake_dir "cmake-${cmake_version}-Darwin-x86_64/CMake.app/Contents/bin")    endif()    set(ninja_url "https://github.com/ninja-build/ninja/releases/download/v${ninja_version}/ninja-${ninja_suffix}")    file(DOWNLOAD "${ninja_url}" ./ninja.zip SHOW_PROGRESS)    execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./ninja.zip)    set(cmake_url "https://github.com/Kitware/CMake/releases/download/v${cmake_version}/cmake-${cmake_version}-${cmake_suffix}")    file(DOWNLOAD "${cmake_url}" ./cmake.zip SHOW_PROGRESS)    execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./cmake.zip)    # Save the path for other steps    file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/${cmake_dir}" cmake_dir)    message("::set-output name=cmake_dir::${cmake_dir}")    if (NOT "${{ runner.os }}" STREQUAL "Windows")      execute_process(        COMMAND chmod +x ninja        COMMAND chmod +x ${cmake_dir}/cmake      )    endif()

Шаг настройки


Теперь, когда у меня есть CMake и Ninja, все, что мне нужно сделать, это настроить проект таким образом:


- name: Configure  shell: cmake -P {0}  run: |    set(ENV{CC} ${{ matrix.config.cc }})    set(ENV{CXX} ${{ matrix.config.cxx }})    if ("${{ runner.os }}" STREQUAL "Windows" AND NOT "x${{ matrix.config.environment_script }}" STREQUAL "x")      execute_process(        COMMAND "${{ matrix.config.environment_script }}" && set        OUTPUT_FILE environment_script_output.txt      )      file(STRINGS environment_script_output.txt output_lines)      foreach(line IN LISTS output_lines)        if (line MATCHES "^([a-zA-Z0-9_-]+)=(.*)$")          set(ENV{${CMAKE_MATCH_1}} "${CMAKE_MATCH_2}")        endif()      endforeach()    endif()    file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/ninja" ninja_program)    execute_process(      COMMAND ${{ steps.cmake_and_ninja.outputs.cmake_dir }}/cmake        -S .        -B build        -D CMAKE_BUILD_TYPE=${{ matrix.config.build_type }}        -G Ninja        -D CMAKE_MAKE_PROGRAM=${ninja_program}      RESULT_VARIABLE result    )    if (NOT result EQUAL 0)      message(FATAL_ERROR "Bad exit status")    endif()

Я установил переменные окружения CC и CXX, а для MSVC мне пришлось выполнить скрипт vcvars64.bat, получить все переменные окружения и установить их для выполняющегося скрипта CMake.


Шаг сборки


Шаг сборки включает в себя запуск CMake с параметром --build:


- name: Build  shell: cmake -P {0}  run: |    set(ENV{NINJA_STATUS} "[%f/%t %o/sec] ")    if ("${{ runner.os }}" STREQUAL "Windows" AND NOT "x${{ matrix.config.environment_script }}" STREQUAL "x")      file(STRINGS environment_script_output.txt output_lines)      foreach(line IN LISTS output_lines)        if (line MATCHES "^([a-zA-Z0-9_-]+)=(.*)$")          set(ENV{${CMAKE_MATCH_1}} "${CMAKE_MATCH_2}")        endif()      endforeach()    endif()    execute_process(      COMMAND ${{ steps.cmake_and_ninja.outputs.cmake_dir }}/cmake --build build      RESULT_VARIABLE result    )    if (NOT result EQUAL 0)      message(FATAL_ERROR "Bad exit status")    endif()

Что бы увидеть скорость компиляции на разном виртуальном окружении, я установил переменную NINJA_STATUS.


Для переменных MSVC я использовал скрипт environment_script_output.txt, полученный на шаге настройки.


Шаг запуска тестов


На этом шаге вызывается ctest с передачей числа ядер процессора через аргумент -j:


- name: Run tests  shell: cmake -P {0}  run: |    include(ProcessorCount)    ProcessorCount(N)    execute_process(      COMMAND ${{ steps.cmake_and_ninja.outputs.cmake_dir }}/ctest -j ${N}      WORKING_DIRECTORY build      RESULT_VARIABLE result    )    if (NOT result EQUAL 0)      message(FATAL_ERROR "Running tests failed!")    endif()

Шаги установки, упаковки и загрузки


Эти шаги включают запуск CMake с --install, последующий вызов CMake для создания архива tar.xz и загрузку архива как артефакта сборки.


- name: Install Strip  run: ${{ steps.cmake_and_ninja.outputs.cmake_dir }}/cmake --install build --prefix instdir --strip- name: Pack  working-directory: instdir  run: ${{ steps.cmake_and_ninja.outputs.cmake_dir }}/cmake -E tar cJfv ../${{ matrix.config.artifact }} .- name: Upload  uses: actions/upload-artifact@v1  with:    path: ./${{ matrix.config.artifact }}    name: ${{ matrix.config.artifact }}

Я не стал использовать CMake в качестве языка сценариев для простых вызовов CMake с параметрами, оболочки по умолчанию прекрасно с этим справляются.


Обработка релизов


Когда вы помечаете релиз в git, вы также хотите, чтобы артефакты сборки прикрепились к релизу:


git tag -a v1.0.0 -m "Release v1.0.0"git push origin v1.0.0

Ниже приведён код для этого, который сработает, если git refpath содержит tags/v:


release:  if: contains(github.ref, 'tags/v')  runs-on: ubuntu-latest  needs: build  steps:  - name: Create Release    id: create_release    uses: actions/create-release@v1.0.0    env:      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}    with:      tag_name: ${{ github.ref }}      release_name: Release ${{ github.ref }}      draft: false      prerelease: false  - name: Store Release url    run: |      echo "${{ steps.create_release.outputs.upload_url }}" > ./upload_url  - uses: actions/upload-artifact@v1    with:      path: ./upload_url      name: upload_urlpublish:  if: contains(github.ref, 'tags/v')  name: ${{ matrix.config.name }}  runs-on: ${{ matrix.config.os }}  strategy:    fail-fast: false    matrix:      config:      - {          name: "Windows Latest MSVC", artifact: "Windows-MSVC.tar.xz",          os: ubuntu-latest        }      - {          name: "Windows Latest MinGW", artifact: "Windows-MinGW.tar.xz",          os: ubuntu-latest        }      - {          name: "Ubuntu Latest GCC", artifact: "Linux.tar.xz",          os: ubuntu-latest        }      - {          name: "macOS Latest Clang", artifact: "macOS.tar.xz",          os: ubuntu-latest        }  needs: release  steps:  - name: Download artifact    uses: actions/download-artifact@v1    with:      name: ${{ matrix.config.artifact }}      path: ./  - name: Download URL    uses: actions/download-artifact@v1    with:      name: upload_url      path: ./  - id: set_upload_url    run: |      upload_url=`cat ./upload_url`      echo ::set-output name=upload_url::$upload_url  - name: Upload to Release    id: upload_to_release    uses: actions/upload-release-asset@v1.0.1    env:      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}    with:      upload_url: ${{ steps.set_upload_url.outputs.upload_url }}      asset_path: ./${{ matrix.config.artifact }}      asset_name: ${{ matrix.config.artifact }}      asset_content_type: application/x-gtar

Это выглядит сложным, но это необходимо, так как actions/create-release можно вызвать однократно, иначе это действие закончится ошибкой. Это обсуждается в issue #14 и issue #27.


Несмотря на то, что вы можете использовать рабочий процесс до 6 часов, токен secrets.GITHUB_TOKEN действителен один час. Вы можете создать личный токен или загрузить артефакты в релиз вручную. Подробности в обсуждении сообщества GitHub.


Заключение


Включить GitHub Actions в вашем проекте на CMake становится проще, если создать файл .github/workflows/build_cmake.yml с содержимым из build_cmake.yml.


Вы можете посмотреть GitHub Actions в моем проекте Hello World GitHub.


Оригинальный текст опубликован под лицензией CC BY 4.0.

Подробнее..

Финальный релиз этого года CLion 2020.3! С новыми функциями в отладчике, проверками MISRA и улучшениями для Qt

08.12.2020 00:17:38 | Автор: admin
Привет, Хабр!

Год подходит к концу, и мы в JetBrains выпускаем традиционный паровоз релизов для наших десктопных инструментов. Про некоторые из них (WebStorm, DataGrip) мы уже писали тут на Хабре. А сегодня пришло время рассказать про обновление нашей кроссплатформенной среды разработки на C и C++ CLion 2020.3!

CLion 2020.3 release

Коротко о самом главном:
  • В отладчике появились возможности исследовать дампы памяти и запускать конфигурацию с привилегиями администратора. А еще теперь можно перемещать точку исполнения по коду в любом направлении прямо во время сеанса отладки.
  • Для модульного тестирования мы добавили поддержку CTest инструмента запуска тестов, идущего в комплекте с проектной моделью CMake.
  • Для проектов на Qt добавлены шаблоны для создания новых Qt-проектов и новых классов UI, функция автодополнения адаптирована для работы с сигналами и слотами, а автоимпорт следует принятому в Qt стилю.
  • Существенно расширилось множество проектов, использующих Makefile, которые можно успешно открывать в CLion. А для проектов CMake появилась возможность отключать временно неиспользуемые профили CMake.
  • Для разработчиков встроенных систем мы включили начальную поддержку стандартов MISRA C 2012 и MISRA C ++ 2008.
  • А также множество других улучшений для конфигураций запуска и отладки, в поддержке систем контроля версий и для режима удаленной разработки. Разнообразные приятные улучшения в UI. И долгожданное превью нового сервиса для совместной разработки и парного программирования.


Новую версию можно скачать с сайта и попробовать бесплатно в течение 30 дней.Если у вас есть активная подписка на CLion или All Products Pack, просто обновите версию на 2020.3. Напоминаем, что при покупке годовой подписки на любой продукт предоставляется резервная бессрочная лицензия.

А теперь поговорим о нововведениях и улучшения версии 2020.3 подробнее.

Отладчик


Релиз 2020.3 стал большой вехой в развитии интеграций с отладчиками в CLion. И это неспроста, ведь эту интеграцию использует не один, а сразу несколько продуктов компании! CLion, плагин IntelliJ Rust и раннее превью среды для разработки игр Rider for Unreal Engine. Совместными усилиями мы смогли реализовать много важных новых возможностей в отладчике.

Отладка с дампами памяти


Процесс завершился нештатно, проще говоря, упал, оставив после себя дамп памяти? Новое действие Run | Open Core Dump, доступное для Linux и macOS, позволит открыть дамп памяти упавшего процесса в CLion для дальнейшей отладки:
Open Core Dump

В диалоге требуется указать путь к дампу памяти, путь к файлу с отладочными символами (подойдет, например, исполняемый файл программы, если была включена сборка в режиме с отладочной информацией), сопоставление путей (если сборка исполняемого файла производилась на другой машине). Далее CLion создаст конфигурацию для отладки этого дампа памяти, которую вы сможете запустить.

Диалог умеет показывать список уже созданных конфигураций. Конфигурации также можно создавать вручную из меню Run | Edit Configurations. Во время отладки с дампом памяти можно анализировать информацию о фреймах, изучать значения переменных, просматривать состояние памяти и код на ассемблере, вычислять выражения и запускать команды из консоли отладчика. При этом, по понятным причинам, отключена пошаговая отладка и недоступно окно вывода процесса.
Debug Core Dump

Из текущих ограничений, помимо недоступности новой функции на платформе Windows, стоит еще отметить, что в случае LLDB пока что не используется файл с отладочными символами. А возможности отладки дампов, собранных на другой машине, и удаленная отладка дампов сильно ограничены (CPP-22736, CPP-22656).

Запуск и отладка с привилегиями администратора


В конфигурациях запуска и отладки с этого релиза появился новый флажок запускать конфигурацию с привилегиями администратора. Настройка поддержана для многих типов конфигураций: CMake, Makefile, Gradle Native, Custom Build, CTest.

Чтобы использовать новую возможность было удобнее на практике, мы написали специальный демон, который предлагает вам оставаться авторизованным от имени администратора при запуске таких конфигураций в течение выбранного периода времени:
Elevation Settings

Подробнее о работе этой новой возможности читайте здесь (на английском).

Установка точки исполнения


Пользователи Visual Studio могут быть знакомы с такой полезной возможностью, как изменение точки исполнения во время сеанса отладки. Для всех остальных: представьте, что вы хотите пропустить исполнение целого цикла, поменять ветку условного оператора, вернуться на несколько шагов назад в потоке исполнения программы прямо во время сеанса отладки. Теперь для этого в CLion есть новое действие Set Execution Point to Cursor, или можно вручную переставлять желтую стрелочку на нужную строку прямо в редакторе:
Set Execution Point

Оговоримся, что подобное действие может сломать программу (например, если вы пропустите команду инициализации переменной). Но при умелом использовании, оно позволит вам отлаживать приложение очень эффективно.

Интерактивные подсказки


Практически во всех наших IDE на основе платформы IntelliJ в версии 2020.3 появились интерактивные подсказки и встроенные watches. Еще до 2020.3 во время сеанса отладки вы могли видеть значения переменных прямо в редакторе. Теперь эти подсказки стали интерактивными переменную можно раскрыть и посмотреть значение всех ее полей:
Interactive hints

А еще можно добавить произвольное выражение для подсчета и просмотра прямо в редакторе (рядом с нужной строкой кода). Это оказывается удобнее обычных watches (которые постоянно показываются в окне отладчика) тогда, когда используемые в выражении переменные имеют смысл только в конкретном месте кода (например, локальные переменные).

Хотите увидеть новые возможности в действии? Попробуйте сами или посмотрите это видео от нашего девелопер-адвоката:


Модульное тестирование


Что касается фреймворков для модульного тестирования, CLion поддерживает Google Test, Catch(2), Boost.Test и doctest. По результатам нашего исследования экосистемы разработки 2020 года 31% C++-разработчиков используют Google Test. Поэтому мы потратили время, чтобы улучшить представление результатов запуска Google Test в CLion:
  • Научились строить дерево тестов сразу, еще до выполнения всех тестов.
  • Начали отображать значения параметров тестов (для параметризованных тестов).
  • Ввели специальный значок для пометки отключенных (DISABLED) тестов в дереве.
  • А главное, существенно ускорили процесс поиска тестов в проекте.

GT run

Наши пользователи (в частности, здесь на Хабре) активно просили добавить поддержку CTest инструмента запуска тестов, идущего в комплекте с проектной моделью CMake. Это было не очень просто, так как CTest это сам по себе инструмент запуска, а не очередной фреймворк, и поэтому в существующий API укладывался плохо. Но мы наконец сделали это! CLion теперь автоматически находит тесты CTest в проекте, создает для них конфигурации запуска и отладки, строит дерево с отображением результатов тестов. Вы даже можете отлаживать тесты при этом CLion запустит именно тест, а не процесс ctest.

Что касается ограничений, стоит отметить, что CLion поддерживает версии CTest 3.14 и выше. К тому же, если в качестве теста CTest запускается блок тестов из уже поддерживаемого фреймворка (Google Test, Catch(2), Boost.Test и doctest), такой блок будет иметь одну запись в дереве результатов (то есть соответствовать одному тесту).

Традиционное видео от Фила Нэша, посвященное улучшениям для модульного тестирования:


Проекты Qt


Мы видим, что в CLion часто пишут проекты с использованием фреймворка Qt. И, хотя делать свой дизайнер интерфейсов или поддерживать проектную модель qmake мы пока не планируем, кое-что для улучшения пользовательского опыта в CLion в этом направлении мы все же решили сделать.

Шаблоны проектов и классов UI


Диалог создания нового проекта теперь предлагает два новых типа Qt Console Executable и Qt Widgets Executable:
New Qt project

Указываете необходимые значения CLion создает стартовый CMake-проект выбранного типа, и вот уже простейший виджет или консольное приложение у вас в кармане! Кстати, говоря о CMake и Qt, Qt6 предлагает устанавливать некоторые библиотеки через Conan (у CLion также есть соответствующий плагин) и собирать их через CMake и Ninja. Чем не повод попробовать CLion для разработки с использованием Qt?

Кстати, при добавлении нового класса Qt UI, CLion умеет создавать сразу три файла (.ui и файлы класса). Для этого выберите действие QT UI Class в меню добавления нового файла.

Работа с кодом Qt


Код Qt это, в целом, обычный код на C++, но есть и свои особенности. Так, в Qt принят определенный стиль импортов заголовочных файлов. Например, можно корректно включить QtCore/qurl.h, но будет более правильным использовать QUrl. Стиль теперь поддержан при автоимпорте в CLion:
Qt autoimport

Функция дополнения кода теперь понимает, когда необходимо предлагать варианты только сигналов или только слотов для основных сущностей Qt:
Qt completion

Это удобно, так как в выпадающем списке показываются только подходящие по смыслу варианты, а не все те, которые совпадают по набранным символам.

А какой возможности для Qt лично вам не хватает в CLion? Пишите в комментариях!

Проектные модели в CLion


Мы постепенно включаем в CLion поддержку все большего числа видов проектов с использованием Makefile (список протестированных проектов мы ведем тут). В релизе 2020.3 мы поддержали проекты, которые использую инструменты ccache, libtool, dolt, slibtool и jlibtool. Это проекты ZFS, PHP, Mono, Curl и другие. Конфигурации запуска и отладки для целей из файла Makefile верхнего уровня создаются автоматически. Кроме того, для проектов Makefile появилась возможность перекомпиляции отдельного файла без необходимости пересобирать весь проект (в раскладке по умолчанию Ctrl+Shift+F9 на Windows/Linux и F9 на macOS).

Для проектов CMake теперь можно отключить временно неиспользуемые профили CMake. Это особенно полезно, если в проекте настроено сразу несколько профилей для удаленной разработки (часть из них может быть временно отключена) или для разнообразных тулчейнов (тоже не всегда используемых все вместе). При отключении таких профилей время загрузки проекта заметно сокращается. Раньше для этого профили надо было удалять, а теперь вы просто можете их выключить. Сделать это можно из настроек профилей в Settings/Preferences | Build, Execution, Deployment | CMake либо из диалога загрузки CMake:
Disable/enable CMake profiles

Чтобы узнать подробнее об улучшениях для проектов на Qt и в проектных моделях, смотрите выступление нашего девелопера-адвоката.

Стандарты MISRA


Среди наших клиентов много разработчиков встроенных систем и представителей автомобильной отрасли. Для них важной частью процесса разработки является сертификация кода по стандартам MISRA. С самой сертификацией помочь мы пока не можем, а вот указать на возможные несоответствия стандартам MISRA на раннем этапе разработки нам вполне по силам! В версии CLion 2020.3 мы начали добавлять проверки стандартов MISRA C 2012 и MISRA C++ 2008 во встроенный статический анализатор кода:
MISRA checks

Поддержано еще не все; полный список можно найти на этой странице. Настроить инспекции довольно просто:
MISRA settings

В будущем мы добавим больше проверок MISRA. Возможно, также появятся проверки AUTOSAR.

Code With Me новый инструмент для совместной разработки


Практикует ли ваша команда парное программирование? Как насчет инструмента для совместного изучения кода? Совсем недавно мы запустили программу раннего доступа для нашего нового инструмента совместной разработки Code With Me. По сути, это плагин, доступный почти для всех наших десктопных IDE (пока что за исключением JetBrains Rider и DataGrip). С помощью него вы и ваша команда можете совместно работать над проектами прямо из своих IDE. Чтобы попробовать Code With Me, установите плагин в Preferences / Settings | Plugins.
Code With Me

Подробнее о возможностях плагина можно почитать в этих блог-постах. Code With Me все еще в стадии активной разработки. Если вы столкнетесь с какими-либо проблемами при его использовании, пожалуйста, сообщите нам об этом тут.

И многое другое


Из других важных улучшений хочется отметить:
  • Теперь, чтобы настроить окружение, в котором будет запускаться конфигурация запуска/отладки, можно использовать скрипт. К тому же, редактировать конфигурации запуска/отладки теперь можно прямо во время индексирования проекта.
  • Мы расширили возможности автодополнения сниппетами Clang. Они помогут поправить не только ключевые слова, но и синтаксис целых выражений:
    Clang snippets
  • Цветовую схему CLion теперь можно синхронизировать с темой вашей операционной системы. Чтобы включить эту возможность, зайдите в меню Settings / Preferences | Appearance & Behavior | Appearance и выберите опцию Sync with OS.
  • Чтобы разделить окно на несколько частей и иметь перед глазами сразу несколько открытых вкладок, теперь можно использовать простейшее перетаскивание файлов (Drag&Drop). То же самое можно сделать при помощи действия Open in Right Split, выбрав нужные файлы в окне Project, Recent Files или Search Everywhere.
  • В интеграции с системой контроля версий появилась поддержка Git-стейджинга. Меню VCS теперь учитывает то, какую VCS вы используете в проекте (например, Git). А в диалоге Search Everywhere появилась вкладка Git. Теперь там можно искать хэши, сообщения коммита, теги и ветки.


На этом у нас все. Мы рады, что вы дочитали до конца. Спасибо за внимание! Оставляйте свои вопросы, мысли и предложения в комментариях нам интересно, что вы думаете, и мы всегда рады помочь!

Команда CLion
The Drive to Develop
Подробнее..

Опыт команды PVS-Studio повышение производительности C анализатора на Windows при переходе на Clang

31.05.2021 18:12:13 | Автор: admin

С самого своего начала C++ анализатор PVS-Studio для Windows (тогда еще Viva64 версии 1.00 в 2006 году) собирался компилятором MSVC. С выходом новых релизов C++ ядро анализатора научилось работать на Linux и macOS, и структура проекта была переведена на использование CMake. Но под Windows сборка по-прежнему происходила с помощью компилятора MSVC. 29 апреля 2019 года разработчики Visual Studio объявили о включении в свою среду разработки набора утилит LLVM и компилятора Clang. И сейчас у нас наконец дошли руки, чтобы попробовать его в действии.

Тестирование производительности

В качестве бенчмарка воспользуемся нашей утилитой для регрессионного тестирования анализатора под названием SelfTester. Суть её работы заключается в анализе набора разных проектов и сравнении результатов анализа с эталонными. Например, если при каких-то правках в ядре анализатора появились ложные предупреждения или пропали правильные, значит появилась регрессия, которую надо исправить. Более подробно про SelfTester можно прочитать в статье "Лучшее враг хорошего".

Среди тестовой базы достаточно разнообразные по объёму кода проекты. Как правило, если рабочий компьютер или тестовый сервер не нагружен, то время тестирования SelfTester'ом на одной и той же версии ядра варьируется в пределах погрешности. В случае если производительность анализатора не уберегли, это значительно скажется на общем времени тестирования.

После того как сборка C++ ядра перешла на Clang, SelfTester стал проходить на 11 минут быстрее.

Выигрыш по производительности в 13% это довольно заметно, учитывая, что достаточно просто поменять компилятор, не так ли?

Минусы тоже есть, но незначительные. Сборка дистрибутива замедлилась на 8 минут, а размер исполняемого файла подрос на 1,6 Мбайт (из них ~500 Кбайт из-за статической линковки рантайма).

Видимо, производительность достигается более долгим этапом LTO (большую часть сборки занимает именно линковка) и более агрессивным раскручиванием циклов и встраиванием функций.

Далее хочется поделиться подводными камнями, возникшими в процессе перехода.

Генерация сборки под Clang

Скрипты CMake позволяют нам собирать свой код всеми мейнстримными компиляторами под нужные операционные системы.

Прежде всего необходимо установить компоненты компилятора Clang через Visual Studio Installer.

Clang-cl это так называемый "драйвер", который позволяет использовать clang с параметрами от cl.exe. Таким образом, он должен прозрачно взаимодействовать с MSBuild, практически как родной компилятор.

Также можно воспользоваться официальными сборками от проекта LLVM, которые можно найти на их репозитории GitHub. Однако для них нужно установить дополнительный плагин, чтобы Visual Studio смогла найти компиляторы. Имя toolset'а будет llvm, а не clangcl, как показано дальше в примерах.

Указываем toolchain в команде генерации solution для Visual Studio:

cmake -G "Visual Studio 16 2019" -Tclangcl <src>

Либо используем GUI:

Открываем получившийся проект, собираем. И, конечно же, получаем пачку ошибок.

Чиним сборку

Хоть сlang-cl внешне и ведет себя как CL, под капотом это совсем другой компилятор, со своими приколами.

Мы стараемся не игнорировать предупреждения компиляторов, поэтому используем флаги /W4 и /WX. Однако Clang может генерировать дополнительные предупреждения, которые сейчас мешают сборке. Пока выключим их:

if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")  ....  if (WIN32)    add_compile_options(-Wno-error=deprecated-declarations                        -Wno-error=reorder-ctor                        -Wno-error=format-security                        -Wno-error=macro-redefined                        -Wno-error=bitwise-op-parentheses                        -Wno-error=missing-field-initializers                        -Wno-error=overloaded-virtual                        -Wno-error=invalid-source-encoding                        -Wno-error=multichar                        -Wno-unused-local-typedef                        -Wno-c++11-narrowing)  ....  endif()endif()

Немного получше.

Компиляторы GCC и Clang имеют встроенную поддержку типа int128, в отличие от MSVC под Windows. Поэтому в своё время была написана обертка с реализацией Int128 для Windows (на ассемблерных вставках и обернутая ifdef'ами, в лучших традициях C/C++). Поправим определения для препроцессора, заменив:

if (MSVC)  set(DEFAULT_INT128_ASM ON)else ()  set(DEFAULT_INT128_ASM OFF)endif ()

на

if (MSVC AND NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")  set(DEFAULT_INT128_ASM ON)else ()  set(DEFAULT_INT128_ASM OFF)endif ()

Обычно библиотеку с builtin'ами линкеру (lld) передает драйвер компилятора, будь то clang.exe или clang-cl.exe. Но в данном случае линкером заправляет MSBuild напрямую, который не знает, что нужно её использовать. Соответственно, драйвер никак не может передать флаги линкеру, поэтому приходится разбираться самим.

if (CMAKE_GENERATOR MATCHES "Visual Studio")  link_libraries("$(LLVMInstallDir)\\lib\\clang\\\${CMAKE_CXX_COMPILER_VERSION}\\lib\\windows\\\clang_rt.builtins-x86_64.lib")else()  link_libraries(clang_rt.builtins-x86_64)endif()

Ура! Сборка заработала. Однако дальше при запуске тестов нас ждала куча ошибок сегментации:

Отладчик при этом показывает какое-то странное значение в IntegerInterval, а на самом деле проблема находится немного дальше:

В разных структурах для Dataflow-механизма активно применяется ранее упомянутый тип Int128, а для работы с ним используются SIMD-инструкции. И падение вызвано невыровненным адресом:

Инструкция MOVAPS перемещает из памяти набор чисел с плавающей запятой в регистры для SIMD-операций. Адрес при этом обязан быть выровнен, в его конце должен стоять 0, а оказалась 8. Придется помочь компилятору, задав правильное выравнивание:

class alignas(16) Int128

Порядок.

Последняя проблема вылезла из-за Docker-контейнеров:

Сборка под MSVC всегда делалась со статической линковкой рантайма, а для экспериментов с Clang рантайм переключили на динамический. Оказалось, что в образах с Windows по умолчанию не установлены Microsoft Visual C++ Redistributable. Решили вернуть статическую линковку, чтобы у пользователей не возникало таких же неприятностей.

Заключение

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

Последующие релизы PVS-Studio на Windows будут собираться с помощью компилятора Clang.

Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Alexey Govorov, Sergey Larin. PVS-Studio Team: Switching to Clang Improved PVS-Studio C++ Analyzer's Performance.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru