Задавшись этим вопросом я, в первую очередь, сформулировал требования: жесткие и опциональные (но желательные) для системы сборки и графической среды разработки.
Сразу хочу отметить что речь идет о написании C++ кода не под какую-то специфичную платформу типа Android или фреймворка, например Qt, — где все уже готово, как с построением так и с редактированием кода, а об generic коде не привязанному к конкретной платформе или фреймворку.

Общие:


  • Свободный.
  • Кросплатформенный (по крайней мере Windows и Linux).

Система сборки:


  • Единая команда для сборки на разных платформах.
  • Инкрементальная сборка с корректным учетом всех зависимостей: заголовочных файлов и сторонних компонентов, использующихся для сборки.
  • Сборочный скрипт должен содержать только необходимый минимум конфигурации специфичный для конкретного проекта. Общая логика билда не должна кочевать из скрипта в скрипт, а находится в билд системе или ее плагинах.
  • Встроенная параллельная сборка.
  • Поддержка различных тулчейнов (хотя бы gcc, Visual C++, CLang).
  • Возможность смены тулчейна с минимальными затратами, без переписывания всего билд скрипта.
  • Легко переключаемые варианты построения: Debug и Release.
  • Совершенно нежелательны зависимости на какие-то дополнительные низкоуровневые тулзы типа make. Одним словом система сборки должна быть самодостаточной.
  • Очень желательна интеграция системы сборки с репозиториями сторонних компонентов типа pkg-config или как Maven Central для JVM.
  • Система сборки должна быть расширяемой плагинами, т.к. процедура сборки для каждого конкретного проекта может оказаться сложнее типовой концепции построения (генерация кода, например, или сборка некоего нестандартного образа).
  • Удобно, когда сценарий сборки представляет собой какой-то высокоуровневый язык программирования или еще лучше DSL. Это позволит не особо затратно и выразительно менять поведение построения прямо в скрипте.
  • При настройке компилятора и линковщика из сценария сборки весьма удобно когда билд системой предоставляются хотя бы базовые абстракции: например, хочется добавить макрос — зачем думать какой параметр командной строки компилятора отвечает за это? /D на MSVC или -D на gcc — пусть система сборки разрулит эти несущественные детали сама.
  • Хорошая интеграция с графическими средами разработки (IDE).

IDE:


  • Способность IDE корректно «понимать» C++ код. IDE должна уметь индексировать все файлы проекта, а также все сторонние и системные заголовочные файлы и определения (defines, macro).
  • IDE должна предоставлять возможность кастомизации команд для построения проекта, а так же где искать заголовочные файлы и определения.
  • Должна эффективно помогать в наборе кода, т.е. предлагать наиболее подходящие варианты завершения, предупреждать об ошибках синтаксиса и т.д.
  • Навигация по большому проекту должна быть удобной, а нахождение использования быстрым и простым.
  • Предоставлять широкие возможности для рефакторинга: переименование и т.д.
  • Также необходима способность к генерации шаблонного кода — создание каркаса нового класса, заголовочного файла и файла с реализацией. Генерация геттеров/сеттеров, определения методов, перегрузка вирутальных методов, шаблоны реализации чисто виртуальных классов (интерфейсов) и т.д.
  • Подсветка и поддержка тегов документирования кода, таких, как Doxygen.

В свете этих «хотелок» мной были рассмотрены несколько систем сборки и графических сред разработки. Этот небольшой обзор ни в коей мере не претендует на полноту и содержит мои субъективные оценки, но, возможно, кому-то это покажется полезным в качестве начальной ступени.

Make[античность] мастодонт и заслуженный ветеран систем сборки, которого все никак не хотят отпустить на пенсию, а заставляют везти на себе все новые и новые проекты. Это очень низкоуровневая тулза со своим специфичном языком, где за пробел вместо таба вам сразу же грозит расстрел на месте. С помощью make можно сделать все, что угодно — билд любой сложности, но за это придется заплатить усилиями для написания скрипта, а также его поддержки в актуальном состоянии. Переносить логику билда из проекта в проект также будет накладно. Существуют некие современные «заменители» make-а: типа ninja и jam, но сути они не меняют — это очень низкоуровневые инструменты. Так же, как и на ассемблере можно написать все что угодно, только стоит ли?

CMake[средневековье] первая попытка уйти от низкоуровневых деталей make-а. Но, к сожалению, далеко уйти не удалось — движком здесь служит все тот же make для которого CMake генерирует огромные make-файлы на основе другого текстового файла с более выскоуровневым описанием билда. По схожему принципу работает и qmake. Такой подход напоминает мне красивый фасад старого деревянного дома, который заботливо обшили свежим пластиком. CMake стабильная и хорошо зарекомендовавшая себя система, есть даже встроенная интеграция с Eclipse, но, к сожалению, мне не подошла потому что противоречит части требований изложенных в начале статьи. Под Linux все вроде бы хорошо, но если нужно построить тот же проект под Windows с помощью MSVC — а я предпочитаю нативный компилятор MinGW-шному, будут сгенерированы файлы для NMake. Т.е. зависимости на еще одну тулзу и разные команды на сборку для другой платформы. И все это следствия чуток кривоватой архитектуры, когда основная часть работы выполняется другими «помощниками».

Ant[эпоха возрождения] своеобразный клон make для Java. Скажу честно, я потратил совсем немного времени для проверки Ant (а так же Maven) в качестве билд системы для C++. И у меня сразу же появилось ощущение что поддержка С++ здесь чисто «для галочки» и недостаточно развита. К тому же даже в Java проектах Ant уже используется достаточно редко. В качестве языка сценария (так же как и для Maven) здесь выбран XML — этот гнусный птичий язык :). Этот факт оптимизма мне совсем не прибавил для дальнейшего погружения в тему.

SCons[новые времена] самодостаточная, кросплатформенная билд система, написанная на Python. SCons одинаково хорошо справляется как с Java так и с C++ билдами. Зависимости хидеров для инкрементальной сборки отрабатываются корректно (насколько я понял создается некая база данных с метаданными билда), а на Windows «без бубна» работает MSVC. Язык сценария сборки — Python. Весьма достойная система, и я даже хотел закончить свои изыскания на ней, но как известно, нет пределу совершенства, и при более детальном осмотре выявились некоторые минусы в свете вышеизложенных требований.

Нет никаких абстрактных настроек для компилятора, поэтому если, например, возникнет необходимость сменить тулчейн, возможно, понадобиться искать места в билд скрипте для внесения изменений. Те же макросы придется прописывать с вложенными условиями — если это Виндовс то сделай так, если это GCC сделай так и т.д.

Нет поддержки удаленных артефакториев и высокоуровневой зависимости одного билда на другой.

Общая архитектура построена так, что так называемые user defined builders существуют практически изолированно и нет возможности заиспользовать уже существующую логику билда, чтобы дополнить ее своей через несложный плагин. Но в целом это достойный выбор для небольших проектов.

Gradle [современность] — у меня уже был позитивный опыт использования Gradle для Java и Kotlin проектов и я возлагал на него большие надежды.

Для JVM языков в Gradle очень удобная концепция работы с библиотеками, необходимыми для построения проекта (билд зависимостями):

  • В скрипте прописываются адреса репозиториев с артефактами: maven или ivy — например. Так же это может быть репозиторий любого другого типа/формата — лишь бы был плагин для него. Это может быть удаленный репозиторий, какой-нибудь Maven Central или ваш личный хостинг где-нибудь в сети или просто локальная репа на файловой системе.
  • Так же в специальном разделе скрипта указываются непосредственно зависимости для построения — список необходимых бинарных артефактов с указанием версий.
  • Перед началом построения Gradle пытается зарезолвить все зависимости и ищет артефакты с заданными версиями по всем репозиториям. Бинарники загружаются в кэш и автоматически добавляются в билд. Это очень удобно и я надеялся, что для C++, возможно, сделали нечто подобное.

Сначала я заценил «старый» плагин для поддержки C++ — `cpp` — и был разочарован — структура скрипта не интуитивная: model, component, nativespec — и какая-то мешанина из различных типов бинарей: и выполнимые и библиотеки все в одном скрипте. Непонятно где размещать юнит тесты. Такая структура сильно отличалась от того что я использовал для Java.

Но, оказалось, что есть и «новые» плагины для поддержки C++: `cpp-application` — для приложений, `cpp-library` для библиотек: статических и динамических и наконец `cpp-unit-test` для юнит тестирования. И это было то что я искал! :)

Структура папок проекта по умолчанию похожа на проект для Java:

  • src/main/cpp — корневая папка для основных файлов *.cpp проекта.
  • src/main/headers — папка для внутренних заголовочных файлов.
  • src/main/public — папка для экспортируемых заголовков — для библиотек.
  • src/test/cpp — папка для файлов *.cpp юнит теста.

Такая структура не жесткая — ее всегда можно поменять в скрипте, но все же не стоит этого делать без особой необходимости, она вполне разумна.

Кстати, билд скрипт — обычно build.gradle, это DSL языка Groovy или Kotlin (build.gradle.kts) на выбор. Внутри скрипта всегда доступен Gradle API и API добавленных в скрипт плагинов.

Для библиотек можно выбрать тип: статическая или динамическая (или собрать оба варианта).
По умолчанию сконфигурированы два варианта построения: Debug (gradle assemble) и Release (gradle assembleRelease).

