Ошибки Makefile с 2 исполняемыми файлами: несколько определений 'main'

У меня есть проект, для которого требуются два отдельных исполняемых файла, каждый из которых имеет «основную» функцию. Они совместно используют заголовочный файл и еще один файл с определениями функций. Makefile, который я использую, выдает ошибку "множественное определение `main'". Я хочу скомпилировать оба исполняемых файла в папку «./bld». Может ли кто-нибудь дать мне несколько советов о том, что я делаю неправильно? Спасибо.

   CC := gcc
   CFLAGS := -g -Wall -Werror


   RM := rm
   MKDIR := mkdir -p
   OUT_DIR := bld
   OBJ_DIR := $(OUT_DIR)/obj


   SOURCES := $(wildcard *.c)


   OBJECTS := $(addprefix $(OBJ_DIR)/, $(SOURCES:.c=.o))


   TARGET := $(addprefix $(OUT_DIR)/, $(SOURCES:.c=))


   .PHONY: all clean

   all: $(TARGET)

   clean:
       $(RM) -rf $(OUT_DIR)

   $(TARGET): $(OBJECTS)
       $(CC) $(CFLAGS) $^ -o $@

   $(OBJ_DIR)/%.o: %.c
       @$(MKDIR) $(dir $@)
       $(CC) $(CFLAGS) -c $< -o $@

person RErik    schedule 09.02.2019    source источник
comment
Вам нужно иметь две отдельные цели и указывать файлы c для каждой отдельно, а не использовать *.c   -  person bruceg    schedule 09.02.2019


Ответы (2)


Для моих проектов C/C++ я использую другой тип шаблона для моего Makefile, но вот как шаблон будет выглядеть для вашего случая

SRC1 = main1.c \
      other.c

OBJ1 =   $(SRC1:.c=.o)

NAME1 =  executableName1

SRC2 = main2.c \
      other.c

OBJ2 =   $(SRC2:.c=.o)

NAME2 =  executableName2

all: $(NAME1) $(NAME2)

$(NAME1): $(OBJ1)
        gcc -o $(NAME1) $(OBJ1)

$(NAME2): $(OBJ2)
        gcc -o $(NAME2) $(OBJ2)

clean:
        rm -Rf $(OBJ1)
        rm -Rf $(OBJ2)

fclean: clean
        rm -Rf $(NAME1)
        rm -Rf $(NAME2)

re: fclean all

.PHONY: all clean fclean re

Как видите, я не использую *.c, потому что таким образом я мог бы хранить весь свой исходный код в одной папке без компиляции файлов, которые мне не нужны для каждого исполняемого файла. Используя этот Makefile, вы можете собрать оба исполняемых файла, вызвав «make» или «make all», и вы можете собрать каждый исполняемый файл отдельно, вызвав «make executableName1» и «make executableName2». Если вы хотите сохранить свой шаблон как есть, я предлагаю вам немного изучить Makefile, чтобы понять оба шаблона и посмотреть, как их объединить ;)

person Mewen LE RESTE    schedule 09.02.2019
comment
Ах, это очень ясно и помогло мне понять нюансы Makefiles. Большое спасибо, это именно то, что мне было нужно! - person RErik; 10.02.2019

Глядя на ваш Makefile, кажется, что вы вызываете gcc только один раз, чтобы собрать два исполняемых файла. Чтобы собрать два исполняемых файла, вам нужно дважды вызвать gcc, один с источниками первого исполняемого файла, а другой с источниками второго исполняемого файла.

person Mewen LE RESTE    schedule 09.02.2019
comment
Эти комментарии полезны, но я новичок в Makefiles; Я строю на основе шаблона, который нашел в другом месте. Можете ли вы привести пример того, как это сделать? Спасибо. - person RErik; 09.02.2019