stunpix

Персональный бортжурнал

Слабые стороны cmake

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

Хочу рассказать о слабых местах cmake. Возможно эта заметка поможет тому, кто начинает новый проект и нужно принять решение собирать его используя cmake или нет.

Два слова о том где я использую cmake и почему на мой опыт можно принимать во внимание. Как я уже писал где-то ранее в блоге, мой основной проект - это браузер webkit для автомобильных систем и для сборок мы используем cmake. Для сборки используется Ubuntu, а целевые платформы это qnx arm/i386 и linux arm. В нашем случае cmake генерирует makefile'ы, а дальнейшая сборка идёт при помощи обычного make. Чтобы представить весь зоопарк, который нам нужно собрать скажу только, что только в пределах одной платформы webkit собирается в 2-3 конфигурациях с разным функционалом. Решение взять cmake было продиктовано тем, что в webkit комьюнити уже имеется вариант сборки при помощи cmake. Поначалу мы использовали cmake скрипты из комьюнити, но когда список конфигураций перевалил за десяток - стало резко неудобно, поскольку cmake скрипты превратились в лапшу из наших патчей. В итоге я переписал с нуля все cmake скрипты для наших нужд.

Чем больше я углублялся в сборку на базе cmake, тем явственнее вылазили его слабые места. У cmake есть много вещей на которые можно ткнуть пальцем и сказать "это должно быть проще/лучше/понятнее", но в целом это можно так или иначе решить. То, слабое место о котором я хотел бы рассказать - это кросскомпиляция.

Toolchain

Первое с чем сталкивается разработчик кросплатформенного проекта - это toolchain, т.е. набор утилит с помощью которого производится сборка под целевую платформу и архитектуру. К примеру в мире скриптов configure принято, что toolchain можно переопределить с помощью переменных окружения, например CC и LD, которые указывают компилятор и линковщик. В мире cmake можно забыть об этом - cmake не только не видит этих общепринятых переменных окружения, но и своих не имеет. Идеология cmake подразумевает, что ваша основаная задача - это собрать проект только для той платформы на которой запускается cmake, т.е. текущей.

Для понимания слабой стороны, надо в понять как работает cmake. В двух словах это можно описать примерно так: cmake определяет на какой платформе он запустился, в зависимости от платформы подгружает свои конфигурационные скрипты, выбирает стандартный для данной платформы компилятор+линковщик, в соответствии с платформой/компилятором устанавливает набор разных опций, затем несколько раз запускает компилятор, чтобы собрать о нём информацию, затем загружает главный скрипт CMakefile.txt, приступает к его разбору и наконец генерирует makefiles (либо проекты для IDE). Всё это удобно пока ваша целевая платформа та, на которой вы собираетесь.

Что надо сделать чтобы запустить кросскомпиляцию под совершенно другую архитектуру и платформу? Тут мы сталкиваемся с первой непродуманностью: кросскомпиляция, по всей видимости, изначально не задумывалась (это моё субъективное мнение) и создаётся впечатление, что её прилепили гараздо позже как смогли. Так вот, чтобы указать список компиляторов и линковщиков для cmake надо создать специальный файл, к примеру toolchain.cmake, с таким содержимым:

set(CMAKE_C_COMPILER my_arm_gcc)
set(CMAKE_CXX_COMPILER my_arm_g++)
set(CMAKE_AR my_arm_ar)

После того как файл создан, надо запустить cmake и указать ему этот файл в переменной CMAKE_TOOLCHAIN_FILE:

cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake

Т.е. чтобы собрать под другую платформу, требуется создать дополнительный файл, присвоить его имя переменной CMAKE_TOOLCHAIN_FILE, которую можно передать только в аргументах cmake. Иначе никак. Я это нахожу достаточно неудобным. Возможно, те кто уже имел дело с cmake спросят: «а почему бы не указать переменные CMAKE_C_COMPILER, CMAKE_CXX_COMPILER и другие непосредственно внутри основного скрипта? Зачем этот отдельный файл?». Короткий ответ: из-за особенности cmake не получится.