Принцип запуска юнит тестирования такой же как в Java: gradle test выполнит простройку основного компонента, потом тестов, если они есть в папке src/test/cpp, а затем выполнит тестовое приложение.

Пресловутые дефайны можно задавать абстрактно — Gradle сам сгенерирует необходимы параметры компилятора. Есть еще несколько абстрактных настроек типа оптимизации, отладочной информации и т.д.

Из коробки поддерживаются GCC, Microsoft Visual C++, CLang.

Система плагинов очень развита, а архитектура расширений устроена удобно — можно взять готовую логику и задекорировать/расширить ее. Плагины бывают двух видов: динамические, которые пишутся прямо на Groovy и встраиваются в скрипт или написанные на Java (или на другом языке с JVM) и скомпилированные в бинарные артефакты. Для плагинов существует бесплатный Gradle-артифакторий, в котором любой желающий может разместить свой плагин, который будет доступен всем. Что успешно и проделал автор этой статьи :) но об этом чуть позже.
Хотелось бы подробнее остановиться теперь на системе работы с бинарными компонентами в Gradle для C++: она почти такая же как в Java! Билд зависимости работают практически так же как я описал выше.

Возьмем для примера композитный билд:

  • utils — папка с библиотекой
  • app — папка с приложением, которое использует utils.
  • settings.gradle — Gradle файл для объединения этих двух компонент в композитный билд.

В файле build.gradle из папки app достаточно прописать такую зависимость:

    dependencies {
        implementation project(':utils')
    }

А все остальное проделает Gradle! Добавит в компилятор путь для поиска заголовочных файлов utils и прилинкует бинарь библиотеки.

И все это одинаково хорошо сработает как под Linux GCC, так и под Windows MSVC.
Инкрементальная сборка, естественно, тоже замечательно работает и при изменении хидеров в utils будет перестроен app.

Как оказалось, в Gradle пошли дальше и реализовали возможность выкладывать C++ артефакты в Maven Repository! Для этого используется стандартный `maven-publish` плагин.

В скрипте необходимо указать репозиторий куда вы хотите выложить свой артефакт и сделать gradle publish (или gradle publishToMavenLocal для локальной публикации). Gradle сбилдит проект и
выложит в специальном формате — с учетом версии, платформы, архитектуры и варианта билда.

Выкладываются сами бинарные файлы библиотек и публичные заголовочные файлы — из папки src/main/public.

Понятно что выложить С++ артефакт на Maven Cental нельзя — он не пройдет обязательные проверки системы. Но поднять Maven репозиторий в сети совсем нетрудно, а для локального репозитория вообще ничего делать не нужно — это просто папка на диске.

Теперь если вы хотите использовать в своем проекте чью-то библиотеку вы можете написать в билд скрипте что-то вроде:

    repositories {
        maven {
            url = 'https://akornilov.bitbucket.io/maven'
        }
    }
    unitTest {
        dependencies {
            implementation 'org.bitbucket.akornilov.tools:gtest:1.8.1'
       }
    }

Здесь говориться что для юнит тестирования нужно использовать артефакт gtest версии 1.8.1 из Maven репозитория.

Это, кстати, вполне реальный репозиторий в котором выложен мой билд Google Test v1.8.1, простроенный с помощью Gradle для Windows и Linux x86_64.

Естественно, что всю низкоуровневую работу по конфигурированию компилятора и линковщика для работы с внешним компонентом Gradle берет на себя. Вам достаточно заявить о своих намерениях использовать такую-то библиотеку с такой-то версией из такого-то репозитория.

Для интеграции с IDE в Gradle есть два встроенных плагина для Visual Studio и XCode. Они хорошо работают, за исключением того что Visual Studio плагин игнорирует код юнит тестов из папки src/test/cpp и генерирует проект только для основного кода.

Теперь пришло время поговорить об IDE и о том как подружить их с Gradle


Eclipse CDT (2018-12R) — зрелый и качественный продукт. Если ему удалось успешно пропарсить Ваш проект, значит Вам повезло — редактировать будет комфортно. Скорее всего он даже «поймет» самые замороченные типы auto. Но если нет… Тогда он будет яростно подчеркивать красным пунктиром все подряд и ругаться нехорошими словами. Например, он не переваривает стандартные заголовочные файлы MSVC и Windows SDK. Даже вполне безобидный printf подчеркивается красным пунктиром и не воспринимается как нечто осмысленное. Там же оказался и std::string. Под Linux с родным ему gcc все замечательно. Но даже при попытке заставить его индексировать проект из родственного Android Native начались проблемы. В заголовках bionic он в упор отказывался видеть определение size_t, а заодно и всех функций которые его использовали. Наверное, под Windows можно исправить ситуацию если вместо заголовочных файлов Microsoft подсунуть ему, например, Cygwin или MinGW SDK, но мне такие фокусы не очень интересны, мне бы все же хотелось чтобы софт такого уровня «кушал то что дают», а не только то что он «любит».
Возможности по навигации, рефакторингу и генерации шаблонного кода замечательные, но вот к помощнику при наборе букв есть вопросы: допустим набираем несколько символов из какого-то длиннющего имени, почему бы не предложить варианты завершения? Нет, помощник терпеливо дожидается пока пользователь доберется до. или -> или ::. Приходится постоянно нажимать Ctrl + Space — раздражает. В Java эту досадную недоделку можно было исправить выбрав в качестве триггера весь алфавит в CDT же я не нашел простого решения.





NetBeans 8.1/10.0 — доводилось пользоваться этим IDE для Java, запомнился как неплохой и легковесный софт со всем необходимым функционалом. Для C++ у него есть плагин разработанный не сообществом, а непосредственно NetBeans. Для C++ проектов существует довольная жесткая зависимость на make и gcc. Редактор кода неторопливый. В генераторе шаблонного кода не нашел очень простую вещь: добавляем новый метод в заголовочном файле класса — нужно сгенерировать тело метода в cpp файле — не умеет. Степень «понимания» кода средняя, вроде бы что-то парсит, а что-то нет. Например, итерирование по мапе с автоитератором для него уже сложновато. На макросы из Google Test ругается. Закастомизировать билд команды проблематично — на Linux при доступном gcc и make (это при том что используется уже другая билд система) сработает, на Windows потребует MinGW, но даже при его наличии откажется построить. В целом работа в NetBeans с C++ возможна, но комфортной я бы ее не назвал, наверное, надо очень любить эту среду, чтобы не замечать разные ее болячки.





KDevelop 5.3.1 — когда-то задумывался как инструмент разработчика для KDE (Linux), но сейчас есть версия и под Windows. Имеет быстрый и приятный редактор кода с красивой подсветкой синтаксиса (основан на Kate). Закостомизировать левую билд систему не получится — для него основная система сборки CMake. Толерантно относится к MSVC и Windows SDK заголовкам, во всяком случае printf и std::string точно не приводят его в ступор как Eclipse CDT. Очень шустрый помощник по написанию кода — хорошие варианты завершения предлагает почти сразу во время набора текста. Имеет интересную возможность по генерации шаблонного кода: можно написать свой шаблон и выложить его онлайн. При создании по шаблону можно подключиться к базе данных готовых шаблонов и загрузить понравившийся. Единственное что расстроило: встроенный шаблон по созданию нового класса криво работает как под Windows так и под Linux. Wizard-а по созданию класса имеет несколько окон, в которым можно много чего настроить: какие конструкторы нужны, какие члены класса и т.д. Но на финальной стадии под Windows выскакивает какая-то ошибка успеть разглядеть текст которой невозможно и создаются два файла h и cpp размером 1 байт. В Linux почему-то нельзя выбрать конструкторы — вкладка пустая, а на выходе корректно генерится только заголовочный файл. В общем-то, детские болезни для такого зрелого продукта смотрятся как-то несерьезно.





QtCreator 4.8.1 (open source edition) — наверное, услышав это название, Вы недоумеваете, как сюда затесался этот монстр заточенный под Qt с дистрибутивом в гигабайт с гаком. Но речь идет о «легкой» версии среды для generic проектов. Его дистрибутив весит всего около 150 Мб и не тащит с собой вещи специфичные для Qt: download.qt.io/official_releases/qtcreator/4.8.
Собственно, он умеет делать почти все, о чем я написал в своих требованиях, быстро и корректно. Он парсит стандартные заголовки как Windows так и Linux, кастомизируется под любую билд систему, подсказывает варианты завершения, удобно генерит новый классы, тела методов, позволяет выполнять рефакторинг и навигацию по коду. Если хочется просто комфортно работать, не думая постоянно о том, как побороть ту или иную проблему есть смысл присмотреться к QtCreator-у.





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

Для этой цели мной был написан плагин для Gradle `cpp-ide-generator` и опубликован на Gradle Plugin Portal.

Плагин может использоваться только совместно с `cpp-application`, `cpp-library` и `cpp-unit-test`.
Вот пример его использования в build.gradle:

    plugins {
        id ‘cpp-library’
        id ‘maven-publish’
        id ‘cpp-unit-test’
        id ‘org.bitbucket.akornilov.cpp-ide-generator’ version ‘0.3’
    }

    library {
          // Library specific parameters
    }

    // Configuration block of plugin:
    ide {
        autoGenerate = false
        eclipse = true
        qtCreator = true
        netBeans = true
        kdevelop = true
    }

