Size: a a a

2ch /s/ - программы

2016 January 08

NK

ID:162236709 in 2ch /s/ - программы
у меня всегда была
источник

DM

Damage Melody in 2ch /s/ - программы
я вчера регал во многих странах
источник

DM

Damage Melody in 2ch /s/ - программы
и у вас было типо карты или телефон
источник

DM

Damage Melody in 2ch /s/ - программы
в австралии только карты
источник

DM

Damage Melody in 2ch /s/ - программы
а в других можно без этого
источник

DM

Damage Melody in 2ch /s/ - программы
источник

DM

Damage Melody in 2ch /s/ - программы
блять, вот о чем я говорил
источник

DM

Damage Melody in 2ch /s/ - программы
кароче если регион меняешь, то нужно чем то пруфать
источник

NK

ID:158818357 in 2ch /s/ - программы
Кто тут осью ТЭН пользуеься
источник

JK

Jebediah Kerman in 2ch /s/ - программы
ID:158818357
Кто тут осью ТЭН пользуеься
Только ты.
источник

NK

ID:110771442 in 2ch /s/ - программы
ID:158818357
Кто тут осью ТЭН пользуеься
Это которая OS X?
источник

NK

ID:158818357 in 2ch /s/ - программы
ID:110771442
Это которая OS X?
Не
источник

𝙨

𝙨𝙖𝙧𝙙𝙚𝙡𝙠𝙞𝙣 in 2ch /s/ - программы
ID:158818357
Кто тут осью ТЭН пользуеься
я
источник

分解物質 in 2ch /s/ - программы
источник

MF

