Сводный план курса «Разработка программного обеспечения для GNU/Linux»
Сборочное окружение
IDE и не-IDE
Начнём с середины
Разработка: программирование → тестирование → развёртывание. Но программирование — это тоже программирование → тестирование → развёртывание:
- средства «программирования» (разработки)
- средства сборки
- средства запуска/отладки
- средства развёртывания бинарников и отправки исходного кода (deployment)
Моделирование IDE:
- Пользовательское окружение (zsh, mc, ...)
- Текстовый редактор особого вида
- GUI. А зачем GUI?
- EMACS
- mcedit
- ...
- Компиляторы / интерпретаторы
- Компоновщик
- Поддержка разработки со стороны ЯП. На примере C:
- devel-версии библиотек
- h-файлы
- Отладчик, strace
- debuginfo и исходники несобственного кода
- Документация на инструменты и библиотеки
- Средства совместной разработки (git, hg, ...)
- Разное (lint, тестовые инструментарии и т. п.)
Материалы
Пример компиляции программы из FreeBSD developers Handbook
Перевод книжки "Просто о vim"
Сборочные зависимости
- Библиотеки и инструменты сборки
- Порядок сборки
Вручную
- Установим «всё»
- Полностью перекомпилируем все файлы
Недостатки:
Что такое «всё»?
Прядок?
=> Сценарий
Мальчик для битья (об стенку) по теме: GNU Hello
Make
- Зависимости и проверка старшинства
- Запуск shell-команд
- Правила по умолчанию
- Переменные, подстановки, .PHONY и прочее
+ самодельный configure
Кроссплатформенность?
Autotools
Генерация configure — autoconf
+ autoheader (сводный .h-файл найденного)
Автоматическое конструирование Makefile.in для autoconf — automake
Автоматическая проверка зависимостей в .h-файлах — autoscan
Переопределение процедур поиска для конкретной системы — aclocal
+ libtool для сборки библиотек и компиляции с ними
А попроще?
pkg-config — Только способ запуска gcc для .h и библиотек
SCons, Rake, Ant, Premake (прямо по википедии:)
CMake
- Аналог automake
- + Простой входной файл
- + Разные back-end-ы (Makefile, VC++-проект, XCode), ...
- - Собственный модули определения библиотек
- Поддержка out-of-tree сборки
Отладка и трассировка
Информация о файле
objdump, nm
Пакет elfutils
Пошаговое выполнение
- Аппаратное
- Эмулируемое
Что ещё может быть нужно:
- Исходные тексты
- Debug info (соответствие src ⟷ debuginfo)
Исходные тексты и debuginfo всех библиотек
GDB
- Выполнение
run
continue
next
step
finish
advance
- Точки останова
По номеру строки (оптимизация ) breakpoint
По изменению ячейки (=> выражения) watchpoint
По C++-исключению catchpoint
- syscall
- Просмотр
Ячейки (=> выражения, в т. ч. адресного) print, display
куска исходника вокруг точки останова list
дампа памяти dump
- Стек вызовов
Просмотр backtrace
Переход up, down
- …
Шпаргалка по GDB: gdb-refcard.pdf
Трассировка
- Разделяемые библиотеки и их открытие
dlopen()
ld.so
objdump, nm
- Загрузка библиотеки
ldd
LD_LIBRARY_PATH и LD_PRELOAD
=> ltrace
Особенности glibc и strace
Поиск memory corruption
Перегрузка malloc() и подобных:
DUMA (бывший EFence)
G-Perftools (бывший Google Performance Tools)
Работа с исходным текстом
Передача файла:
diff и patch
patch -pN, diff -ru, .rej/.orig …
patchutils
Недостатки обмена патчами.
Задачи:
- Учёт версий
- Доступное хранение всего кода
- Поддержка совместной разработки
Учёт версий
SCCS (Source Code Control System, 1972г ) — маркировка файлов строковой константой (сохраняется в объектнике!)
- RCS + история изменений (с вычислением дельты)
Хранение кода и совместная разработка
Общее название — VCS (Version Control System)
- CVS + централизованный сервер-хранилище
- SVN = CVS «на стероидах»
- …
=> совместная работа
- Дисциплина
- Права доступа
- Просмотр истории
- В т. ч. по коммитерам
Дисциплина обновления хранилища
Малый цикл (локальная модификация):
- Редактирование (до некоторого промежуточного результата)
- Проверка того, что результат достигнут
Регистрация изменений (commit)
В случае централизованного сервера с общим доступом превращается в большой цикл:
Обновление рабочей копии(pull)
- Редактирование. Не имеет смысла без (1)
- Проверка
- Регистрация изменений. Не имеет смысла без (5)
Обновление хранилища (push).
Ветки
Большой цикл не всегда успешен => конфликт:
- Сделать commit побольше (когда всё готово)
- Как можно чаще синхронизовать
=> Собственные версии хранилища, branches (ветки)
- до некоторого коммита имеют общую историю
- далее ведутся как заблагорассудится
А обратно? => Слияние веток (merge). Дерево превращается в орграф.
- Алгоритмы слияния
Конфликты (формат diff3)
DVCS
Не заталкивать всё на сервер, а скачивать друг у друга?
- Bazaar
- Mercuirial
- Git
- Darcs
- Monotone
- …
Свойства:
- Полная локальная копия хранилища (+ы и -ы)
- Необходимость публикации
- Например,
- Поддержка малого цикла обновления
=> Одно изменение = один коммит
- Необходимость организации информационного пространства
теги (tags)
описание коммита (commit messages)
- аутентификация коммитеров (подпись)
Git
История: BitKeeper, Larry McVoy, Andrew Tridgell и Линус
Работа:
clone
Малый цикл: pull → (hack+ → add → commit)+
Исправление коммита git commit -amend
Публикация: push в своё публичное хранилище
Работа с произвольными исходниками:
git init
git add .
git commit -a -m "INITIAL"
git tag Start
- Малый цикл
Если не понравилось: git reset --hard Start и git clean -f
Создание патчей git fotmat-patch Start
Всякое:
Полезные команды: git am, git stash, git rebase [--interactive]…
инфраструктура: GitHub, Gitorius etc.; gitolite, gitosis etc.; gitweb
Материалы
Их туча.
http://ru.wikipedia.org/wiki/Git в разделе ссылки
Дисциплина оформления и ведения исходного текста
Совместная разработка =>
Дисциплина использования корпуса текстов (хранилища)
Дисциплина формирования исходного текста
Пример дисциплины работы с хранилищем (git)
- Одно изменение — один коммит
- Двухчастный commit-message (резюме+полный текст)
- Трёхпоточная разработка в ветках (devel, release, legacy)
- Многоуровневый нециклический орграф слияния (merge) хранилищ
Дисциплина оформления кода
Цель: продуктивная совместная работа
- Не «качество кода»
- Не «унификация кода»
- Не «скорость написания кода»
- …
(хотя могут стоять такие задачи)
- Индивидуальная продуктивность (типичные ошибки, «удобный» вид, планирование)
- Включение в общее инф. пространство (документирование, комментарии, повторнаое использование кода)
- Доступность сообществу (KISS, следование общим правилам)
(greg@kroah.com со ссылкой на Elliot Solloway & Kate Ehrlich): добровольное использование разумных правил позволяет надеяться на то, что все в сообществе также используют эти правила
- Учёт специфики проекта и сообщества:
- Размер и ротация сообщества
- Требования к надёжности кода
- Специфика ЯП и предметной области
Что стоит фиксировать
- Внешний вид
- Именование объектов
- (не-)Использование конструкций ЯП
- Разбиение на модули (C: функции, .c и .h файлы)
- Комментарии
- Использование системных и библиотечных примитивов
=> Отдельная дисциплина при работе с большими инструментариями
Пример: Linux Kernel Coding Style
«First off, I'd suggest printing out a copy of the GNU coding standards, and NOT read it. Burn them, it's a great symbolic gesture.» 1
- Indentation
- Breaking long lines and strings
- Placing Braces and Spaces
- Naming
- Typedefs
- Functions
- Centralized exiting of functions
- Commenting
You've made a mess of it
- Kconfig configuration files
- Data structures
- Macros, Enums and RTL
- Printing kernel messages
- Allocating memory
- The inline disease
- Function return values and names
- Don't re-invent the kernel macros
- Editor modelines and other cruft
- Inline assembly
Замечания от greg@croah
Информационное пространство дерева исходных текстов
Информация в исходном коде:
- Документирование самих исходных текстов: комментарии, встроенная документация
- Структура дерева каталогов и подразумеваемые файлы
- Собственно «документация»
Документирование исходных текстов
Задачи:
- Документирование исходного кода
- Создание технической документации «по месту»
Методы:
- Комментарии
- Конструкции ЯП
- Literate programming
На примере Doxygen:
Описания функций, макросов, классов…
Диаграммы (вызовы, классы, кооперации, каталоги, зависимости…)
- Навигация по коду (индексы, подсветка синтаксиса, поиск…) и перекрёстные ссылки
- Специфика самого проекта и вспомогательные тексты
- Внешние объекты (напр., иллюстрации)
- Несколько выходных форматов для разных целей (HTML, XML, man, LaTeX, PS/PDF…)
Использование размеченного текста (Markdown, HTML)
- ЯП: IDL, Java, C*, D, PHP, Python, Fortran, VHDL, VHDL
Python: самодокументируемость
Внешняя документация
- Man
*roff. Применимость man
Системы форматирования документации
Системы подготовки документации
- Подручные средства (Wiki, ODT, …)
Структура каталога с исходниками
Задачи:
Унифицировать начальные действия человека (AUTHORS, COPYING, INSTALL, NEWS, README, THANKS, TODO, …)
Разделять файлы по назначению (src, doc, lib, tests, po, …)
- Обеспечить раздельную сборку
- Структурировать области видимости
- Поддержка in-tree сборки
Пример автоматического создания проекта: http://kdevelop.org/KDevelop
Контроль качества программного продукта
Исходный код сам по себе — прошлая лекция.
Ниже « » означает попытку автоматизации.
Сборка
Собираемость, в т. ч. под разные архитектуры
- Регрессии в диагностике
:
- Выяснение необходимости пересборки
- Площадка для пересборки всех целевых продуктов
См. Buildbot
Интеграция
В составе дистрибутива или внутри определённого окружения: новые/изменённые требования к окружению или изменение предоставляемых компонент окружения.
- Системное тестирование (библиотеки, программное окружение, …)
=> отслеживание зависимостей
- Изменения в ABI и формате данных
- Проблема создания пространства имён и её решение.
Работоспособность
- Приёмочное тестирование: деплоймент и эксплуатация
- Проблема создания тестового окружения
UI: xautomation, Xpresser
- WWW: … (тысячи их)
- Порождение тестов
- Общий недостаток: дисциплина оформления кода
«Разработка через… тестирование»
- контрактное программирование и т. п.
- заглушки
- Компромисс: трёхуровневое тестирование (модульное → системное → приёмочное)
Модульное тестирование (unit testing)
- Test case
- Test fixtures
- Test suites
- setup() / teardown()
- Assertions
Инструментов ОЧЕНЬ МНОГО:
Примеры:
C: CUnit, [[http://check.sourceforge.net/|Check], …
C++: Boost Test, …
Python: http://docs.python.org/3/library/unittest.html, все остальные
- …
Цикл автоматического тестирования
- Сборка из исходников
- Модульное тестирование
- Формирование дистрибутива
- Системное тестирование
- Тестирование деплоймента
- Тестирование функциональности
- Публикация
Обратите внимание на то, что на каждом этапе необходимы различные аппаратно-программные окружения Пример: Buildbot
Бета-тестирование
Это уже из области социониженерии, не в этот раз .
Инструментарии
Целевые библиотеки
Аксиома: найдётся всё (©ямдекс)
- Разнообразие библиотек: хорошо или плохо?
- NIH-синдром и FLOSS
- Сначала поиск, потом разработка
Ресурсы: http://sf.net, http://googlecode.com, http://launchpad.net, … , http://www.cpan.org, http://pypi.python.org, … Критерии качества:
- Команда и сообщество
- Возраст
- Регулярность разработки
- Качество кода
- Лицензия
- …
Инструментарии (frameworks)
Цели инструментария:
- Кроссплатформенность (возможно, прозрачная!)
- Расширение и переписывание стандартов
- Связное информационное пространство
- Общая идеология разработки
=> привлечение сообщества
GLib/GObject
Glib (Си):
- типы данных
- всякие
- строковые функции, кодировки
- случайные числа
- РВ
- i18n
- память, куча, динамическая загрузка кода
- атомарные операции
- процессы, нити, таймеры
- лексический анализатор, синтаксические анализаторы…
- I/O, потоки
- Отладка и диагностика, модульное тестирование
GObject (Си):
- Аналоги типов в Си (числа, ссылки, строки и т. п.)
- Классы (в смысле ООП), интерфейсы, простые контейнеры и классы с метаданными
- Сигналы и замыкания
Boost
C++:
- Алгоритмы
- Разные компиляторы
- Многопоточное программирование
- Контейнеры
- Модульное тестирование
- Структуры данных
- Функциональные объекты
- Обобщённое программирование
- Графы
- Работа с геометрическими данными
- Ввод/вывод
- Межъязыковая поддержка
- Итераторы
- Математические и числовые алгоритмы
- Работа с памятью
- Синтаксический и лексический разбор
- Метапрограммирование на основе препроцессора
- Метапрограммирование на основе шаблонов
- «Умные указатели»
- Обработка строк и текста
Что общего с GLib и в чём различие? Почему?
Qt
C++ и метапрограммирование как основа (обработка moc исходных текстов) Названия компонентов вполне говорящие:
QtCore
QtGui
QtNetwork
- !QtOpenGL
QtSql
QtScript
QtSvg
QtXml
QtAssistant
QtTest
QtWebKit
- Phonon
- !QtCLucene — модуль для поддержки полнотекстового поиска
ActiveQt — модуль для работы с ActiveX
- WoC (widgets on canvas)
В чём отличие от двух предыдущих?
???
Набор библиотек vs инструментарий.
ЯПВУ как инструментарии
- Python / Perl / Ruby / чёрта в ступе
- Java / Mono / …
Технологии программирования
Имя им легион, регулируют самые разные стороны:
- Extreme programming (взаимодействие разработчиков)
- Rails (подход к проектированию)
- Design patterns, ACE (подход к разработке кода)
- Rational (подход к процессу разработки)
- … (ещё примеры?)
Интернационализация
Главная ссылка по теме: лекция Андрея черепанова
I18n — адаптация ПО к использованию в национальном контексте:
- Перевод текстов в составе ПО (всё ли?)
- Планирование интерфейса (размер, LTR…)
- Звуки
- Изображения: текст на них и культурная атрибуция
Управляющие клавиши (иероглифы, ага )
- Шрифты (за пять лет стало лучше)
Локаль (LANG=ru_RU.KOI8-R LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION LC_ALL)
- Ссылки на внешние ресурсы (поддержка, издатель и пр.; телефоны, url и пр.)
Что ещё требует i18n:
- Электронная документация
- Непрограммные данные (шаблоны документов и форм и т. п.)
- Бумажная документация и др. сопутствующие предметы
Процесс i18n
1 язык = 1 исходник — хуже только бинарные патчи (достоинства?)
=> +уровень косвенности (globalization + localization)
Что автоматизируется на уровне глобализации/использования локализующих библиотек?
- Словоформы (множественные и падежные)
- Размер и LTR (решается виждет-инструментариями)
- Выбор локализованных ресурсов (картинки, звуки, …)
Частично:
- Перевод новых версий (особенно сообщений)
i18n и переводчики
- Общие словари
- Translation memory: размеченные корпусы текстов vs. строки сообщений
Moving target
- Modern latin
- Знать Москву или знать русский?
=> координация переводов и распределение ответственности
- Неграмотная программа хотя бы не работает…
Gettext
Глобализация (автоматическоя часть) — замена "" на _("")
- Исходный текст как ID
- Числовые словоформы
- Неточный перевод (fuzzy) и работа с ним
*-format
- Комментарии и привязки
Другие системы
- Qt i18n
- Самопальные преобразования вида «отобразить ресурс такой-то» (mozilla / OOo)
- …
Инструменты
- QTLinquist / lokalize / gtranslator / ...
- Pootle (+amagama +virtaal +ttoolit) (mozilla, OOo) /
- poedit , po.vim, emacs PO mode
- просто текстовый редактор
- OmegaT
Linux-specific
или за что вас будут ненавидеть пользователи *BSD и Solaris, когда будут портировать ваш код
- API:
- Дополнительные возможности
Управление памятью
mbind \- set memory policy for a memory range mremap \- remap a virtual memory address remap_file_pages \- create a nonlinear file mapping
Управление процессами
clone, __clone2 \- create a child process prlimit \- get/set resource limits ioprio_get, ioprio_set \- get/set I/O scheduling class and priority personality \- set the process execution domain prctl \- operations on a process sched_setaffinity, sched_getaffinity \- \ sched_setscheduler, sched_getscheduler \-
Неймспейсы
setns \- reassociate thread with a namespace
Треды
exit_group \- exit all threads in a process get_thread_area \- get a thread-local storage (TLS) area gettid \- get thread identification set_thread_area \- set a thread local storage (TLS) area set_tid_address \- set pointer to thread ID tkill, tgkill \- send a signal to a thread
epoll
epoll_create, epoll_create1 \- open an epoll file descriptor epoll_ctl \- control interface for an epoll descriptor epoll_wait, epoll_pwait \- wait for an I/O event on an epoll file descriptor
extended attributes
getxattr, lgetxattr, fgetxattr \- retrieve an extended attribute value listxattr, llistxattr, flistxattr \- list extended attribute names removexattr, lremovexattr, fremovexattr \- remove an extended attribute setxattr, lsetxattr, fsetxattr \- set an extended attribute value
numa
get_mempolicy \- retrieve NUMA memory policy for a process getcpu \- determine CPU and NUMA node on which the calling thread is running migrate_pages \- move all pages in a process to another set of nodes move_pages \- move individual pages of a process to another node set_mempolicy \- set default NUMA memory policy for a process and its children
dnotify/inotify
fcntl \- manipulate file descriptor (F_GETOWN_EX, F_SETOWN_EX, F_SETPIPE_SZ, F_GETPIPE_SZ, F_GETSIG, F_SETSIG, F_NOTIFY, F_GETLEASE, F_SETLEASE) inotify_add_watch \- add a watch to an initialized inotify instance inotify_init, inotify_init1 \- initialize an inotify instance inotify_rm_watch \- remove an existing watch from an inotify instance
capabilities
capget, capset \- set/get capabilities of thread(s)
futex
futex \- fast user-space locking
Костыли
adjtimex \- tune kernel clock bdflush \- start, flush, or tune buffer-dirty-flush daemon idle - make process 0 idle (legacy) ioperm \- set port input/output permissions (obscure) iopl \- change I/O privilege level (obscure) ipc \- System V IPC system calls kexec_load \- load a new kernel for later execution lookup_dcookie \- return a directory entry's path (obscure) mount \- mount file system nfsservctl \- syscall interface to kernel nfs daemon pciconfig_read, pciconfig_write, pciconfig_iobase \- pci device information handling readahead \- perform file readahead into page cache readdir \- read directory entry (legacy) reboot \- reboot or enable/disable Ctrl-Alt-Del sendfile \- transfer data between file descriptors setup \- setup devices and file systems, mount root file system (obscure) swapon, swapoff \- start/stop swapping to file/device sync, syncfs \- commit buffer cache to disk sync_file_range \- sync a file segment with disk sysctl \- read/write system parameters sysinfo \- returns information on overall system statistics umount, umount2 \- unmount file system
Управление модулями
create_module \- create a loadable module entry delete_module \- unload a kernel module get_kernel_syms \- retrieve exported kernel and module symbols init_module \- load a kernel module query_module \- query the kernel for various bits pertaining to modules
Security
pivot_root \- change the root file system setfsgid \- set group identity used for file system checks setfsuid \- set user identity used for file system checks unshare \- disassociate parts of the process execution context
Расширение POSIX
dup3 \- duplicate a file descriptor eventfd \- create a file descriptor for event notification fallocate \- manipulate file space (есть posix_fallocate) fcntl \- manipulate file descriptor (F_GETOWN_EX, F_SETOWN_EX, F_SETPIPE_SZ, F_GETPIPE_SZ, F_GETSIG, F_SETSIG, F_NOTIFY, F_GETLEASE, F_SETLEASE) getrusage \- get resource usage (потребление потока) _llseek \- reposition read/write file offset (legac5) madvise \- give advice about use of memory (posix_madvise) mmap2 \- map files or devices into memory msgctl \- message control operations (IPC_INFO, MSG_INFO, MSG_STAT) pipe2 \- create pipe ppoll \- wait for some event on a file descriptor rt_sigqueueinfo, rt_tgsigqueueinfo \- queue a signal and data pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO \- semctl \- semaphore control operations (IPC_INFO, SEM_INFO, SEM_STAT) recvmmsg sendmmsg signalfd \- create a file descriptor for accepting signals shmctl \- shared memory control (IPC_INFO, SHN_INFO, SHM_STAT, SHM_LOCK/SHM_UNLOCK) splice \- splice data to/from a pipe statfs, fstatfs \- get file system statistics tee \- duplicating pipe content timer_create \- create a POSIX per-process timer timerfd_create, timerfd_settime, timerfd_gettime \- uselib \- load shared library vhangup \- virtually hangup the current tty vmsplice \- splice user pages into a pipe
aio
io_cancel \- cancel an outstanding asynchronous I/O operation io_destroy \- destroy an asynchronous I/O context io_getevents \- read asynchronous I/O events from the completion queue io_setup \- create an asynchronous I/O context io_submit \- submit asynchronous I/O blocks for processing
personality
personality \- set the process execution domain
Platform-specific особенности
alloc_hugepages (obscure, x86-64 only) arch_prctl - set architecture-specific thread state (obscure, x86-64 only) cacheflush \- flush contents of instruction and/or data cache (obscure, MIPS only) modify_ldt \- get or set ldt (obscure, x86 only) spu_create \- create a new spu context (obscure, ppc only) spu_run \- execute an SPU context (obscure, ppc only) subpage_prot \- define a subpage protection for an address range (ppc only) vm86 (obscure, x86 only)
- Дополнительные возможности
- procfs, sysfs, configfs
- procfs
- kobjects
- sysfs
- selinux
- pam
- limits, cgroups
- bash
- Как минимум, bash не стандартизирован со всеми вытекающими. И никто никогда (почти) не проверяет текущую версию bash для проверки наличия данной возможности в bash (так как это неудобно) при написании скриптов на bash.
Ср. http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html и, например, http://www.tldp.org/LDP/abs/html/abs-guide.html
Советы по переписыванию скриптов с bash на dash на ubuntuwiki
- GNU extensions
- Например, GNU-specific параметры и утилиты в GNU *utils
- glibc
- ld: переменные окружения
- feature test macros
- Макросы, функции, поведение
LDPRELOAD=linus_memcpy.so
Информационное-технологическое обеспечение разработки
(вне рассмотрения)
- Инструменты, упомянутые в лекциях
- Средства ОС (настройка и системная документация)
- Средства индивидуальной разработки и IDE
- …
Информационное пространство
Четыре области:
- Информация о ЯП
- Информация об инструментарии
- Информация об ОС
- Техническая документация разрабатываемого проекта
Где искать 1—3 ?
- Документация, поставляемая с ЯП/Инструментарием
- Документация, встроенная в IDE
- Дистрибутив и его сообщество
Базовая документация и README.дистрибутив
- Рассылки (возможно, специфические)
- Базовый сайт сообщества и его подстраницы
- ЯП/Инструментарий и его сообщество
- Базовый сайт и ресурсы сообщества
Рассылки (This wiki is not for random discussion of GCC, nor for asking questions. It is here to provide information. If you have questions, please use the mailing list. Do not add questions to these pages!)
Что ещё?
- Участие в разработке ЯП/инструментария/компонента (см. ниже)
- Учебники и методички
- Чуждой код (в т. ч. тренировочный)
- Велосипеды
Разработка проекта
- Хранилище кода
- Информационный обмен
- Рассылка
- Mailman
- IM (IRC / Jabber / …)
- Рассылка
- Отслеживание ошибок
- Управление разработкой
Системы управления проектами (тысячи их) — ?, интеграция с описанным выше
Всё сразу:
- Github, Gitorius, Sourceforge, Googlecode+Googleвсё, Bitbucket, Launchpad, …