Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
книги хакеры / Питер_Гудлиф_Ремесло_программиста_Практика_написания_хорошего_кода.pdf
Скачиваний:
16
Добавлен:
19.04.2024
Размер:
9.23 Mб
Скачать

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

Механикаm

сборки

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

253Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

гут возникнуть проблемы с поиском таинственно скрывающихся ошибок.

Сборка должна проходить без лишних сообщений. Это зависит не столько от процедуры сборки, сколько от вашего исходного кода.1 Если код генерирует ошибки компилятора, значит, в нем нужно раз% бираться. Переделайте код так, чтобы компилятор работал молча. За многочисленными дурацкими предупреждениями можно про# смотреть более коварные сообщения.

Для большей уверенности активируйте вывод компилятором всех предупредительных сообщений; отключение их вывода не устраня% ет проблему, а скрывает ее.

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

Механика сборки

За этими соображениями качества стоят практические вопросы систе% мы сборки. Чтобы поговорить о них конкретно, мы подробно обсудим make, конкретную систему сборки и make%файлы, но не пугайтесь – за исключением различий в синтаксисе, другие системы сборки следуют аналогичным соглашениям (даже красивые графические пакеты).

Выбор целей

Make%файлы определяют правила, описывающие, как нужно собирать цели. (Другие системы сборки работают очень похожим образом, даже если есть различия в терминологии.) Система умеет определять, какие требуются промежуточные цели, и тоже собирает их. В одном make% файле может быть указано несколько целей. Благодаря этому одна система сборки может генерировать несколько разных выходных объ% ектов, например:

Различные программы (часто встречается, когда код двух про% грамм содержит общие компоненты и потому они располагаются в одном дереве исходного кода для сборки).

Сборка приложения для разных целевых платформ (например, вер% сий для Windows/ Apple/Linux или настольной машины/PDA).

1Сделать это нетрудно – достаточно отключить вывод предупреждений ком% пилятором, и сборка пройдет без лишнего шума. Но это неправильный спо%

соб решения проблемы.

 

 

 

 

hang

e

 

 

 

 

 

 

C

 

E

 

 

 

X

 

 

 

 

 

-

 

 

 

 

 

d

 

F

 

 

 

 

 

 

t

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

to

 

 

 

 

w Click

 

 

 

254m

 

 

 

 

w

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

.

 

 

 

 

 

.c

 

 

p

 

 

 

 

g

 

 

 

 

df

 

 

n

e

 

 

 

 

-xcha

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

Глава 10. Код, который построил ДжекClick

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Различные версии продукта (скажем, полная версия или демонст# рационная, в которой отсутствуют возможности сохранения/печа% ти результатов).

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

Различные уровни сборки (только внутренних библиотек, всего приложения, полного дистрибутива).

Может потребоваться неким образом скомбинировать эти цели, напри% мер собрать демонстрационную версию для PDA.1 Дерево исходного кода можно организовать так, что каждая из этих целей будет соби% раться из одних и тех же файлов. Вам тогда нужно будет не просто вве% сти команду make, а набрать make desktop или make pda, и соответствую% щий исполняемый модуль появится на выходе. (Имя после make – это правило, которое она должна собрать.)

Это значительно лучше, чем заводить для каждой цели свое дерево ис% ходного кода. Одновременное сопровождение нескольких деревьев, в которых бо]льшая часть кода совпадает, – утомительная и чреватая ошибками задача. Очень легко, модифицировав код, позабыть сделать это со всеми его экземплярами.2

В чем же различие между этими целевыми правилами? Фактические различия могут быть такими:

Собираются разные файлы (скажем, save_release.c или save_demo.c).

