Файл не найден при использовании имен переменных файлов - PullRequest
0 голосов
/ 05 декабря 2018

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

В приведенном ниже коде я попытался использовать цикл for для создания 6 исполняемых файлов, по два для каждого уникального файла.

Вот файл makefile:

vpath %.h ../headers/
CXX      := g++
CXXFLAGS := -std=c++11 -I../headers/
LDFLAGS  :=
SUFFIX   := fileA fileB fileC

memory-%.exe: primary-%.o memory.cpp
       $(CXX) $(CXXFLAGS) $^ -o $@
timing-%.exe: primary-%.o timing.cpp
       $(CXX) $(CXXFLAGS) $^ -o $@

all:   for i in $(SUFFIX); \
       do \
       testing-$$i.exe: primary-$$i.o; \
       memory-$$i.exe: primary-$$i.o; \
       done

Iменя встречает ошибка:

\bin\sh: 3: memory-fileA.exe:: not found
\bin\sh: 4: timing-fileA.exe:: not found
\bin\sh: 3: memory-fileB.exe:: not found
\bin\sh: 4: timing-fileB.exe:: not found
\bin\sh: 3: memory-fileC.exe:: not found
\bin\sh: 4: timing-fileC.exe:: not found
make: *** [all] Error 127

Возможно ли это вообще?Мне было просто интересно, можно ли было бы эффективно использовать этот метод.

Любая помощь приветствуется, так как я хотел бы узнать больше о возможностях, которые позволяют make-файлы.Спасибо.

1 Ответ

0 голосов
/ 05 декабря 2018

Вы смешиваете оболочку и строите конструкции.Как указывало tripleee , рецепты правил make являются сценариями оболочки, а не другими правилами make.

Более того, у вашего Makefile есть несколько проблем:

  1. Youобъясните, что вы хотите использовать статические шаблонные правила , но вы написали " simple " шаблонные правила .
  2. Вам не нужно заключать в кавычкиваши суффиксы.И не стоит, делать не оболочку, она их сохраняет.Из-за этого вы получите ошибки.
  3. Использование стандартной переменной make CXXFLAGS крайне необычно.Традиционно он ограничен флагами компилятора, а не самим компилятором, для которого используется CXX.
  4. Вы компилируете исходные файлы и выполняете компоновку одновременно.Это тоже не так уж обычно.Это приводит к бесполезным перекомпиляциям.
  5. Опция c++11 для g++ является новой для меня.Вы уверены, что это не -std=c++11?
  6. Директива vpath бесполезна, поскольку вы не выражаете зависимости от заголовочных файлов.Но давайте сохраним, я думаю, вы не все показываете.

В целом, вы, вероятно, можете достичь желаемого с помощью:

vpath %.h ../headers/
CXX      := g++
CXXFLAGS := -std=c++11 -I../headers/
LDFLAGS  :=
SUFFIX   := fileA fileB fileC
TESTING  := $(patsubst %,testing-%.exe,$(SUFFIX))
MEMORY   := $(patsubst %,memory-%.exe,$(SUFFIX))

.PHONY: all

all: $(TESTING) $(MEMORY)

%.o: %.cpp
    $(CXX) $(CXXFLAGS) -c $^ -o $@

$(TESTING): testing-%.exe: primary-%.o memory.o
    $(CXX) $(LDFLAGS) $^ -o $@

$(MEMORY): memory-%.exe: primary-%.o timing.o
    $(CXX) $(LDFLAGS) $^ -o $@

%.o: %.cpp...правило - это шаблонное правило .Он говорит make, как создать любой объектный файл из соответствующего исходного файла C ++.Два последних правила на самом деле статические шаблонные правила .Например, первый из двух объявляет, что каждая цель testing-<suffix>.exe, указанная в $(TESTING), зависит от соответствующих primary-<suffix>.o и memory.o.Таким образом, это единственное правило статического шаблона эквивалентно этим 3 простым правилам:

testing-fileA.exe: primary-fileA.o memory.o
    g++ primary-fileA.o memory.o -o testing-fileA.exe

testing-fileB.exe: primary-fileB.o memory.o
    g++ primary-fileB.o memory.o -o testing-fileB.exe

testing-fileC.exe: primary-fileC.o memory.o
    g++ primary-fileC.o memory.o -o testing-fileC.exe

Нет необходимости в циклах.Обратите внимание: если вы правильно используете стандартные переменные make CXX и CXXFLAGS, вы можете отбросить правило шаблона (%.o: %.cpp...), это одно из многих неявных правил , которое make уже знает.

...