9.1 Alternatives to make

     

As previously mentioned, the Java developer community enthusiastically adopts new technologies. Let's see how two of these, Ant and IDEs, relate to make .

9.1.1 Ant

The Java community is very active, producing new tools and APIs at an impressive rate. One of these new tools is Ant , a build tool intended to replace make in the Java development process. Like make , Ant uses a description file to indicate the targets and prerequisites of a project. Unlike make , Ant is written in Java and Ant build files are written in XML.

To give you a feel for the XML build file, here is an excerpt from the Ant build file:

 <target name="build"         depends="prepare, check_for_optional_packages"         description="--> compiles the source code">   <mkdir dir="${build.dir}"/>   <mkdir dir="${build.classes}"/>   <mkdir dir="${build.lib}"/>   <javac srcdir="${java.dir}"          destdir="${build.classes}"          debug="${debug}"          deprecation="${deprecation}"          target="${javac.target}"          optimize="${optimize}" >     <classpath ref/>   </javac>   ...   <copy todir="${build.classes}">     <fileset dir="${java.dir}">       <include name="**/*.properties"/>       <include name="**/*.dtd"/>     </fileset>   </copy>  </target> 

As you can see, a target is introduced with an XML <target> tag. Each target has a name and dependency list specified with <name> and <depends> attributes, respectively. Actions are performed by Ant tasks . A task is written in Java and bound to an XML tag. For instance, the task of creating a directory is specified with the <mkdir> tag and triggers the execution of the Java method Mkdir.execute , which eventually calls File.mkdir . As far as possible, all tasks are implemented using the Java API.

An equivalent build file using make syntax would be:

 # compiles the source code build: $(all_javas) prepare check_for_optional_packages         $(MKDIR) -p $(build.dir) $(build.classes) $(build.lib)         $(JAVAC) -sourcepath $(java.dir)                        \                  -d $(build.classes)                            \                  $(debug)                                       \                  $(deprecation)                                 \                  -target $(javac.target)                        \                  $(optimize)                                    \                  -classpath $(classpath)                        \                  @$<         ...         $(FIND) . \( -name '*.properties' -o -name '*.dtd' \)  \         $(TAR) -c -f - -T -  $(TAR) -C $(build.classes) -x -f - 

This snippet of make uses techniques that this book hasn't discussed yet. Suffice to say that the prerequisite all.javas contains a list of all java files to be compiled. The Ant tasks <mkdir> , <javac> , and <copy> also perform dependency checking. That is, if the directory already exists, mkdir is not executed. Likewise, if the Java class files are newer than the source files, the source files are not compiled. Nevertheless, the make command script performs essentially the same functions. Ant includes a generic task, called < exec > , to run a local program.