Компилятору передаются различные макроопределения (напри% мер, компилятор определяет макрос DEMO_VERSION, чтобы выбрать правильный код #ifdef в save.c).

Используются различные опции компилятора (например, вклю% чающие поддержку отладки).

Для сборки выбираются разные наборы инструментов или типы ок% ружения (например, выбирается компилятор, соответствующий целевой платформе).

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

1В этом случае механизм меняется: одновременно можно собрать только од% ну цель, поэтому «демонстративность» станет конфигурацией сборки, а не целью. Ниже будет сказано о конфигурациях.

2Обратите внимание на отличие такого опасного способа от хранения не% скольких ветвей проекта в системе контроля версий. Системы контроля версий предоставляют средства для разнесения модификаций по ветвям

и сравнения ветвей между собой.

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

Механикаm

сборки

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

255Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Жизнь после make

Значительная часть рассматриваемых здесь вопросов относится к циклу разработки в стиле C, в котором компилятор генерирует объектный код и библиотеки из исходных файлов, а затем из них собирается окончательный исполняемый модуль. Для неко% торых языков характерна другая модель. В Java процедура сбор% ки значительно проще; компилятор javac берет на себя функции make, автоматически выполняя проверки зависимостей. Он бо% лее стесняет вас, навязывая определенную структуру дерева сборки, но в результате облегчает вам жизнь.

Простым программам, написанным на Java, не нужна сложная система сборки: всю сборку можно успешно выполнить одной командой javac. Однако в проектах Java покрупнее часто приме% няют make. Мы уже знаем, что сборка не ограничивается компи% лированием исходного кода. Необходим механизм для подготов% ки вспомогательных файлов, выполнения автоматизированных тестов и создания конечного дистрибутива. Make – это удобная среда для того, чтобы избавиться от такой работы, поэтому не стоит считать ее избыточной.

способ предпочтительнее, если он сокращает количество различных существующих сборок, требующих тестирования.

Уборка

Для каждого целевого правила, которое вы определили, должно быть соответствующее правило чистки, которое аннулирует все результаты сборки – удаляет выполняемый модуль программы, промежуточные библиотеки, объектные файлы и все прочие файлы, созданные во вре% мя сборки. Дерево исходного кода должно вернуться в свое исходное состояние, что относительно легко проверяется.1

Отсюда следует, что система сборки, которая физически изменяет ис% ходные файлы, плоха – как потом обращать эти изменения? Следует использовать исходные файлы в качестве шаблона и записывать все изменения в другой выходной файл.

Правила чистки (clean) – это полезное средство для уборки. Они позво% ляют легко убрать весь мусор и выполнить сборку с чистого листа, ес% ли кажется, что вас преследуют темные силы сборки.

1Выполните сборку, затем чистку, а потом проверьте, отличается ли состоя%

ние дерева от исходного.

 

 

 

 

hang

e

 

 

 

 

 

 

C

 

E

 

 

 

X

 

 

 

 

 

-

 

 

 

 

 

d

 

F

 

 

 

 

 

 

t

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

to

 

 

 

 

w Click

 

 

 

256m

 

 

 

 

w

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

.

 

 

 

 

 

.c

 

 

p

 

 

 

 

g

 

 

 

 

df

 

 

n

e

 

 

 

 

-xcha

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

Глава 10. Код, который построил ДжекClick

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Для каждого правила сборки напишите соответствующее правило чистки, которое отменяет всю операцию.

Зависимости

Как может система сборки узнать, что одни файлы зависят от других? Без экстрасенсов это трудновато, поэтому мы попросим помочь тех, кто знает.

Вы сами указываете сведения о зависимостях в правилах, содержащих% ся в make%файлах. Make может построить из зависимостей дерево и дви% гаться по нему – прочесть временные метки всех файлов и выяснить, какие участки нужно собрать заново после проведенной модификации.

Это достаточно просто для правила сборки исполняемого модуля – нужно лишь указать, какие объектные файлы и библиотеки входят в него. Однако не хотелось бы скрупулезно указывать зависимости для каждого из исходных файлов; наверняка в них включено много дру% гих файлов директивой #include, а в тех есть свои #include. Список бу% дет внушительный. Легко можно ошибиться при наборе, а также от% стать от времени: добавить еще один #include и забыть при этом изме% нить make%файл.

Кому же все%таки известна вся информация о зависимостях? Компи% лятору; это тот элемент системы сборки, который реально прослежи% вает все зависимости между исходными файлами. У каждого хороше% го компилятора есть опция, заставляющая его выдать все данные о за% висимостях. Задача в том, чтобы написать для make правило, которое соберет эту информацию, поместит ее в правильно форматированный файл, а потом включит его в дерево зависимостей.

Автоматическая сборка

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

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

Проблемы сборки выявляются на ранних стадиях без вашего допол% нительного труда. Сев утром за рабочий стол с чашечкой кофе в ру%

1Запускать команды в нужное время позволяют утилита cron в UNIX и Пла%

нировщик (Scheduled Tasks ) в Windows.

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

Механикаm

сборки

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

257Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

ке, вы видите, в каком состоянии дерево исходного кода – допускает ли оно сборку. Вы сразу увидите, где требуются исправления, а не станете ждать, когда завершится ваша собственная сборка.

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

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

Можно использовать ночную сборку для выпуска окончательных версий продукта. Ее результаты можно считать надежными, потому что на них не могли повлиять неправильно введенные команды, на% стройки или другие ошибки, связанные с человеческим фактором.

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

Организуйте автоматическую процедуру сборки своего программного продук& та. Проверяйте с ее помощью работоспособность вашего кода.

Автоматическая сборка особенно полезна, если система велика (сбор% ка занимает не один час) или над ней одновременно работает много лю% дей (и не у каждого разработчика в любой момент есть самый свежий вариант исходного кода системы).

Полезная практика для ночных сборок – запись выводимых процеду% рой сборки сообщений в журнал, который всем доступен для просмот% ра. Можно даже рассылать его электронной почтой, если сборка оказа% лась неудачной, чтобы обратить внимание на проблемы. Очень важно следить за тем, что происходит при каждом проведении сборки, осо% бенно при возникновении сбоев.

Ночная сборка становится как бы пульсом разрабатываемого проекта. Если сборки удачны, значит, код развивается правильно и успешно. Есть важное правило, которому следуют во многих проектах: не порть дерево исходного кода – внесение разработчиком в систему кода, из%за которого срывается ночная сборка, влечет суровое и неприятное нака% зание (желательно, с общественным порицанием). Другое правило: ес# ли сборка не прошла, это общая проблема. При сбое ночной сборки все разработчики должны отложить все свои дела и заняться устранением ошибки.