Програмне забезпечення та програмування
Розуміння та управління залежностями C з файлами
Table of Contents
Вступ
У програмі C часто розщеплюється через декілька вихідних файлів і заголовків файлів для поліпшення організації, багаторазовості та швидкості складання. Однак ця модульність представляє завдання: коли змінами файлів заголовка, кожен вихідний файл, який включає його, повинен бути перероблений. Роблячи це вручну є помилкою і трудомістким. Зробіть файли, керовані make] будувати інструмент автоматизації, вирішити цю проблему за допомогою кодування залежностей і автоматизації процесу збірки. Майстерні макіяжу є обрядом проходження для будь-якого серйозного розробника C, але багато новихкомерцій, які лікують їх автоматично чорними коробками. Ця стаття пояснюється надійністю роботи
Що таке файли?
Файл Makefile є простимитекстовими файлами, які визначають набір правил побудови проекту. make утиліта читає ці правила, перевіряє часові заголовки файлу і виконує тільки команди, необхідні для доведення проекту до дати. Основна ідея проста: кожен правило має target] (файл для виробництва), ] ] передумови] (файли, необхідні для побудови цілей), і [Fshell:4[[Fshell:4]
З 1970-х років, і GNU Make є дефолту на Linux і macOS. Синтаксис є лаконічним, але може бути тонким; отримувати залежності правою є основним навичкам розробника C.
Розуміння залежностей
У проекті C не обмежуються файли . Кожен вихідний файл включає один або кілька заголовкових файлів (наприклад, ). Якщо заголовок модифікований, всі файли, які включають його, повинні бути перероблені. Аналогічно, об'єкти файлів залежать від їх відповідних файлів, а кінцевий виконуваний залежить від всіх файлів об'єкта.
Витрата проти нездійсненності
На початку роботи програми, які вказані всі передумови вручну. Цей підхід є крихким: забуваючи заголовок означає стеблові збірки, в той час як список занадто багато спровокує непотрібні відкладки. Похитатися, оскільки проект росте, ручні списки стають незбережені. Сучасний розчин полягає в тому, щоб мати компілятор, що створює залежності автоматично, перетворюючи їх в імміцит, машинно-зчежені передумови.
Ми можемо самі зателефонувати одержувачу і узгодити зручний час і місце вручення квітів, а якщо необхідно, то збережемо сюрприз.
Основна структура макіяжу
Типовий файл Makefile містить змінні визначення, правила та фонізовані цілі. Ось мінімальний, але функціональний приклад для проекту та :
CC = gcc
CFLAGS = -Wall -Wextra -O2
main: main.o utils.o
$(CC) $(CFLAGS) -o main main.o utils.o
main.o: main.c
$(CC) $(CFLAGS) -c main.c
utils.o: utils.c
$(CC) $(CFLAGS) -c utils.c
clean:
rm -f main main.o utils.o
Цей файл має чотири цілі: (зразковий), два об'єкти, і фонізовані цілі ]. Лінії залежностей після того, як колонка розкаже ]make], які файли для перевірки перед викривленням для відновлення цілей.
Поні Цільові
Цільові цілі, як або не представляють файли. Для запобігання make] з конф'юскування їх файлами, вони повинні бути оголошені як фоні:3]:
.PHONY: clean all
Якщо файл, який був представлений , , змейк, буде розглянуто його доопрацьованим і пропустити рецепт.
Управління залежностей Ефективно
Керівництво Makefile вище має серйозний недолік: залежність є правильним, але що про заголовки? Якщо зміни, (який включає його) необхідно перебудовано, але правило говорить це тільки залежить від . Зафіксувати, щоб дати компілятору випускати реальний список залежностей.
Автоматична генерація залежностей з ГКК
GCC (і Clang) може генерувати інформацію про залежності за допомогою сімейства прапорів. Найбільш практичне поєднання для більшості проектів :
- – записує файл залежностей (]) при доборі, списуючи тільки заголовки, які не заголовки системи.
- – визначає назву файлу залежностей.
- – додає фоні цілі для кожного заголовка, попереджаючи помилки при видаленні заголовка.
Ось як включити автоматичне відстеження залежностей в файлі «Дослідник»:
CC = gcc
CFLAGS = -Wall -Wextra -O2 -MMD -MP
SRCDIR = src
OBJDIR = obj
SRCS = $(wildcard $(SRCDIR)/*.c)
OBJS = $(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o,$(SRCS))
DEPS = $(OBJS:.o=.d)
all: myprogram
myprogram: $(OBJS)
$(CC) $(CFLAGS) -o $@ $^
$(OBJDIR)/%.o: $(SRCDIR)/%.c
@mkdir -p $(OBJDIR)
$(CC) $(CFLAGS) -c $< -o $@
-include $(DEPS)
.PHONY: all clean
clean:
rm -rf $(OBJDIR) myprogram
Розгортання:
- збирає всі файли в каталозі джерело.
- перетворює їх на шляхи файлів об'єкта.
- перераховує файли залежностей (наприклад, ).
- ] компілює кожного файл і, через , генерує файл як побічний ефект.
- Лінія читати генерувані файли, перетворюючи їх в реальні передумови для файлів макіяжу. Зошит () пригнічує помилки при файли не існують ще (наприклад, на першому зборі).
Тепер, якщо є модифікованим, наступний вступ буде переохоплювати автоматично, тому що файл ] ] включений ] як передумова.
Додаткові методи
Обробка Generated залежностей
Коли заголовок видалено, файл може доторкнутися його, викликаючи make, щоб не вдалося з відсутністю помилки цілі. прапор адреси, які додають порожні правила фоні для кожного заголовка залежностей. Якщо заголовок вийшов, make просто працює підробкове правило (що нічого не робить) і продовжується.
Включаючи файли залежностей після зміни джерела
Один тонкий: якщо файл джерела додає або видаляє , відповідний файл повинен бути регенерований. Тому що файл є найбільш передумовою об'єкта, make буде помітити зміни часової та рекомпонентної, яка відновлює файл . Цей рецидив працює автоматично, коли перша будівля завершена.
Використання додаткових умов замовлення
Іноді вам потрібно каталог, щоб існувати до будівлі, але ви не хочете, щоб його час запускати реставрацію. Це роль order‐only передумов] (розділений ). У правилах шаблону вище, ми використовували всередині рецепта; альтернатива:
$(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR)
$(CC) $(CFLAGS) -c $< -o $@
$(OBJDIR):
mkdir -p $@
Цей каталог забезпечує створення каталогу перед будь-яким компіляціям, але зміною до каталогу (наприклад, новий файл всередині) не буде викликати повторне порівняння.
Кращі практики управління залежностями
- Використовувати автоматичне генерування залежностей з дня Навіть для одностороннього проекту, це гарне місце. Це коштує нічого і не перешкоджає майбутнім помилкам.
- Використовувати файли залежностей, відокремлені від вихідних файлів Поставити їх в або ]] каталог. Це полегшує очищення і дозволяє уникнути захаращування джерела дерева.
- Включає створене файли після правил, які створюються їх прямої дії є тонким, але розміщення його після правило шаблону забезпечує, що make вперше знає, як побудувати об'єкти файлів перед спробами прочитати файли.
- Використовувати фонізовані цілі для прибирання будинків , , , а . Завжди оголошуйте їх .
- Leverage змінні для прапорів компілятора, каталогів джерел та списку файлів . Це робить файл, що багаторазово передається через проекти та простіше налаштувати.
- Test your Makefile with the навмисний header edit Модифікувати заголовок, запустити , і підтвердити тільки уражені файли об'єкта перезняті. Якщо відбувається повне відновлення, то щось неправильно з відстеженням залежностей.
- Keep the Makefile простий, але не простий, ніж необхідний Over‐engineering з розширеними функціями, такими як може зробити відбілювання болючим. Починаючи з шаблону, показаної в цій статті; він добре вагає десятки файлів.
Зовнішні ресурси
Щоб поглибити своє розуміння, зверніться до цих авторитетних посилань:
- GNU Make Manual] – Визначений посібник з створення синтаксису, функцій та розширених функцій.
- , , і пов'язані прапори.
- Makefile Tutorial by Chase Lambert – Практичний, добреструктурований підручник, що охоплює багато випадків використання в реальному середовищі.
Висновок
Управління програмами C з файлами Makefiles не є розкіш, але необхідність для будь-якого проекту, який випускає єдиний файл. Поєднуючи правила шаблону, автоматичне покоління залежностей з , і обережне включення створених файлів, ви можете створити систему побудови, яка є одночасно швидкою і правильною. Методи показали тут, усунути ручне відстеження, зменшити час побудови і запобігти тонких помилок, викликаних файлами об'єкта. Після того, як ви внутрішнєізите ці візерунки, ви ніколи не будете писати ручний список залежностей. Інвестиції в навчання належного управління залежностей окупається кожен раз, коли ви працюєте і дивитися тільки файли змінені файли.