Плагин поддерживает интеграцию со всеми вышеперечисленными графическими средами разработки, но в конфигурационном блоке плагина — ide можно отключить поддержку ненужных IDE:

    kdevelop = false

Если параметр autoGenerate выставлен в true, проектные файлы для всех разрешенных IDE будут автоматически генерироваться прямо во время билда. Также в режиме автоматической генерации проектные файлы будут удаляться при очистке билда: gradle clean.

Поддерживается инкрементальная генерация, т.е. обновляться будут только те файлы, которые требуют реального обновления.

Вот список целей, которые добавляет плагин:

  • generateIde — сгенерировать проектные файлы для всех разрешенных IDE.
  • cleanIde — удалить проектные файлы для всех разрешенных IDE.
  • generateIde[имя] — сгенерировать проектные файлы для IDE с заданным именем (IDE должно быть разрешено), например generateIdeQtCreator.
  • Доступные имена: Eclipse, NetBeans, QtCreator, KDevelop.
  • cleanIde[имя] — удалить проектные файлы для IDE с заданным именем, например cleanIdeQtCreator.

Во время генерации плагин «обнюхивает» билд и извлекает из него всю необходимую информацию для создания проектных файлов. После открытия проекта в IDE должны быть видны все исходные файлы, прописаны пути ко всем хидерам, а так же настроены базовые билд комманды — построить/очистить.

