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

Проект представляет собой простой чат с каналами и вилками, и мне нужно создать Makefile для компиляции программы. Вот мой make-файл:

CC=cc
FLAGS=-c -Wall
LIBS=-lm
OBS=cliente.o server.o

all : cliente server

cliente.c : cliente
    $(CC) $(FLAGS) cliente.c

server.c : server
    $(CC) $(FLAGS) server.c

И вывод:

make: Circular cliente.c <- cliente dependency dropped.
cc    -c -o cliente.o cliente.c
cc   cliente.o   -o cliente
make: Circular server.c <- server dependency dropped.

Спасибо за помощь.

0
João Vieira 29 Май 2017 в 01:26

2 ответа

Лучший ответ

Во-первых, у вас есть свои правила в обратном направлении. Правильный синтаксис для правил Makefile:

target-you-are-trying-to-build: things it depends on
        command to build target from things it depends on

Поэтому вы хотите написать:

cliente : cliente.c
    $(CC) $(FLAGS) cliente.c

server: server.c
    $(CC) $(FLAGS) server.c

(Обратите внимание на переворачивание исполняемого файла и исходного файла в первой строке каждого правила.)

Причина, по которой ваш оригинальный Makefile работает вообще, заключается в том, что make имеет некоторые встроенные правила, поэтому при вводе make он пытается построить all, для которого требуется {{X4} } и server, и он генерирует автоматические правила для сборки cliente из cliente.c и server из server.c. (Вы можете сказать, что он использует свои внутренние правила, а не ваши, потому что он игнорирует ваш FLAGS.)

Сообщения об ошибках об удаленных зависимостях вызваны тем, что вы сказали ему построить cliente, который, как он знает, может построить из cliente.c, но ваши правила говорят, что cliente.c должен быть построен из { {X3}}, который делает круговую зависимость, поэтому он жалуется.

Однако , как вы заметили в комментарии, это все равно не будет работать правильно. Это потому, что ваши правила для сборки cliente и server на самом деле не строят cliente и server. Команда:

cc -c -Wall cliente.c

Только компилирует cliente.c в объектный файл cliente.o из-за флага -c. Он не связывает и не выводит исполняемый файл. Измененная версия в ответе @ InvicibleWolf, которая эквивалентна:

cc -c -Wall -o cliente -c client.c

Тоже не будет работать, потому что (множественные) флаги -c создают объектные файлы, а не исполняемые файлы, даже если вы заставите вывод перейти к cliente вместо значения по умолчанию cliente.o. Вы получаете сообщение об ошибке «Отказано в доступе», поскольку по умолчанию объектные файлы создаются без разрешений на выполнение. (Предоставление им разрешений на выполнение не поможет - объектные файлы не могут быть запущены напрямую, поэтому вы получите другую ошибку.)

Здесь есть пара подходов:

Используйте исключительно make встроенные правила

Следующее Makefile будет работать:

CC=cc                 # should be "CC=", not "C="
CFLAGS=-Wall          # internal rules use CFLAGS not FLAGS, don't need -c
LDLIBS=-lm            # internal rules use LDLIBS not LIBS

all : cliente server

cliente: cliente.o

server: server.o

Это говорит о том, что cliente может быть построен из cliente.o, а make достаточно умен, чтобы сгенерировать правило, эквивалентное:

cc cliente.o -lm -o cliente

Используя ваше определение CC и LDLIBS. Он также автоматически сгенерирует правило для сборки cliente.o из cliente.c без каких-либо указаний, что эквивалентно:

cc -Wall -c -o cliente.o cliente.c

Используя ваше определение CFLAGS. (Он предоставляет флаги -c автоматически.)

Используйте явные правила, которые напрямую генерируют исполняемый файл из файла C

Это тоже будет работать. Это именно то, что @InvicibleWolf написал выше с исправленной опечаткой, пропущенным -c и включенным в правила значением LIBS:

CC=cc             ## use CC=, not C=
FLAGS=-Wall       ## no -c flag
LIBS=-lm

all : cliente server

cliente: cliente.c
        $(CC) $(FLAGS) $(LIBS) -o cliente cliente.c    # no -c, and use LIBS

server: server.c
        $(CC) $(FLAGS) $(LIBS) -o server server.c      # no -c, and use LIBS
2
K. A. Buhr 28 Май 2017 в 23:15

Для компиляции вашего файла make следует следовать правилу @K. А. Бур упоминается в ответе. Makefile в своем ответе будет просто создавать объектные файлы. Учитывая ваш вопрос, я думаю, что вы хотите сделать два двоичных файла клиентом и сервером, поэтому ваш make-файл должен выглядеть следующим образом:

C=cc
FLAGS= -Wall
LIBS=-lm
# OBS=cliente.o server.o not necessary if you are clreating to different binaries

all : cliente server

cliente: cliente.c
        $(CC) $(FLAGS) -o cliente cliente.c

server: server.c
        $(CC) $(FLAGS) -o server server.c

Это создаст как объектный файл, так и двоичные файлы. Опция -o предназначена для вывода в файл сервера / клиента, а опция -c означает компиляцию и сборку, но не связывает или другими словами генерирует объектные файлы.

0
InvisibleWolf 28 Май 2017 в 23:39