Развёрнутый ответ: это требуется из-за того, что cmake работает с некоторыми переменными иначе чем со всеми остальными. В cmake есть некоторое количество переменных которые cmake отслеживает и если они в какой-то момент изменились, то выполняется некоторое действие. Так, например, если установить CMAKE_C_COMPILER или CMAKE_CXX_COMPILER в новое значение, то cmake это отследит и запустит диагностику его возможностей. Поэтому, после установки этих переменных происходит перезапуск стадии диагностики и последующая повторная загрузка основного CMakefile.txt в котором... снова установка переменной компилятора. В общем чистой воды рекурсия. Чтобы её избежать и требуется внешний файл, который загрузится до основного скрипта только один раз и никаких перезапусков основного скрипта не потребуется.

Замена линковщика

У cmake есть ещё одна неприятная особенность – у него нельзя штатными средствами изменить линковщик отличный от того, что выбрал cmake. На linux/unix платформах gcc является универсальным фасадом для целого набора утилит и в зависимости от того, что будет на входе, gcc может либо компилировать исходный код, либо линковать объектные файлы в финальный исполняемый бинарник. Поэтому если ваш основной toolchain основан на gcc, то cmake для линковки и компиляции будет использовать только фасад gcc. Отсюда вытекает неожиданное следствие - переменная CMAKE_C_COMPILER определяет не только компилятор, но и линковщик. Переменных чтобы установить линковщик попросту нет.

Чем же это плохо? Пример из нашего проекта: мы столкнулись с тем, что qnx toolchain существует только 32 разрядный и при debug сборке некоторые статические библиотеки превышают 2Гб. Как следствие у 32 разрядного qnx toolchain начинаются проблемы с их линковкой. Было принято решение заменить штатный qnx линковщик на более современный gold, но нас ждал большой сюрприз, когда выяснилось, что мы этого не можем сделать без глубоких хаков.

На счёт глубоких хаков. После некоторых поисков и изучения внутренних скриптов cmake я обнаружил, что стадию линковки всё же можно изменить переопределив переменную CMAKE_C_LINK_EXECUTABLE (важно: эта переменная - полная командная строка с аргументами для линковки, а не просто имя линковщика). Но даже используя эту переменную нам не получилось толком подменить линковщик на gold, поскольку cmake считает, что линковщик только gcc совместимый и передаёт ему аргументы как для gcc, а gold их не понимает. В итоге мы отказались от этой затеи и для debug сборки мы разделили большие библиотеки на более маленькие.

Выводы

Исходя из личного опыта я бы не рекомендовал cmake для сложных проектов c кросскомпиляцией под множественные платформы и большим разнообразием toolchain'ов. До поры до времени, вы сможете решать встающие перед вами ограничения, но рано или поздно вы упрётесь во что-то, что не сможете обойти без грязного хака (при условии что вы найдёте его). В этой заметке я описал только два существенных упущения в дизайне cmake, но на самом деле их немного больше чем два, но писать об этом можно долго. В таких проектах всё же лучше использовать старый добрый make поскольку он позволяет гараздо обширнее контролировать этапы сборки и toolchain'ы.


Как я сравнивал Sony XBA-4, Ultimate Ears UE900/700/600 и Apple EarPods

Находясь в данный момент в Сеуле я решил заскочить в магазин аудиотехники и послушать разные наушники. Не буду рассказывать про то, что в местных магазинах выбор широкий, а самое приятное – всё можно послушать. Буквально пол года назад находясь в Германии, я заходил в большой супермаркет электроники MediaMart и не увидел особого разнообразия IEM наушников (или «затычек» по нашему). Но раз мне тут представилась возможность – послушаю как можно больше. Примерно так изнутри выглядит рай (в жизни магазин EarphoneShop) для любителей звука:

В данный момент я являюсь обладателем четырёхдрайверных арматурных наушников Sony XBA-4i, а предыдущие наушники у меня были Ultimate Ears UE700 (они же мои первые арматурные) и тогда я узнал, что такое Звук после обычных динамических. До UE700 у меня были Beyerdynamic DTX100, а до них AKG K324P.

Делаю сразу заметку: я не тяну на аудиофила - я инженер, поэтому субъективных оценок вроде «лёгкий напористый бас в нижней части середины» – это не про меня. У меня всё проще: низы, середна и верхи, никаких субъективных имён для звука.