Второй плагин, который мне пришлось сделать, называется `cpp-build-tuner` и он также работает в паре с cpp-application`, `cpp-library` и `cpp-unit-test`.

У плагина нет никаких настроек, его достаточно просто зааплаить:

    plugins {
        id ‘cpp-library’
        id ‘maven-publish’
        id ‘cpp-unit-test’
        id ‘org.bitbucket.akornilov.cpp-build-tuner’ version ‘0.5’
    }

Плагин выполняет небольшие манипуляции с настройками тулчейнов (компилятора и линковщика) для разных вариантов билда — Debug и Release. Поддерживаются MSVC, gcc, CLang.

Особенно это актуально для MSVC, потому что по умолчанию в результате релизного билда Вы получите «жирный», не эстетичный бинарь с дебажной информацией и статически прилинкованной стандартной библиотекой. Часть настроек для MSVC я «подсмотрел» в самой Visual Studio, которые по дефолту он добавляет в свои C++ проекты. Как для gcc/CLang так и для MSVC в профиле Release включаются link time optmizations.

Заметка: Плагины проверялись с последней версией Gradle v5.2.1 и не тестировались на совместимость с предыдущими версиями.

Исходные коды плагинов, а так же простенькие примеры использования Gradle для библиотек: статических и динамических, а так же приложения, которое их использует можно посмотреть: bitbucket.org/akornilov/tools дальше gradle/cpp.

Так же в примерах показано, как пользоваться Google Test для юнит тестирования библиотек.

Maven Repository с простроенной в Gradle Google Test v1.8.1 (без mock).

Комментарии (94)


  1. nekipelov
    05.03.2019 17:35
    +7

    CMake — [средневековье] первая попытка уйти от низкоуровневых деталей make-а.

    Зря вы, не разобравшись, списываете удобный инструмент.


    Такой подход напоминает мне красивый фасад старого деревянного дома, который заботливо обшили свежим пластиком.
    И все это следствия чуток кривоватой архитектуры, когда основная часть работы выполняется другими «помощниками».

    Это называется unix-way: "Write programs that do one thing and do it well.". Cmake — это генератор. И у него хорошо это получается. Отслеживание зависимостей хорошо получается у make/ninja и других инструментов.


    Под Linux все вроде бы хорошо, но если нужно построить тот же проект под Windows с помощью MSVC — а я предпочитаю нативный компилятор MinGW-шному, будут сгенерированы файлы для NMake

    Cmake умеет генерировать не только nmake/make, но и проекты для MSVC (https://cmake.org/cmake/help/v3.12/manual/cmake-generators.7.html). Как-то так: cmake -G "Visual Studio 15"


    1. bigfatbrowncat
      05.03.2019 20:12

      Добавлю от себя, что на сегодняшний день CMake — единственный инструмент, который позволит вам написанием единственного билд-скрипта поддержать:

      1. Windows + MSVC + Visual Studio
      2. MacOS + Clang + XCode
      3. Linux/MSYS + gnu toolchain (включая make) + (подставьте любую IDE, кроме перечисленных)
      4. Какую-нибудь ninja или nmake — там есть и такие генераторы для любителей чего-то необычного

      Во всех трех случаях, конечно, будут небольшие особенности (например, поддержка Debug/Release в MSBuild сделана не так, как у остальных), но все эти проекты будут успешно и совершенно одинаково собираться, одним и тем же способом тащить завиимости, запускаться и отлаживаться.

      IMHO, если вы разрабатываете кросс-платформенный проект на C++, то на данный момент альтернатив CMake просто не существует.


      1. Filippok
        05.03.2019 20:26

        то на данный момент альтернатив CMake просто не существует

        Да их полно. premake например. Если говорить не о генераторах, а о нормальных билд системах — jam, fastbuild. Список можно продолжать до бесконечности. Свет клином не сошелся на этом вашем CMake.


        1. kosmonaFFFt
          05.03.2019 20:33

          jam это который в Boost? Или есть еще какой-то с таким именем?



        1. bigfatbrowncat
          05.03.2019 21:23

          >Если говорить не о генераторах, а о нормальных билд системах
          Смысл моего комментария состоял в том, что CMake — это именно генератор. И его основной смысл именно в этом. Билд-систем — завались. А вот сделать проект так, чтобы можно было его девелопить откуда попало можно только на CMake


          1. Filippok
            05.03.2019 21:43

            premake

            meson генерит ninja файлы.
            fastbuild тоже умеет генерить всякие солюшны.


            Я же говорю — альтернатив полно.


          1. akornilov Автор
            06.03.2019 12:25
            -1

            Не только :)


        1. 0xd34df00d
          06.03.2019 02:03

          Find-модуль для любой мало-мальски популярной библиотеки для cmake легко найти. Как у остальных систем с этим?


        1. Cfyz
          06.03.2019 12:24

          Мне нравился premake где-то лет пять тому назад, но с тех CMake стал чуть не стандартом де-факто (кого чаще всего видно в корне репозитория?), а premake до сих пор так и не вылез из состояния «вот-вот будет готово».

          У CMake при всех его недостатках есть одно огромное преимущество — популярность. Теперь остальным инструментам недостаточно быть хорошими, придется предложить прямо какую-то киллер-фичу. А до тех пор люди будут готовы потерпеть синтаксис CMake ради того, чтобы проект в два щелчка открывался во всех популярных IDE на всех популярных ОС.


      1. Ivaneo
        05.03.2019 23:55

        на данный момент альтернатив CMake просто не существует.

        Возможно Вам стоит взглянуть на Sharpmake, продукт написанный и используемый внутри Ubisoft, недавно был опубликован на github. Не знаю можно ли тут выкладывать ссылку, легко гуглится. Хоть это и урезанная версия, например не содержит готовых настроек для консолей, но это из-за требований first party, что в прочем не мешает вам их добавить. В целом позволяет очень быстро генерировать огромные проекты под Visual Studio, XCode или makefile's, а главное очень гибкая и простая настройка т.к. все написано на C#, вы можете включить в генератор абсолютно любую логику, платформы и сборки.
        Например на проекте в несколько миллионов строк кода, над которым я сейчас работаю, Sharpmake генерирует solution для Visual Studio под 5 различных платформ, debug|release|profile|retail + blob + fastbuild меньше чем за минуту на 8ми ядерном процессоре.


      1. akornilov Автор
        06.03.2019 12:24

        По первым трем пунктам Gradle вполне себе альтернатива — он все этом может.
        А четвертый пункт для него не актуален т.к. он прдставлет собой полноценную билд систему, а не генератор.


        1. bigfatbrowncat
          06.03.2019 14:19

          А как открыть Gradle проект в Visual Studio?
          А у Gradle есть fallback вида «сгенерим makefile, чтобы в [idename], которая его не поддерживает можно было девелопить»?


          1. akornilov Автор
            06.03.2019 14:29
            +1

            С Visual Studio и XCode у него прекрасная встроенна интеграция:

            Нужно добавить в билд скрипт плагин:

            plugins {
                id 'visual-studio'
            }
            


            А затем сгенерировать проектные файлы: gradle visualStudio

            Получите готовый проект, который сразу же настроен под простройку gradle-ом.


      1. vyo
        06.03.2019 15:31

        Ещё забыли CMake в андроид проектах для C/C++ кода.
        Был очень рад, когда `ndk-build` стало наконец можно выкинуть куда подальше и поддерживать весь список файлов/зависимостей/флагов/прочего в одном месте.


    1. akornilov Автор
      06.03.2019 12:21

      Зря вы, не разобравшись, списываете удобный инструмент.

      Ну почему же не разобравшись? :) Не могу назвать себя продвинутым пользователем CMake, но писать несложные билд скрипты, а тем более пользоваться доводилось.
      Просто те недостатки, которые, на мой взгляд, присущи CMake перевесили для меня его плюсы.

      Это называется unix-way: «Write programs that do one thing and do it well.». Cmake — это генератор. И у него хорошо это получается. Отслеживание зависимостей хорошо получается у make/ninja и других инструментов.

      Я ничего не имею против unix-way, но если мы говорим о системе сборки в целом, проектное решение в котором основную работу будет выполнять сторонняя тулза — мне несимпатично. Это жесткая зависисмоть на компонент, который развивается неазвисимо и поддерживается другой командой разработчиков. Такой подход делает архитектуру негибкой и в перспективе может тормозить развите проекта.
      Никто не мешает внутри билд системы разбить ее на компоненты, каждый из которых будет хорошо выполнять свою работу, только разработчики всегда смогут договориться о взаимодействии компонентов внутри системы.

      Cmake умеет генерировать не только nmake/make, но и проекты для MSVC (https://cmake.org/cmake/help/v3.12/manual/cmake-generators.7.html). Как-то так: cmake -G «Visual Studio 15»

      Верно. Но строить здесь надо либо из самой IDE либо msbuild <имя проектного файла>. Снова зависимость на новую тулзу, снова другая команда для построение и снова это следствия архитектуры CMake.


  1. augorelov
    05.03.2019 18:18
    +1

    на Windows потребует MinGW, но даже при его наличии откажется построить.

    Вы просто не умеете его готовить.


    1. akornilov Автор
      06.03.2019 12:28

      Умею — кухня там довольно примитивная :) если сможете сконфигурировать NetBeans под Windows чтобы он не требовал MinGW и билдил проект произвольными командами — например, gradle assemble — расскажите обязательно, добавлю в плагин :)


      1. ex3ger
        07.03.2019 12:40

        без MinGW — можно указать путь к своему любимому tool collection:
        image
        билд проекта произвольными командами:
        image

        А еще у NetBeans killer feature — это кроссплатформенная удаленная разработка, то есть можно девелопить из любой хостовой ОС на удаленной машине с любой ОС лишь бы по ssh можно было достучаться.

        P.S. картинки из интернета. Поверьте, MinGW и qmake тут совсем не обязательны.


        1. akornilov Автор
          07.03.2019 12:49

          А вот вам картинки не из интерента, а реальные :)

          Прописываем команды gradle:

          Это прекрасно работает на Linux.

          Запускаем на Windows и видим:


          Это при том что MinGW видится как доступный тулчейн:


          Уточню что sh и bash доступны через PATH — из комплекта Виндового GIT-а.

          Только спрашивается зачем NetBeans какие-то еще тулзы когда я уже явно указал ему что нужно запустить для постройки и очистки?

          Подозреваю, что проблема вот в этом:


          Вероятно, он зачем-то пытается еще выполнить какую-то, никому не нужную компиляцию проекта. Потому что если убрать эти дефолтные команды или изменить на gradle compileDebug он вообще отказываается строить даже под Linux.


          1. ex3ger
            07.03.2019 17:48

            К сожалению, не имею опыта с gradle… Могу попробовать заставить его работать, если приведете ссылку на какой-нибудь «hello world» проект с инструкцией как его собрать из command line, я еще не встречал проект, который не собирался бы из NetBeans (challenge accepted). Это довольно мощный инструмент, изменить компилятор и команду сборки не должно быть проблемой, хотя я и не отрицаю возможных ограничений под Win.


            1. akornilov Автор
              07.03.2019 18:29

              Не возражаете если приведу проект «hello world» прямо здесь?

              Это всего два файла будет:

              build.gradle (в корневой папке):

              plugins {
                  id 'cpp-application'
              }
              

              и

              src/main/cpp/main.cpp:
              #include <stdio.h>
              
              int main(void) {
                  printf("Hello, world!\n");
                  return 0;
              }


              Нужно установить последнюю версию gradle (v5.2.1): gradle.org/install

              Билдить из корневой папки (там где build.gradle):
              Debug: gradle assemble
              Release: gradle assembleRelease


  1. domix32
    05.03.2019 18:21

    Вот неплох Qt Creator, но настроить в нем работающий кит дикая проблема. То cmake подвисает, то ABI умудряется путать, то папку сборки наглухо отказывается перекэшировать под новый вариант сборки. Но если удалось можно радоваться.
    Не увидел VS Code в качестве кандидатов в IDE.


    1. akornilov Автор
      06.03.2019 12:32

      Вы, навреное, все-таки говорите о полноценной версии Qt Creator-а для Qt проектов.
      В моем случае я говорил именно о типе проекта generic + Gradle в качестве билд системы (кастомные шаги для построения проекта) — там кит не нужен.

      С VS Code незнаком — посмотрю, спасибо.


      1. domix32
        07.03.2019 01:11

        Не, с Qt в QtCreator проблем нет совсем. Оно спокойно ставится встроенными средствами и работает почти из коробки.
        А вот попытка работать с Cmake проектом на Windows — тот еще квест. Даже однажды корректно заведеный кит не гарантируют его работу на соседне проекте.
        Под линукс были проблемы с переключениями типов сборок и перекэшированием файлов проекта, поэтому иногда приходилось чистить папку сборки. Плюс настройки флагов cmake непонятно по каким правилам обновляются. В четвертой версии поддержку улучшили, но иногда моменты все же всплывают. А так пожалуй лучший из IDE которым доводилось пользоваться. CLion только у коллеги в пользовании видел и он как и прочие Idea IDE был довольно неповоротлив и тоже не имел какой-то фишки. Не то определения не мог скрафтить, не то какие-то базовые операции со строками не осиливал. Сейчас уже не вспомню.
        Градлу так или иначе нужно указать какой компилятор использовать из списка уже установленных. Да и возможно дебаггер прикрутить. Так что считай тоже кит настроить.


        1. akornilov Автор
          07.03.2019 11:35

          Градлу так или иначе нужно указать какой компилятор использовать из списка уже установленных

          Он берет одну из доступных тулчейнов по каким-то своим приоритетам, если хочется указать конкретную, нужно прописать это в билд.


    1. NickSin
      06.03.2019 13:03
      +1

      Не увидел VS Code в качестве кандидатов в IDE.

      Возможно потому, что это не IDE, а текстовый редактор с поддержкой подсветки синтаксиса и плагинов.


      1. snizovtsev
        06.03.2019 13:22

        И там среди "плагинов" есть кросс-платформенный билд майкрософтовского проприетарного IntelliSense в виде Language Server-а (который их изобретение, и туда лучше всех интегрирован). Пытался его прикрутить к Vim, но оказалось проще взять cquery. Современные "текстовые редакторы с плагинами" вполне себе конкурируют с IDE, разница только в сложности настройки и повышенных глюках. На Emacs, например, раньше был (ныне заброшенный) Semantic, многих его фич не видел в IDE.


        1. NickSin
          06.03.2019 14:30
          +1

          А зачем прикручивать плагин от МС куда-то еще, если оно изначально заточено под одно ПО? Используйте другие аналоги: cquery, clangd и т.д.
          Они конечно конкурируют, но в плане написания кода, когда дело доходит до отладки или анализа производительно — простых плагинов в редакторе будет не достаточно.


          1. snizovtsev
            06.03.2019 15:10

            Да посмотреть, вдруг оно будет лучше этих. Протокол то типа универсальный (хотя TypeScript в стандарте намекает).
            Увы, инструменты IDE работают только в очень простых и типовых случаях. Вот взять профайлинг через perf в CLion. Он заточен под локальный запуск бинаря. А на практике мне было нужно профайлить запуски на сотнях машин с внешним шедулером и большими данными, а потом аггрегировать результат и рисовать картинку. Ещё, наверняка, и опции кастомные подбирал под задачу.
            Взять отладку. В IDE никакой автоматизации обычно не наблюдал, хотя gdb отлично скриптуется. На практике я к gdb писал плагин, сокращающий излишние неймсейсы проекта, чтобы backtrace был читабельным.
            Кмк, главная проблема IDE — она не мотивирует к изучению инструментов, которые лежат под ней, что потом выливается в потерю времени от неумения автоматизировать отладку/профайлинг. Вторая проблема — неприятный высокий input lag, но я давно смотрел.


  1. berez
    05.03.2019 18:26
    +1

    Существуют некие современные «заменители» make-а: типа ninja и jam, но сути они не меняют — это очень низкоуровневые инструменты.

    Самый главный заменитель make'а — это, наверное, все-таки gmake (GNU make). И я бы не сказал, что он уж очень низкоуровневый. На нем много чего хитрого наваять можно.
    Ninja — это вообще промежуточная система сборки. Где-то читал, что автор рассчитывал в основном на генерируемые файлы сборки, а не на писанные вручную.

    CMake — [средневековье] первая попытка уйти от низкоуровневых деталей make-а.

    Они вроде как со SCons'ом появились почти ноздря в ноздрю.

    Но, к сожалению, далеко уйти не удалось — движком здесь служит все тот же make для которого CMake генерирует огромные make-файлы на основе другого текстового файла с более выскоуровневым описанием билда.

    Вовсе не обязательно. CMake может генерировать файлы под довольно широкий спектр сборочных систем — включая майкрософтовский MSBuild, майкрософтовский же nmake, ту же ninja и еще много подо что.
    Основное преимущество CMake в том, что он позволяет выжать из нативной системы сборки все возможное (ну, по мере сил), но при этом не заморачиваться с ее тонкостями.
    Из недостатков CMake — убогий удивительный язык описания билда, довольно многословный и местами неочевидный.

    SCons — [новые времена] самодостаточная, кросплатформенная билд система, написанная на Python. SCons одинаково хорошо справляется как с Java так и с C++ билдами. Зависимости хидеров для инкрементальной сборки отрабатываются корректно (насколько я понял создается некая база данных с метаданными билда), а на Windows «без бубна» работает MSVC.

    У SCons ранних версий были проблемы с производительностью. Авторы захотели «надежно» отслеживать изменения файлов, поэтому вместо проверки даты-времени последней модификации они сравнивали хэш первых нескольких килобайт файла (ЕМНИП, первых двух или четырех). Потом, слава аллаху, сделали этот режим опциональным.
    А еще у SCons, когда я его использовал, были нетривиальные требования к версии питона. С 3-й версией он вываливался с ошибкой, да и вторая подходила далеко не всякая.

    Gradle [современность] — у меня уже был позитивный опыт использования Gradle для Java и Kotlin проектов и я возлагал на него большие надежды.

    Т. е. в итоге вы остановились на том, с чем уже успешно работали. Ожидаемо, но хотелось бы увидеть сравнение билд-систем немного пошире и поглубже. :)

    Как оказалось, в Gradle пошли дальше и реализовали возможность выкладывать C++ артефакты в Maven Repository!

    Это здорово, если человек знаком с java и maven. А если у меня кровавый энтерпрайз, JRE на машине не установлен, никакого maven и в помине нет (зато есть subversion) — насколько мне поможет gradle?

    Естественно, что всю низкоуровневую работу по конфигурированию компилятора и линковщика для работы с внешним компонентом Gradle берет на себя. Вам достаточно заявить о своих намерениях использовать такую-то библиотеку с такой-то версией из такого-то репозитория.

    А если его понятия о том, с какими опциями собирать проект, не совпадают с корпоративными? Насколько сложно поменять опции компилятора и линкера?

    Особенно это актуально для MSVC потому что по умолчанию в результате релизного билда Вы получите «жирный», не эстетичный бинарь с дебажной информацией и статически прилинкованной стандартной библиотекой.

    Ну, статически прилинкованная стандартная библиотека не так уж жирна по нынешним меркам. Сколько там — килобайт двести? Это ж ни о чем. :)
    Гораздо страшнее то, что в большинстве сторонних библиотек стандартная библиотека прилинкована динамически. В результате при попытке все собрать до кучи вылезает длинная простыня маловразумительных ошибок линкера.

    Кстати, а как насчет сборки инсталляторов под винду и готовых пакетов (rpm, deb, etc) под линукс? В CMake что-то такое есть, но пощупать нормально так и не удалось.


    1. MechanicZelenyy
      05.03.2019 18:51

      Я не автор, но постараюсь ответить, поскольку сам в последнее время думаю о переходе с cmake на gradle.

      Это здорово, если человек знаком с java и maven. А если у меня кровавый энтерпрайз, JRE на машине не установлен, никакого maven и в помине нет (зато есть subversion) — насколько мне поможет gradle?


      Он умеет собирать из исходников и из удаленных репозиториев (по крайней мере git), выбор автором maven репозиториев обусловлен я думаю не в последнюю очередь м что для cpp не каких общепринятых репозиториев, кроме репозиториев от майнтенеров *nix ОС.


      1. akornilov Автор
        06.03.2019 13:28

        Совершенно верно.


    1. akornilov Автор
      06.03.2019 13:27

      Т. е. в итоге вы остановились на том, с чем уже успешно работали.

      Не совсем. С make я знаком гораздо глубже чем мне самому хотелось бы :) доводилось писать на нем целую билд систему, состоящую из «модулей» подключаемых через include. Это был монстр, но работал исправно, хотя поддерживать его было затратно.
      Наверное, именно поэтому я так обрадовался возможностям Gradle, когда с билдом можно «разговаривать» на более высоком уровне :)

      Ожидаемо, но хотелось бы увидеть сравнение билд-систем немного пошире и поглубже. :)

      Ну по билд системам можно и диссертацию написать при желании :) у меня же цель чисто в практической плоскости.

      Это здорово, если человек знаком с java и maven. А если у меня кровавый энтерпрайз, JRE на машине не установлен, никакого maven и в помине нет (зато есть subversion) — насколько мне поможет gradle?

      Вам достаточно поставить только JDK, остальное Gradle подтянет из сети при необходимости. Maven ставить не нужно, это просто тип репозитория. На локальном диске это обычная папка в которой лежат бинари с описаниями (версий, платформа и т.д.).
      Локальный Maven репозиторий обычно создается в /.m2.
      Вы можете сделать публиуацию в локальный репозиторий и посмотреть как это выглядит. Также можно тянуть билдовые зависимости из локальной репы.

      А если его понятия о том, с какими опциями собирать проект, не совпадают с корпоративными? Насколько сложно поменять опции компилятора и линкера?

      Самый простой способ поменять их прямо в билд скрипте (3-4 строчки).
      Но правильный путь, на мой взгляд, написать плагин и использовать его во всех билд скриптах — усилий чуток побольше — зато, при необходимости что-то поменять в глобальных политиках нужно будет поправить только плагин.

      Кстати, а как насчет сборки инсталляторов под винду и готовых пакетов (rpm, deb, etc) под линукс? В CMake что-то такое есть, но пощупать нормально так и не удалось.

      Есть два плагина:
      1) plugins.gradle.org/plugin/nebula.deb умеет собирать DEB и RPM
      2) plugins.gradle.org/plugin/de.inetsoftware.setupbuilder а этот еще MSI под Винду
      Но попробовать еще руки не дошли.


  1. DmitryKoterov
    05.03.2019 18:40

    Что-тотвы buck и clion даже не упомянули.


    1. akornilov Автор
      06.03.2019 12:36
      -1

      CLion — платная, там вроде бы нет Community версии, но, наверное, хороша — ребята из JetBrains молодцы.

      С Buck незнаком.

      Вообще вариантов много еще можно найти. Помню когда-то любил кодить в SourceInsight, в Linux даже под wine запускал его :)
      CodeBlocks
      Geany,
      Sublimate
      и т.д.
      Но мне пока что QtCreator понравился :)


      1. ak47cccp
        06.03.2019 17:12
        +1

        CLion поддерживает только CMake сборщик. Т.е. даже makefile не поддерживает, что делает его неудобным при работе с каким-нибудь уже готовым opensource проектом. Даже с CMake у него не все гладко (Давно попробовал открыть в нем базовый репо OpenCV — впечатления плохие остались). В общем очень странна такая его ограниченность, хотя я сам люблю другие продукты от jetbrains)


        1. 0xd34df00d
          06.03.2019 17:55

          Глаже всего в CMake вообще было у KDevelop.

          Но у меня своя атмосфера и свои требования — проект с парой сотен таргетов-бинарников (много плагинов) и ещё с примерно тысячей таргетов типа «перегенерировать переводы». В KDevelop работа с такими проектами отлично сделана, можно собирать несколько таргетов сразу подряд, и всё такое. В CLion хуже, но можно относительно легко между ними переключаться. В QtCreator вообще ад, ибо предлагается идти на страницу настроек проекта и руками вбивать там таргет, когда надо его переключить.


        1. Ryppka
          07.03.2019 20:02

          Makefile'ы он прекрасно поддерживает с помощью плагина: прекрасно armcc собираю проекты, gcc параллельно на CMake. По поддержке очень больших и хитровымученных кодовых баз CLion уступает QtCreator'у, но последний заметно отстает по анализу кода и навигации. Это исправляется со временем, но пока желания пересесть нет.


  1. snizovtsev
    05.03.2019 20:04
    +2

    Популярные в опенсорс meson и autotools не рассмотрели. Популярные у корпораций bazel/buck/pants не рассмотрели. Лидер по IDE CLion не рассмотрели. Популярные у гиков Vim/Emacs/VSCode с YCM или LSP тоже обошли стороной.


    1. akornilov Автор
      06.03.2019 12:43

      Дело в том, что я не ставил целью исследовать все существующие в природе IDE, у меня к ним интерес чисто практический.

      autotools — я не знаю, что именно курили ребята, когда работали над этой тулзой, но садистскими наклонностями они явно обладали :)
      Если серьезно, то autotools опали мгновенно по требованию «кросплатформенность», но даже если бы существовал порт на Windows я бы ни в коем случае не использовал этот тихий ужас :)


  1. opaopa
    05.03.2019 20:06

    automake?
    Даже гибче cmake, имхо, а делает то же: генерирует универсальный Makefile.


    1. bigfatbrowncat
      05.03.2019 20:13
      +1

      CMake делает не «универсальный makefile», а полноценный файл проекта для любой популярной IDE. Я выше уже написал…


    1. berez
      06.03.2019 09:26

      У automake есть пара фатальных недостатков. :)
      Во-первых, не кроссплатформенный: заставить его работать под виндой — это тот еще квест.
      Во-вторых, сборка плохо параллелится: максимальная единица сборки — это подкаталог. Т. е. пока все файлы в подкаталоге не соберутся, сборка дальше не пойдет. Если в проекте множество мелких подкаталогов, теряются преимущества параллельной сборки.

      Помнится, делал бенчмарки по сборке одного и того же проекта тремя системами: automake, scons и cmake. Билд-сервер был многоядерный (ЕМНИП 32 ядра), но сами ядра — не очень быстрые. Так что преимущества параллельной сборки были очень видны. Подкаталогов было не очень много (с десяток; в основном там собирались статические библиотеки). Результаты были такие:
      — хуже всех — Automake. За счет того, что каждый подкаталог собирается отдельно, приходилось ждать, пока в каждом подкаталоге соберутся все исходники и слинкуются в библиотеку.
      — второй по скорости — CMake (генерировались UNIX Makefiles). На «холодном старте» он проигрывал SCons из-за наличия фазы проверки системы и генерации мейкфайлов. Но и при пересборке проекта из-за пары изменившихся файлов он на пару-тройку процентов проигрывал SCons. Подозреваю, что это из-за ставшего слишком хитромудрым GNU make, который на каждое правило проверяет по десятку файлов.
      — Лидером стал SCons. Помню, меня это тогда весьма удивило, потому как в то время на каждом углу писали, что scons очень медленный.


  1. kosmonaFFFt
    05.03.2019 20:31

    Для C++ проектов существует довольная жесткая зависимость на make и gcc.

    NetBeans при настройке проекта с существующими исходниками позволяет указать как генерировать сборочный скрипт (CMake или autotools например), где и как собирать (хоть make, хоть ninja), что получается в результате сборки и как это запускать (например экзешник или тесты, или можно заливку в контроллер какой-нибудь задать например).
    В плане парсера кода у него все более-менее нормально, но на каком-нибудь Boost Spirit парсер может не выдержать и тихо уйти в сторону.


  1. MechanicZelenyy
    05.03.2019 21:17

    Возможно автор поста подскажет, как закинуть плюсовый артифакт не в maven репозиторий, а в артифакторий JFrog?

    Если конкретнее, то меня инересует что надо написать в теле maven{}:
    publishing {
    publications {
    maven(MavenPublication) {
    }
    }
    }



    1. akornilov Автор
      06.03.2019 13:53

      Для публикации плюсового артефакта в локальную папку будет достаточно:

      plugins {
          id 'maven-publish'
      <..>
      }
      group = 'org.example.group'
      version = '1.0'
      publishing {
          repositories {
              maven {
                  url = "$buildDir/repo"
              }
          }
      }
      


      Если нужен удаленный репозиторий, тогда:
      publishing {
          repositories {
              maven {
                  url = "https://..." // Адрес удаленного репозитория
      
                  credentials {
                      username <имя юзера> // Эти данные желательно выносить в проперти файл, чтобы не светить в скрипте
                      password <пароль>
                  }
              }
          }
      }


      Если хочется добавить описание можно расширить:
      publishing {
          repositories {
              maven {
                  url = "https://..." // Адрес удаленного репозитория
      
                  credentials {
                      username <имя юзера> // Эти данные желательно выносить в проперти файл, чтобы не светить в скрипте
                      password <пароль>
                  }
              }
          }
      
          publications {
              maven(MavenPublication) {
                  artifactId = ''
      
                  pom {
                      name = ''
                      description = ''
                      url = ''
      
                      licenses {
                          license {
                              name = 'The Apache License, Version 2.0'
                              url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                          }
                      }
      
                      developers {
                          developer {
                              id = ''
                              name = ''
                              email = '
                          }
                      }
      
                      scm {
                          connection = ''
                          developerConnection = ''
                          url = ''
                      }
                  }
              }
          }
      }


      Если сервак требует подписанные артефакты, тогда нужен плагин:
      plugins {
          id 'maven-publish'
          id 'signing'
      }
      
      signing {
          sign publishing.publications.maven
      }
      

      Для подписи нужно будет создать ключ и сконфигурировать доступ к нему.


  1. kovserg
    05.03.2019 22:02

    Еще IDE codelite.org и пакетный менеджер conan.io ( docs.conan.io/en/latest/introduction.html#cross-platform-build-system-agnostic )

    ps: Хочется посмотреть как с помощью gradle подключается хотя бы libSDL2 с mixer,image,net,rtf, и ttf


    1. akornilov Автор
      06.03.2019 14:13

      К сожалению, на данный момент в Gradle нет плагина для интеграции с pkg-config. Но сделать такой плагин задача тривиальная.
      А вот как добавить libSDL2 в билд прямо в скрипте:

          binaries.configureEach {
              if (targetMachine.operatingSystemFamily.linux) {
                  compileTask.get().macros["_REENTRANT"] = "1"
                  compileTask.get().compilerArgs.add("-I/usr/include/SDL2")
                  linkTask.get().linkerArgs.add("-lSDL2")
              }
          }
      


      1. kovserg
        07.03.2019 08:20

        В линуксе-то всё гладко, а в винде?

        # sdl2-config --cflags
        -I/usr/local/include/SDL2 -D_REENTRANT
        # sdl2-config --static-libs
        -L/usr/local/lib -Wl,-rpath,/usr/local/lib -Wl,--enable-new-dtags -lSDL2 -Wl,--no-undefined -lm -ldl -lpthread -lrt

        SDL2 тянет за собой SDL2_image который тянет libjpeg,libpng,libtiff, SDL2_mixer который тянет libogg,libvorbis,mpg123,opus, SDL_rtf и SDL2_ttf тянет freetype не говоря уже о zlib и подобном.


        1. akornilov Автор
          07.03.2019 11:37

          В Винде пропишете эти флаги MinGW-шному компилятору в скрипте — принцип такой же как я написал выше.


          1. kovserg
            07.03.2019 14:22

            Я к тому что, в принципе можно собрать любой системой сборки. Но на практике с gradle возни будет ничуть не меньше.


            1. akornilov Автор
              07.03.2019 14:56

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


              1. kovserg
                07.03.2019 17:01
                +1

                Не знаю как у других, но у меня от gradle постоянно чувство что КПД этой вундервафли близко в 0. То что makefile собирает 10сек, gradle умудряется маслать минуты, причем в первые разы еще норовит пару гигабайт подсосать из интернетов.


                1. akornilov Автор
                  07.03.2019 17:29

                  По идее лишнего тянуть не дожен, а когда все билд зависимости разрешены и запущен билд-демон — должен строиться быстро.

                  На самом деле, сравнение тут не совсем корректно: make это довольно тупая тулза которая делает только финальную часть работы. А основную за нее проделали вы руками (написали make-файл, поставили dev пакеты и т.д.) или какой-нибудь CMake.
                  А gradle это полноценная билд система и ей нужно сделать много работы чтобы подготовить для вас готовый билд на основе простого и понятно скрипта.
                  Как по мне, так лучше один раз написать простейший скрипт для gradle и подождать первый раз пока все подтянется-простроиться, чем сидеть с красными глазами в безумных make файлах :)


  1. Inobelar
    05.03.2019 22:53
    -1

    Лихо Вы замахнулись! Чтобы билдить C++ (с шаблонами, например boost) — систему сборки на java (gradle) приплели. А ведь так можно забыть, как напрямую использовать gcc для компиляции, что есть компиляция и линковка, неговоря о makefile'ах и всё что выше их. Почитайте-ка suckless


    1. fRoStBiT
      06.03.2019 09:53

      Почитайте-ка suckless

      Этих ребят почитать — так вообще получается на C++ не надо писать. Только C. Для всего.


      использовать gcc
      makefile'ах и всё что выше их

      Почитайте-ка suckless


    1. akornilov Автор
      06.03.2019 12:51

      Лихо Вы замахнулись! Чтобы билдить C++ (с шаблонами, например boost) — систему сборки на java (gradle)

      По вашему выходит, что билдить C++ код можно только билд системой написанной на C++? :)

      А ведь так можно забыть, как напрямую использовать gcc для компиляции, что есть компиляция и линковка, неговоря о makefile'ах и всё что выше их.

      Система сборки и графическая среда разработки это всего лишь инструменты в арсенале разработчика. Перед основной работой есть смысл отобрать лучшие инструмены, разобраться как ими правильно и эффективно пользоваться, а потом можно и забыть некоторые несущественные детали и сосредоточиться на самой работе.

      Почитайте-ка suckless

      Давайте попробуем обойтись без повелительных наклонений :)


      1. Inobelar
        06.03.2019 23:10

        Прошу простить за характер комментария — писал "с пылу с жару". Проводя ретроспективу вижу проф. дефформацию — приходится писать код под пару плаформ — linux x86 + arm, windows, и эксперименты wasm для души, и под-тюнивать сборку под компилятор(ы), читать verbose вывод смотреть на во что разворачиваются плюсы и чего потом стоят, и забыл об удобстве инструментов и систем сборок.


        1. akornilov Автор
          07.03.2019 11:52

          Понимаю. У каждого проекта своя спицифика, каждый смортрит, так сказать, со своей колокольни.


  1. kaapython
    06.03.2019 07:42

    Самый доступный способ сделать так, что бы просто и без вопросов можно быть набирать код и отлаживаться на всех платформах (ну, в разумных пределах, но как минимум Linux+macOS+Windows) – это взять CLion. Он даст и интеграцию с CMake и очень хорошую поддержку C++. Не бесплатно, но мы вроде тоже не за интерес работаем.

    Отказываться от CMake очень неосмотрительно, так как он де-факто стандарт современной C++ разработки. В купе с тем же VCPKG можно очень быстро и просто подключить нужную библиотеку, обкатать идею, быстро и просто запустить юнит-тесты, подготовить бинарники к дальнейшей запаковки инсталлятором. Так же CMake позволит не думать об IDE в принципе, все возьмут то, к чему привыкли и будут работать. На всех платформах.


  1. ledocool
    06.03.2019 07:59

    В генераторе шаблонного кода не нашел очень простую вещь: добавляем новый метод в заголовочном файле класса — нужно сгенерировать тело метода в cpp файле — не умеет.
    не помню точно, базовая ли это функциональность, но выход есть. Заходим в cpp, жмем ctrl+space и в подсказках будет генерация тел первыми строками.


    1. akornilov Автор
      06.03.2019 12:52

      Ок, спасибо.


  1. jknight
    06.03.2019 08:41
    +1

    В этом посте нужна фотка про петуханов, нетбинс, и Kokoko.


    1. akornilov Автор
      06.03.2019 13:03

      Опубликуете в своем :)


  1. Temmokan
    06.03.2019 09:49

    Как водится, комментарии к статье не менее (а то и более) информативны, нежели сама статья. Вот что значит качественно задеть за живое.

    От себя ещё добавлю Code::Blocks, Anjuta.


    1. akornilov Автор
      06.03.2019 12:54

      Не было бы статьи — не было бы и коментариев :) каждый находит то что ищет.


    1. domix32
      06.03.2019 13:12

      Я все еще ниасилил настроить Code::Blocks, чтобы он мог компилить хоть что-то. Виндовым гайдом не поделитесь?


      1. Temmokan
        07.03.2019 07:38

        Не собираю из-под Windows. А что, тамошний FAQ совсем не соотносится с реальностью?


        1. domix32
          07.03.2019 21:43

          Честно говоря не читал FAQ. Залез в настройки, прописал пути к компиляторам, попытался собрать hello world, не собралось, пошаманил, погуглил, забил.
          Изначально хотел настроить SFML и собирать его из сорцов каким-то особенным компилятором. В то время он требовал какие-то определенные версии для сборки который не поставлялся с Code::Blocks и конфликтовал с уже поставленным MinGW. В общем забил на это грязное дело.


          1. Synoecium
            08.03.2019 09:19

            я кстати тоже игрался с SFML в CodeBlocks под Windows 7 и все получилось. Если интересует, можно списаться в личке.


      1. Synoecium
        07.03.2019 11:43

        а что там настраивать, все ставится из коробки, GCC идет в комплекте с CodeBlocks. Разве что в Path прописать путь к компилятору. А, еще один нюанс, рекомендую ставить в каталог, путь к которому состоит из латинских букв и не содержит пробелов. Видимо наследие тяжелого прошлого сказывается.


  1. abagnale
    06.03.2019 10:19

    Qt Creator [...] монстр, заточенный под Qt, с дистрибутивом в гигабайт с гаком
    Но речь идет о «легкой» версии среды для generic проектов. Его дистрибутив весит всего около 150 Мб и не тащит с собой вещи специфичные для Qt

    У Qt Creator нет «лёгкой» версии (и нет «тяжёлой» весом в гигабайт и специфичными вещами). Есть просто Qt Creator, который может использоваться для разработки как с Qt, так и с «generic».


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


    1. akornilov Автор
      06.03.2019 12:59

      Вот полная версия: www.qt.io/offline-installers — 1.4Gb
      Ссылка в статье на сам QtCreator без допов.


      1. abagnale
        06.03.2019 13:04

        Qt 5.12.1 for Linux 64-bit (1.4 GB)

        Вы про эту ссылку? Как я и сказал, это установщик самого Qt (который в своём составе содержит и Qt Creator), а вовсе не "полная версия" Qt Creator. У Qt Creator нет никаких "полных" или "лёгких" версий.


        Ссылки отдельно на Qt Creator, кстати, есть на этой же странице в соответствующей вкладке (на неё ссылку дать нельзя, к сожалению, потому что ребята из маркетинга и до этой страницы добрались со своими "оптимизациями").


        Ссылка в статье на сам QtCreator без допов

        Это не "допы", а сам Qt. И я в предыдущем комментарии тоже дал ссылки для загрузки только Qt Creator.


        1. akornilov Автор
          06.03.2019 13:29

          ок


  1. raiSadam
    06.03.2019 10:29
    +1

    CMake… Modern CMake… More Modern CMake, это понятия, появившиеся за последние 3 — 4 года (кроме самого понятия cmake, конечно). Работа в режиме сервера, интеграция с пакетными менеджерами, поддержка в качестве файлов проекта «из коробки» для топ C++ IDE (я имею ввиду CLion, QtCreator и MS Visual Studio). Ну не тянет как-то на сердневековье. Безусловно gradle хорош, но не думаю, что это первое, что нужно брать или советовать людям для написания C++ кода.


    1. akornilov Автор
      06.03.2019 13:02

      Я думаю возможности CMake уже и так достаточно хорошо известны, нет смысла писать об этом, а о Gradle в качестве билд системы для C++ не так много информации.
      В целом статья это скорее информация к размышлению, а не призыв к действию.


      1. raiSadam
        06.03.2019 13:09

        Ок, тогда было бы интересно почитать о «лучших практиках» применения gradle при сборке c++ проектов, например в ключе общего проекта в android приложении или что-то подобное.


        1. akornilov Автор
          06.03.2019 14:16

          А чем не устроили стандартные средства Android-а?
          «Лучшие практики», на мой взгляд, это использование бинарных артефакториев для C++ и gradle позволяет это сделать.


  1. at91sam7a3
    06.03.2019 15:26

    Статья пример того когда человек описывает сложные инструменты, не поработав с ними как следует (а судя по описанию CMake — даже не прочитав описание)


    1. akornilov Автор
      06.03.2019 15:39

      Хм… ну что тут скажешь? :) Обменяемся любезностями тогда: а вот это пример коментария когда человеку совершенно нечего сказать по сути, но очень хочется хоть что-то написать (судя по содержанию даже не прочитав статью). :)


      1. at91sam7a3
        06.03.2019 16:35
        -1

        Вы подняли очень больную тему, можно даже сказать — холиварную, и SCons у Вас описывается более современным и лучшим решением чем CMake. А теперь представьте, что у Вас большой тяжелый проект. Что выбрать — СMake, который можно по итогу открыть как проект тем же креатором, и распараллелить его сборку хоть через increadibuild, сделав студийный олюшен, хоть distCC, или тормозный питоновский SCons, который по факту недоразумение, о котором на родном сайте написано:
        When compared to scons, CMake is:
        Faster
        Requires less code for common tasks
        Arguably more stable
        Supports outputting to projects like Code::Blocks, Xcode, etc. which scons does not


        1. akornilov Автор
          06.03.2019 17:05

          Вот выше в коментариях человек проводил исследования по скорости разных билд систем:

          — хуже всех — Automake. За счет того, что каждый подкаталог собирается отдельно, приходилось ждать, пока в каждом подкаталоге соберутся все исходники и слинкуются в библиотеку.
          — второй по скорости — CMake (генерировались UNIX Makefiles). На «холодном старте» он проигрывал SCons из-за наличия фазы проверки системы и генерации мейкфайлов. Но и при пересборке проекта из-за пары изменившихся файлов он на пару-тройку процентов проигрывал SCons. Подозреваю, что это из-за ставшего слишком хитромудрым GNU make, который на каждое правило проверяет по десятку файлов.
          — Лидером стал SCons. Помню, меня это тогда весьма удивило, потому как в то время на каждом углу писали, что scons очень медленный.

          Как я уже написал в статье — я предпочитаю монолитную систему сборки, а не «генераторы», даже если они неплохо генерируют мегабайты makefiles-ов, поэтому SCons в моем личном рейтинге оказался выше CMake.
          Еще SCons, вроде бы, умеет кешировать собираемые файлы для ускорения параллельной сборки — подобно ccache, но для любых типов файлов.
          По моим личным впечатлениям я бы не назвал его тормозным или «недоразумением», на вики вон пишут что его VMware использует, но мож баян :)
          Но вот с интеграцией в IDE у него действительно все печально…
          Поэтому мне больше понравился gradle :)

          Ну вы бы хоть ссылку выкладывали или хотя бы цитировали целиком, а то выхватили из контекста только то что вам понравилось :)
          github.com/scons/scons/wiki/SconsVsOtherBuildTools

          CMake is a principal competitor to both GNU Autotools and SCons. It is a build system generator, i.e. after running CMake, the user has a native Visual Studio file at his disposal, or a native Makefile, or nmake file, or whatever their preference is. Off-the-shelf build capabilities are comprehensive and proven for large scale software development. The implementation architecture is far more unified than GNU Autotools and it runs much faster. CMake has its own scripting language that runs on all platforms that CMake targets. It is Yet Another Scripting Language, which puts some people off, but it has the advantage of not introducing any additional language dependencies to a project.

          When compared to scons, CMake is:

          • Faster
          • Requires less code for common tasks
          • Arguably more stable
          • Supports outputting to projects like Code::Blocks, Xcode, etc. which scons does not

          But:
          • Uses its own language, reinventing the wheel and not providing access to the extensibility and power of a real language.
          • Arguably not as extensible as scons
          • For terminal builds, still requires the use of 'make' (which, depending on your point of view, may or may not be a disadvantage) while scons is self-contained, all-in-one To sum up, my very subjective opinion is that scons is a better idea, but CMake has a stronger implementation


          1. at91sam7a3
            06.03.2019 18:31

            И вот снова Вы пишете про проблемы мейкфайлов.
            CMake — генератор хоть мейкфайлов, хоть солюшенов для вижуал студии, хоть проектов для XCode. Это тулза другого уровня. Не смешивайте генератор билдскриптов и сами билдскрипты.
            Мейк — это один конкретный частный случай. Мейк вообще может отсутствовать как шаг.
            For terminal builds, still requires the use of 'make' (which, depending on your point of view, may or may not be a disadvantage) — Неверно. В среде Microsoft Windows Вы можете сделать солюшен, и с консоли набрать devenv --build project.sln (ну как-то так) и проект соберется студийным тулчейном с nmake, например.
            Все эти вещи нужно проверять на больших проектах.
            2 моих последних проекта — на СMake и SCons. Первый 10 000 000 строк кода(собирается 2 часа), второй — на SCons. Размер не известен, но билдится 6 часов.
            В случае с первым работа тривиальна. Кто-то напрямую открывает Cmake как проект, кто-то экспортит в студию. В случа со вторым злые красноглазые разработчики педалят в notepad++, кто-то импортит проект в эклипс или вижуал студио код (или что еще умеет импортить папку) но всё равно не получает нормальной навигации по коду, билды запускаются из консоли а поиск ошибки это скроллинг длинного билдлога в поиске слова error. И весь бонус которые там есть, это какие-то захардкоженные в питон вещи, которые делают то, что могли бы делаться из простого батника.


            1. akornilov Автор
              06.03.2019 19:24

              И вот снова Вы пишете про проблемы мейкфайлов.

              Нет, я говорил только, что архитектура монолитной билд системы мне нравится больше нежели концепция «генераторов».
              Принцип работы CMake мне понятен, не расходуйте порох на объяснения :)

              Все эти вещи нужно проверять на больших проектах.

              Здравая мысль. Только кто ж захочет запилить огромный проект на две билд системы ради сравнения их производительности? Это попахивает большим количеством человекодней :)

              2 моих последних проекта — на СMake и SCons. Первый 10 000 000 строк кода(собирается 2 часа), второй — на SCons. Размер не известен, но билдится 6 часов.

              Такое сравнение, к сожалению, ни о чем. Если бы один и тот же проект в 10 000 000 строк билдился двумя разными системами и разница получилась бы в 4 часа, то это да, был бы серьезный косяк для SCons-а. При условии что тулчейн будет один и тот же.

              В случа со вторым злые красноглазые разработчики педалят в notepad++, кто-то импортит проект в эклипс или вижуал студио код (или что еще умеет импортить папку) но всё равно не получает нормальной навигации по коду, билды запускаются из консоли а поиск ошибки это скроллинг длинного билдлога в поиске слова error.

              Тут я с вами уже согласился — отсутсвие интеграции с IDE для SCons это серьезный недостаток.
              Хотя помню работали с одной платформой, натаянута она была на Linux, а все ее сервисы использовали некую вариацию IDL — файлы с описанием интерфесов. C++ код по этим файлам генерился прямо во время построения. В качестве билд системы там был как раз CMake — билдилось все хорошо, но вот проектные файлы для Eclipse он генерил какие-то кривые — возможно, это было связано с использованием этих IDL.


              1. at91sam7a3
                06.03.2019 23:43

                Добавлю ещё 5 копеек
                Перевод гигантских проектов с одной билд системы на другую, с сохранением параллельно старой и новой — довольно типичный случай, если вы аутсорсер портирующий какой-нибудь фотошоп с виндовса на линукс, и старый билд механизм будет жить до последнего, ведь кроме вас ещё кто-то работает над другими частями кода, но к сожалению scone->cmake ещё не делал, он как раз в процессе. Да и нередко выделяется время на оптимизацию времени сборки, которое впоследствии окупается. И именно портирование с Scons это большая боль. Потому что другие билд системы это обычно батник запускающий билд систему + до или после сопутствующие действия, типа цифровой подписи, упаковки в инсталлятор и т.п. и замена билдсистемы не влияет на весь процесс. Но в сконсе же эти сопутствующие действия надо выковыривать отдельно и выносить в скрипты, и замена билд системы выливается в правки во всем конвейере.


                1. akornilov Автор
                  07.03.2019 12:19

                  Это, конечно, интересно будет посмотреть лобовое сравнение перфоманса CMake и SCons в таком большом проекте.
                  На мой взгляд, производительность системы сборки, в основном, будет зависить от ее способности эффективно распараллеливать задачи.
                  Возьмем для примера три динамические библиотеки которые зависят друг от друга:
                  A -> B -> C — сначала нужно построить A, потому, что ее использует B, и только потом C потому, что она использует B.
                  Не могу утверждать какой makefile сгенерирует для такого случая CMake, но, вероятно, здесь будет происходить последовательная сборка с расспаралеливанием только внутри построения A, B, C. Учитывая, что каждая библиотека содержит несколько исходных файлов это будет эффективно, т.к. компиляция будет происходить параллельно, а возможно, что и с раскидыванием на разные ядра CPU.
                  Но Make не в состоянии понять высокоуровневую структуру билда, он будет параллелить только свои низкоуровневые задачи.
                  А вот полноценная билд система в состоянии понять, что зависисмости B на A и C на B возникают только на стадии сборки. А компилировать можно A, B и C параллельно и такая совместная компиляция может принести прирост производительности.

                  Потому что другие билд системы это обычно батник запускающий билд систему + до или после сопутствующие действия, типа цифровой подписи, упаковки в инсталлятор и т.п. и замена билдсистемы не влияет на весь процесс.

                  Возможно, выполнять такие действия до или после билда проще и удобней, но тогда, в какой-то степени, теряются преимущества инкрементальной сборки — т.е. они будут выполняться безусловно, даже если в системе ничего не изменилось. На мой взгляд, предпочтительней такие задачи все же делать частью билд процедуры. В gradle не трудно написать плагин для таких целей.


                  1. berez
                    07.03.2019 14:10

                    Не могу утверждать какой makefile сгенерирует для такого случая CMake, но, вероятно, здесь будет происходить последовательная сборка с расспаралеливанием только внутри построения A, B, C.

                    Ошибаетесь.
                    CMake сгенерирует файл, который будет параллелить не зависящие друг от друга таргеты.
                    Другое дело, что кроме CMake нужно учитывать и ту билд-систему, под которую CMake генерит файлы. Например, если это будет ninja, то билд больших проектов будет чуточку быстрее, чем если это будет gmake. Просто потому, что ninja — проще, и не пытается найти на файловой системе кучу несуществующих файлов (полюбоваться, сколько всякого говна ищет по всему диску gmake, можно, проанализировав вывод gmake -d).
                    Да, возвращаясь к CMake. Если сгенерировать под виндой мейкфайлы для NMake, то мы автоматически получим однопоточную и жутко тормозящую систему сборки, ибо nmake параллелит плёхо. Но это не дефект CMake, а особенность целевой системы сборки (NMake).


                    1. akornilov Автор
                      07.03.2019 15:02

                      Ошибаетесь.
                      CMake сгенерирует файл, который будет параллелить не зависящие друг от друга таргеты.

                      Почему ошибаюсь? Я как раз и говорил о ЗАВИСЯЩИХ друг от друга таргетах. Только зависимости бывают разными, если, например, одна библиотека зависит от другой — КОМПИЛИРОВАТЬ их можно параллельно, а СОБИРАТЬ (линковать), только когда зависимая будет полностью готова. А вот определить тип зависимости, думаю, под силу будет только целиковой билд системе.


  1. guinzoo
    06.03.2019 16:43
    +1

    Пользуюсь GYP для сборки игры под Windows, macOS, iOS, и сервера под linux. Очень нравится, но автору статьи вряд ли подойдет. Гугл проект почти не поддерживает, но на гитхабе недавно появился форк, где энтузиасты во всю коммитят изменения. Изначально пытался пользоваться cmake, но по ряду причин он мне не подошел.


    1. bigfatbrowncat
      06.03.2019 17:18

      Посмотрите в сторону bazel. Как я понимаю, его позиционируют на замену gyp


  1. Sergey_Cheban
    07.03.2019 23:05

    В качестве билд-системы — cmake, однозначно:
    1. Кроссплатформенный, способен сгенерировать билд-файлы под любую билд-систему. Под windows это не обязательно однопоточный nmake, можно указать и что-нибудь вроде «Visual Studio 15 2017 Win64».
    2. Способен сам же запустить то, что сгенерировал: «cmake --build .» вызовет хоть make, хоть nmake, хоть любую другую систему сборки.
    3. Популярен, активно разрабатывается и поддерживается.
    4. В современном виде — весьма мощен и удобен.
    5. Очень ответственно относится к вопросам обратной совместимости.


  1. GooRoo
    08.03.2019 10:38

    (Пока что) ещё есть Qbs.