⇤ ← Версия 1 от 2020-10-05 16:04:34
4893
Комментарий:
|
4852
|
Удаления помечены так. | Добавления помечены так. |
Строка 3: | Строка 3: |
Сначала про настройку окружения * `.dircolors`; grep; man; `PS1` * `vim`: цветовые схемы, `*~`-файлы, `vimbackup` * `zsh`/`bash`: раскраска командной строки, алиасы * велосипедный парк * ??? == Сборка из нескольких файлов == * Зачем много файлов? * Быстрее компилировать не все * Проще ориентироваться * Си: пространства имён! * (!) пример * Скомпилировать сразу все файлы? * (пере)компиляция только изменённых 1. Компиляция до `.o` 1. [[ FrBrGeorge/LinkingC |Компоновка]] * (повтор: сложность компоновки вручную с помощью `ld`) == Make == Проблемы многофайловой сборки: вручную муторно, сценарий делает много лишнего 1. Перекомпиляция только обновлённых исходников * Построение графа зависимостей и подграфа пересборки 1. Удаление генератов * В том числе того, что ''разработчик'' считает генератом 1. Скриптование / code reuse приёмов сборки * в т. ч. уникальных для проекта {{{#!wiki caution ТАБУЛЯЦИИ! }}} === Gnu make === (есть много, но этот популярнее всех остальных, вместе взатых) * Цели и рецепты * Как правило «как создать файл из других файлов» (например, `prog.o` из `prog.c`) * Вариант: «как создать файл ''определённого типа'' из других файлов ''другого определённого типа''» (например `.o` из `.c` * Командный интерпретатор ОС в качестве языка сценариев (как правило, shell) * ⇒ нужен shell под системы без shell * Переменные * Специальные переменные * Подстановка * Отложенное и немедленное присваивание * Много правил по умолчанию * … (что успеем) === Литература по GNU Make === * [[http://grep.cs.msu.ru/BESTA/ruprog/make.doc.txt|Очень старый]] учебник по старому Make (зато подробный и с объяснениями) * [[https://www.oreilly.com/library/view/managing-projects-with/0596006101/|Managing Projects with GNU Make, 3rd Edition]] * [[https://www.gnu.org/software/make/manual/make.html|Documentation]] * [[http://rus-linux.net/nlib.php?name=/MyLDP/algol/gnu_make/gnu_make_3-79_russian_manual.html|Русский перевод]] * Книга Владимира Игнатова [[https://www.opennet.ru/docs/RUS/gnumake/|Эффективное использование GNU Make]] == Пример == |
|
Строка 57: | Строка 5: |
|| <<MiniPage({{{#!highlight c\n#include "outlib.h"\nint main(int argc, char *argv[]) {\n Count = argc;\n output("<INIT>");\n output(argc>1 ? argv[1] : "<NOPE>");\n output("<DONE>");\n return 0;\n}\n}}})>> || <<MiniPage({{{#!highlight c\n#include <stdio.h>\n#include "outlib.h"\nvoid output(char *str) {\n printf("%d: %s\n", Count++, str);\n}\n}}})>> || | || <<MiniPage({{{#!highlight c\n#include "outlib.h"\nint main(int argc, char *argv[]) {\n Count = argc;\n output("<INIT>");\n output(argc>1 ? argv[1] : "<NOPE>");\n output("<DONE>");\n return 0;\n}\n}}})>> || <<MiniPage({{{#!highlight c\n#include <stdio.h>\n#include "outlib.h"\nvoid output(char *str) {\n printf("%d: %s\012", Count++, str);\n}\n}}})>> || |
Строка 89: | Строка 37: |
* Кстати, вот альтернативная форма, в которой нет табуляций. | * Раздельная компиляция работает: {{{#!highlight console $ make clean rm -f prog a.out *.o $ make prog cc const.c -c -o const.o cc fun.c -c -o fun.o cc prog.c -c -o prog.o cc const.o fun.o prog.o -o prog $ touch fun.c $ make prog cc fun.c -c -o fun.o cc const.o fun.o prog.o -o prog $ touch fun.o $ make prog cc const.o fun.o prog.o -o prog }}} * Кстати, вот альтернативная форма, в которой нет табуляций. Она малочитаема, не будем ей пользоваться: {{{#!highlight makefile prog: const.o fun.o prog.o ; cc const.o fun.o prog.o -o prog fun.o: fun.c ; cc fun.c -c -o fun.o prog.o: prog.c ; cc prog.c -c -o prog.o const.o: const.c ; cc const.c -c -o const.o clean: ; rm -f prog a.out *. }}} (а табуляции и пробелы становятся обычными разделителями) * И ещё одна. На этот раз полями рецепта определяются не табуляции, а тильды (а табуляции и пробелы становятся обычными разделителями): {{{#!highlight makefile .RECIPEPREFIX = ~ prog: const.o fun.o prog.o ~ cc const.o fun.o prog.o -o prog fun.o: fun.c ~ cc fun.c -c -o fun.o prog.o: prog.c ~ cc prog.c -c -o prog.o const.o: const.c ~ cc const.c -c -o const.o clean: ~ rm -f prog a.out *.o }}} 1. Хорошо бы задать правило по умолчанию, как делать `.o` файлы из `.c`. {{{#!highlight makefile %.o: %.c cc $< -c -o $@ prog: const.o fun.o prog.o cc $^ -o $@ clean: rm -f prog a.out *.o }}} * Конструкции, начинающиеся с `$` — подстановки значения некоторых переменных Make: * `$@` означает цель (похожа на цель в тире) * `$<` означает первую из зависимостей * `$^` означает список всех зависимостей 1. В Make есть и нормальные переменные, только их подстановка должна заключаться в круглые скобки. Заодно усложним и нашу программу. || prog.c || fun.c || || <<MiniPage({{{#!highlight c\n#include <stdio.h>\n#include "outlib.h"\nint main(int argc, char *argv[]) {\n int i;\n if((Count = argc)>1) {\n output("<INIT>");\n for(i=1; i<argc; i++)\n output(argv[i]);\n output("<DONE>");\n }\n else\n usage(argv[0]);\n return 0;\n}\n}}})>> || <<MiniPage({{{#!highlight c\n#include <stdio.h>\n#include "outlib.h"\nvoid output(char *str) {\n printf("%d: %s\012", Count++, str);\n}\n\nvoid usage(char *prog) {\n fprintf(stderr, "%s: Print all arguments\012\t"\\n "Usage: %s arg1 [arg2 […]]\012", prog, prog);\n}\n}}})>> || || const.c || outlib.h || || <<MiniPage({{{#!highlight c\nint Count=0;\n}}})>> || <<MiniPage({{{#!highlight c\nvoid output(char *);\nvoid usage(char *);\nextern int Count;\n}}})>> || |
Пример написания и использования Makefile
Начнём с таких вот файлов:
prog.c |
fun.c |
|
|
const.c |
outlib.h |
1 int Count=0;
|
|
Их можно собрать в один файл просто с помощью cc *.c -o prog
- Напишем простейший Makefile для этого:
- Помните о табах!
Заодно сделаем цель clean. Пробуем make, make clean.
- Так можно и скриптом было сделать. Обеспечим раздельную компиляцию и компоновку.
- Раздельная компиляция работает:
1 $ make clean 2 rm -f prog a.out *.o 3 $ make prog 4 cc const.c -c -o const.o 5 cc fun.c -c -o fun.o 6 cc prog.c -c -o prog.o 7 cc const.o fun.o prog.o -o prog 8 $ touch fun.c 9 $ make prog 10 cc fun.c -c -o fun.o 11 cc const.o fun.o prog.o -o prog 12 $ touch fun.o 13 $ make prog 14 cc const.o fun.o prog.o -o prog 15
- Кстати, вот альтернативная форма, в которой нет табуляций. Она малочитаема, не будем ей пользоваться:
- (а табуляции и пробелы становятся обычными разделителями)
- И ещё одна. На этот раз полями рецепта определяются не табуляции, а тильды (а табуляции и пробелы становятся обычными разделителями):
- Раздельная компиляция работает:
Хорошо бы задать правило по умолчанию, как делать .o файлы из .c.
Конструкции, начинающиеся с $ — подстановки значения некоторых переменных Make:
$@ означает цель (похожа на цель в тире)
$< означает первую из зависимостей
$^ означает список всех зависимостей
- В Make есть и нормальные переменные, только их подстановка должна заключаться в круглые скобки. Заодно усложним и нашу программу.
prog.c |
fun.c |
|
|
const.c |
outlib.h |
1 int Count=0;
|
|