пятница, 9 августа 2013 г.

[prog] Способ управления расположением результатов компиляции в Mxx_ru

В далеком уже 2004-м году я в очередной раз сделал собственный кроссплатформенный build tool, но уже на основе языка Ruby -- Mxx_ru. С тех пор им и пользуюсь.

В Mxx_ru есть возможность управлять размещением результатов компиляции C/C++ проектов (как то: объектные файлы, исполнимые файлы, динамически-загружаемые библиотеки, статические библиотеки, библиотеки импорта, res-файлы). Это осуществляется посредством методов obj_placement и global_obj_placement, которые доступны внутри target-а. Для того, чтобы изменить способ размещения результатов компиляции нужно создать соответствующий объект и передать его в метод obj_placement/global_obj_placement. Например:

MxxRu::Cpp::exe_target {
   target 'hello_world'

   obj_placement MxxRu::Cpp::CustomSubdirObjPlacement.new(
      'bin32',
      'tmp32' )

   ...
}

В результате этого все объектные файлы, относящиеся к цели 'hello_world' будут помещены в подкаталог tmp32 текущего каталога. А исполнимый файл hello_world (или hello_world.exe) будет помещен в подкаталог bin32 текущего каталога.

Если бы вместо метода obj_placement был вызван метод global_obj_placement, то эти настройки применялись бы не только к цели hello_world, но и ко всем другим целям, которые строятся вместе с hello_world. Обычным местом для обращения к global_obj_placement является корневой проектный файл build.rb.

В текущих версиях Mxx_ru есть три готовых реализации ObjPlacement, которые готовы к использованию "из коробки":

  • SourceSubdirObjPlacement. В этом случае объектные файлы размещаются в подкаталогах рядом с исходными файлами;
  • CustomSubdirObjPlacement (упомянут выше). В этом случае отдельно от всего остального размещаются конечные результаты компиляции (exe/dll/lib/so/a-файлы) и промежуточные файлы (obj/o/res);
  • RuntimeSubdirObjPlacement. В этом случае создается отдельные деревья подкаталогов для разных режимов компиляции: для RELEASE, DEBUG и DEFAULT билдов.

По умолчанию используется вариант SourceSubdirObjPlacement. Потому, что для меня он очень долго был самым удобным: обычно на конкретной рабочей станции или на инстансе виртуальной машины я использовал всего один компилятор и собирал проекты всегда в RELEASE-режиме (крайне редко использовал DEBUG-сборки в последние 10-15 лет).

Но вот сейчас, в связи с возобновлением активного собственного участия в разработке SObjectizer, ситуация несколько изменилась: рабочая станция в распоряжении всего одна, а проверять проект нужно под разными компиляторами. В таких условиях SourceSubdirObjPlacement не подходит. Ведь для того, чтобы, например, после проверки 64-битовым VC++ перейти к проверке 64-х битовым MinGW, а затем еще и к 32-х битовому VC++, нужно делать полные clean-апы, а потом полные ребилды новым компилятором. Если нужно проверить небольшую правку в исходниках с прогоном unit-тестов, то это явно не вариант.

В таких условиях на помощь приходит RuntimeSubdirObjPlacement. Ему в конструктор можно передать имя корня дерева каталогов. Если это имя строить с учетом текущего тулсета, то как раз получается, что результаты работы разных компиляторов будут находиться в разных каталогах и не будут мешать друг другу. Я сейчас задействую эту возможность следующим образом:

version = toolset.tag( 'ver_hi''x' ) + '_' + toolset.tag( 'ver_lo''x' )
arch = ENV'Platform' ] ? ENV'Platform' ] : 'generic'
global_obj_placement MxxRu::Cpp::RuntimeSubdirObjPlacement.new(
 '_' + toolset.name + '_' + version + '_' + arch )

Такой вариант позволяет получать имена каталогов вроде '_vc_10_0_X64' и '_gcc_x_x_generic'.

Это работает, но выглядит не очень красиво. На данный момент у toolset-а нет метода, который бы построил какое-то довольно уникальное развернутое имя toolset-а. Штатный метод toolset.name возвращает сокращенные имена семейств инструментов, вроде vc или gcc. Поэтому сейчас я строю такое уникальное имя вручную на основании знаний о некоторых деталях реализации тулсетов и особенностей компиляторов.

