make: Нічого не слід робити для `` усіх ''


97

Я проходжу, наприклад, 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

Makefilefile

# 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і перевірте, чи це працює.
Mat

1
Ви також повинні додати .phony: all clean, оскільки allі cleanне є іменами файлів.
Kerrek SB

3
Не кладіть -c у ваші CFLAGS.
wildplasser

Відповіді:


121

Іноді помилка "Нічого не слід робити для всіх" може бути спричинена пробілами перед командою в правилі makefile замість вкладки. Переконайтеся, що ви використовуєте вкладки замість пробілів усередині ваших правил.

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

замість

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

Будь ласка, дивіться інструкцію з виготовлення GNU для опису синтаксису правила: https://www.gnu.org/software/make/manual/make.html#Rule-Syntax


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
Нарендра Джаггі

чи вказаний вище файл є дійсним?
Нарендра Джаггі

У контексті батьківських файлів дочірніх файлів іноді помилка "Нічого не слід робити для всіх" може бути спричинена неправильним позначенням дочірніх цілей, оголошених .PHONY у батьківському файлі Make.
донхектор

У мене було 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ціль намагається знайти відповідний файл у файловій системі. Якщо він знаходить його та оновлений із залежними файлами, робити нічого.


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, тобто "все". Ви вказали, що "все" залежить від "привіт", який залежить від main.o, factorial.o та hello.o. Тож „make“ намагається з’ясувати, чи є ці файли.

Якщо вони присутні, 'make' бачить, чи змінилися їх залежності, наприклад main.o має залежність main.c. Якщо вони змінилися, зробіть їх відновлення, інакше правило пропускає. Подібним чином він рекурсивно продовжує створювати файли, які змінилися, і, нарешті, запускає найвищу команду "все" у вашому випадку, щоб дати вам виконуваний файл, "привіт" у вашому випадку.

Якщо їх немає, make зробіть наосліп все за правилом.

Що стосується вашої проблеми, це не помилка, але "make" означає, що кожна залежність у вашому файлі make up оновлена, і їй не потрібно нічого робити!


16

Маке поводиться коректно. helloвже існує і не старший за .cфайли, а отже, роботи ще не потрібно зробити. Є чотири сценарії, в яких make потрібно буде (пере) будувати:

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

4

Я думаю, ви пропустили вкладку в 9-му рядку. Рядок, що слідує за всіма: привіт, повинен бути пустою вкладкою. Переконайтеся, що у вас є порожня вкладка в 9-му рядку. Це дасть інтерпретатору зрозуміти, що ви хочете використовувати рецепт за замовчуванням для makefile.


4

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

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


0

Я дійшов до цієї своєрідної, важкої для налагодження помилки іншим шляхом. Моя проблема закінчилася тим, що я використовував правило шаблону на етапі побудови, коли ціль та залежність були розташовані в різних каталогах. Щось на зразок цього:

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

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

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

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

Сподіваюся, це комусь допоможе!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.