Как вы понимаете исходный код GNU?

Мне очень жаль, если это звучит немного глупо. Я только что закончил читать K & R, и я работал над некоторыми упражнениями. Этим летом, для моего проекта, я думаю о повторной реализации Linux-утилиты, чтобы расширить свое понимание C дальше, поэтому я загрузил источник для GNU tar и sed, поскольку они оба кажутся интересными. Тем не менее, у меня возникли проблемы с пониманием того, где он начинается, где основная реализация, откуда пришли все странные макросы и т.д.

У меня много времени, так что это не проблема. Должен ли я сначала познакомиться с инструментальной сетью GNU (т.е. Make, binutils,..), чтобы понять программы? Или, может быть, я должен начать с чего-то немного меньшего (если есть такая вещь)?

У меня мало опыта работы с Java, С++ и python, если это имеет значение.

Спасибо!

Ответы

Ответ 1

Программы GNU большие и сложные. Размер GNU Hello World показывает, что даже простейший проект GNU нуждается в большом количестве кода и конфигурации вокруг него.

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

Чтобы прочитать код, вам нужен хороший редактор (VIM, Emacs) или IDE (Eclipse) и некоторые инструменты для навигации по источнику. Проект tar содержит каталог src, который является хорошим местом для запуска. Программа всегда начинается с основной функции, поэтому

grep main *.c

или используйте свою IDE для поиска этой функции. Он находится в tar.c. Теперь пропустите все файлы инициализации, пока

/* Main command execution.  */

Там вы видите переключатель для подкоманд. Если вы передаете -x, это делает это, если вы передаете -c, он делает это и т.д. Это структура ветвления для этих команд. Если вы хотите знать, что такое макрос, запустите

grep EXTRACT_SUBCOMMAND *.h

там вы можете видеть, что они перечислены в common.h.

Ниже EXTRACT_SUBCOMMAND вы видите что-то смешное:

read_and (extract_archive);

Определение read_and() (снова полученное с помощью grep):

read_and (void (*do_something) (void))

Единственный параметр - это указатель на функцию, например обратный вызов, поэтому read_and, предположительно, что-то прочитает, а затем вызовет функцию extract_archive. Опять же, grep на нем, и вы увидите следующее:

  if (prepare_to_extract (current_stat_info.file_name, typeflag, &fun))
    {
      if (fun && (*fun) (current_stat_info.file_name, typeflag)
      && backup_option)
    undo_last_backup ();
    }
  else
    skip_member ();

Обратите внимание, что реальная работа происходит при вызове fun. fun снова является указателем функции, который устанавливается в файле prepare_to_extract. fun может указывать на extract_file, который выполняет собственно запись.

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

Ответ 2

Проблема с такими программами, как tar и sed, двояка (это, конечно, мое мнение!). Прежде всего, они оба очень старые. Это означает, что на протяжении многих лет их поддерживали несколько человек, с разными стилями кодирования и разными личностями. Для утилит GNU это обычно довольно хорошо, потому что они обычно обеспечивают разумно согласованный стиль кодирования, но это все еще проблема. Другая проблема заключается в том, что они невероятно переносимы. Обычно "переносимость" воспринимается как хорошая вещь, но когда ее принимают до крайности, это означает, что ваша кодовая база заканчивается небольшими взломами и трюками для работы с неясными ошибками и угловыми случаями в конкретных частях оборудования и систем. А для программ, которые широко портируются как tar и sed, это означает, что нужно учитывать множество угловых случаев и непонятное оборудование/компиляторы/операционные системы.

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

С хорошо зарекомендовавшими себя программами, такими как tar и sed, вы увидите результат обсуждений, которые произошли бы, но вы не можете видеть, как решения и изменения дизайна программного обеспечения выполняются в режиме реального времени. Это может произойти только с активно поддерживаемым программным обеспечением.

Это просто мое мнение, конечно, и вы можете взять его с солью, если хотите:)

Ответ 3

Почему бы не загрузить источник coreutils (http://ftp.gnu.org/gnu/coreutils/) и взглянуть на такие инструменты, как yes? Менее 100 строк кода C и полностью функциональная, полезная и действительно базовая часть программного обеспечения GNU.

Ответ 4

GNU Hello, вероятно, самая маленькая, простейшая программа GNU и понятна.

Ответ 5

Я знаю, что иногда бесполезно перемещаться по C-коду, особенно если вы не знакомы с ним. Я предлагаю вам использовать инструмент который поможет вам просмотреть функции, символы, макросы и т.д. Затем найдите функцию main().

Конечно, вам нужно ознакомиться с инструментами, но вам не обязательно становиться экспертом.

Ответ 6

Узнайте, как использовать grep, если вы этого еще не знаете, и используйте его для поиска функции main и всего остального, что вас интересует. Вы также можете использовать инструменты просмотра кода, такие как ctags или cscope, который также может интегрироваться с vim и emacs или использовать IDE, если вам это нравится.

Ответ 7

Я предлагаю использовать ctags или cscope для просмотра. Вы можете использовать их с vim/emacs. Они широко используются в мире с открытым исходным кодом.

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

Ответ 8

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

  • Установите инструменты разработки Qt и Qt Creator

  • Загрузите источники, которые хотите проверить, и настройте их для компиляции (обычно просто ./configure для материала GNU).

  • Запустите qmake -project в корневой каталог исходного кода, чтобы создать Qt .pro файл для Qt Creator.

  • Откройте файл .pro в Qt Creator (не используйте теневую сборку, когда он спрашивает).

  • Чтобы быть в безопасности, в представлении проектов Qt Creator удалите шаги сборки по умолчанию. Файл .pro предназначен для навигации внутри Qt Creator.

  • Необязательно: настроить пользовательские сборки и выполнить шаги, если вы хотите создать и запустить/отладить в Qt Creator. Не требуется только для навигации.

  • Используйте Qt Creator для просмотра кода. Обратите внимание, особенно на локатор (kb shortcut Ctrl + K), чтобы найти материал по имени и "следовать символу под курсором" (kb shortcut F2) и "находить обычаи" (kb shortcut Ctrl-Shift-U).