我的makefile总是重建项目,即使没有进行任何更改。
我该如何解决?
我的项目结构遵循通常的bin /,src /,Makefile模式。
Makefile文件:
# output directory BIN = bin/ # input directory SRC = src/ # java compiler JC = javac # compile flags JFLAGS = -d $(BIN) -cp $(SRC) sourcefiles = $(addprefix $(SRC), \ A.java \ B.java \ C.java) classfiles = $(sourcefiles:.java=.class) all: $(classfiles) %.class: %.java $(JC) $(JFLAGS) $< clean: $(RM) $(BIN)*.class我从网上找到的例子中创建了这个makefile,但我不确定我是否理解所做的一切,所以如果我也能得到解释,那就太棒了:3
My makefile always rebuilds the project, even if no changes were made.
How can I fix it?
My project structure follows the usual bin/, src/, Makefile pattern.
Makefile:
# output directory BIN = bin/ # input directory SRC = src/ # java compiler JC = javac # compile flags JFLAGS = -d $(BIN) -cp $(SRC) sourcefiles = $(addprefix $(SRC), \ A.java \ B.java \ C.java) classfiles = $(sourcefiles:.java=.class) all: $(classfiles) %.class: %.java $(JC) $(JFLAGS) $< clean: $(RM) $(BIN)*.classI made this makefile from examples I found online, but I'm not sure I understand everything being done, so if I could also get an explanation, that would be great :3
最满意答案
通常, make不适合Java。 使用与传统编译器类似的工具最佳:它们采用输入文件foo.X (也可能是其他一些输入文件),并生成单个输出文件foo.Y 对于C编译器,例如X是c , Y是o ( foo.c编译为foo.o )。
在单个调用编译器生成多个输出文件的情况下很难使用Make,并且当输出文件的名称与输入文件的名称没有直接关系时(在这种情况下)使用它并不简单你必须编写所有显式规则,而不是模式规则)。
对于Java编译器,单个.java输入文件可以生成多个不同的.class文件,并且.class文件的名称不一定与.java文件的名称相关。
在你的情况下,我敢打赌,如果你看看javac为你的A.java文件生成的输出文件,你会发现它没有生成A.class 。 因为A.class不存在,make将始终尝试重建它。
哦。 也。 您将文件放在不同的目录中。 因此,即使您将自己限制在名称相同的情况下,您也必须像这样编写模式:
# ... Keep the first part as in your example classfiles = $(patsubst $(SRC)%.java,$(BIN)%.class,$(sourcefiles)) all: $(classfiles) $(BIN)%.class : $(SRC)%.java $(JC) $(JFLAGS) $< # ... Keep the clean rule as in your example模式%必须相同; 如果你把东西放在不同的目录中,它们就不一样了。
In general, make is not a good fit for Java. Make works best with tools that behave similarly to traditional compilers: they take an input file foo.X (and maybe some other input files as well) and they generate a single output file foo.Y. For a C compiler for example X is c and Y is o (foo.c compiles to foo.o).
Make is hard to use in situations where a single invocation of the compiler generates more than one output file, and it's not simple to use when the name of the output file doesn't relate directly to the name of the input file (in this case you have to write all explicit rules, not pattern rules).
For Java compilers a single .java input file can generate multiple different .class files, and the names of the .class files are not necessarily related to the name of the .java file.
In your situation, I'll bet if you look at the output files that javac is generating for your A.java file you'll see it's not generating A.class. Because A.class doesn't exist, make will always try to rebuild it.
Oh. Also. You're putting files in different directories. So even if you DO restrict yourself to situations where the names are identical, you have to write your pattern like this:
# ... Keep the first part as in your example classfiles = $(patsubst $(SRC)%.java,$(BIN)%.class,$(sourcefiles)) all: $(classfiles) $(BIN)%.class : $(SRC)%.java $(JC) $(JFLAGS) $< # ... Keep the clean rule as in your exampleThe patterns % must be identical; if you put things in different directories they're not identical.
更多推荐
发布评论