Wil*_*ung 183
Make和Java的基本问题是,Make的前提是您已指定依赖项,然后是规则来解决该依赖项.
使用基本C,通常"将main.c文件转换为main.o文件,运行"cc main.c".
你可以在java中做到这一点,但你很快就能学到一些东西.
大多数情况下,javac编译器启动缓慢.
和...之间的不同:
javac Main.java
javac This.java
javac That.java
javac Other.java
Run Code Online (Sandbox Code Playgroud)
和
javac Main.java This.java That.java Other.java
Run Code Online (Sandbox Code Playgroud)
是白天和黑夜.
加剧了数百个课程,而且它变得难以为继.
然后你将它与java倾向于组织为目录中的文件组,而C和其他倾向于更平坦结构的事实相结合.Make对使用文件层次结构没有太多直接支持.
Make也不是很擅长在收集级别确定哪些文件已过期.
使用Ant,它将遍历并总结所有过时的文件,然后一次编译它们.Make将简单地在每个单独的文件上调用java编译器.如果没有这样做需要足够的外部工具来真正显示Make不能完成任务.
这就是Ant和Maven等替代品升级的原因.
Gre*_*ill 32
古老的make程序可以很好地处理C和C++等单独编译的语言.编译模块,它用于#include引入其他包含文件的文本,并将单个目标文件写为输出.编译器是一个一次一个系统,具有单独的链接步骤以将目标文件绑定到可执行二进制文件中.
但是,在Java中,编译器必须实际编译您导入的其他类import.尽管可以编写一些从Java源代码生成所有必需依赖项的东西,make以便一次一个地以正确的顺序构建类,但这仍然不能处理诸如循环依赖项之类的情况.
通过缓存其他类的编译结果,同时编译依赖于已编译的结果的其他类,Java编译器也可以更高效.make单独使用这种自动依赖性评估实际上是不可能的.
Han*_*Gay 28
问题是基于一个不正确的假设:一个非常微不足道的开发人员确实使用了make.请参阅Java构建工具:Ant与Maven.至于为什么开发人员不会使用make:许多开发人员要么从未使用过make,要么使用过它并且用火烧得比一千个太阳更热.因此,他们使用替代工具.
use*_*840 22
实际上,make可以在所有过时的java文件的一个命令中处理重新编译.如果您不想编译目录中的所有文件或想要特定订单,请更改第一行...
JAVA_FILES:=$(wildcard *.java)
#
# the rest is independent of the directory
#
JAVA_CLASSES:=$(patsubst %.java,%.class,$(JAVA_FILES))
.PHONY: classes
LIST:=
classes: $(JAVA_CLASSES)
if [ ! -z "$(LIST)" ] ; then \
javac $(LIST) ; \
fi
$(JAVA_CLASSES) : %.class : %.java
$(eval LIST+=$$<)
Run Code Online (Sandbox Code Playgroud)
Dan*_*ark 17
关于每个技术优点的所有其他答案都是正确的.Ant并且Maven可能比Java更适合Java,或者正如Hank Gay指出的那样,他们可能不会:)
但是,你问过Ant和Maven是用Java编写的.虽然在StackOverflow上我们不考虑这样的想法(关闭!与编程无关!等等),当然是其中的一部分.在rails上我们使用Rake,C dudes使用make,在Java中我们使用Ant和Maven.虽然Ant或Maven开发人员可能会比其他开发人员更好地照顾Java开发人员,但还有另一个问题:你在什么时候编写Ant任务?Java的.如果您是Java开发人员,那很容易.
所以,是的,部分原因是使用以您正在使用的语言编写的工具.
Osc*_*Ryz 12
Ant和后来的Maven旨在解决由Make(在创建过程中创建新的)引起的一些麻烦.它只是进化.
...此后不久,一些开源Java项目意识到Ant可以解决他们使用Makefiles时遇到的问题....
来自http://ant.apache.org/faq.html#history
他们是解决任何问题还是只是创建一个额外的格式来学习是一个主观的话题.事实是,这几乎是每一项新发明的历史:创造者说它解决了很多问题,原始用户说这些都是美德.
它的主要优点是可以与java集成.
我想例如类似的历史rake.
简短的回答:因为make不好。即使在 C 方面,您也会看到许多替代品出现。
长答案:make有几个缺陷使它几乎不适合编译 C,而且根本不适合编译 Java。如果需要,您可以强制它编译 Java,但预计会遇到问题,其中一些没有合适的解决方案或变通方法。以下是一些:
make固有地期望文件彼此之间具有树状依赖关系,其中一个文件是构建其他几个文件的输出。在处理头文件时,这在 C 中已经适得其反。make需要make生成一个特定的包含文件来表示 C 文件对其头文件的依赖关系,因此对后者的更改将导致重新构建之前的文件。但是,由于 C 文件本身不会重新创建(只是重新构建),因此 make 通常需要将目标指定为.PHONY. 幸运的是,GCC 支持自动生成这些文件。
在 Java 中,依赖可以是循环的,并且没有用于自动生成make格式类依赖的工具。相反,它ant的Depend任务可以直接读取类文件,确定它导入哪些类,如果其中任何一个类文件已过期,则删除该类文件。没有这个,任何非平凡的依赖都可能导致您被迫使用重复的干净构建,从而消除使用构建工具的任何优势。
虽然 Java 和 C 都不鼓励在源代码文件名中使用空格,但make即使空格在文件路径中,这也可能是问题。例如,考虑一下您的源代码是否存在于C:\My Documents\My Code\program\src. 这足以打破make。这是因为make将文件名视为字符串。ant将路径视为特殊对象。
make需要明确设置为每个目标构建哪些文件。ant允许指定要自动扫描源文件的文件夹。这似乎是一个次要的便利,但考虑到在 Java 中每个新类都需要一个新文件。将文件添加到项目可能会很快成为一个大麻烦。
最大的问题是make:
Java 的座右铭是“一次编译,到处运行”。但是,将编译限制在基于 POSIX 的系统上,其中 Java 支持实际上是最差的,并不是我们的意图。
构建规则make本质上是小bash脚本。即使有makeWindows的端口,为了使其正常工作,它也必须与 的端口捆绑在一起bash,其中包括文件系统的 POSIX 仿真层。
这有两种:
MSYS 它试图将 POSIX 转换限制为文件路径,因此在运行不是专门为它设计的外部工具时可能会遇到令人不快的问题。
cygwin它提供了完整的 POSIX 仿真。然而,由此产生的程序往往仍然依赖于该仿真层。
出于这个原因,在 Windows 上,标准构建工具甚至根本不是make,而是MSBuild,它也是一个基于 XML 的工具,原则上更接近于ant.
相比之下,它ant是用 Java 构建的,可以在任何地方运行,并包含称为“任务”的内部工具,用于以独立于平台的方式操作文件和执行命令。它的用途非常广泛,实际上ant与使用make.
还有最后一个小问题:
您最初可能没有注意到这一点,但 C 程序通常不附带Makefile. 它们附带一个CMakeLists.txt,或一个bash配置脚本,它生成实际的Makefile. 相比之下,使用构建的 Java 程序的源代码ant附带了一个ant预构建的脚本。AMakefile是其他工具的产物 - 这就是make它本身不适合作为构建工具的程度。ant是独立的,可以处理 Java 构建过程所需的一切,没有任何额外的要求或依赖项。
当您ant在任何平台上运行时,它都可以正常工作(tm)。你不能用make. 它非常依赖平台和配置。
我认为最可能的解释是,在关键时期(20世纪90年代末),有几个因素阻碍了Java社区中make的使用:
简而言之,虽然make肯定可以用于Java项目,但是有一个机会使它成为事实上的Java构建工具.那一刻过去了.
除非我不是任何人,否则假设没有人(错误)使用 make for java 是错误的。
“使用 GNU Make 管理项目”(在 GFDL 下可用)包含一个完整的章节,专门用于make与 java 项目一起使用。
因为它包含了一个很长的(希望是公平的)使用 make 而不是其他工具的利弊列表,你可能想看看那里。(见:http : //oreilly.com/catalog/make3/book/)