Располагать рассматренные наушники я буду в порядке возрастания качества, начиная с наименее понравившихся из прослушанных мной. Всё прослушивание делалось в магазине при помощи iPhone 5, который в тот момент только и был под рукой. И самое главное: я сравнивал все модели просто переходя от стенда к стенду, что определённо повышает точность определения разницы между наушниками, т.к. не приходится полагаться на отдалённую память, что ты когда-то там слушал.

Ultimate Ears UE 600

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

Sony XBA-4i

Да-да. Не смотря на то, что я владелец сонек я отдаю им предпоследнее по качеству место. У этого есть много причин.

Во-первых, конструкция. Она крайне неудачная на мой взгляд. Вставляются в уши они более-менее, но удобство ношения из-за их конструктива – ужасное. Да и выглядят они далеко не отлично. Учитывая, что я крупного телосложения – даже на мне они смотрятся неудачно торчащими из ушей, как у какого-то робота.

Пустить провод поверх уха – ещё более не удобно, т.к. провода не имеют специального укрепления для этого и через минуту всё вываливается из уха. Да и вообще, при любом раскладе вываливаются - это вопрос времени. Среди других особенностей конструкции стоит отметить какой-то странный феномен с щелчками. Да, именно с щелчками. Я был удивлён, но иногда появляется лёгкое потрескивание во время прослушивания, причём в такт музыке. Хотя если пальцем слегка прижать наушник к уху, то щелчки в большинстве случаев пропадали. То ли что-то не прилегает как надо, то ли от хороших басов резинка отходит от ушного канала с характерным пощёлкиванием - не ясно. Иногда это не проявляется, иногда прижав пальцем избавляешься, а иногда не получается избавиться "пальцевым" методом и приходится идти по улице и слушать с потрескиванием. Итог простой – конструкция неудобная и вызывает разные проблемы.

Вторая причина – провод. Провод у наушников излишне длинный. Sony в комплект включила даже катушку на которую можно наматывать провод, что я и делаю. Как следствие у меня катушка болтается снаружи. Конечно можно постараться её в карман засунуть, но в моём случае я ношу телефон в карманах джинс, а катушка по размерам с мизинец (что крупно), то у меня нет другого варианта, как оставить её болтаться снаружи. Так же не порадовал и профиль кабеля – он не круглый, а приплюснутый. Это не удобно, т.к. как только начинаешь сматывать наушники, то кабель норовит стать ребром усложняя сматывание. Ну и при ношении он немного закручивается и это выглядит неопрятно, т.к. с приплюснутым кабелем особенно заметно на сколько сильно он закрутился.

Третья причина – звук. За те деньги, что просит Sony – звук расстроил. Причиной покупки сонек стала неожиданная смерть UE700 (провода перегнулись и оборвались) и пришлось что-то искать им на замену. После некоторых поисков и чтения обзоров head-fi.org я выбрал эту Соньку. На ресурсе Соньке дали 9/10 баллов за звук учитывая, что в том обзоре участвовало более 200 IEM и только десяток IEM получил оценку выше 9, так что Сонька смотрелась выгодно. В итоге, даже учитывая, что между покупкой соньки и поломкой предыдущих прошло около двух месяцев – я всё равно почуствовал, что с серединой у сонек какие-то проблемы. Итак звук. В наушниках стоят 4 излучателя – сверхнизкие, низкие, средние и высокие. К области низких и верхних претензий нет – всё отлично, басы насыщены даже чуть более чем надо (сони это выкатывает как фишку этой модели). Но вот с серединой, что-то нехорошо. Середина вроде играет, но постоянно не покидает ощущение, что она то ли приглушённая, то ли не вытягивает и голоса звучат невнятно. Иногда вообще кажется, что запись плохая и на столько пережатая, что среднина так искажена. Но тут же спохватывашься, что lossless трек играет хорошо ведь низы и верхи отлично отыгрывают!

Вердикт – ну ни как не тянут эти наушники на 9 баллов из 10 – максимум на 5 из 10.

Apple EarPods

