GNU Make | Как создать зависимость между иерархией исходного кода и выходом компилятора h-hy? - PullRequest
0 голосов
/ 17 апреля 2019

Некоторый код из Makefile:

tempDir := ...
javaSources := $(wildcard src/java/**/%.java)
javaClasses := $(subst src/java, $(tempDir)/java/classes, $(subst .java,.class, $(javaSources)))

$(javaClasses): $(javaSources)
  mkdir -p $(tempDir)/java/classes || true
  javac \
    -d  $(tempDir)/java/classes \
    -cp $(tempDir)/java/classes \
  $?

Как создать правило шаблона (например, здесь ) для сохранения в / из порядка?

@ MadScientist

Ответы [ 2 ]

1 голос
/ 17 апреля 2019

Во-первых, ваш wildcard не будет работать.GNU make использует только базовое глобирование оболочки, что означает, что он не может понимать расширенное глобирование, например **, что означает «поиск по всем подкаталогам».Во-вторых, % вообще не является символом, вызывающим оболочку, поэтому вы просто ищете файлы с буквальным названием %.java.

Вместо этого вы, вероятно, хотите что-то вроде этого:

javaSources := $(shell find src/java -name '*.java')

Далее, для создания javaClasses контента, который вы действительно не хотите использовать subst, потому что он заменяет везде, что может дать ложные совпадения (например, $(subst .x,.y,foo.xbar) даст foo.ybar, что, вероятно, не то, что вы хотите).

Что-то вроде этого проще понять:

javaClasses := $(patsubst src/java/%.java,$(tempdir)/java/classes/%.class,$(javaSources))

Наконец, вы повторяете точно ту же ошибку, что и в предыдущем вопросе, где вы пытались перечислить все цели и всепредпосылки в том же правиле.Как я уже сказал для этого вопроса, это не правильно.

Ответ точно такой же, как и в предыдущем вопросе: вы должны написать шаблонное правило, которое описывает, как построить одну единственную цель из один единственный исходный файл .

И снова вам нужна цель all или аналогичная, которая зависит от всех выходов.

0 голосов
/ 17 апреля 2019

В дополнение к ответу MadScientist вам, вероятно, следует использовать шаблонное правило, например:

$(tempDir)/java/classes/%.class: src/java/%.java
    mkdir -p $(dir $@)
    javac -d $(dir $@) -cp $(dir $@) $<

(не уверен, что -cp должно быть в этом случае, это зависит от вашего конкретного проекта). И, как и предположил MadScientist , вам потребуется:

.PHONY: all
all: $(javaClasses)

такой, что вы можете позвонить make all, чтобы скомпилировать все исходные файлы, которые должны быть. Поставьте его перед любой другой явной целью, если вы хотите, чтобы all была целью по умолчанию (цель make выбирает, если вы просто вызываете make), или используйте специальную переменную .DEFAULT_GOAL:

.DEFAULT_GOAL := all
...