Хочется эту ситуацию улучшить. Пока есть идея ввести в состав toolset-а метод describe или make_descriptive_name, который бы возвращал готовый результат, пригодный для передачи в RuntimeSubdirObjPlacement. Чтобы все эти специфические для компилятора детали обрабатывались во внутренностях toolset-а. Там больше возможностей для того, чтобы, скажем, запустить 'gcc -v', распарсить его результат и получить что-то вроде: gcc__4_7_1_tdm64_1__x86_64-w64-mingw32 или gcc__4_8_1_GCC__x86_64-pc-cygwin.

Надеюсь, в следующих версиях Mxx_ru эта функциональность появится. Поэтому, если у кого-то есть идеи или предложения на этот счет, то я их с удовольствием и большим вниманием выслушаю.

четверг, 8 августа 2013 г.

[prog.business] Несколько ссылок на тему заработка на OpenSource

Ссылка первая. Презентация Michael Widenius (отца MySQL и MariaDB) "How to create a successful open source project" с конференции OSCON 2013.

Ссылка вторая. Запись в блоге все того же Michael Widenius кастельно новой бизнес-модели: Business Source (A software license with some Open Source aspects).

Ссылка третья. Статья Michael Widenius и Linus Nyman, более подробно рассказывающая о понятии Business Source: "Introducing “Business Source”: The Future of Corporate Open Source Licensing?"


Коротко о том, что за идея лежит в основе Business Source.

Есть три устоявшиеся модели заработка на основе Open Source разработок:

1. Получение денег не за сам продукт (который полностью открыт), а за сопутствующие "услуги": обучение/консультирование, техподдержка, разработка кастомных версий или внедрение на площадке заказчика. Характеризуется невысокой долей прибыльности и высокими затратами -- необходимо вести и разработку продукта, и те самые дополнительные услуги. Зато при этом пользователи продукта имеют в своем распоряжении весь продукт, что стимулирует их участвовать в разработке (тем самым беря на себя часть издержек разработчика продукта). Так же клиенты защищены от т.н. vendor lock (опять же потому, что код всего продукта полностью свободен).

2. Разделение продукта на открытую составляющую и закрытую (т.н. модель Open Core). Клиенты бесплатно пользуются полностью открытой частью продукта, но вынуждены платить за использование закрытой части. При этом необязательно клиенты получают доступ к исходникам этой закрытой части. Примером продукта на модели Open Core является EnterpriseDB, где бизнес строится вокруг платных дополнений к открытой PostgeSQL. Достоинством этой модели для производителя продукта является более высокая (по сравнению с первой моделью) прибыльность. Но, с другой стороны, клиенты находятся в зависимости от поставщика закрытой части (т.е. такой же vendor lock, как и в случае с полностью проприетарными продуктами). Плюс, если у клиентов нет доступа к исходникам закрытой части, то они не могут принимать участие в их разработке/развитии, тем самым производитель продукта сам несет все издержки по его разработке.

3. Двойное лицензирование. Для некоммерческого использования продукт распространяется, как правило, под GPL лицензией. Для коммерческого использования продукт поставляется под отдельной лицензией, за которую нужно платить. Яркий пример: библиотека Qt, которая очень долгое время была под GPL и отдельной коммерческой лицензией. Эта модель так же более прибыльная, чем первая. Но при этом у клиентов нет vendor lock-а, клиенту доступен весь исходный код, что может сподвигнуть клиента на помощь в разработке/сопровождении продукта. Однако, тут могут возникнуть проблемы с тем, на каких условиях перелицензируется код, получаемый в виде патчей от клиентов: если все права передаются производителю продукта, то у клиента снижается стимул заниматься этими патчами.

К этим моделям предлагается еще одна: весь код продукта распространяется под специальной двойной лицензией. Эта лицензия для бОльшей части пользователей продукта оставляет возможность бесплатного использования продукта. Но малой части (рекомендуется ориентироваться на диапазон в рамках 1/1000..1/100 от общего количества) пользователей нужно платить за продукт. В простейшем случае обычное двойное лицензирование: некоммерческое использование бесплатно, коммерческое платно.

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

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

