Linux нет команды patch

Полезные утилиты. Приложение A из книги «О ядре Linux вкратце»

Получение, сборка, обновление и поддержка дерева исходных кодов ядра Linux включает в себя множество различных шагов, которые уже были описаны в этой книге. Разработчики, будучи от природы ленивыми существами, создали несколько разных программ для облегчения различных рутинных задач. Здесь будут описаны некоторые из этих полезных инструментов и даны основные рекомендации по их использованию.

Разработка ядра Linux во многом отличается от традиционной разработки программного обеспечения. Вот часть специфических требований, предъявляемых разработчикам ядра:

  • Постоянное отслеживание плана разработки ядра и соответственная корректировка вносимых вами изменений;
  • Разрешение конфликтов между изменениями, внесенными вами и другими людьми;
  • Выдача ваших изменений в формате, позволяющем другим легко работать с ними.

Один из наиболее распространенных методов работы с ядром заключается в использовании программ patch и diff. Для использования этих инструментов необходимы два разных дерева каталогов: «чистое» («clean») и «рабочее» («working»). В «чистом» дереве содержится релиз ядра, а в «рабочем» — та же самая версия, но модифицированная вами. И тогда вы сможете, используя patch и diff, вычленить внесенные вами изменения и отправить их в новый релиз.

Для примера создайте два каталога, содержащих последнюю версию ядра, как это описано в главе 3 под названием «Получение исходных текстов ядра»:

$ tar -zxf linux-2.6.19.tar.gz
$ mv linux-2.6.19 linux-2.6.19-dirty
$ tar -zxf linux-2.6.19.tar.gz
$ ls
linux-2.6.19/
linux-2.6.19-dirty/

Теперь внесите желаемые изменения в файлы, находящиеся в каталоге «-dirty», не трогая при этом файлы в каталоге с оригиналом ядра. После завершения работы вам нужно будет создать патч для отправки другим разработчикам:

$ diff -Naur -X linux-2.6.19/Documentation/dontdiff linux-2.6.19/ linux-2.6.19-dirty/ > my_patch

Эта команда создаст файл с именем my_patch, содержащий различия между вашей «рабочей» и «чистой» версиями ядра 2.6.19. Этот патч затем можно будет переслать кому-либо по электронной почте.

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

  1. Сгенерируйте свой патч способом, приведенным в предыдущем примере.
  2. Используя официальный патч с kernel.org, обновите старое ядро до следующего релиза:
  3. $ cd linux-2.6.19
    $ patch -p1
  4. 4. Обновите ваш рабочий каталог до следующего релиза, удалив свой патч, а затем примените свежее обновление:
  5. $ cd linux-2.6.19-dirty
    $ patch -p1 -R
  6. После этого попробуйте наложить на исходные тексты свой патч:
  7. $ cd linux-2.6.20-dirty
    $ patch -p1
  8. Если ваш патч не накладывается корректно, устраните все возникшие конфликты. Команда patch сообщит вам о них, попутно создав файлы .rej и .orig, чтобы вы могли сравнить их и исправить вручную, используя свой любимый текстовый редактор. Этот процесс слияния может стать наиболее трудной частью работы, особенно если вы вносите изменения в те части кода, которые уже были изменены другими разработчиками.