Даю яблочным ушам оценку выше чем сонькам потому, что я попросту соньку я постепенно перестал носить взяв на замену родные EarPods из компекта iPhone. Конструктив у этих наушников просто отменный. Прекрасно лежат в ушах, очень удобная кнопка управления на проводе (у сони кстати это тоже минус), звук как для динамических наушников (причём стоковых) просто отличный. Я не сильно почувствовал, что потерял в звуке когда перестал носить соньки. Да, у EarPods не такие кристальные верхи. Да, не такие глубокие басы, но всё равно они очень хорошо звучат. Верхи достаточно чёткие, не урезанные, низы вполне приятные, середина просто хорошая. Можно наслаждаться и музыкой и удобным конструктивом. Как по мне, то эти наушники просто обязаны быть де-факто среди стоковых наушников. Ложка дёгтя конечно есть, но она не столь драматична – изоляция от внешнего мира очень и очень слаба. В вашу музыку постоянно кто-то будет врываться – то грохот проезжающего транспорта, то громкие сигналы авто, то ругань пассажиров автобуса. Ну и конечно же окружающие будут слышать вашу музыку. Мой вердикт – пусть эти наушники не идеальны в звуке, но за свои деньги, да ещё с удобным конструктивом они просто отличные.

Ultimate Ears UE700

Это лучший кандидат на апгрейд после динамических наушников. Это двухдрайвенная модель вполне логичная последовательница UE600. Эти наушники имеют выраженное V-образное звучание – низы глубоки, верхи кристальны и резки, а середина… ну середина просто есть. Находясь в магазине я снова их одел и вспомнил как они звучат на фоне всех остальных. Верхи немного резковатые, но всё равно вполне очень и очень хорошо звучат после любых обычных динамических. Когда я впервые одел эти наушники, я был сильно поражён – я будто заново слушал музыку с вытащенной из ушей ватой. Я поначалу был очень опечален плохими низами, но перепробовав разные насадки – выбрал нужные и басы зазвучали. Не так чтобы аж мурашки по коже, но гораздо лучше. Так что общая рекомендация для любителей «затычек» – если чувствуете, что не хватает басов – меняйте насадки, вероятно наушники плохо прилегают к ушному каналу и воздух просачивается не создавая достаточного давления для басов.

Почему же я поставил эту модель выше сонек? Почти по всем параметрам: цена значительно ниже, конструктив просто отличный (наушники крохотные и отлично ложатся в ухо), звук очень хороший. Возможно не очень хорошо, что у этой модели он V-образный, но у меня не возникло ощущения, что середина была как-то искажена как в соньках. Но куда уж без ложки дёгтя: провода. Провода сделаны из какого-то материала, который на ощупь как мягкая резина и на морозе он затвердевает. При неаккуратном движении затвердевший провод «выталквает» наушники из ушей. Второй неприятный момент с проводами – они недолговечны. Мои провода перетёрлись и лопнули в районе разъёма и наушников, а затем и вовсе оторвались менее чем за год.

Вывод – очень хорошие наушники, хоть высокие слегка резковаты, а низов могло бы быть чуточку больше, плюс середина не особо выделяется, но в целом звучание чистое, чёткое, яркое. Человеку не избалованным Hi-End аппаратурой звук покажется очень ярким и чистым. После динамических музыка открывается с новой стороны. Провода, увы, не долговечные, но в любом случае очень рекомендую как апгрейд с динамических. Хотя есть ещё один минус у наушников – они исчезают из продажи, так что если решили купить, то стоит поторопиться.

Ultimate Ears UE900

Одевал я UE900 в магазине минуты две. Пытался разобраться как же они перебрасываются через ухо и был слегка расстроен излишней сложностью. Одевание усложняется тем, что кабель у наушников отсоединяемый и как следствие наушники вращаются в месте крепления - это немного усложняет попытку одеть. Когда я их всё же одел, тут же почувствовал себя в них очень комфортно – конструктив выше похвал, наушники легли как влитые без каких либо тенденций вывалится. Когда я нажал Play на телефоне, я тут же понял о чём все твердят на форумах – звук действительно ровный (или как некоторые говорят – плоский). Но ровный он в самом хорошем смысле – это значит, что все частоты на своих местах: низы очень приятные в меру глубокие, середина хорошо слышна, верхи не такие резкие как в UE700, а просто как надо чистые и чёткие. Звук получается естественный и «правильный» без каких-либо задираний. Я удивился как быстро я услышал эту ровность и естественность звука. Видимо сыграл тот момент, что в магазине я переходил от модели к модели, потому сразу и слышал особенности звука разных наушников.

