Развенчание мифов о мета-объектном компиляторе Qt +46
Вступление
Moc — это один из инструментов разработчика и часть библиотеки Qt. Его задача — поддерживать расширение языка С++, необходимое для интроспекции и рефлексии в Qt (сюда относятся сигналы, слоты и QML). Для более детального объяснение вы можете почитать о том, как работают сигналы и слоты в Qt.
Необходимость использования moc является одним из главных объектов критики Qt. Это даже привело к появлению форков Qt, принципиально отказавшихся от moc (например, CopperSpice). Но всё-же большинство приписываемых moc так называемых недостатков не обоснованы.
Мифы
Moc переписывает ваш код перед тем, как передать его компилятору
Это распространённое заблуждение. Moc не модифицирует и не переписывает ваш код. Он просто парсит часть кода для того, чтобы сгенерировать дополнительные С++ файлы, которые потом будут компилироваться независимо. Это не очень большое отличие, но всё-же важное техническое недопонимание.
Moc просто автоматически генерирует шаблонный код, который можно было бы долго и нудно писать вручную, если бы moc не существовало. Если вы мазохист, то и сейчас вполне возможно взять и написать самостоятельно все таблицы для интроспекции и реализации сигналов. Ну или положиться на надёжный инструмент, который сделает это за вас.
Используя Qt, вы не пишете на настоящем С++
Я слышал этот довод много раз, но он попросту неверен. Макросы, используемые moc для аннотации кода — это стандартные макросы С++. Они должны быть корректно распознаны любым инструментом, способным анализировать код на С++. Когда вы добавляете в код Q_OBJECT, то просто дописываете объявление нескольких функций. Когда вы пишете «signals:», то просто добавляете макрос, который превратится в «public:». Многие другие макросы Qt вообще ни во что не раскрываются. Moc просто находит их и генерирует код эмиттеров сигналов и таблиц интроспекции.
Тот факт, что ваш код теперь может быть прочитан ещё одним инструментом, не делает его «менее соответствующим стандарту С++». Вы же не считаете код, написанный с расчётом на использование gettext или doxygen каким-то «менее правильным С++»?
Moc усложняет процесс сборки кода
Если вы используете любую промышленную систему сборки кода, вроде CMake или qmake, то получаете нативную поддержку Qt. Даже с какой-то собственной системой сборки речь идёт о всего-лишь одном дополнительном запуске команды обработки заголовочных файлов. Все известные мне системы сборки позволяют добавлять шаги по запуску дополнительных команд перед запуском компилятора, поскольку многие проекты в том или ином виде используют генерацию кода при сборке проекта. Вспомните, например, инструменты вроде yacc/bison, gperf, llvm/TableGen.
Moc делает отладку сложнее
Поскольку moc генерирует код на чистом С++, то отладчики не должны иметь никаких проблем с ним. Мы стараемся поддерживать сгенерированный код в таком состоянии, чтобы он не вызывал предупреждений компиляторов или инструментов статического или динамического анализа кода. Да, иногда при отладке вы будете видеть в колстеке следы сгенерированного moc кода. В некоторых редких случаях вы можете получить ошибку, связанную с кодом, созданным moc, но обычно причины достаточно легко обнаружить. Код, сгенерированный moc, достаточно человекочитаем. Также его, вероятно, понимать и отлаживать даже проще, чем те печально известные ошибки некоторых библиотек, построенных на продвинутом использовании шаблонов.
Отказ от moc улучшает производительность на этапе выполнения кода
Это прямая цитата с главной страницы CopperSpice, и, вероятно, самая большая их ложь. Код, генерируемый moc, старается избегать динамических аллокаций и уменьшить количество реаллокаций памяти. Генерируемые moc таблицы являют собой константные массивы и хранятся в read-only сегменте данных. CopperSpice же регистрирует свои QMetaObject (информацию о сигналах, слотах и свойствах) на рантайме.
Milian Wolff проделал некоторые сравнения производительности Qt и CopperSpice в его докладе на CppCon2015. Вот скриншот одного из его слайдов (меньше — лучше).
Также нужно отметить, что код на Qt даже с учётом запуска moc компилируется быстрее, чем код на CopperSpice.
Устаревшие мифы
Некоторая критика когда-то была справедливой, но более таковой не является.
Макрос не может быть использован при объявлении сигнала, слота, базового класса объекта, а также ...
До выхода Qt5 утилита moc действительно не раскрывала макросы. Но начиная с Qt 5.0 moc полностью поддерживает макросы во всех вышеперечисленных местах, так что это больше совершенно не является проблемой.
Перечисления (enums) и переопределения типов (typedefs) должны строго соответствовать при использовании их в качестве параметров сигналов и слотов
Это является проблемой только если вы всё ещё хотите использовать синтаксис соединений, основанный на строках (поскольку там действительно используется прямое сравнение названий типов). С выходом Qt5 и новым синтаксисом это больше не препятствие.
Q_PROPERTY не позволяет использовать запятые в типах
Q_PROPERTY это макрос с одним аргументом, который ни во что не раскрывается и служит лишь для помощи moc. Но, поскольку это всё ещё макрос, запятая в, например, QMap<Foo, Bar> разделяет аргументы макроса и вызывает ошибку компиляции. Когда я увидел, как CopperSpice использует этот аргумент против Qt, то потратил 5 минут на то, чтобы исправить это с использованием variadic-макросов из стандарта С++11.
Другая критика
Шаблоны, вложенные классы или классы, используемые множественное наследование, не могут быть QObject-ами
Хотя это и является правдой, но эти возможности просто пока не поддерживаются QObject, хотя и вполне могут быть реализованы в moc, если мы этого захотим. Проект Qt в данный момент не считает данные фичи приоритетными.
Я однажды добавил поддержку шаблонных QObjects в moc, но это изменение не вошло в основную ветку разработки, поскольку никто больше не выразил интереса к данной функциональности.
Ещё нужно отметить поддержку шаблонных и вложенных классов в moc-ng.
Множественное наследование уже само по себе является очень неоднозначным. Чаще всего оно указывает на проблемы с архитектурой приложения и многие современные языки напрямую его запрещают. Вы всё ещё можете использовать множественное наследование с Qt, если если QObject является первым базовым классом в цепочке наследования. Это небольшое ограничение позволяет нам применять полезные оптимизации. Когда-нибудь задумывались почему qobject_cast настолько быстрее, чем dynamic_cast?
Выводы
Я не думаю, что moc — это проблема. Макросы Qt действительно помогают реализовать необходимую Qt функциональность. Сравнивая их с подходом CopperSpice мы можем заметить в последнем значительную избыточность служебного кода, а также недружелюбный синтаксис макросов (не говоря уже о потерях производительности на рантайме). Синтаксис сигналов и слотов, который существует в Qt с 90-ых годов — одна из фундаментальных вещей, обеспечивших успех фреймворка.
Вам может быть также интересно изучить некоторые эксперименты, связанные с moc, вроде moc-ng (это moc, переписанный с использованием библиотек clang). Также есть вот это исследование замены moc с помощью инструментов рефлексии С++. Ну и библиотека Verdigris, с макросами, создающими QMetaObject без moc.
Комментарии (66)
Satus
24.04.2017 14:26-2Moc усложняет процесс сборки кода
Ну, так-то усложняет. Добавляет ещё один сторонний этап сборки.
С выходом Qt5 и новым синтаксисом это больше не препятствие.
Только если типы объектов известны в compile-time.iroln
24.04.2017 17:38Ну, так-то усложняет. Добавляет ещё один сторонний этап сборки
Усложнение для кого/чего, разработчика или компьютера? Если для компьютера, то какая разница, если для разработчика накладные расходы на автоматический запуск qmake в IDE равны нулю?
Только если типы объектов известны в compile-time.
Приведите реальный пример.
Satus
24.04.2017 18:27+3Приведите реальный пример.
Присоедините С++ к qml объекту из С++ кода. Как вы это сделаете в compile-time?
Усложнение для кого/чего, разработчика или компьютера?
Для обоих. Для компьютера добавляется ещё один препроцессор, для человека — ещё один этап сборки, о котором нужно знать (недавно пришлось вручную выключать moc на некоторых заголовочных файлах, иначе он просто падал).iroln
24.04.2017 18:35Так про связку C++ и QML в документации написано, что functor-based подход в этом случае не работает.
ещё один этап сборки
Звучит так, словно это что-то невероятно сложное. Но на фоне того, как зачастую устроена сборка большого C++ проекта, запуск qmake — это капля в море.
Satus
24.04.2017 18:42+2Так про связку C++ и QML в документации написано, что functor-based подход в этом случае не работает.
Оригинальное утверждение говорило читателю (по крайней мере как я это понял), что новая система решает проблемы старой. Это так. Я всего лишь отметил, что есть ситуации, когда новая система неприменима, и приходиться пользоваться старой.Звучит так, словно это что-то невероятно сложное. Но на фоне того, как зачастую устроена сборка большого C++ проекта, запуск qmake — это капля в море.
Я не говорю, что это сложно или просто. Утверждение было, что moc не делает сборку сложнее. Это не так. (x+1) этапов сборки больше чем (х) этапов сборки, что добавляет соответствующие потенциальные проблемы в виде багов moc'a и moc-aware систем сборки.
Насколько сложно — уже другой вопрос, к моему изначальному утверждению не относящийся.oYASo
25.04.2017 01:14-2Это не так. (x+1) этапов сборки больше чем (х) этапов сборки, что добавляет соответствующие потенциальные проблемы в виде багов moc'a и moc-aware систем сборки.
Ну это звучит так, как будто вы докопались к формулировке. В том же cmake вся проблема со сборкой решается банально одной строчкой:
set(CMAKE_AUTOMOC ON)
Насчет именно этапов: я готов согласится с автором, что если перенести moc на макросы и шаблоны, вычислительных ресурсов будет потрачено больше (инстанцирование шаблонов). Так что в некотором роде можно сказать, что с moc это даже проще.Satus
25.04.2017 01:45Насчет именно этапов: я готов согласится с автором, что если перенести moc на макросы и шаблоны, вычислительных ресурсов будет потрачено больше
Мой опыт говорит скорее об обратном. Думаю, это зависит от конкретного проекта.
msts2017
24.04.2017 14:47+8т.е. когда какой нибудь хром при сборке генерит питоном кучку исходников это нормально а когда это делает Qt это плохо, мда…
Tantrido
24.04.2017 15:43Интересно как в CopperSpice работает рефлексия без moc?! Они утверждают, что Qt программа будет работать с CopperSpice без модификаций после конвертации. Или там рефлексия не работает?
BratSinot
25.04.2017 10:21+1Как как, они свой вариант рефлексии написали, на основе фичь из C++11 (т.е. без сторонней кодогенерации, все делает компилятор). Как-то конференция (эдак в году 15-м) по этому поводу была.
Tantrido
24.04.2017 16:01-1Когда я увидел, как CopperSpice использует этот аргумент против Qt, то потратил 5 минут на то, чтобы исправить это с использованием variadic-макросов из стандарта С++11.
Это в какой версии появилось? В 5.8?
Tantrido
24.04.2017 16:03-2Когда-нибудь задумывались почему qobject_cast настолько быстрее, чем dynamic_cast?
И почему?
Barafu
24.04.2017 16:49У меня, как у упёртого линуксоида, к Qt одна "претензия", и то не совсем к нему. Извините за сумбурность, это и в беседе-то сложно объяснить.
На Линуксе давно надо навести порядок в области создания десктопных юзерских программ. Qt отлично подошёл бы в роли главного, "стандартного" фреймворка для создания гуя. А Python для Линукса — де факто главный язык пользовательского софта. Но вот эта конструкция с moc и генерируемым кодом создаёт сложности при попытке привязать Qt к другому языку. В частности, Qt для Python сообщество не осилило — "народный" проект PySide остановился на Qt4, замерев вместе с Nokia, которая его курировала. Остался только PyQT, который выпускает коммерческая фирма. Он идёт под лицензией GPL или коммерческой за 500$. И вот смотрите, что получается:
- Опенсорсники рады, но не все. Ты можешь хотеть выложить свой код под MIT или вообще PD, но облом. Мало того, в одну программу нельзя юридически включать PyQT и коммерческую библиотеку. Есть конечно способы извернуться, да и в основном всем просто пофиг, но всё равно неприятно: ты хочешь потрудиться на благо сообщества, а вместо этого юлишь между законами как Остап Бендер.
- Корпорации обычно рады, им эти 500$ ничего не значат.
- А вот стартапы в полном пролёте.
Именно мелкие стартапы не сумеют заработать на софте под GPL. Если пара человек захотят попробовать написать коммерческую софтинку, то они не будут сходу для первой версии покупать лицензию за 500$, a возьмут другой фреймворк. А ко второй, когда стартап поймёт, что дело двинулось, они может и могли бы выделить 500$, но уже привыкли к тому, что у них есть. В результате мелкий коммерческий софт под Линукс написан кто во что горазд: С++/Qt, Python/Gtk, Go/wxWidgets, NodeJS/(какой фреймворк? ручками нарисую!). Свобода выбора, конечно хорошо, с точки зрения разработчика. А вот с точки зрения пользователя хочется уже устаканивания всего этого зоопарка в какую-то единую, одинаково работающую и одинаково глючащую систему. Чтобы не приходилось в ответ на вопрос, "а умеет ли Линукс HiDPI? Экраны Брайля? Скины? Чтение с экрана?" переспрашивать "А какими именно программами будете пользоваться?"
Самое обидное, что эта проблема созрела ровно настолько, чтобы быть проблемой, но ещё никто не хотел взяться за её исправление. Большинству достаточно того, что есть. А в глобальных размышлениях о судьбах Линукса они не участвуют. Поэтому, хотя Линукс и переходит понемногу на Qt, серьёзного сдвига и на горизонте не видно.
TL:DR — GPL это хорошо, но ключевые библиотеки Линукса должны быть под более свободной лицензией, иначе не видать нам стандартизации интерфейса.iroln
24.04.2017 17:34+1Про PySide2 слышали?
https://github.com/pyside/pyside2Barafu
24.04.2017 17:45Офигеть. Нет, не слышал. И вокруг меня — никто не слышал. Это и удивительно. Сейчас буду изучать, чего там есть/нет. Но один только факт, что его нет в главрепе Арча, уже смущает. Значит, сколько-то известного софта на нём тоже нет.
iroln
24.04.2017 17:54Он не так давно (относительно) разрабатывается, но разрабатывается он официально разработчиками Qt, поэтому стоит ожидать, что проект не забросят как первый PySide.
abagnale
25.04.2017 16:22+1Да, сейчас планируется вернуть PySide в состав Qt, чтобы он был доступен "из коробки" в официальных инсталляторах. Я как раз забыл об этом рассказать в статье про roadmap. Будет доступен как в Open Source версии, так и в коммерческой (включая поддержку).
Разработка ведётся не совсем внутри Qt (первый пост от товарища Кнолла), но с участием, да.
tangro
24.04.2017 18:05-2Это всё вообще не о Qt, а о том, что надо переставать говорить о том, что GPL — это хорошо. GPL это зло, которое давит как опенсорс, так и коммерческий софт. Должны остаться по-настоящему свободные лицензии вроде LGPL и коммерческие закрытые. И будет всем счастье.
Barafu
24.04.2017 19:22+6GPL — это средство обороны открытых проектов от воровства. Как и любое средство обороны, применять его нужно умеючи, доставать в крайнем случае, и не размахивать направо и налево. GPL — лицензия для конечного софта, препятствует явлению в мир множества "Антивирусов Бабушкина". Но для ключевых библиотек Линукса — это действительно проблема.
boblenin
24.04.2017 22:38GPL — это лицензия ты мне — я тебе. Способ увеличить количество исходников доступных для изучения.
tangro
25.04.2017 11:22GPL — это средство повышения и защиты чувства собственной важности. Если ты хочешь писать закрытый код за деньги — это ок. Если ты хочешь нести счастье людям — бери MIT или LGPL. А писатель под GPL хочет света софитов и аплодисментов, а на пользователей ему плевать с высокой колокольни.
phprus
30.04.2017 14:54Хуже то, что многие не понимают возможности и ограничения, которые накладываются GPL и по этому данная лицензия может использоваться как наиболее популярная, а не наиболее подходящая.
Из практики — есть в интернете приложение под GPL (сейчас уже очень давно не развивающиеся), которое для своей работы требует одну исключительно закрытую и сильно платную библиотеку. Без этой библиотеки работать ничего не будет, так как она используется в основных алгоритмах.
Вот вопрос, да, приложение под GPL, но фактически им пользоваться нельзя даже если сильно платная библиотека у вас куплена.
Даже если пользоваться им подпольно у себя, то сделать форк и выложить его уже не получится, будет мешать хвост коммерческой библиотеки (ее то под GPL вы не выложите, а надо, так как GPL вирусная).
А будь приложение под LGPL или MIT/BSD/Apache, то таких проблем бы не было, но GPL банально известнее и для человека, который в лицензиях разбираться не хочет куда проще поставить шильдик GPL.RPG18
30.04.2017 21:06-2Не понимаю, почему из-за GPL нельзя пользоваться ПО. Вот стоит у меня GNOME и я им пользуюсь. Не понимаю, как GPL мне может это запретить или ограничить.
мешать хвост коммерческой библиотеки
Как она может мешать, если изначальная версия программы написана с пользованием этой библиотекой?phprus
30.04.2017 21:25Какую проприетарную библиотеку в своем ядре использует GNOME? Если брать то ПО, про которое я говорю, то для его использования/запуска/компиляции требовалась библиотека стоимостью ЕМНИП порядка 1000$ в ценах 5-6 летней давности.
Теперь пойдем с конца. Пусть я доработал эту программу и хочу распространять форк. По условиям GPL я должен и зависимости под GPL распространять, но код использует коммерческую библиотеку, делая такое распространение невозможным.
Аналогичную логику можно применить и к оригинальному автору, те возникает вопрос, могу ли я вообще легально использовать эту программу на условиях GPL.
У GNOME все зависимости либо под GPL либо под совместимыми лицензиями, те которые могут автоматически перелицензироваться под GPL при их использовании.RPG18
01.05.2017 00:57-2Теперь пойдем с конца. Пусть я доработал эту программу и хочу распространять форк.
Пожалуйста. Вы берете код распространяемый по GPL. Модифицируете, изменения лицензируете под GPL. Вот и все, ничего не нарушено. Можете распространять виде тех же исходных кодов.
Аналогичную логику можно применить и к оригинальному автору
Автор защитил своё право, на написанный код. Более того, автор позволил изучить его код, что дает вам возможность написать новый код с нуля и распространять на любых условиях.
Аналогичную логику можно применить и к оригинальному автору, те возникает вопрос, могу ли я вообще легально использовать эту программу на условиях GPL.
GPL где то накладывает запреты на использование готовой программы?
phprus
01.05.2017 09:13+2Получается вы считаете, что GPL позволяет линьковаться с закрытым кодом без нарушения GPL и без распространения GPL на закрытый код? Если это так, то в чем же тогда вирусность GPL?
Мне кажется, что Вы путаете GPL и LGPL, в которой сказанное вами разрешено.
Вы упорно игнорируете тот факт, что неотъемлемым компонентом обсуждаемой программы является проприетарный код, распространять который под GPL невозможно.RPG18
01.05.2017 20:32Получается вы считаете, что GPL позволяет линьковаться с закрытым кодом без нарушения GPL и без распространения GPL на закрытый код? Если это так, то в чем же тогда вирусность GPL?
А где GPL мне как автору кода запрещает линковаться с закрытой библиотекой? Вирусность заключается в использовании gpl библиотеки с не gpl приложением.
Вы упорно игнорируете тот факт, что неотъемлемым компонентом обсуждаемой программы является проприетарный код, распространять который под GPL невозможно.
Если человек получил такую программу, то у него уже есть эта библиотека в том или ином виде. Почему он не может пересобрать GPL код и слинковаться с тем же экземпляром библиотеки? Можно библиотеку подгружать в рантайме и тогда всё будет чисто.
phprus
01.05.2017 21:10-1> А где GPL мне как автору кода запрещает линковаться с закрытой библиотекой?
У автора кода все хорошо. Он в любом случае не обременен какой-либо лицензией на свой код, но находится он далеко за океаном и это не я.
> Вирусность заключается в использовании gpl библиотеки с не gpl приложением.
И наоборот. GPL в этом отношении симметрична. А у меня по условиям GPL есть обязанность и зависимости GPL совместимые использовать. А я не могу так делать, так как они проприетарные.
> Если человек получил такую программу, то у него уже есть эта библиотека в том или ином виде.
Конечно же нету! Человек получил эту программу в виде набора исходников, скаченных с SF много лет назад. Понятно, что в этом наборе исходников коммерческой библиотеки нет.
> Почему он не может пересобрать GPL код и слинковаться с тем же экземпляром библиотеки?
Ровно потому, что распространять это даже в исходниках не нарушив GPL будет невозможно. Более того, у меня есть подозрение, что и использование может GPL нарушать.
> Можно библиотеку подгружать в рантайме и тогда всё будет чисто.
Это ни на что не повлияет, так как библиотека является необъемлемым компонентом. Без нее не будет работать основная логика.RPG18
01.05.2017 22:38Конечно же нету! Человек получил эту программу в виде набора исходников, скаченных с SF много лет назад. Понятно, что в этом наборе исходников коммерческой библиотеки нет.
И как смена GPL на что-то другое поможет в описанной вами ситуации:
А будь приложение под LGPL или MIT/BSD/Apache, то таких проблем бы не было, но GPL банально известнее и для человека, который в лицензиях разбираться не хочет куда проще поставить шильдик GPL.
phprus
02.05.2017 08:23+1Еще раз.
GPL не позволяет линковаться с зависимостями, которые распространяются под не совместимыми с GPL лицензиями.
Всегда не позволяет. Без исключений. Для libstdc++ отдельное runtime exception пришлось добавлять к лицензии, чтобы ее можно было с закрытым кодом линьковать не смотря на GPL.
Если Вы знаете о существовании исключений, позволяющих линьковать GPL и закрытый код, то прямо укажите пункт GPL, который позволит линьковать GPL код и закрытый код.
LGPL или MIT/BSD/Apache позволяют линьковать открытый и закрытый код. Вот чем они помогут в данной ситуации. Я смогу легально скачать LGPL код зависящий от закрытого кода, использовать его, доработать его и, что самое главное, открыть миру свои изменения под LGPL не нарушив ее! И при этом у меня не будет обязанности открыть под GPL зависимости — те этот краеугольный закрытый код, которого у меня даже и нету, только готовая библиотека.
И еще, скачайте, пожалуйста, демо версию коммерческой поставки Qt и opensource версию Qt и посмотрите на драйвера к базам данных в модуле QtSQL. Вы обнаружите, что OpenSource Qt не содержит драйверов к закрытым базам данных, а если вы посмотрите в документацию к Qt, то там написано, что часть драйверов отсутствуют в открытой Qt из-за несовместимости проприетарного кода и GPL. Те ситуация один в один, как я и описываю.
И да, минусы ставить куда проще, чем привести пункт GPL, который разрешает линьковать закрытый и GPL код, что сразу бы прекратило спор, но я такого пункта там не видел…
А закрытый код — это данность, от которой не уйти. Intel MKL, Intel IPP, тот же IMSL с которым правда работать не доводилось — это закрытый код, у которого и близких OpenSource конкурентов по производительности нету.RPG18
02.05.2017 12:06GPL не позволяет линковаться с зависимостями, которые распространяются под не совместимыми с GPL лицензиями.
Всегда не позволяет. Без исключений. Для libstdc++ отдельное runtime exception пришлось добавлять к лицензии, чтобы ее можно было с закрытым кодом линьковать не смотря на GPL.GPL запрещает делать закрытое приложение с открытыми библиотеками. Об обратном GPL ничего не говорит.
Те ситуация один в один, как я и описываю.
Это другая ситуация. Qt это библиотека. Она не может распространять библиотеки связанные с MS SQL или Oracle. Однако при наличие необходимых библиотек, вы можете собрать драйвер.
Я смогу легально скачать LGPL код зависящий от закрытого кода, использовать его, доработать его и, что самое главное, открыть миру свои изменения под LGPL не нарушив ее! И при этом у меня не будет обязанности открыть под GPL зависимости — те этот краеугольный закрытый код, которого у меня даже и нету, только готовая библиотека.
А будь приложение под LGPL или MIT/BSD/Apache, то таких проблем бы не было, но GPL банально известнее и для человека, который в лицензиях разбираться не хочет куда проще поставить шильдик GPL.Так у вас есть библиотека или нет? Можно сделать как в Qt и работу с библиотекой сделать через плагин. Вы не линкуетесь с библиотекой и с GPL все чисто.
phprus
02.05.2017 13:04+1> GPL запрещает делать закрытое приложение с открытыми библиотеками. Об обратном GPL ничего не говорит.
GPL не разделяет приложение и библиотеки, а оперирует понятием «Corresponding Source»: The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. (обратите внимание на «run the object code»).
Особенно обратите внимание на часть: For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.
А дальше пошли обязанности:
You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:
Как я смогу распространять Corresponding Source дальше на условиях GPL, если в него входит «dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work», а эта самая dynamically linked subprograms имеет закрытый код?
> Так у вас есть библиотека или нет?
Да.
> Можно сделать как в Qt и работу с библиотекой сделать через плагин.
С библиотекой, которая всю математику ядра приложения считает? Ну ну…
Но даже плагин меня не спасет от запрета на распространение измененного кода…
tangro
30.04.2017 23:21-4Очень просто, приходит к вам заказчик и говорит — вот есть GNOME, меня в нём многое устраивает, но надо изменить это, это и это, плачу миллион долларов. Ах да, код изменений должен быть только у меня. Вы могли бы здорово заработать, да и человеку, может быть, помочь — а хрен там, GPL говорит вам валить лесом. И что самое гадкое, сколь бы мелочные фиксы не требовались и сколь бы ни была огромна сумма, за это предлагаемая — её даже некому заплатить! Ни у кого нет права взять денег за то, чтобы вдруг завтра изменить лицензию GNOME. Получается, что GPL вообще перечёркивает рыночную экономику и возможность производства добавленной стоимости продукта или услуги. Это тормоз прогресса, без всяких натяжек.
RPG18
01.05.2017 00:35Очень просто, приходит к вам заказчик и говорит — вот есть GNOME, меня в нём многое устраивает, но надо изменить это, это и это, плачу миллион долларов. Ах да, код изменений должен быть только у меня. Вы могли бы здорово заработать, да и человеку, может быть, помочь — а хрен там, GPL говорит вам валить лесом.
Мне как разработчику вообще шикарно. Работу выполнил, все права на свой код передал заказчику. Дальше забота заказчика, что он будет с этим кодом делать.
tangro
01.05.2017 17:57-4Вы как-то странно понимаете GPL. Если Вы написали какой-то код, расширяющий GPL-код, то не можете просто «передать его заказчику». GPL не даёт Вам такого права. Вы должны либо открыть его всем, либо не передавать никому.
RPG18
01.05.2017 20:45не можете просто «передать его заказчику»
В РФ я могу это сделать через договор об отчуждении исключительного права. Я отказываюсь от своих авторских прав в пользу заказчика.Собственно в РФ по трудовому законодательству так все и происходит. Любой мой код, является собственностью работодателя.
tangro
02.05.2017 23:54-1Получается, что GPL не только говорит что вам писать можно, а что нельзя, но и какую форму трудовых отношений с работодателем вы должны выбирать! Конечно, если работать наёмным сотрудником по трудовому договору — то весь головняк с правами и распространением ложится на работодателя. А если хочется работать частным предпринимателем или своим ООО? Передавать права на написанное не получится, поскольку вы этими правами в случае модификации кода на GPL не обладаете.
RPG18
03.05.2017 01:00форму трудовых отношений с работодателем вы должны выбирать
Где это написано?
Передавать права на написанное не получится, поскольку вы этими правами в случае модификации кода на GPL не обладаете.
Я обладаю авторским правом на изменения. Это право я могу передать.
tangro
03.05.2017 11:40-1Где это написано?
В Вашем комментарии выше.
Я обладаю авторским правом на изменения. Это право я могу передать.
Так а толку? Для получения конечного продукта заказчику придётся взять не только Ваши изменения, но и оригинал кода (который под GPL). И получить всю прелесть невозможности его использования для большинства классических коммерческих кейсов.RPG18
03.05.2017 12:27-1И получить всю прелесть невозможности его использования для большинства классических коммерческих кейсов.
Меня как исполнителя это не беспокоит. Мне поставили задачу модифицировать GNOME, я его модифицировал. Что дальше будет делать заказчик с этой версией меня не волнует.
tangro
03.05.2017 16:17-1Меня как исполнителя это не беспокоит.
Беспокоит, потому, что Вы не получите этого заказа. Потому, что законный бизнес не создаст запроса на такой заказ. Хотя могут быть и нуждающиеся в этом пользователи, и техническая возможность реализации. И поэтому GPL — это зло.RPG18
03.05.2017 17:01Бизнес разный бывает. Можно предоставлять услуги сопровождения, интеграции, поддержки.
encyclopedist
03.05.2017 11:52+1Вы категорически ошибаетесь. GPL обязывает только передавать код вместе с продуктом. Я могу передать измененный GPL код одному заказчику. (Другое дело, что я не могу запретить заказчику передавать код дальше, но заказчик во многих случаях и сам в этом не заинтересован).
tangro
03.05.2017 16:22-1Заказчик как-раз заинтересован в том, чтобы дальше продать бинарники без кода, но сделать этого он не может, а значит и заказывать разработку такого кода не будет. Реализация же того же функционала с нуля может быть коммерчески не выгодной, поэтому мы имеем то, что имеем: с одной стороны не доведённый до ума опенсорс (зато свободный!), с другой стороны — более или менее стабильный, но дорогой и недостаточно гибкий коммерческий софт. Варианта дать денег авторам GPL-кода чаще всего нет, а значит построение гибкого, стабильного и дешевого софта становится невозможным. Спасибо, GPL.
RPG18
24.04.2017 23:16+1На Линуксе давно надо навести порядок в области создания десктопных юзерских программ.
Это невозможно. Это opensource в действие. Здесь если кому-то, что-то не нравится, то пишут своё. Поэтому и имеет вагон gui библиотек для C++, куча DE, а всяких плееров и не счесть.
А вот стартапы в полном пролёте.
Странные стартапы. Т.к. фонд заработной платы с участием middle и senior разработчиков намного больше 500$. Может быть вы имели ввиду фрилансеров?
В результате мелкий коммерческий софт под Линукс написан кто во что горазд
Пишут на том, что лучше всего знают.
grossws
25.04.2017 00:25Пишут на том, что лучше всего знают.
Или на том, что лучше подходит в конкретной задаче. Например, когда уже активно используется glib вполне и разработчики в большинстве пишет на Си, а не на плюсах, gtk является вполне логичным выбором.
maisvendoo
25.04.2017 07:20
qrKot
25.04.2017 11:23+5Вы уж извините за прямоту, но больше на поток сознания похоже.
>> Python для Линукса — де факто главный язык пользовательского софта.
Вот это вы откуда взяли?
>> Но вот эта конструкция с moc и генерируемым кодом создаёт сложности при попытке привязать Qt к другому языку.
Вообще не оттуда сложности берутся…
>> Ты можешь хотеть выложить свой код под MIT или вообще PD, но облом… в одну программу нельзя юридически включать PyQT и коммерческую библиотеку… ты хочешь потрудиться на благо сообщества, а вместо этого юлишь между законами
Собственно, если хочешь потрудиться на благо сообщества — чем GPL не устраивает? Она для того и придумывалась, чтобы трудиться на благо сообщества.
Тем более, что юлить между законами, как правило, наказуемо, «способы извернуться» — заведомо неверный путь, а «в основном всем просто пофиг» — откровенно ошибочное мнение.
>> кто во что горазд: С++/Qt, Python/Gtk, Go/wxWidgets, NodeJS/(какой фреймворк? ручками нарисую!)
Собственно «C++/Qt» — дефолтное поведение, для того и разрабатывалось, «Python/Gtk» — а почему не Java/Gtk? не C/Gtk? Не С++/Gtk?
>> «а умеет ли Линукс HiDPI? Экраны Брайля? Скины? Чтение с экрана?»
Какбэ, вот эта унификация изначально в другой плоскости. Ждите Wayland-во-все-поля, остальное подтянется.
>> А в глобальных размышлениях о судьбах Линукса они не участвуют.
Какбэ, и слава Б-гу. И вы завязывайте!)
>> хотя Линукс и переходит понемногу на Qt
Вот это вы откуда взяли? Торвальдс в курсе?
TrueBers
С современными фичами C++, мок тупо не нужен, имхо. Он создавался в бородатые времена, когда компиляторы даже базовый стандарт не поддерживали, не говоря уже о шаблонах и прочих стандартных библиотеках, и приходилось городить свои костыли в виде сабжа. Сейчас же практически любую его фичу можно реализовать средствами языка.
Другое дело, что полностью отказываться от него никто не будет в здравом уме…
hasu0
Какие такие современные фичи C++, которые позволят вам сделать рефлексию? Разве что накрутить тех же макросов, которые в итоге и будут разворачиваться во что-то подобное тому, что генерит moc.
TrueBers
Ну так отличие в том, что макросы — это стандарт, а moc — костыль.
Да и до 20-го стандарта не долго осталось уже.
oYASo
Код с примером рефлексии на чистом новом, хоть C++17, можно от вас увидеть? И без boost, пожалуйста.
BratSinot
Смотрите код CS, они там его и реализовывали.
Кстати, если не ошибаюсь то группа занимающаяся стандартом рассматривает рефлексию в C++17? Или я что-то путаю?
Смысл всего этого был в том, чтоб напрямую линковать CS библиотеки к программе, т.е. не нужен qmake/moc, компилятор поддерживающий стандарт все это сделает сам. Идея отличная, насчет реализации не знаю. CS так и не собрался попробовать.
Хотя я так и не нашел информации по *.ui, т.е. в Qt (если я не ошибаюсь) moc так-же транслирует *.ui файлы интерфейса в *.cpp/*.h.
iroln
Этим занимается не moc, а uic. Вообще ui файлы можно динамически грузить в приложение без трансляции в h-файлы.
BratSinot
А ну да, в CS таки есть одна единственная страница посвященная этому делу.
Нужно будет попробовать его полноценно с QtCreator связать.
yshurik
Транслирует ui инструмент uic, который генерирует h/cpp
TrueBers
17-й стандарт был принят в марте, там нет рефлексии. Обещают к 20-му.
На самом деле, в CS продумали довольно много мелочей, которые множество недостатков Кьюта устраняют нативно из коробки без оверхеда и потери информации о типах, плюшки вводят нативные. Рефлексия там на макросах и шаблонах. Но вот, что-то с разработкой у них как-то слишком тухло. Пулл-риквесты рассматривают по полгода, к сожалению. Закрылись от мира, сидят своей кучкой что-то кодят, только релизы синхронизируют с гитхабом, когда им вздумается. А задумка изначально интересная…
oYASo
Да не надо ничего гуглить, я читаю блог автора, у него есть своя реализация QMetaObject без moc. Практически все фичи свежего Qt 5 работают.
Я просил код не потому, что это сделать нельзя, а потому что это такие же костыли. При этом, если у Оливера получилось сделать Qt без moc почти также со стороны производительности, времени компиляции, бинарной совместимости, то у CS получилось откровенное хреново все.
Может быть позже, когда это все будет в стандарте, я полностью соглашусь с мнением, что moc можно выбросить на помойку, но сейчас замена одних костылей на другие костыли едва ли принесет хоть какую-то пользу.
oYASo
Рефлексию будут рассматривать в C++20. Ну и не факт, что примут (и это будет жаль).
Причем здесь линковка, qmake и moc? Идея CS — убрать moc, то есть генерацию исходников с кодом метаинформации на основе других исходников, использующих макрос Q_OBJECT. Идея-то, в целом, хорошая, позволит, например, использовать шаблонные классы с QObject, но на текущий момент она решается точно таким же костылированием, что и moc. При этом, еще и выдает намного меньшую скорость.
BratSinot
А при том, что программу на Qt нельзя просто так взять и (примерно):
Потому-что moc еще должен сгенерировать того, чего нет. А так как в CS рефлексия реализована чисто на C++11, то можно просто «заинклудить» и «прилинковать» что нужно.
oYASo
А, ну вы про компиляцию, а не линковку — тут вопросов нет.
Как я уже писал в соседних сообщениях, это все будет хорошо, если будет в стандарте. Пока у CS есть и обратная сторона:
1) время компиляции
2) размер получаемых файлов
3) производительность
и самый важный косяк
4) нет бинарной совместимости
BratSinot
А у Qt лучше что-ль? Вот была у меня программа которая использовала WebView, так этот единственный модуль тащил за собой (из-за того что слинкован с оными) совершенно ненужные вещи, такие как QtSensor, QML, Quick и еще что-то, чего я уже не помню.
В Qt Lite начались какие-то подвижки в сторону разрешения подобных вещей, но опять-же это началось относительно недавно.
Да и вообще, есть же LTO. Можно сразу разрабатывать с оглядкой на него.
А можете пояснить где ломается ABI? Если у них рефлексия вся в заголовочных файлах (макросы и другая магия), то на библиотеки вообще плевать, оно все static получается.
oYASo
Размеры бинарников Qt находятся на адекватном уровне. QtCore где-то в 3.5 раза больше libstdc++, но и предоставляемый функционал намного шире. Собранного CS у меня нет, но, вангую, из-за
Соглашусь, конечно, что иногда нужный функционал лежит где-то не там, и брать здоровенный модуль ради одной нужной функции очень не хочется. Но это проблема всегда будет преследовать большие проекты — что и куда класть, как разделять логику модулей.
Ну Qt с LTO собирается.
Если мы инлайним шаблонный код в сорцы нашей либы, то любое изменение каких-либо задействованных структур данных приведет к полной перекомпиляции либы, которая станет несовместимой с предыдущей реализацией. Конечно, есть решения, но это дополнительная сложность. Почитать, например, можно тут.
encyclopedist
magic_get Рефлексия без макросов, правда только для POD типов.