Если вы придерживаетесь такого метода разработки, я настоятельно рекомендую использовать набор программ patchutils ( http://cyberelk.net/tim/patchutils ). Эти программы позволяют легко манипулировать патчами и избавляют разработчиков ядра от многих часов нудной работы.

Управление патчами с помощью quilt

Разработка ядра с использованием patch и diff обычно идет неплохо. Но со временем большинство людей начинают уставать и искать другой способ, не требующий такого количества утомительной работы с патчами и объединением кода. К счастью, несколько разработчиков ядра создали программу под названием quilt , призванную значительно упростить процесс манипулирования патчами.

История создания quilt уходит корнями в набор скриптов, первоначально написанный Эндрю Мортоном для поддержки подсистемы управления памятью, а затем — и для всего дерева исходных текстов ядра, находящегося в разработке. Эти скрипты были очень сильно привязаны к его рабочему процессу, но идеи, послужившие основой для их создания, обладали огромным потенциалом. Андреас Грюнбахер взял эти идеи и создал quilt.

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

Для начала, как обычно, создайте дерево исходного кода ядра:

$ tar -zxf linux-2.6.19.tar.gz
$ ls
linux-2.6.19/

Перейдите в созданный каталог:

$ cd linux-2.6.19

Создайте подкаталог под названием patches, который будет содержать все ваши патчи:

$ mkdir patches

Затем создайте новый патч под названием patch1:

$ quilt new patch1
Patch patches/patch1 is now on top

Утилите quilt нужно «сказать» обо всех файлах, которые будут изменены этим патчем. Для этого используйте команду add:

$ quilt add Makefile
File Makefile added to patch patches/patch1

Отредактируйте Makefile, изменив строку EXTRAVERSION и сохраните файл. После этого обновите патч с помощью команды refresh:

$ quilt refresh
Refreshed patch patches/patch1

Файл patches/patch1 будет содержать только что сделанные вами изменения:

$ cat patches/patch1
Index: linux-2.6.19/Makefile
===================================================================
— linux-2.6.19.orig/Makefile
+++ linux-2.6.19/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 19
-EXTRAVERSION =
+EXTRAVERSION = -dirty
NAME=Crazed Snow-Weasel

Далее вы можете продолжить работу над этим патчем или же создать еще один для наложения поверх него. Например, если создать три разных патча, скажем, patch1, patch2 и patch3, то они будут наложены каждый поверх предыдущего.

Вот так можно увидеть список примененных патчей:

$ quilt series -v
+ patches/patch1
+ patches/patch2
= patches/patch3

В этом выводе показано, что применены все три патча и текущим является patch3.

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

  1. Удалите все патчи, находящиеся в данный момент в дереве исходного кода:
  2. $ quilt pop -a
    Removing patch patches/patch3
    Restoring drivers/usb/Makefile

Removing patch patches/patch2
Restoring drivers/Makefile

Removing patch patches/patch1
Restoring Makefile

No patches applied

  • Используя официальный патч с http://kernel.org , обновите старую версию ядра до текущего релиза:
  • $ patch -p1
  • Теперь с помощью команды quilt push верните все патчи в обновленное дерево:
  • $ quilt push
    Applying patch patches/patch1
    patching file Makefile
    Hunk #1 FAILED at 1.
    1 out of 1 hunk FAILED — rejects in file Makefile
    Patch patches/patch1 does not apply (enforce with -f)
  • Так как первый патч не применился из-за ошибки, наложите его принудительно, а затем решите проблему:
  • $ quilt push -f
    Applying patch patches/patch1
    patching file Makefile
    Hunk #1 FAILED at 1.
    1 out of 1 hunk FAILED — saving rejects to file Makefile.rej
    Applied patch patches/patch1 (forced; needs refresh)
    $ vim Makefile.rej Makefile
  • После применения патча обновите его:
  • $ quilt refresh
    Refreshed patch patches/patch1
  • Затем продолжайте добавление других патчей:
  • $ quilt push
    Applying patch patches/patch2
    patching file drivers/Makefile

    Now at patch patches/patch2
    $ quilt push
    Applying patch patches/patch3
    patching file drivers/usb/Makefile

    Now at patch patches/patch3

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

    Если вы хотите принять какое-либо участие в разработке ядра, настоятельно рекомендуется использовать quilt даже для отслеживания всего лишь нескольких патчей вместо более трудоемкой связки diff и patch.

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

    git — это средство для управления исходными текстами, изначально написанное Линусом Торвальдсом во время поисков новой системы управления исходным кодом ядра Linux. Это распределенная система, отличающаяся от традиционных, таких как cvs, тем, что не требует подключения к серверу для отправки коммита в репозиторий.

    git — одна из наиболее мощных, гибких и быстрых систем контроля исходного кода, доступных в настоящее время; за ней стоит активная команда разработчиков. Ее главная веб-страница находится по адресу http://git.or.cz/ . Каждому новому пользователю git рекомендуется ознакомиться с учебными материалами для того, чтобы лучше ознакомиться с работой системы и принципами ее правильного использования.

    Ядро Linux разрабатывается с использованием git; последнюю версию ядра можно найти по адресу http://www.kernel.org/git/ совместно с обширным списком git-репозиториев других разработчиков ядра.

    Использование git в процессе разработки ядра Linux необязательно, но очень полезно для отслеживания ошибок в ядре. Если вы отправляете отчет об ошибке разработчикам ядра Linux, они могут попросить использовать команду git bisect для того, чтобы точно определить изменение, вызвавшее ошибку.

    ketchup — это очень удобное средство для обновления или переключения между различными версиями дерева исходных текстов ядра, имеющее следующие возможности:

    • поиск самой свежей версии ядра, его загрузка его и распаковка;
    • обновление текущей версии дерева исходных текстов ядра до любой другой путем наложения патчей;
    • управление различными разрабатываемыми и стабильными ветвями дерева исходных текстов, включая -mm и -stable;
    • загрузка любых патчей или архивов, необходимых для обновления, если они отсутствуют;
    • проверка GPG-подписей архивов и патчей.

    ketchup можно загрузить с сайта http://www.selenic.com/ketchup/ , а по адресу http://www.selenic.com/ketchup/wiki/ имеется много дополнительной документации.

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

    Чтобы скачать дерево исходных текстов ядра 2.6.16.24 в некоторый каталог, а затем переименовать этот каталог в соответствии с версией ядра, введите следующие команды:

    $ mkdir foo
    $ cd foo
    $ ketchup -r 2.6.16.24
    None -> 2.6.16.24
    Unpacking linux-2.6.17.tar.bz2
    Applying patch-2.6.17.bz2 -R
    Applying patch-2.6.16.24.bz2
    Current directory renamed to /home/gregkh/linux/linux-2.6.16.24

    Теперь для обновления до последнего стабильного релиза введите это:

    $ ketchup -r 2.6 2.6.16.24 -> 2.6.17.11
    Applying patch-2.6.16.24.bz2 -R
    Applying patch-2.6.17.bz2
    Downloading patch-2.6.17.11.bz2
    —22:21:14—
    http://www.kernel.org/pub/linux/kernel/v2.6/patch-2.6.17.11.bz2 => `/home/greg/.ketchup/patch-2.6.17.11.bz2.partial’
    Resolving www.kernel.org. 204.152.191.37, 204.152.191.5
    Connecting to www.kernel.org|204.152.191.37|:80. connected.
    HTTP request sent, awaiting response. 200 OK
    Length: 36,809 (36K) [application/x-bzip2]

    22:21:14 (92.87 KB/s) —
    `/home/greg/.ketchup/patch-2.6.17.11.bz2.partial’ saved [36809/36809]

    Downloading patch-2.6.17.11.bz2.sign
    —22:21:14—
    http://www.kernel.org/pub/linux/kernel/v2.6/patch-2.6.17.11.bz2.sign => `/home/greg/.ketchup/patch-2.6.17.11.bz2.sign.partial’
    Resolving www.kernel.org. 204.152.191.37, 204.152.191.5
    Connecting to www.kernel.org|204.152.191.37|:80. connected.
    HTTP request sent, awaiting response. 200 OK
    Length: 248 [application/pgp-signature]

    22:21:14 (21.50 MB/s) —
    `/home/greg/.ketchup/patch-2.6.17.11.bz2.sign.partial’ saved [248/248]

    Verifying signature.
    gpg: Signature made Wed Aug 23 15:01:04 2006 PDT using DSA key ID 517D0F0E
    gpg: Good signature from «Linux Kernel Archives Verification Key >ftpadmin@kernel.org»
    gpg: WARNING: This key is not certified with a trusted signature!
    gpg: There is no indication that the signature belongs to the owner.
    Primary key fingerprint: C75D C40A 11D7 AF88 9981 ED5B C86B A06A 517D 0F0E
    Applying patch-2.6.17.11.bz2
    Current directory renamed to /home/greg/linux/tmp/x/linux-2.6.17.11

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

    Если вы хотите загрузить какое-либо дерево исходных текстов ядра Linux, настоятельно рекомендуется использовать ketchup. Эта утилита берет на себя всю работу по отысканию нужного патча, а затем автоматически проверяет его подпись и применяет его. Сочетая ketchup и quilt вы получаете очень мощную связку, которая содержит все необходимое для эффективной работы с исходными текстами ядра Linux.

    Источник

    Установка патчей в Linux – работа с утилитой patch

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

    Что такое патч?

    Говоря о патчах вкупе с утилитой patch, следует подразумевать, что это касается исключительно текстовых данных. Другими словами, происходит работа с исходными кодами проекта, будь то код C++, PHP, HTML и т. д. Вообще, все самые «суровые» программисты или разработчики в процессе своей совместной работы над проектом обмениваются исключительно отдельными правками, а не пересылают друг другу актуальные версии проектов целиком.

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

    Утилита patch умеет быстро и эффективно распоряжаться данными из файла-патча, используя для этого хранящиеся в нём инструкции. И таким образом выполняет все рутинные действия по редактированию. Пользователю (разработчику) необходимо лишь правильно выполнить соответствующую команду, задав все необходимые аргументы и опции.

    Синтаксис и основные опции команды patch

    Нет ничего удивительного в том, что утилита patch относится к категории ПО, которое обязательно должно быть установлено на любой машине для разработки программ, да и вообще для ведения разработки. Практически любой дистрибутив Linux предоставляет утилиту patch предустановленной по-умолчанию.

    Стоит также отметить, что по своей функциональности, patch довольно сложна и обладает, без преувеличения, просто огромным набором опций. По этой причине в данной статье будут приведены только самые распространённые приёмы при работе с этой утилитой и только сопутствующие им опции команд. Синтаксис команды patch следующий:

    Здесь originalfile – это файл, который необходимо «пропатчить» до актуального состояния. А patchfile – файл-патч. Сразу возникает вопрос: а откуда берётся этот файл-патч? Ответ: он генерируется другой утилитой — diff, которая находит построчные различия между файлами. Либо же патч может быть составлен вручную, автором, если он знаком с соответствующим форматом. Но это бывает крайне редко, обычно прибегают к помощи diff или её аналогов.
    В следующей таблице приведены опции команды patch, которые используются наиболее часто:

    Помещает неудавшиеся (отклонённые) изменения в отдельный файл rejecfile вместо файла .rej по-умолчанию.

    Опция Значение
    -i patchfile Читает информацию из патч-файла, указываемого параметром patchfile.
    -r rejectfile, —reject-file=rejectfile
    -N, —forward Когда патч не применяется, то утилита patch обычно пытается определить, выглядит ли ситуация так, как если бы патч уже был применён. Опция -N отключает такое поведение.
    -pnum, strip=num Обрезает части пути к файлу, разделяемые символом косой черты до уровня, указанного в параметре num. Например: p0 оставит путь /u/john/src/blurfl/blurfl.cpp неизменным, а p4 обрежет тот же путь до blurfl/blurfl.cpp.
    -o outputfile, —output=outputfile Отправляет вывод в указываемый в параметре outputfile файл. Не следует использовать эту опцию, если в качестве outputfile указывается файл, который должен быть пропатчен. Если в качестве outputfile указать символ дефиса «-», то вывод будет направляться в стандартный поток STD_OUT.
    -E, —remove-empty-file Удаляет файлы, оказавшиеся пустыми после применения патча. Эта опция имеет смысл, когда используемые патчи имеют не контекстный формат.
    —dry-run Печатает результаты применения патча без реальной модификации файлов. Полезно для быстрого и безопасного тестирования патчей.
    -R, —reverse Откатывает все изменения (если они возможны), т. е. отменяет установку патча.
    -c, —context Интерпретирует файл патча как обычный контекстный формат, генерируемый утилитой diff.
    -b, —backup Создаёт резервную копию оригинального файла вместо его удаления.

    Применение патчей к отдельным файлам

    Прежде, чем начать рассмотрение практических примеров, необходимо сказать несколько слов о той самой утилите, которая и создаёт патчи — diff. Она может генерировать патчи трёх типов — простой, контекстный и контекстный унифицированный. Простой гораздо более компактный по размеру, чем контекстные, но последние гораздо более удобочитаемы и понятны для восприятия пользователем. Для того, чтобы сгенерировать простой патч, для команды diff никаких специальных опций не требуется. А для генерации контекстного или унифицированного контекстного патчей предназначены опции -с и -u соответственно:

    Пусть имеется файл с кодом C++ ChildClass.cpp:

    И пусть в этот файл было внесено следующее изменение: метод valueSqr() был переименован в calcSqr(). Тогда контекстный патч (файл contextpatch) будет выглядеть следующим образом:

    Теперь, чтобы пропатчить старую версию ChildClass.cpp, нужно выполнить команду:

    В результате будет получен файл ChildClass_new.cpp с актуальным содержимым.

    Работа с проектами

    С помощью утилиты patch можно также применять патчи для нескольких файлов, причём расположенных в разных каталогах. Это удобно, когда изменения проводятся в масштабах целого проекта. Но в этом случае и сам патч должен быть особым образом подготовлен утилитой diff.

    Пусть имеется старый проект в каталоге base-project. Внутри него имеются подкаталоги include и src, в которых, в свою очередь находятся файлы с изменениями — ChildClass.h (в каталоге include) и ChildClass.cpp (в каталоге src). Сам изменённый (актуальный) проект был помещён в отдельный каталог new-project. Подготовка патча будет выглядеть следующим образом:

    Сгенерированный файл-патч project-patch:

    Следует обратить внимание, что в данных примерах указываются относительные пути. Файл-патч будет помещён в текущий активный каталог.
    Чтобы применить патч нужно выполнить следующую команду:

    Как видно, вместо ключа -i можно использовать символ «

    Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

    Источник

    Читайте также:  Как удалить sublime text linux
  • Оцените статью