вторник, 6 августа 2013 г.

[prog.jvm] Язык Gosu выглядит как уже готовая замена Java

Полагаю, что среди действующих Java-разработчиков (т.е. тех, кто зарабатывает себе на жизнь разработкой на Java), найдется немало желающих сменить Java на что-нибудь более удобное, мощное, но не слишком сложное. Такой заменой лично мне ранее представлялся язык Scala. Но, предположу, что его сложность уже давно превысила все мыслимые для мейнстрима пределы :) Поэтому обычные, средние разработчики, которым язык программирования нужен не для решения головоломок и разминания мозгов для удовольствия (к коим я отношу и себя), на Scala перейдут без энтузиазма и только в приказном порядке :)

Может я преувеличиваю, но мне кажется, что есть достаточное количество Java-программистов, которые с интересом смотрят на развитие Ceylon-а и Kotlin-а. Очень надеюсь, что не без основания. Мне самому, например, очень интересно будет посмотреть на официально выпущенные релизные версии этих языков (могу ошибаться, но, по-моему, ни один из них пока не дошел до версии 1.0).

Однако, на днях с удивлением и интересом обнаружил, что для JVM уже есть очень симпатичный язык, который, по первому взгляду на него, производит впечатление правильно сделанной замены Java. Это язык Gosu.

Сразу скажу, что на Gosu я не программировал. Мои знания заканчиваются где-то вскоре за пределами краткого введения в язык + еще нескольких материалов, ссылки на которые я дам в конце заметки. Но то, что я увидел при беглом просмотре, выглядит весьма привлекательно. Так что, возникни у меня сейчас настоятельная необходимость начать делать что-то большое и серьезное на JVM, я бы в первую очередь посмотрел на язык Gosu.