Музыку я слушал я несколько минут, но всё же решил остановиться, чтобы снова вернуться к Соньке, UE700 и UE600. Теперь я гораздо чётче услышал, что у соньки присутствует V-образность, басы сильнее, верхи чуточку резче, а середину всё же кто-то искажает. Снова услышал, что UE700 ярко выражены в своей V-образной форме звука и верхи звучат всё же резковато (будто эквалайзер подкрутили). Ну а у UE600 совсем всё плохо с верхними – пресловутый эффект «ваты в ушах».

Когда я вернулся к UE900, то одел наушники уже более оперативно (так что это дело привычки) и снова вслушался в приятный ровный и честный звук. Правду говорят по разным форумам, что UE900 очень близки к мониторным, когда разные диапазоны не "выпячиваются", а звучат спокойно и натурально, без яркого доминирования каких-либо диапазонов будь-то низы, середина или верхи.

Выводы – UE900 мне очень и очень понравились своим очень чистым и очень естественным звуком. Вообще никаких нареканий с моей стороны как не аудиофила. =) Конструктив великолепен и одетые наушники сидят прекрасно. Кабель из стандартной поставки немного на любителя, т.к. он витой (а в версии для айфона он ещё и синий), но это сложно записать в большие минусы, поскольку кабель съёмный и можно купить другой, более подходящий. Благо разъёмы у UE900 совместимы с Shure SE535 и Weston 4R, так что на ebay всегда можно будет найти что-то по душе.

Заключение

Для себя я сделал вывод, что у Sony их первые арматурные XBA-4 вышли настоящим первым комом и к покупке не могу рекомендовать из-за конструктивных недостатков ухудшающих удобство ношения, а так же неоправданно высокой цены. Если вы очень и очень ограниченны в средствах, но желаете что-то удобное с хорошим звуком – Apple EarBuds ваш выбор. Если вы считаете, что вы выросли из недорогих моделей наушников и хочется нового уровня звука – UE700 ваш прямой путь, не пожалеете (разве что провода будут досаждать). Ну а если вы не стеснены в средствах и вам хочется максимально честного и качественного звука – ваш быбор UE900. Для себя же я сделал однозначный выбор в сторону UE900 и при первой возможности приобрету их. В Сеуле этого делать нет смысла, поскольку местные цены очень завышены на большинство электроники. К примеру UE900 на ebay можно купить в 1,5 раза дешевле чем самые дешёвые найденные в Сеуле.

Happy listening! =)


Отключение файла подкачки в Mac OS X

Эта заметка о том почему отключать файл подкачки (или swap файл) в mac os x - это плохо. Где-то год назад я купил 16Гб памяти в свой мак и решил, что "уж теперь-то файл подкачки мне точно не нужен". Решил я это сам по себе, а некоторые непорядочные статьи в сети подбадривали "это хорошо и улучшает производительность". Так вот, это не то что "не хорошо", а очень даже плохо.

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

Это было на версии системы 10.7. С переходом на 10.8 проблема изменилась на другую - мак выходя из гибернации (когда батарея разрядилась в ноль и память сбрасывается на диск чтобы отключить питание) я получал зависание и 3 гудка. Причём только при выходе из hibernate. При выходе из обычного сна всё было окей.

Я озадачился этой проблемой и в первую очередь начал грешить на купленную память. Я делал разные тесты, искал в сети ответ, но тщетно. Разные форумы что-то говорили, но это было всё не то. Недавно я нашёл статью, в которой говорилось, что это проблема с файлом гибернации sleepimage. Предлагалось его удалить и пересоздать. Я в это не верил особо, но попробовал. Результат был нулевой.

Решение было найдено, когда на одном закрытом форуме такой же бедолага как и я выплеснул своё отчаяние по поводу этой проблемы. В одном из коментариев лаконично и коротко сказали - "включи файл подкачки". Я последовал совету и включил swap командой:

sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist

После этого всё заработало просто великолепно.

Выводы

Выключать свап нельзя. По всей вероятности, swap используется для сохранения каких-то данных перед погружением в hibernate. При попытке выйти из сна данные в свап файле не находится и начинаются интересные приколы вплоть за зависания с 3-мя гудками. По этой причине я даже не даю совета как отключить swap, а только как включить.

← Новое 3 из 11 Старое →