LINUX.ORG.RU

Простой makefile


0

1

Я начинающий программист сделал makefile, но при попытки сборки программы вылетает ошибка

make: *** Нет правила для сборки цели `stdio.h', требуемой для `get_opt.o'

где я ошибся? вот его содержание:

all: get_opt

get_opt : get_opt.o

cc -o get_opt get_opt.o

get_opt.o : get_opt.c stdio.h stdlib.h unistd.h

cc -c get_opt.c

clean:

rm get_opt get_opt.o


get_opt.o : get_opt.c stdio.h stdlib.h unistd.h

Ну ты указал файлы .h но как из «собирать» не сказал. Если хотел казать инклуды, до посмотри на параметр -I у ссю

Kakadu ()
Ответ на: комментарий от Kakadu

либо генери зависимости через gcc -M, либо не клади в зависимости системные хедеры, либо используй полные пути к ним. Так как ты указал, оно ищет таргеты в текущем каталоге.

slapin ★★★★★ ()
Ответ на: комментарий от slapin

если пишу полный путь до хедера то все работает, а если пишу

get_opt.o : get_opt.c stdio.h stdlib.h unistd.h

gcc -c -M get_opt.c

то та же ошибка

ekso ()
Ответ на: комментарий от ekso

Мммммм...

cat >helloworld.c <<EOF
#include <stdio.h>

int main()
{
    printf("Hello, world!\n");
    return 0;
}
EOF
cat >Makefile <<EOF
all: dep main
main: helloworld.o
        $(CC) -o $@ $<
dep:
        $(CC) -M helloworld.c >dep

-include dep

Компилируем:

$make
cc -M helloworld.c >dep
cc    -c -o helloworld.o helloworld.c
cc -o main helloworld.o
$cat dep
helloworld.o: helloworld.c /usr/include/stdio.h /usr/include/features.h \
 /usr/include/i386-linux-gnu/bits/predefs.h \
 /usr/include/i386-linux-gnu/sys/cdefs.h \
 /usr/include/i386-linux-gnu/bits/wordsize.h \
 /usr/include/i386-linux-gnu/gnu/stubs.h \
 /usr/include/i386-linux-gnu/gnu/stubs-32.h \
 /usr/lib/gcc/i486-linux-gnu/4.6/include/stddef.h \
 /usr/include/i386-linux-gnu/bits/types.h \
 /usr/include/i386-linux-gnu/bits/typesizes.h /usr/include/libio.h \
 /usr/include/_G_config.h /usr/include/wchar.h \
 /usr/lib/gcc/i486-linux-gnu/4.6/include/stdarg.h \
 /usr/include/i386-linux-gnu/bits/stdio_lim.h \
 /usr/include/i386-linux-gnu/bits/sys_errlist.h
slapin ★★★★★ ()

просто убери stdio.h stdlib.h unistd.h нахрен, компилятор/линкер умеет искать стандартные заголовочные файлы.

unanimous ★★★★★ ()
Ответ на: комментарий от slapin

Ну, в начале лучше сделать make dep, конечно же.

И код с Makefile должен выглядеть так:

cat >Makefile <<EOF
all: dep main
main: helloworld.o
        $(CC) -o $@ $<
dep:
        $(CC) -M helloworld.c >dep

-include dep
EOF
slapin ★★★★★ ()
Ответ на: комментарий от slapin

Хотя зачем тебе прописывать зависимости на системные хедеры - не могу понять. Если ты хочешь, чтобы твою софтину перекомпилировали каждый раз после обновления glibc, например, то тогда это имеет смысл, конечно. Если нет, используй gcc -MM вместо gcc -M.

у gcc есть еще фишка - можно генерить эти зависимости прямо в Makefile. Но там точно лучше делать с -MM иначе очень чревато сюрпризами...

slapin ★★★★★ ()

У тебя вот в чем проблема: ты говоришь make, что get_opt.o надо собрать из get_opt.c, stdio.h, stdlib.h и unistd.h. Но make (в отличие от компилятора, который может искать инклуды в системных директориях) воспринимает все пути к файлам как относительные (если не указан абсолютный путь). У тебя в папке с исходниками файла stdlib.h нету, поэтому он не может из него собрать get_opt.o. Он бы попробовал его создать .h из чего-то другого (есть там такие «правила по умолчанию», читай ман), но ничего другого, подходящего для создания stdio.h, у тебя в папке тоже нет.

У тебя два пути. Либо включить полный путь к заголовочному файлу stdlib.h (плохой способ) или убрать его из зависимостей. Я бы выбрал второй.

А вообще, прочитай все-таки ман к мэйку, хотя бы самые основы (что такое цели, зависимости, правила, как они работают). Ссылку дал aedeph_ выше.

Kiborg ★★★ ()
Ответ на: комментарий от Kiborg

Вкратце, почему первый способ плохой:

1. Абсолютный путь. Он на другой системе может оказаться другим.

2. Зависимости в целях служат тому, что при изменении зависимости цель автоматически пересобирается. После этого, если эта цель была в зависимостях у кого-то еще, он тоже пересобирается и т. д. Системные заголовочные файлы изменяются очень редко, и пересборки софта в 99% случаев не требуют. Поэтому указывать их в зависимостях не нужно.

Kiborg ★★★ ()
Ответ на: комментарий от unanimous

просто убери stdio.h stdlib.h unistd.h нахрен,

+100500

компилятор/линкер умеет искать стандартные заголовочные файлы.

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

ananas ★★★★★ ()

Может, стоит сразу начать cmake'ом каким-нибудь пользоваться, чтобы километровые простыни мейкфайлов вручную не писать?

Eddy_Em ☆☆☆☆☆ ()

Всем спасибо. Прочитал рекомендованное, разобрался!!!

ekso ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.