make: Ничего не нужно делать для всех

98

Я просматриваю, например, pgm, чтобы создать файл make.

http://mrbook.org/tutorials/make/

Моя папка eg_make_creation содержит следующие файлы,

desktop:~/eg_make_creation$ ls
factorial.c  functions.h  hello  hello.c  main.c  Makefile

Makefile

# I am a comment, and I want to say that the variable CC will be
# the compiler to use.
CC=gcc
# Hwy!, I am comment no.2. I want to say that CFLAGS will be the
#options I'll pass to the compiler
CFLAGS=-c -Wall

all:hello

hello:main.o factorial.o hello.o
  $(CC) main.o factorial.o hello.o -o hello

main.o:main.c
  $(CC) $(CFLAGS) main.c

factorial.o:factorial.c
  $(CC) $(CFLAGS) factorial.c

hello.o:hello.c
  $(CC) $(CFLAGS) hello.c

clean:
  rm -rf *o hello

ошибка:

desktop:~/eg_make_creation$ make all
make: Nothing to be done for `all'.

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

Ангус
источник
12
Попробуйте выполнить «очистить», а затем «очистить все»
Пол Р.
11
Это не ошибка, это просто означает helloактуальность. Измените cleanна, rm -f *.o helloпрежде чем он сделает что-нибудь неожиданное, затем запустите make clean allи посмотрите, работает ли это.
Мат
1
Вы также должны добавить .phony: all clean, поскольку allи cleanне являются именами файлов.
Kerrek SB
3
Не ставьте -c в свои CFLAGS.
wildplasser

Ответы:

123

Иногда ошибка «Нечего делать для всех» может быть вызвана пробелами перед командой в правиле makefile вместо табуляции. Пожалуйста, убедитесь, что вы используете табуляцию вместо пробелов внутри ваших правил.

all:
<\t>$(CC) $(CFLAGS) ...

вместо того

all:
    $(CC) $(CFLAGS) ...

См. Описание синтаксиса правила в руководстве GNU make: https://www.gnu.org/software/make/manual/make.html#Rule-Syntax

VirtualVDX
источник
obj-m + = hello.o all: </t> make -C / lib / modules / $ (shell uname -r) / build M = $ (PWD) чистые модули: make -C / lib / modules / $ ( shell uname -r) / build M = $ (PWD) clean
Нарендра Джагги
является ли указанный выше файл действительным файлом ??
Нарендра Джагги
В контексте родительско-дочерних make-файлов иногда ошибка «Ничего не нужно делать для всех» может быть вызвана неправильной пометкой дочерних целей как объявленных .PHONY в родительском Makefile.
donhector
У меня было all : src/server/mod_wsgi.la, на которое я перешел all : </t> src/server/mod_wsgi.la. Теперь я получаю сообщение об ошибке: make: execvp: src/server/mod_wsgi.la: Permission denied Makefile:29: recipe for target 'all' failed make: *** [all] Error 127после sudo make. Любая помощь?
Mooncrater
@Mooncrater См gnu.org/software/make/manual/make.html#Rule-Syntax . Здесь читается: Строки рецепта начинаются с символа табуляции (или первого символа в значении переменной .RECIPEPREFIX; см. Специальные переменные). Первая строка рецепта может появиться в строке после предварительных условий с помощью символа табуляции или может появиться в той же строке с точкой с запятой. В любом случае эффект один и тот же. Итак, вашим обязательным условием просто стал рецепт. В этом случае вкладка не требуется.
VirtualVDX
31

Удалите helloфайл из папки и попробуйте еще раз.

allЦели зависит от helloцели. helloЦель сначала пытается найти соответствующий файл в файловой системе. Если он его найдет и все зависимые файлы обновлены - делать нечего.

Weekens
источник
obj-m + = hello.o all: </t> make -C / lib / modules / $ (shell uname -r) / build M = $ (PWD) modules clean: make -C / lib / modules / $ ( shell uname -r) / build M = $ (PWD) clean
Нарендра Джагги
это действительный файл make?
Нарендра Джагги
21

Когда вы просто отдаете команду make, она создает первое правило в вашем make-файле, то есть «все». Вы указали, что «все» зависит от «hello», которое зависит от main.o, factorial.o и hello.o. Итак, make пытается увидеть, есть ли эти файлы.

Если они присутствуют, make проверяет, изменились ли их зависимости, например, main.o имеет зависимость main.c. Если они изменились, make перестраивает их, иначе правило пропускается. Точно так же он рекурсивно создает файлы, которые были изменены, и, наконец, запускает самую верхнюю команду, «all» в вашем случае, чтобы дать вам исполняемый файл, «hello» в вашем случае.

Если их нет, make вслепую строит все по правилу.

Переходя к вашей проблеме, это не ошибка, но make говорит, что все зависимости в вашем make-файле обновлены и не нужно ничего делать!

Четан Равиндранатх
источник
16

Make ведет себя правильно. helloуже существует и не старше .cфайлов, поэтому больше нечего делать. Существует четыре сценария, в которых программе make потребуется (пере) собрать:

  • Если вы измените один из своих .cфайлов, он будет новее hello, а затем его придется перестраивать при запуске make.
  • Если удалить hello, то его явно придется восстанавливать
  • Вы можете заставить make все перестроить с помощью -Bопции.make -B all
  • make clean allудалит helloи потребует перестройки. (Предлагаю вам посмотреть комментарий @Mat оrm -f *.o hello
Аарон МакДэйд
источник
4

Я думаю, вы пропустили вкладку в 9-й строке. Строка после all: hello должна быть пустой вкладкой. Убедитесь, что у вас есть пустая вкладка в 9-й строке. Это даст интерпретатору понять, что вы хотите использовать рецепт по умолчанию для make-файла.

Techie
источник
4

Это не ошибка; команда make в unix работает на основе меток времени. То есть, допустим, если вы внесли определенные изменения factorial.cppи скомпилировали с помощью, makeто make показывает информацию о том, что cc -o factorial.cppвыполняется только команда. В следующий раз, если вы выполните ту же команду, то есть makeбез внесения каких-либо изменений в какой-либо файл с .cppрасширением, компилятор сообщит, что выходной файл обновлен. Компилятор предоставляет эту информацию, пока мы не внесем в какие-либо определенные изменения file.cpp.

Преимущество этого метода makefileзаключается в том, что он сокращает время перекомпиляции за счет компиляции только измененных .oфайлов и прямого использования файлов object ( ) немодифицированных файлов.

Muneshwar
источник
0

Я пришел к этой специфической, трудно поддающейся отладке ошибке другим путем. Моя проблема заключалась в том, что я использовал шаблонное правило на этапе сборки, когда цель и зависимость находились в разных каталогах. Что-то вроде этого:

foo/apple.o: bar/apple.c $(FOODEPS)

%.o: %.c
    $(CC) $< -o $@

У меня было настроено несколько зависимостей таким образом, и я пытался использовать один рецепт шаблона для всех. Ясно, что единственная замена "%" здесь не сработает. Я установил четкие правила для каждой зависимости и снова оказался среди щенков и единорогов!

foo/apple.o: bar/apple.c $(FOODEPS)
    $(CC) $< -o $@

Надеюсь, это кому-то поможет!

сфалерон
источник