Что такое эффективный рабочий процесс с C? - Makefile + скрипт bash

Я работаю над одним из своих первых проектов, который будет охватывать более одного файла C. Для моих первых двух тренировочных программ я просто написал свой код на main.c и скомпилировал с использованием gcc main.c -o main. Это работало для меня, когда я учился.

Сейчас я работаю над более крупным проектом самостоятельно. Я хочу продолжить компиляцию самостоятельно (или, по крайней мере, настроить ее вручную), чтобы понять процесс. Почитав немного, я решил сделать Makefile.

Примечание. Я также использую GTK+, поэтому мне пришлось искать, как добавить это в команду компиляции.

Вот как это выглядит после небольшого исследования:

main:
    gcc -Wall -g main.c -o main `pkg-config --cflags --libs gtk+-2.0`

Сначала я просто запускал make. Затем у меня возникли проблемы с получением ошибки «основной обновлен», хотя я изменил файл.

Итак, я написал сценарий:

#!/bin/bash
rm main
make
./main

Итак, я вношу изменения, а затем запускаю этот скрипт.

Это хорошая/нормальная система? Я хочу иметь масштабируемую систему, так как мой проект будет расти. Я предполагаю, что могу сохранить этот скрипт и просто добавить зависимости в make-файл и изменить основную команду компиляции в make-файле. Я прав?

Заранее спасибо.

ИЗМЕНИТЬ:

Спасибо за отзыв о том, как исправить мой Makefile.

Итак, типичный процесс компиляции 1) введите make, затем 2) ./main независимо от того, как настроен проект или его размер (при условии, что вы написали правильный make-файл)?


person mouche    schedule 02.09.2010    source источник
comment
Да, ты прав. Сначала вы делаете make, а затем делаете ./main   -  person codaddict    schedule 02.09.2010
comment
Большое спасибо! Кажется, довольно легко учиться до сих пор.   -  person mouche    schedule 02.09.2010


Ответы (3)


Вам нужно сказать make, что main зависит от main.c. Таким образом, каждый раз, когда вы вносите изменения в main.c, а затем запускаете make, main создается заново. Чтобы удалить main, вы можете иметь фальшивую цель с именем clean как:

main:main.c
    gcc -Wall -g main.c -o main `pkg-config --cflags --libs gtk+-2.0`

.PHONY: clean
clean:
    rm -f main

Теперь, чтобы удалить main, вы можете сделать: make clean

Если вы получаете make: main is up to date., это означает, что вы не изменяли main.c и, следовательно, нет необходимости регенерировать main. Но если вам нужно принудительно регенерировать main, даже если зависимости не были обновлены, вы также можете использовать параметр -B для make, как это предлагается Sjoerd в другом ответе.

person codaddict    schedule 02.09.2010
comment
Полезно добавить строку .PHONY: clean над целью clean на тот случай, если файл с именем «чистый» (например, сценарий оболочки) окажется в каталоге. Если это произойдет, make увидит файл и не запустит чистую цель. PHONY велит ему даже не смотреть. - person aaronasterling; 02.09.2010
comment
Очень полезный комментарий, @aaron. Спасибо. - person mouche; 02.09.2010

  • Используйте make -B или make --always-make для компиляции, даже если цель обновлена.
  • Добавьте имена файлов после двоеточия, чтобы проверить, обновлены ли они.

Пример:

a: a.c
        gcc -o a a.c

a будет построен только в том случае, если a.c новее, чем a.

person Sjoerd    schedule 02.09.2010
comment
Для более крупного проекта make -B, вероятно, не то, что люди хотят использовать. - person Christopher Creutzig; 02.09.2010
comment
Правильно. -B будет полезен, если время модификации некоторых файлов неверно. Это происходит, например, когда вы копируете что-то поверх выходного файла. - person Sjoerd; 02.09.2010

Я считаю, что командной строки make вполне достаточно для моих нужд, но писать Makefiles вручную становится довольно муторно. По мере усложнения вашего проекта вы обнаружите, что управление зависимостями вручную становится все более и более раздражающим. Я предлагаю вам научиться делать хотя бы одно из следующего:

  • Напишите отслеживание зависимостей Makefile, вызвав, например, gcc -M.
  • Научитесь использовать генератор Makefile, например automake или CMake. Я лично предпочитаю automake, потому что он более зрелый (и не делает глупостей, таких как попытки поместить списки, разделенные точкой с запятой, в командной строке).
person Jack Kelly    schedule 02.09.2010
comment
+1 за упоминание доступных генераторов Makefile. Я проверю их. - person mouche; 02.09.2010