Short answer: Because make
isn't good. Even on the C front you see many alternatives popping up.
Long answer: make
has several flaws that make it barely suitable for compiling C, and unsuitable at all for compiling Java. You can force it to compile Java, if you want, but expect running into issues, some of which do not have a suitable solution or workaround. Here are a few:
Dependency resolution
make
inherently expects files to have a tree-like dependency on each other, in which one file is the output of building several others. This already backfires in C when dealing with header files. make
requires a make
-specific include file to be generated to represent the dependency of a C file on its header files, so a change to the latter would cause the prior to be rebuilt. However, since the C file itself isn't recreated (merely rebuilt), make often requires specifying the target as .PHONY
. Fortunately, GCC supports generating those files automatically.
In Java, dependency can be circular, and there's no tool for auto-generating class dependencies in make
format. ant
's Depend
task can, instead, read the class file directly, determine which classes it imports, and delete the class file if any of them are out of date. Without this, any non-trivial dependency may result in you being forced to use repeated clean builds, removing any advantage of using a build tool.
Spaces in filenames
While neither Java nor C encourage using spaces in your source code filenames, in make
this can be problem even if the spaces are in the file path. Consider, for example, if your source code exists in C:\My Documents\My Code\program\src
. This would be enough to break make
. This is because make
treats filenames as strings. ant
treats paths as special objects.
Scanning files for build
make
requires explicitly setting which files are to be built for each target. ant
allows specifying a folder which is to be auto-scanned for source files. It may seem like a minor convenience, but consider that in Java each new class requires a new file. Adding files to the project can become a big hassle fast.
And the biggest problem with make
:
make is POSIX-dependent
Java's motto is "compile once run everywhere". But restricting that compilation to POSIX-based systems, in which Java support is actually the worst, is not the intention.
Build rules in make
are essentially small bash
scripts. Even though there is a port of make
to Windows, for it to work properly, it has to be bundled with a port of bash
, which includes a POSIX emulation layer for the file system.
This comes in two varieties:
MSYS
which tries to limit the POSIX translation to file paths, and can therefore have unpleasant gotchas when running external tools not made especially for it.
cygwin
which provides a complete POSIX emulation. The resulting programs, however, tend to still rely on that emulation layer.
For that reason, on Windows, the standard build tool isn't even make
at all, but rather MSBuild
, which is also an XML-based tool, closer in principle to ant
.
By contrast, ant
is built in Java, can run everywhere, and contains internal tools, called "tasks", for manipulating files and executing commands in a platform-independent way. It's sufficiently versatile that you can actually have an easier time building a C program in Windows using ant
than using make
.
And one last minor one:
Even C programs don't use make natively
You may not initially notice this, but C programs generally aren't shipped with a Makefile
. They are shipped with a CMakeLists.txt
, or a bash
configuration script, which generates the actual Makefile
. By contrast, the source of a Java program built using ant
is shipped with an ant
script pre-built. A Makefile
is a product of other tools - That's how much make
is unsuitable to be a build tool on its own. ant
is standalone, and deals with everything you need for your Java build process, without any additional requirements or dependencies.
When you run ant
on any platform, it Just Works(tm). You can't get that with make
. It's incredibly platform and configuration dependent.
make
. And having a makefile which only works on one system isn't very nice for a cross-platform language. – Joey