Ant is a clever and fresh approach to build tools; however, it presents some issues worth considering:

  • Although Ant has found wide acceptance in the Java community, it is still relatively unknown elsewhere. Also, it seems doubtful that its popularity will spread much beyond Java (for the reasons listed here). make , on the other hand, has consistently been applied to a broad range of fields including software development, document processing and typesetting, and web site and workstation maintenance, to name a few. Understanding make is important for anyone who needs to work on a variety of software systems.

  • The choice of XML as the description language is appropriate for a Java-based tool. But XML is not particularly pleasant to write or to read (for many). Good XML editors can be difficult to find and often do not integrate well with existing tools (either my integrated development environment includes a good XML editor or I must leave my IDE and find a separate tool). As you can see from the previous example, XML and the Ant dialect , in particular, are verbose compared with make and shell syntax. And the XML is filled with its own idiosyncrasies.

  • When writing Ant build files you must contend with another layer of indirection. The Ant <mkdir> task does not invoke the underlying mkdir program for your system. Instead, it executes the Java mkdir( ) method of the java.io.File class. This may or may not do what you expect. Essentially, any knowledge a programmer brings to Ant about the behavior of common tools is suspect and must be checked against the Ant documentation, Java documentation, or the Ant source. In addition, to invoke the Java compiler, for instance, I may be forced to navigate through a dozen or more unfamiliar XML attributes, such as <srcdir> , <debug> , etc., that are not documented in the compiler manual. In contrast, the make script is completely transparent, that is, I can typically type the commands directly into a shell to see how they behave.

  • Although Ant is certainly portable, so is make . As shown in Chapter 7, writing portable makefile s, like writing portable Ant files, requires experience and knowledge. Programmers have been writing portable makefile s for two decades. Furthermore, the Ant documentation notes that there are portability issues with symbolic links on Unix and long filenames on Windows, that MacOS X is the only supported Apple operating system, and that support for other platforms is not guaranteed . Also, basic operations like setting the execution bit on a file cannot be performed from the Java API. An external program must be used. Portability is never easy or complete.

  • The Ant tool does not explain precisely what it is doing. Since Ant tasks are not generally implemented by executing shell commands, the Ant tool has a difficult time displaying its actions. Typically, the display consists of natural language prose from print statements added by the task author. These print statements cannot be executed by a user from a shell. In contrast, the lines echoed by make are usually command lines that a user can copy and paste into a shell for reexecution. This means the Ant build is less useful to developers trying to understand the build process and tools. Also, it is not possible for a developer to reuse parts of a task, impromptu, at the keyboard.

  • Last and most importantly, Ant shifts the build paradigm from a scripted to a nonscripted programming language. Ant tasks are written in Java. If a task does not exist or does not do what you want, you must either write your own task in Java or use the <exec> task. (Of course, if you use the <exec> task often, you would do far better to simply use make with its macros, functions, and more compact syntax.)

  • Scripting languages, on the other hand, were invented and flourish precisely to address this type of issue. make has existed for nearly 30 years and can be used in the most complex situations without extending its implementation. Of course, there have been a handful of extensions in those 30 years . Many of them conceived and implemented in GNU make .

Ant is a marvelous tool that is widely accepted in the Java community. However, before embarking on a new project, consider carefully if Ant is appropriate for your development environment. This chapter will hopefully prove to you that make can powerfully meet your Java build needs.

9.1.2 IDEs

Many Java developers use Integrated Development Environments (IDEs) that bundle an editor, compiler, debugger, and code browser in a single (typically) graphical environment. Examples include the open source Eclipse (http://www.eclipse.org) and Emacs JDEE (http://jdee.sunsite.dk), and, from commercial vendors , Sun Java Studio (http://wwws.sun.com/software/sundev/jde) and JBuilder (http://www.borland.com/jbuilder). These environments typically have the notion of a project-build process that compiles the necessary files and enables the application execution.

If the IDEs support all this, why should we consider using make ? The most obvious reason is portability. If there is ever a need to build the project on another platform, the build may fail when ported to the new target. Although Java itself is portable across platforms, the support tools are often not. For instance, if the configuration files for your project include Unix- or Windows-style paths, these may generate errors when the build is run on the other operating system. A second reason to use make is to support unattended builds. Some IDEs support batch building and some do not. The quality of support for this feature also varies. Finally, the build support included is often limited. If you hope to implement customized release directory structures, integrate help files from external applications, support automated testing, and handle branching and parallel lines of development, you may find the integrated build support inadequate.

In my own experience, I have found the IDEs to be fine for small scale or localized development, but production builds require the more comprehensive support that make can provide. I typically use an IDE to write and debug code, and write a makefile for production builds and releases. During development I use the IDE to compile the project to a state suitable for debugging. But if I change many files or modify files that are input to code generators, then I run the makefile . The IDEs I've used do not have good support for external source code generation tools. Usually the result of an IDE build is not suitable for release to internal or external customers. For that task I use make .



Managing Projects with GNU make
Managing Projects with GNU Make (Nutshell Handbooks)
ISBN: 0596006101
EAN: 2147483647
Year: 2003
Pages: 131

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net