Master Foo in 2ch /s/ - программы
Make originated with a visit from Steve Johnson (author of yacc, etc.), storming into my office, cursing the Fates that had caused him to waste a morning debugging a correct program (bug had been fixed, file hadn't been compiled, cc *.o was therefore unaffected). As I had spent a part of the previous evening coping with the same disaster on a project I was working on, the idea of a tool to solve it came up. It began with an elaborate idea of a dependency analyzer, boiled down to something much simpler, and turned into Make that weekend. Use of tools that were still wet was part of the culture. Makefiles were text files, not magically encoded binaries, because that was the Unix ethos: printable, debuggable, understandable stuff.
источник

MF

Master Foo in 2ch /s/ - программы
Make из Беркли отличается от GNU Make
источник

MF

Master Foo in 2ch /s/ - программы
Интересно, что туда добавили
источник

NK

ID:110771442 in 2ch /s/ - программы
GNU make — широко известная утилита для автоматической сборки проектов. В мире UNIX она является стандартом де-факто для этой задачи. Являясь не такой популярной среди Windows-разработчиков, тем не менее, привела к появлению таких аналогов, как nmake от Microsoft.

Однако, несмотря на свою популярность, make — во многом ущербный инструмент. Его надёжность вызывает сомнения; производительность низка, особенно для больших проектов; сам же язык файлов makefile выглядит заумно и при этом в нём отсутствуют многие базовые элементы, которые изначально присутствуют во многих других языках программирования.

Конечно, make — не единственная утилита для автоматизации сборки. Множество других средств были созданы для избавления от ограничений make’а. Некоторые из них однозначно лучше оригинального make’а, но на популярности make’а это сказалось мало. Цель этого документа, говоря простым языком, — рассказать о некоторых проблемах, связанных с make’ом — чтобы они не стали для вас неожиданностью.

Большинство аргументов в этой статье относятся к оригинальному UNIX make’у и GNU make’у. Так как GNU make сегодня, скорее всего, гораздо более распространён, то когда мы будем упоминать make или «makefiles», мы будем имеем в виду GNU make.

В статье также предполагается, что читатель уже знаком на базовом уровне с make’ом и понимает такие концепции как «правила», «цели» и «зависимости».

Дизайн языка

Каждый, кто хоть раз писал makefile, скорее всего уже натолкнулся на «особенность» его синтаксиса: в нём используются табуляции. Каждая строка, описывающая запуск команды, должна начинаться с символа табуляции. Пробелы не подходят — только табуляция. К сожалению, это только один из странных аспектов языка make’а.

Рекурсивный make

«Рекурсивный make» это распространённый паттерн при задании правил makefile’а когда правило создаёт другую сессию make’а. Так как каждая сессия make’а только один раз читает makefile верхнего уровня, то это — естественный способ для описания makefile’а для проекта, состоящего из нескольких под-проектов.

«Рекурсивный make» создаёт так много проблем, что даже была написана статья, показывающая, чем плохо это решение. В ней обозначены многие трудности (некоторые из них упомянуты ниже по тексту), но писать makefile’ы, которые не используют рекурсию — на самом деле сложная задача.

Парсер

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

Парсер make’а не следует этой стандартной модели. Вы не можете распарсить makefile без одновременного его выполнения. Замена переменных («variable substitution») может произойти в любом месте, и так как вы не знаете значения переменной, вы не можете продолжить синтаксический разбор. Как следствие, это очень нетривиальная задача — написать отдельную утилиту, которая может парсить makefile’ы, так как вам придётся написать реализацию всего языка.

Также отсутствует чёткое разделение на лексемы в языке. К примеру, посмотрим, как обрабатывается запятая.

Иногда запятая является частью строки и не имеет особого статуса:

X = y,z



Иногда запятая разделяет строки, которые сравниваются в операторе if:

ifeq ($(X),$(Y))



Иногда запятая разделяет аргументы функции:

$(filter %.c,$(SRC_FILES))



Но иногда, даже среди аргументов функций, запятая — всего лишь часть строки:

$(filter %.c,a.c b.c c.cpp d,e.c)


(так как <b>filter</b> принимает только два параметра, последняя запятая не добавляет нового параметра; она становится просто одним из символов второго аргумента)
источник

NK

ID:110771442 in 2ch /s/ - программы
Пробелы следуют таким же малопонятным правилам. Иногда пробелы учитываются, иногда нет. Строки не заключаются в кавычки, из-за этого визуально не ясно, какие пробелы значимы. Из-за отсутствия такого типа данных как «список» (существуют только строки), пробелы должны быть использованы как разделитель элементов списка. Как следствие, это приводит к избыточному усложнению логики, например, если имя файла просто содержит пробел.

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

NOTHING :=
SPACE := $(NOTHING) $(NOTHING)
CC_TARGET_PREFIX := -o$(SPACE)
# вот теперь можно писать правила вида $(CC_TARGET_PREFIX)$@



А мы только коснулись запятых и пробелов. Всего несколько человек понимают все хитросплетения парсера make’а.

Неинициализированные переменные и переменные окружения.

Если в makefile’е происходит обращение к неинициализированной переменной, make не сообщает об ошибке. Вместо этого он получает значение этой переменной из переменной окружения с таким же именем. Если же переменная окружения с таким именем не найдена, то просто считается, что значением будет пустая строка.

Это приводит к двум типам проблем. Первая — опечатки не отлавливаются и не считаются ошибками (вы можете заставить make выдавать предупреждения для таких ситуаций, но такое поведение отключено по умолчанию, а иногда неинициализированные переменные используются умышленно). Вторая — переменные окружения могут неожиданно влиять на код вашего makefile’а. Вы не можете знать наверняка, какие переменные могли быть установлены пользователем, поэтому, для надёжности, вы должны инициализировать все переменные до ссылки на них или добавления через <b>+=</b>

Также есть запутывающая разница между поведение make’а если его вызывать как "<b>make FOO=1</b>" с вызовом "<b>export FOO=1 ; make</b>". В первом случае строка в makefile’е <b>FOO = 0</b> не имеет эффекта! Вместо этого, вы должны писать <b>override FOO = 0</b>.

Синтаксис условных выражений

Один из главных недостатков языка makefile’ов — это ограниченная поддержка для условных выражений (условные операторы, в частности, важны для написания кросс-платформенных makefile’ов). Новые версии make’а уже содержат поддержку для "else if" синтаксиса. Конечно, у оператора if существует только четыре базовых варианта: ifeq, ifneq, ifdef, и ifndef. Если ваше условие более сложное и требует проверки на «и/или/не», то приходится писать более громоздкий код.

Допустим, нам надо определять Linux/x86 как целевую платформу. Следующий хак — обычный способ для замены условия «и» его суррогатом:

ifeq ($(TARGET_OS)-$(TARGET_CPU),linux-x86)
   foo = bar
endif



Условие «или» уже не будет таким простым. Допустим нам надо определять x86 или x86_64, а также вместо "foo = bar" у нас кода на 10+ строк и мы не хотим его дублировать. У нас есть несколько вариантов, каждых из которых плох:


# Кратко, но непонятно
ifneq (,$(filter x86 x86_64,$(TARGET_CPU))
 foo = bar
endif
# Многословно, но более понятно
ifeq ($(TARGET_CPU),x86)
 TARGET_CPU_IS_X86 := 1
else ifeq ($(TARGET_CPU),x86_64)
 TARGET_CPU_IS_X86 := 1
else
 TARGET_CPU_IS_X86 := 0
endif
ifeq ($(TARGET_CPU_IS_X86),1)
 foo = bar
endif



Множество мест в makefile’ах могли бы быть упрощены, если бы язык поддерживал полноценный синтаксис.

Два вида переменных

Существуют два вида присваиваний переменных в make’е. ":=" вычисляет выражение справа сразу. Обычный "=" вычисляет выражение позже, когда переменная используется. Первый вариант используется в большинстве других языков программирования и, как правило, более эффективный, в частности, если выражение сложное для вычисления. Второй вариант, конечно же, используется в большинстве в makefile’ов.
источник

NK

ID:110771442 in 2ch /s/ - программы
Есть объективные причины для использования "=" (с отложенным вычислением). Но часто от него можно избавиться, используя более аккуратную архитектуру makefile’ов. Даже не учитывая проблему с производительностью, отложенные вычисления делают код makefile’ов более сложным для чтения и понимания.

Обычно, вы можете читать программу с начала к концу — в том же порядке, в котором она исполняется, и точно знать, в каком именно состоянии она находится в каждый момент времени. С отложенным вычислением же, вы не можете знать значение переменной без знания что произойдёт дальше в программе. Переменная может менять своё значение косвенно, без непосредственного её изменения. Если же вы попробуете искать ошибки в makefile’е используя «отладочный вывод», например так:

$(warning VAR=$(VAR))

…вы можете не получить то, что вам надо.

Шаблонные подстановки и поиск файлов

Некоторые правила используют знак % для обозначения основной части имени файла (без расширения) — для того, чтобы задать правило генерации одних файлов из других. Например, правило "%.o: %.c" для компиляции .c файлов в объектный файл с расширением .o.

Допустим, нам нужно постоить объектный файл foo.o но исходный файл foo.c находится где-то не в текущей директории. У make’а есть директива vpath, которая сообщает ему, где искать такие файлы. К сожалению, если в директориях файл с именем foo.c встретится два раза, make может выбрать ошибочный файл.

Следующий стандартный паттерн программирования makefile’ов даёт сбой, если два исходных файла имеют одинаковое имя (но разное расширение) и лежат рядом. Проблема в том, что преобразование «имя исходного файла => имя объектного файла» теряет часть информации, но дизайн make’а требует этого для выполнения обратного отображения.

O_FILES := $(patsubst %.c,%.o,$(notdir $(C_FILES)))
vpath %.c $(sort $(dir $(C_FILES)))
$(LIB): $(O_FILES)



И другие отсутствующие возможности

make не знает никаких типов данных — только строки. Нет булевского типа, списков, словарей.
Нет понятия «область видимости». Все переменные — глобальные.
Поддержка для циклов ограничена. $(foreach) будет вычислять выражение несколько раз и объединять результаты, но вы не сможете использовать $(foreach) для создания, к примеру, группы правил.
Функции, определяемые пользователем, существуют, но имеют такие же ограничения, что и foreach. Они могут лишь заниматься подстановкой переменных и не могут использовать синтаксис языка полностью или создавать новые зависимости.

Надёжность

Надежность make’а низка, особенно на больших проектах или инкрементальной компиляции. Иногда сборка падает со странной ошибкой, и вам придётся использовать «магические заклинания» такие как make clean и надеяться, что всё починится. Иногда же (более опасная ситуация) всё выглядит благополучно, но что-то не было перекомпилировано и ваше приложение будет падать после запуска.

Отсутствующие зависимости

Вы должны рассказать make’у обо всех зависимостях каждой цели. Если вы этого не сделаете, он не перекомпилирует цель когда зависимый файл изменится. Для C/C++ многие компиляторы могут генерировать информацию о зависимостях в формате, понимаемом make’ом. Для других утилит, однако, ситуация существенно хуже. Допустим, у нас есть питоновский скрипт, который включает в себя другие модули. Изменения в скрипте приводят к изменению его результатов работы; это очевидно и легко внести в makefile. Но изменение в одном из модулей также могут изменить вывод скрипта. Полное описание же всех этих зависимостей и поддержка их в актуальном состоянии являются нетривиальной задачей.

Использование метки «время последней модификации файла»
источник