Makefile : do not recompile files not updated (sep

2019-09-01 06:34发布

问题:

I wonder how it's possible for a makefile, to compile only classes (Java, Scala) with changes.

My .scala are in the src directory. And when I compile, the output (.class) go to the bin directory.

In a project, when you have ~50 classes it's too long to compile all classes each time.

Do you know how to solve my problem ?

I tried maven but it seems to have the same problem.

My makefile (for Scala) :

SRC = src
SOURCES = $(shell find . -name *.scala)
S = scala
SC = scalac
TARGET = bin
CP = bin

run: compile
    @echo ":: Executing..."
    @$(S) -cp $(CP) -encoding utf8 App -feature


compile: $(SOURCES:.scala=.class)

%.class: %.scala
    clear
    @echo ":: Compiling..."
    @echo "Compiling $*.scala.."
    @$(SC) -sourcepath $(SRC) -cp $(CP) -d $(TARGET) -encoding utf8 $*.scala

EDIT : I've found a solution : compare date of creation of .java and .bin. Here is my makefile : https://gist.github.com/Dnomyar/d01d886731ccc88d3c63

SRC = src
SOURCES = $(shell find ./src/ -name *.java)
S = java
SC = javac
TARGET = bin
CP = bin
VPATH=bin

run: compile
@echo ":: Executing..."
@$(S) -cp $(CP) App

compile: $(SOURCES:.%.java=.%.class)

%.class: %.java
clear
@echo ":: Compiling..."
@echo "Compiling $*.java.."
@if [ $(shell stat -c %Y $*.java) -lt $(shell stat -c %Y $(shell echo "$*.class" | sed 's/src/bin/g')) ]; then echo ; else $(SC) -sourcepath $(SRC) -cp $(CP) -d $(TARGET) -encoding utf-8 $*.java; fi




clean:
@rm -R bin/*

# Pour supprimer les fichier .fuse* créés par sublime text
fuse:
@rm `find -name "*fuse*"`

回答1:

You could specify the make to where to search for the dependencies using the VPATH variable. For your case you can assign VPATH=bin where the make compares the timestamp of the files under bin folder.

Example:

VPATH= obj
all: hello
        @echo "Makeing - all"
        touch all
hello:
        @echo "Making - hello"
        touch obj/hello

Output:

sagar@CPU-117:~/learning/makefiles/VPATH$ ls
Makefile  obj
sagar@CPU-117:~/learning/makefiles/VPATH$ make
Making - hello
touch obj/hello
Makeing - all
touch all
sagar@CPU-117:~/learning/makefiles/VPATH$ ls
all  Makefile  obj
sagar@CPU-117:~/learning/makefiles/VPATH$ make
make: 'all' is up to date.
sagar@CPU-117:~/learning/makefiles/VPATH$ touch obj/hello 
sagar@CPU-117:~/learning/makefiles/VPATH$ make
Makeing - all
touch all
sagar@CPU-117:~/learning/makefiles/VPATH$


回答2:

I've found a solution https://gist.github.com/Dnomyar/d01d886731ccc88d3c63 It's a little bit ugly but it seems to work.