Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

If Java is a general purpose language, and building a program is something that can be described using the Java language, why isn't this the best way to write build files and instead we use tools like Ant, Maven, and Gradle? Wouldn't that be more straightforward, and also remove the need to learn yet another programming language? (BTW - this question can also be applied to other languages, like C#)

share|improve this question
6  
You might have a bit more interesting of a question as to "why aren't general purpose languages used for build languages" - I mean, C isn't a build language either. I'd also suggest looking at the ceremony around compiling a single .java file in Java –  MichaelT Mar 25 at 20:42
3  
This could probably be generalized as "Why bother with DSLs?" –  FrustratedWithFormsDesigner Mar 25 at 20:48
1  
A better question might be; why are IDEs/compilers/tools so bad that build tools are needed in the first place. –  Brendan Mar 26 at 1:43
5  
@Brendan that's a non-question as build tools and IDEs serve different purposes. –  jwenting 2 days ago
    
Because the "general purpose" languages should never be used instead of the well-defined, simple domain-specific languages. And, if a need to learn "yet another programming language" concerns you, you should not really be programming, try some other trade. –  SK-logic 2 days ago
show 3 more comments

We're looking for long answers that provide some explanation and context. Don't just give a one-line answer; explain why your answer is right, ideally with citations. Answers that don't include explanations may be removed.

5 Answers

Java is an imperative language, Ant, Maven, etc. are declarative languages:

We could define the difference as follows:

  • Imperative programming: telling the "machine" how to do something, and as a result what you want to happen will happen.
  • Declarative programming: telling the "machine" what you would like to happen, and let the computer figure out how to do it.1

Build languages tell the builder what should be done, from where it should be taken, etc. The engine which runs the build (which is written in an imperative language, like @ElliottFrisch has noted), reads these instructions, and fulfills them.

Declarative languages may seem more appropriate in build scenarios, since build tasks are generally the same all over, and it is considered more maintainable and readable in that form than in full-fledged code form.

share|improve this answer
1  
There's at least one build system that uses an imperative language though. Scons uses Python. –  user16764 Mar 25 at 21:50
    
Making it imperative is no harder than writing a class which can contain a list of dependencies, and a method to resolve those dependencies, though. I suspect there's another reason --- such as the JVM startup time, perhaps. –  Lee Mar 26 at 0:14
1  
@Lee: Almost all of the build tools used in the Java world (Ant, Maven, Gradle, SBT, …) also typically run on the JVM (with the exceptions of Rake, Buildr or Scons, which can, but don't have to run on the JVM). –  Jörg W Mittag Mar 26 at 2:50
    
Most people don't really like Ant/Maven/Make, so even if they seem more appropriate for the job, they are not the right solution. Oh, and Gradle is the newest build language, and it is not declarative but imperative –  vainolo 2 days ago
3  
@vainolo "Most people don't really like Ant/Maven/Make" really? That's a bold statement! –  Ben Thurley 2 days ago
show 2 more comments

Specific Tool for a Specific Purpose

  • Verbosity

    General purpose languages are often too verbose. If I had to manage a build in Java, I'd be very depressed very quickly by the size of the beast. However, it could easily be manageable using a DSL written in Java. And to some extent that's how you can see Gradle (for Groovy) and Buildr (for Ruby).

  • Difficulty

    General purpose languages are hard. Well I don't think programming is hard and can't be picked up by anyone, but the point is: your build engineer isn't necessarily your programmer!

  • Purpose

    That's more or less at the intersection of difficulty and verbosity. A language is designed for a purpose, and here we're talking about something very specific. So why would you need or want to use a general purpose language? For builds, you need:

    • branches and conditionals to handle separate configurations, environments, etc...
    • a set of instructions to extract data from your environment,
    • a set of instructions to produce deliverables.

    You don't really need much more.

Sure it's annoying when your build system seems like it's not flexible enough for that one special use case you're after, but it's probably far better than the alternative for most people.

That's probably why there's a polarity between people who prefer declarative build systems over most programmable onces: I guess a developer might have a natural tendency to look for ways to break out of the box.

Wait, Do We Really Need a Tool?

Another related question would be: do we really need a build tool? Isn't the fact that they exist in all languages the sign that they fill a gap that shouldn't even be there in the first place?

Some languages don't necessarily require a build tool. For instance, most scripting languages don't need one and resolve at load time. Or take Go, whose compiler will handle everything for you, which is a nice counterpoint: what if a compiler like gcc suddenly didn't need a bunch of flags, a linker, and a makefile to die everything together? Or if javac didn't need a build.xml or pom.xml to tell him what to do? Shouldn't dependency management directly be part of the language's own tooling, as the dependencies are a part of the final program?

It surely seems like a much simpler approach for the user (the builder). Though one could argue they're just doing in under the hood and taking away your choice and opportunities to influence that build process (but then you'd hope such a tool allows compiler extensions and similar things). Plus we used to see the tools and the language as two separate things, so he might seem unpure to suddenly have them so tightly coupled.

I don't think the language you use to build your programs is sthe issue. It's the language you use to program and its core platform and tooling that should matter, and we're still making headway on that.


Personally, I've used make/gmake/autotools/pmk and been happy with them for C, and I started with Java when all we had was make, then ant, and now I'm generally preferring Maven over all these alternatives. Though I can see value in gradle, buildr and others, but I like the prevalence of maven so far, until a more significant shift occurs. Plus I like that it's rigid, but still leaves you the ability to work around that if necessary. That it's not easy is a good thing.

It's a build tool. Just learn to embrace it and don't fight it. It's a losing battle. Or at least a very very long one.

share|improve this answer
    
Really like your pragmatism. My question is out of curiosity. I use maven (having used make and ant in the past), and it does "black magic" which is sometimes good and sometimes bad. But it is still magic. –  vainolo 2 days ago
add comment

If you look at the features of a typical build system you find:

  1. Lots of data: names, switches, settings, configuration items, strings, etc
  2. Lots of interaction with the environment: commands, environment variables
  3. A relatively straightforward "build engine" handling dependencies, threading, logging etc.

If you set out to write a series of build files using some language (Java/C#/Python/etc), by about the third or fourth iteration you would settle on (a) keeping most of the data and external commands as data in something like XML (b) writing the "build engine" in your favorite language.

You would also find it useful to treat some of the data in your XML as an interpreted language, to trigger various features in the build engine. You might also interpret some macros or perform string substitutions, in the data.

In other words, you would finish up with Make, or Ant, or Rake, or MsBuild. An imperative language for the things it does well, and data structures to describe what you want to do, now usually in XML.

share|improve this answer
add comment

A number of factors count against using Java/C++/C# in these cases.

Firstly, you'd have to compile your build script before you could run it to build your app. How would you specify any packages, flags, compiler versions, tool paths needed to build your build script? Certainly, you could come up with a way around it, but its much more straightforward to have either have a language that doesn't need that build step (e.g. python) or a language that your build tool natively understands.

Secondly, build files are data heavy whereas Java/C++/C# are much more geared towards writing code and algorithms. Java and friends don't have a very succinct representation of all the data you'd want to store.

Thirdly, Java and friends need a lot of boilerplate to be valid. The build file would have to be inside a method inside a class with all of its imports. When using a scripting language or custom language you can avoid all that boilerplate and just have the build details themselves.

share|improve this answer
add comment

Well, technically it is. Ant and Maven are written in java. Basically you're asking "Why would anybody write code that abstracts implementation details?" Or, more succinctly, what is the purpose of a Domain Specific Language?

The short answer is: because there's a very defined process that projects go through called "a build" -- it's where we accumulate code, compile it, put it into packages, and often generate metrics and run unit tests. Rather than using a general purpose language to support his process, we use a tool that is geared toward those specific goals.

Why should I have to think about "Open a file, read it, parse it using an EBNF tree, do transformation of the parsed node tree into an output file using a visitor pattern, close the file" when I can think "compile this".

share|improve this answer
    
first paragraph makes little sense. As pointed in comment to a deleted answer ("Ant and Maven are written in Java...") that tried to make that point already, "your claim could be extended to the absurd and be used to claim that any language is commonly used to script builds. If the C# compiler was written in C, I wrote a C# program, then claimed I wrote my program in C, everyone would think I was mistaken" –  gnat 2 days ago
    
I don't understand why you say it "makes little sense". It makes a lot of sense. Ant, Maven, Gradel, etc. are abstractions. Abstractions prevent us from having to worry about implementation details. That's also why I said "technically", because I didn't want to go down the rabbit hole of infinite abstraction. Then, I followed up with a more complete explanation in the second paragraph. –  Joe Rounceville 2 days ago
add comment

protected by maple_shaft 2 days ago

This question is protected to prevent "thanks!", "me too!", or spam answers by new users. To answer it, you must have earned at least 10 reputation on this site.

Not the answer you're looking for? Browse other questions tagged or ask your own question.