Небольшое предисловие
Разработкой на C++ я занимаюсь уже лет 15 и когда-то начинал с «Watcom С». О нем у меня остались самые теплые воспоминания. Но, так как мне больше приходилось писать для консоли UNIX, я перешел на vim в качестве IDE. В целом, он достаточно удобен. Его плагины творят чудеса, можно настроить autocomplete, просмотр иерархии классов, быстрый переход к определению или поиск, в общем всё, что должны уметь IDE, там можно поднять. Боль приходит в тот момент, когда ты пытаешься установить и освоить новый плагин. Это всё заводится не везде и не всегда, и, зачастую, жрет проц и память похлеще любой java.
Периодически я поглядывал на Qt Creator. Но так и не решился на него перейти.
Первое знакомство

Облом случился довольно скоро. Дело в том что, хоть пишу я на данный момент в основном под linux, в качестве рабочей станции у меня macbook pro. Да, я такой! И искренне считаю извращенцами людей, которые, купив ноутбук apple, устанавливают на него что-нибудь кроме macOS. Поэтому, для меня критически важна возможность удаленной сборки или сборки через docker. А её, сколько пользователи ни просили, в CLion пока нет. Первая попытка перехода закончилась ничем — ведь решения «из коробки» нет.
Вторая попытка
Но боль с настройкой vim никуда не ушла, и я решил дать CLion второй шанс — попробовать решить те проблемы, которые передо мной встали, самостоятельно. А это:
- Отсутствие локально установленный библиотек. CLion не может выдавать подсказки по классам, описания которых не видит
- Собственно сама сборка
До этого, я пользовался библиотеками, которые поставляются в пакетах вместе ОС. С CLion мне бы пришлось все заголовочные файлы ОС закидывать к себе на Mac, чего категорически не хотелось. Но тут меня выручил conan. Он хранит все собранные библиотеки в отдельном каталоге, который легко можно подложить себе.
Со вторым все оказалось не так просто. Я решил просто подменить cmake на свой скрипт, который выполнит сборку внутри docker контейнера. Мне не улыбалось каждый раз, когда я синхронизирую свой код из репозитория или вливаю его обратно, добавлять/удалять дополнительный Target в CMakeLists.txt, как мне советовали. Хотелось иметь возможность склонировать любой проект и тут же собраться без танцев с бубном. Это оказалось не так просто. Основную сложность вызвала сборка тестового проекта CLion, которую он выполняет при смене toolchain, и проброс параметров содержащих пробелы внутрь контейнера. Но я справился.
Если у вас всё хорошо — вы просто ещё не всё знаете
Казалось бы — у меня получилось!
…
Я был наслышан, что сборка на С++ с использованием С++14 или С++17 — довольно медленная штука, и, поначалу, всё списывал на медлительность компилятора. Но потом заметил, что удаленно на выделенном сервере собирается уж как-то слишком шустро. Чем больше становился проект — тем большие сомнения рождались в моей душе.
Докер оказался с двойным дном. Да, сервер поднимается шустро, вот только компиляция на osxfs работает, как оказалось в ТРИ раза медленнее, чем на overlay. Поэтому пришлось перейти на использование rsync. Так же, я открыл для себя настройки томов docker. Если использовать delegated — скорость сборки увеличивается процентов на 15. Подробнее.
Попутно померил время сборки через ninja против стандартного make — разница вышла практически вдвое. Правда CLion требует собираться именно через make, иначе, прощайте подсказки. Пришлось прогонять сборку дважды, один раз через make, для CLion, второй — через ninja. Выигрыш тут в том, что проект меняется довольно редко, а собираться надо часто.
Еще, я попробовал использовать прекомпилированные заголовки (cotire) — эффект оказался неоднозначным. К тому же, это требовало вручную формировать stdafx.h (или любой другой файл) и включать его во все .cpp. А это, в свою очередь, не очень нравится CLion. Он начинает считать все остальные include лишними. Это можно было обойти, но выигрыш был не такой значительный.
Последнее, что я сделал — отказался от ccache. В моем случае, он давал задержку примерно в секунду. Да, если подходящий файл найден, это ускоряет сборку. Но такое не часто случается, когда ты пишешь новый код.
Аппетит приходит во время еды
Раз уж сборка у меня завелась, почему бы не попробовать растолкать и отладку!
Раньше я считал, что gdb внутри docker запустить невозможно. Оказалось, что это не так. Параметр --security-opt seccomp:unconfined снимает данную проблему. А статья подробно описывает, как и что надо настраивать. Но, и тут случился непредвиденный облом. Я собирался через clang (что логично), а для отладки надо использовать gcc. В противном случае, запустить приложение в отладчике вы сможете, но вот посмотреть значения внутри stl контейнеров уже нет. В принципе, собрать через gcc — не проблема. Тогда, и правда всё работает.
Эпилог
Мыши плакали, кололись, но продолжали есть кактус… Ждем! Ждем удаленную сборку. Ждем полноценную поддержку C++17. JetBrains и JFrog в своих рассылках постоянно поминают друг друга, но какой-либо интеграции пока нет. Даже, собираясь локально, придется вводить команды conan вручную. Ждёмс!
Еще было бы неплохо заполучить поддержку сборки через ninja. 50% производительности на дороге валяются.
Кому интересно, мои скрипты и Dockerfile для сборки шаблона можно найти на GitHub.
Комментарии (24)
yarric
25.07.2017 15:32-3Почему бы не использовать Xcode?
eugenebabichenko
25.07.2017 16:48+1Потому что автор использует Linux. Ещё многим просто не нравится Xcode, не поверите :)
klirichek
25.07.2017 20:54Там есть большая подляна.
Вроде всё подсвечивается и собирается (можно из проекта CMake, на котором живёт CLion создать билд-солюшн XCode, и даже открыть его...)
Но! Как только пытаешься редактировать новый код, Он через мгновение очухивается и говорит: а… это не Objective C? Ну тогда я умываю руки… И отключает множество фичей, вроде подсказок и т.д.yarric
25.07.2017 21:42Это какая-то проблема именно при импорте CMake? Какая версия Xcode?
eugenebabichenko
26.07.2017 10:28Это какая-то проблема с C++. Когда я работал над проектом под macOS, в котором портируемое между системами ядро было написано на C++, поддержка его была довольно урезанной. Потому как это было давно, уже точно и не вспомню, что конкретно там было вырезано, но в итоге выяснилось, что со всеми задачами, кроме рисования интерфейса, гораздо лучше справляется AppCode.
yarric
29.07.2017 15:19Вчера сделал проект на C++ в свежем Xcode — подсказки и всё прочее работает. Судить о новом Xcode по какому-нибудь Xcode времён Objective-C как-то странно.
eugenebabichenko
29.07.2017 19:05Так всё, что вы сказали, у меня работало. А вот рефакторинга не было, и это было печально. Речь идёт об Xcode образца зимы этого года.
yarric
29.07.2017 20:53Вот выбрал класс, нажал меню — Refactor -> Rename, Extract, Create Superclass и так далее, чего не хватает?
eugenebabichenko
29.07.2017 20:59Занятно, мне он упорно утверждал, что "Xcode can only refactor C and Objective-C code"
anastasiak2512
25.07.2017 15:43Я оставлю это здесь http://nevkontakte.com/2015/rogue-ninja-support-in-clion.html. На тему CLion + ninja, там слинкован некий скрипт, который позволяет такой вариант «двойной» сборки автоматизировать. Раньше вроде работало.
А вообще надеюсь, что скоро сможем ninja поддержать как генератор в CLion/CMake.klirichek
25.07.2017 20:55ну, вообще-то как генератор в Cmake он давно уже поддерживается.
И если проект CLion рассматривать вне IDE, а просто как проект CMake — аналогично.anastasiak2512
26.07.2017 00:48Я имею в виду поддержать ninja как генератор CMake в CLion. То, что он просто как генератор в CMake уже давно есть, это понятно. Но CLion сейчас рассчитывает, что используется Makefiles генератор, мало того, он и запускает CMake, передавая соответствующий параметр.
apro
25.07.2017 17:13+1Как-то все схематично описано, часть контекста очевидного автору мне совершенно непонятна.
Например,
Его плагины творят чудеса, можно настроить autocomplete, просмотр иерархии классов, быстрый >переход к определению или поиск, в общем всё, что должны уметь IDE, там можно поднять. Боль >приходит в тот момент, когда ты пытаешься установить и освоить новый плагин. Это всё >заводится не везде и не всегда, и, зачастую, жрет проц и память похлеще любой java.
Сколько машин у автора и зачем на них перенастраивать каждый день YouCompleteMe?
До этого, я пользовался библиотеками, которые поставляются в пакетах вместе ОС. С CLion мне >бы пришлось все заголовочные файлы ОС закидывать к себе на Mac, чего категорически не >хотелось
А зачем это вообще нужно? Почему не собрать для mac os x, протестировать на нем,
а потом отправить патч в CI для тестирования на linux. Все-таки системы (mac os x и linux) очень близки в плане API для серверного ПО.
Мне не улыбалось каждый раз, когда я синхронизирую свой код из репозитория или вливаю его >обратно, добавлять/удалять дополнительный Target в CMakeLists.txt, как мне советовали. Хотелось >иметь возможность склонировать любой проект и тут же собраться без танцев с бубном.
Почему не (псевдокод)
if(DEFINED ENV{LOCAL_EXT}) include(${LOCAL_EXT}) endif()
?
выставили бы один раз в ~/.basrc путь до нужного скрипта добавляющего нужный
вам target и горя не знали
Попутно померил время сборки через ninja против стандартного make — разница вышла практически вдвое. Правда CLion требует собираться именно через make, иначе, прощайте подсказки. Пришлось прогонять сборку дважды, один раз через make, для CLion, второй — через ninja
Т.е. вместо 2X время сборки увеличилось до 3X, а ради чего?
Doktor3lo
25.07.2017 17:36Просто, статья не про настройку vim. Я пользовался YCM. У меня есть конфиг для vim, который я, как правило, просто копировал на новое место (+установка некоторого количества плагинов, типа YCM). Как правило проблемы начинаются, когда требуется сложная навигация между файлами. Попробуйте поискать какое-нибудь имя по всему проекту? grep? Может конечно есть плагин. Но сколько сочетаний клавиш вы храните в памяти постоянно? Если забыл — никакого контекстного меню, только хардкор! Я даже, одно время autocomplete не пользовался — память тренировал, пока с boost не столкнулся :)
macOS — это FreeBSD, а это совсем не linux. Например, там нет proc, абсолютно другая логика работы с shared library ну и еще по мелочам, которые, тем не менее, вполне могут испортить жизнь. + я не люблю засорять собственную ОС, предпочитая работать через chroot, virtualbox или docker.
Потому что, это, как ни крути, изменения проекта чисто под себя, чего я делать не хотел.
Возможно я не совсем точно сформулировал мысль. Да, при добавлении новый файлов cmake отрабатывает дольше, за счет двойной работы. Но это небольшая плата за возможность экономить 50% времени, при отладке.
ЗЫ
Я не против vim, до сих пор кое что правлю в нем. Его, в отличие от CLion, можно легко запустить удаленно. Он быстрее грузится. Глупо открывать проект в CLion, чтобы поправить пару строк :)apro
25.07.2017 20:38+1У меня есть конфиг для vim, который я, как правило, просто копировал на новое место (+установка некоторого количества плагинов, типа YCM)
Так в этом и вопрос, ноутбуков с ретиной слишком много? Сколько раз нужно перенастраивать чтобы почувствовать боль и желание что-то изменить, я думаю ноутбуков с ретиной должно быть штук 10?
Как правило проблемы начинаются, когда требуется сложная навигация между файлами. >Попробуйте поискать какое-нибудь имя по всему проекту? grep?
:! find . -name x :! grep -r x *
или просто открыть директорию в буфере и начать путешествие
как в обычном файловом менеджере,
по-моему при условии забытого сочетания клавиш намного быстрее
чем в любой IDE, а если сочетание клавиш помнишь то одинаково быстро
в любом редакторе/IDE.
macOS — это FreeBSD, а это совсем не linux. Например, там нет proc, абсолютно другая логика работы с shared library ну и еще по мелочам, которые, тем не менее, вполне могут испортить жизнь.
я знаю, а еще там kqueue вместо epoll, и что? действительно пишете софт который читает
/proc
, причем каждый день, никаких кроссплатформенных оберток которые прячут эти различия?
я не люблю засорять собственную ОС, предпочитая работать через chroot, virtualbox или docker.
да, пакетные менеджеры под mac os не настолько крутые как под linux,
но они есть и неплохо работают, зачем засорять-то?Doktor3lo
26.07.2017 03:42Какая-то классовая ненависть в голосе…
Повторюсь, vim мне нравится, я им пользуюсь. Но, например, межфайловая навигация в нем — ужасна. Копирование через буфер обмена — тоже та еще рулетка. Нет, всё решаемо, но требует определенного напряжения.
Да, я пишу софт для настройки этой самой ОС и обертки тут не всегда помогают. Отсюда же нежелание запускать что-либо на своей ОС — можно поиметь кучу лишнего геморроя. Даже, когда вместо Mac у меня был Linux, я так не делал.
В процессе экспериментов в ОС скапливается туча ненужных пакетов и каких-то настроек. Создается неповторимое окружение, которое порождает неповторимые сборки (про запуск я вообще молчу). Это как раз тот случай, когда только у разработчика «всё работает».
ElijahTh
26.07.2017 11:26Я так понял, у вас нет завязанности на определённую IDE.
В NetBeans из коробки есть поддержка сценариев «хочу работать из локальной IDE с проектом, который лежит за тридевять земель и собирать его (само-собой) под ОС удалённой машины».
Она называется Remote Development. Небольшое описание здесь [1] и про виды этого Remote Development здесь [2] (отличаются способы доступа к сорцам проекта: можно настроить авто-синхронизацию, можно использовать более щадящий режим, когда машины видят друг друга через NFS/SMB/...).
Собственно, Docker и Conan в этой связке становится не нужен. Поддержка ninja тоже есть из коробки, достаточно указать директорию с build.ninja при создании C/C++ Project With Existing Sources.
[1] https://netbeans.org/kb/docs/cnd/remotedev-tutorial.html
[2] https://netbeans.org/kb/docs/cnd/remote-modes.htmlDoktor3lo
26.07.2017 11:33Спасибо — посмотрю.
Последний раз я смотрел на него довольно давно — это был жуткий тормоз…
Правда, и CLion поначалу был тот еще тормоз :)
knstqq
ccache больше подходит не для случая, если вы занимаетесь разработкой, а для случая, если это build-сервер, который собирает десятки-сотни-тысячи проектов регулярно и не все из них изменяются.
Или если у вас source-based дистрибутив linux, например gentoo.
А так системы сборки, умеющие «инкрементально» дают намного больше пользы
Doktor3lo
ccache может сильно помогать, если вы работаете с несколькими ветками git одновременно и при сборке rpm или deb пакетов.
В данном случае он был добавлен скорее по привычке — обычно проблем от него нет.
knstqq
да, действительно, в случае нескольких git-веток помогать должен