Если попробовать тезисно набросать список достоинств языка, то получится что-то вроде:

  • вывод типов;
  • поддержка т.н. properties (лично для меня это не есть интересная фича, но для мира Java, где принято делать setter-ы и getter-ы на каждый чих, облегчение этой работы не может не радовать);
  • null safety (специальный синтаксис для обращения по ссылкам с проверкой нулевого значения ссылки);
  • именованные аргументы методов и аргументы со значениями по умолчанию;
  • возможность делегирования реализации интерфейса члену класса;
  • конструкция using (аналог таковой из C#, своего рода замена C++ному RAII);
  • лямбда-функции, они же closures, называемые в Gosu блоками (по аналогии с Ruby);
  • возможность расширения чужих классов своими методами под названием enhancements (что-то в духе extension methods из C#);
  • более простые и мощные генерики, чем в Java;
  • встроенный в язык string interpolation (т.е. возможность писать print ("${s1}"), где s1 -- это переменная, строковое значение которой будет вставлено в аргумент для print);
  • удобный синтаксический сахар для работы с коллекциями/контейнерами (достигнутый как синтаксическими возможностями языка, так и enhancement-ами над стандартными классами коллекций);
  • поддержка REPL;
  • при этом все статически типизированное, с полной поддержкой Java, с наличием плагина для IDEA.

В принципе, уже этого было бы достаточно, чтобы дать языку шанс в новом проекте вместо Java. Но главной killer feature языка его авторы считают такую штуку, как Open Type System. Боюсь сейчас соврать (т.к. на Gosu я не программировал), но это выглядит как система плагинов, которые расширяют компилятор Gosu информацией о новых типах/классах. Причем откуда берется эта информация для компилятора не важно -- это может быть XSD схема, описание SQL-ных таблиц, URL-сайта для Web-приложения или что-то еще. Важно, что после того, как соответствующий плагин задействован, программист может работать с подключенной через плагин сущностью как с обычным классом. Вот пример работы с XSD от разработчиков Gosu:

XSD описание:

<xs:element name=”DriverInfo”>
 <xs:complexType>
  <xs:sequence>
   <xs:element ref=”DriversLicense” minOccurs=”0″ maxOccurs=”unbounded”/>
   <xs:element name=”PurposeUse” type=”String” minOccurs=”0″/>
   <xs:element name=”PermissionInd” type=”String” minOccurs=”0″/>
   <xs:element name=”OperatorAtFaultInd” type=”String” minOccurs=”0″/>
  </xs:sequence>
  <xs:attribute name=”id” type=”xs:ID” use=”optional”/>
 </xs:complexType>
</xs:element>
<xs:element name=”DriversLicense”>
 <xs:complexType>
  <xs:sequence>
   <xs:element name=”DriversLicenseNumber” type=”String”/>
   <xs:element name=”StateProv” type=”String” minOccurs=”0″/>
   <xs:element name=”CountryCd” type=”String” minOccurs=”0″/>
  </xs:sequence>
  <xs:attribute name=”id” type=”xs:ID” use=”optional”/>
 </xs:complexType>
</xs:element>

Это то, как с ним можно работать в программе:

uses xsd.driver.DriverInfo
uses xsd.driver.DriversLicense
uses java.util.ArrayList

function makeSampleDriver() : DriverInfo {
  var driver = new DriverInfo(){:PurposeUse = “Truck”}
  driver.DriversLicenses = new ArrayList()
  driver.DriversLicenses.add(new DriversLicense(){:CountryCd = “US”, :StateProv = “AL”})
  return driver
}

При этом разработчику обеспечиваются две важные вещи. Во-первых, он имеет полную поддержку от IDE, включая автокомплит, рефакторинг, всплывающие подсказки и пр. Во-вторых, если XSD-описание изменяется (например, меняются названия элементов), то код перестает компилироваться (т.е. полностью работает статическая типизация).

Повторюсь, авторы Gosu считают Open Type System главной отличительной особенностью языка (весь остальной синтаксический сахар либо есть у аналогов, либо в том или ином виде может появится в самой Java). В доказательство важности этой фичи приведу следующую обширную цитату:

Now with Ronin, the web framework for Gosu created by Gus Prevas, and Tosa, the SQL-focused OR layer for Gosu authored by Alan Keefer and Carson Gross, programmers can be extremely productive building hardcore web applications in Gosu with IntelliJ. Where else can you build web applications where the links are statically verified? Where else can you directly reference your SQL DDL and access queries with static types using code completion, all with no code generation? What other static language lets you modify types corresponding with your web content, even the structure of the types, and immediately see the results in the browser? (I’m going to keep going with this.) Can your JVM language directly expose arbitrary XML schemas where elements are types and attributes are properties with no code generation? Unless you have Dana Lank’s XSD/XML framework and your language is Gosu, it can’t. And even if it could, it couldn’t dream of having an IDE like IntelliJ refactor the name of an XML element and automatically rename all references to it in your code.

Не пользуясь Gosu и не пробуя создать свой плагин для поддержки нужных мне типов (например, через Open Type System в Gosu можно было бы вводить описания SObjectizer-овских агентов или сериализуемых посредством ObjESSty объектов) сложно судить, насколько это действительно важная вещь для разработки прикладного ПО с использованием Gosu. Но сам факт того, что эта возможность есть и она уже встроена в довольно простой язык, который при всем прочем сильно ограничивает полет фантазии и не дает писать комбайны в духе Александреску, не может не привлекать внимание.

Однако для меня неким "знаком качества" и "страховкой", которые заставляют смотреть на Gosu серьезно, а не как на очередную потенциально интересную штуку (коими сейчас являются Ceylon и Kotlin, и которой когда-то давным-давно была Scala), является то, что Gosu создавался и уже длительное время используется для разработки реальных вещей. Он появился внутри компании Guideware в 2002-м году. Сначала как скриптовый язык, затем постепенно он начал обрастать возможностями, которые нужны были разработчикам Guideware для нормальной работы. И постепенно превратился в серьезный и "взрослый" инструмент, который в районе 2010 года был выпущен в свет в качестве открытого инструмента. Т.е. для меня намного важнее сам факт того, что его делают нормальные программисты, которые занимаются нормальной разработкой (напомню, что таковыми были, например, Деннис Ричи (С), Бьёрн Страуструп (С++), Джеймс Гослинг (Java), Андрес Хайлсберг (Dephi, C#) и таковым не был, например, Мартин Одерски (Scala)). В таких условиях вероятность получить практичный язык для повседневных задач намного выше, чем когда развитием языка занимаются ученые от computer science или же обезличенные забюрократизированные комитеты.

Еще один фактор, который сделал бы для меня Gosu более предпочтительным, чем Ceylon или Kotlin -- это объем документации по Gosu, которая доступна на сайте языка. По себе знаю, что снабдить подробной документацией самодельный инструмент, который постоянно используется и постепенно развивается, это намного сложнее, чем создать и развивать этот инструмент.

Ну и еще один очень важный фактор, который крайне субьективен, но именно поэтому и важен лично для меня. Это созвучие мыслей, мнений и идей, высказанных автором языка Gosu с моими собственными мыслями на счет того, каким должен быть мейнстримовый язык. Полагаю, что фанатам Scala или Haskell эти мысли и мнения будут казаться унылыми стенаниями замшелых старперов-ниасиляторов. Ну и флаг вам, дорогие товарищи, в руки. Работы хватит для всех.

А теперь обещанные ссылки:

  • gosu-lang.org -- сайт языка;
  • getting started -- краткая информация о языке, практически рекламного характера. Хороша для того, чтобы составить впечатление о том, привлекает ли язык с эстетической точки зрения;
  • небольшая презентация о языке Gosu в виде PDF, хорошо рассказывающая об основных особенностях языка от его автора Скотта МасКинни;
  • полная документация по языку;
  • серия блог-постов Скотта МасКинни о Gosu: Why Gosu?, Gosu’s Secret Sauce: The Open Type System, What Differentiates Gosu From Other Languages? (очень рекомендую эти заметки для того, чтобы вы сами могли понять, по пути ли вам с разработчиками Gosu или же вы совсем не разделяете их взгляды на то, каким должен быть современный язык программирования для массового применения);
  • Upd. lazygosu.org -- еще один ресурс, который рассказывает об основных особенностях языка.

PS. Понимаю, что мои слова выглядят двусмысленно: мол, сам он язык Gosu использовать не будет, но советует пристально посмотреть на него. Тем не менее, не будь у меня багажа в C++, который я не собираюсь бросать, и будь у меня необходимость работать на JVM, я бы не стал ждать стабилизации Ceylon-а и Kotlin-а, а попробовал задействовать Gosu в какой-нибудь proof-of-concept разработке уже сейчас. Ну и, кстати говоря, если возникнет необходимость портировать SObjectizer на JVM, то Gosu будет первым в списке претендентов на язык реализации SObjectizer-on-JVM.

понедельник, 5 августа 2013 г.

[soft.middleware] Презентация "State of the MQ" c OSCON2012

Просматривая список докладов с прошлогодней конференции OSCON-2012 зацепился взглядом за доклад "State of the MQ". Интересно.

Незадолго до ухода из Интервэйл я инициировал небольшое исследование по выбору системы MQ для организации взаимодействия между разнородными компонентами, разрабатываемыми разными отделами компании. По некоторым причинам с организацией этого исследования я толком не справился. В итоге мы сначала попробовали Apache Qpid, затем довольно быстро отказались от него в пользу RabbitMQ. Хотя с RabbitMQ то же вроде как не все ладно, но с последствиями приходится разбираться уже не мне :(

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

PDF-версия презентации State of the MQ.

Материалы к этой презентации на GitHub, включая исходники тестов.

PS. В презентации понравилась так же цитата по поводу ZeroMQ: Let it be clear, zeromq is useful if you are so stupid you don't understand <socket.h> (by Artur Bergman) ;)

воскресенье, 4 августа 2013 г.

[life] Вопрос к бывалым собаководам

Это мне кажется или хозяева собаки из этого ролика действительно сами наживают себе проблемы с питомцем?

Если верить Animal Planet, то в Штатах в приюте для бездомных собак такую псину бы без сожалений усыпили бы, т.к. она провалила тест на агрессию к человеку (когда собаке в миску с едой подсовывают муляж человеческой руки). Да и вообще, зверь рычит на хозяев, а они его за это на руки берут и ласково успокаивают. Как же ему уразуметь, что нельзя рыпаться на человека?