Search code examples
makefilegnu

GNU Make | How to create dependency between source code hierarchy and compiler output h-hy?


Some code from 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 \
  $?

How to create a pattern rule (like here) to preserve in / out order?

@MadScientist


Solution

  • First, your wildcard won't work. GNU make uses only basic shell globbing, which means it can't understand advanced globbing like ** meaning "search all subdirectories". Second, % is not a shell globbing character at all so you're just looking for files that are literally named %.java.

    Instead you probably want something like this:

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

    Next, to create the javaClasses content you really don't want to use subst because it substitutes everywhere which can give false matches (e.g., $(subst .x,.y,foo.xbar) will yield foo.ybar which is probably not what you want).

    Something like this is simpler to understand:

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

    Finally, you are repeating exactly the same error you made in the previous question, where you tried to list all the targets and all the prerequisites in the same rule. Just as I said for that question, that is not right.

    The answer is exactly the same as in the previous question: you should write a pattern rule that describes how to build one single target from one single source file.

    And again you need an all target or similar which depends on all the outputs.