Возникли проблемы при размещении объектных файлов в новом каталоге с использованием make-файла - PullRequest
1 голос
/ 30 апреля 2019

Я очень новичок в make.До сих пор мне удалось создать следующее с использованием некоторых руководств и руководств по GNU, которые можно найти в Интернете.Я бы хотел, чтобы make поместил все созданные объектные файлы в каталог obj.Мне удалось успешно создать этот каталог, но я не могу понять, как разместить файлы в нем.Любые предложения или советы приветствуются.Кроме того, в целом, есть ли хороший источник для изучения, как работать с make, кроме документации GNU?

# specify compiler
CC          := gcc
# set compiler flags
CFLAGS      := -M -Igen/display -Igen/logic -Iman -Ilib/include -pipe -march=native -ftime-report
# set linker flags
LDFLAGS     := -lglut32 -loglx -lopengl32 -Llib
# specify separate directory for objects
OBJDIR      := obj
# include all sources
SOURCES     := $(wildcard gen/display/*.c gen/logic/*.c man/*.c)
# create objects from the source files
OBJECTS     := $(patsubst %.c,%.o,$(SOURCES)) 
# specify the name and the output directory of executable
EXECUTABLE  := win32/demo

# all isn't a real file
all: $(EXECUTABLE)

# compile
%.o: %.c
    @mkdir -p $(@D)
    $(CC) $(CFLAGS) -c $< -o $(OBJDIR)/$@   

# link
$(EXECUTABLE): $(OBJECTS)
    $(CC) $^ $(LDFLAGS) -o $@

# clean objects
clean:
    @$(RM) -rf $(OBJDIR)

.PHONY: all clean

Ответы [ 2 ]

0 голосов
/ 01 мая 2019

Мне удалось успешно создать этот каталог, но я не могу понять, как поместить в него файлы.

Есть две части, пишущие об этом явно.

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

    %.o: %.c
      # ...
    

    ... но на практике это правило никогда не может быть сопоставлено с файлами вobj/, потому что ваши источники не находятся в этом каталоге.Это может быть более эффективным:

    $(OBJDIR)/%.o: %.c
        @mkdir -p $(@D)
        $(CC) $(CFLAGS) -c $< -o $@
    

    Обратите внимание, в частности, как теперь цель правила соответствует артефакту, фактически произведенному этим правилом.

  • Second, у вас должно быть требование для построения цели правила , обычно это должно быть зависимостью от какого-то другого правила.Обратите внимание, что ваша переменная, определяющая объектные файлы, участвующие в $(EXECUTABLE) , не полагается на объекты из каталога obj/.Он генерируется этой подстановкой шаблона ...

    OBJECTS     := $(patsubst %.c,%.o,$(SOURCES))
    

    ..., которая генерирует имена объектов с тем же путем, что и соответствующие источники.Вы, вероятно, хотите что-то более похожее на это:

    OBJECTS     := $(patsubst %.c,$(OBJDIR)/%.o,$(SOURCES))
    

    Вы заметите, как это также соответствует изменению, представленному в предыдущем пункте.

Но это многоработать за небольшую выгоду.Вам не нужно было бы сильно изменять свою цель clean, чтобы обойтись без нее.Вы можете написать свой файл в несколько более простой и более традиционной форме и при этом получить вывод в отдельный каталог, используя функцию VPATH в GNU (и некоторых других) make.

0 голосов
/ 01 мая 2019

Каждый раз, когда вы видите правило, в котором сгенерированный вывод не попадает в файл $@, вы знаете, что это неправильно.Make установит автоматическую переменную $@ на имя файла, который он ожидает создать, и если рецепт сделает что-то другое, make-файл не будет работать.

Ваше правило отправляет файл на $(OBJDIR)/$@, а не$@, так что это неправильно.

Итак, вам нужно написать свое правило шаблона следующим образом:

%.o: %.c
        @mkdir -p $(@D)
        $(CC) $(CFLAGS) -c $< -o $@

Если это не сработает, вам нужно будет предоставить больше информациитакие как пример строки компиляции make, какие ошибки вы видите и т. д.

...