1
votes

I've got this Makefile that is presenting some odd behaviour:

$ javac -d Classes -sourcepath .. -classpath `for x in \`ls Classes/jars/*\`; do echo -n $x:; done` PCA/PCAClassifier.java

compiles the java just fine. But for somereason when I call

make PCA

I get:

Compiling PCAClassifier
javac -d Classes -sourcepath .. -classpath `for x in \`ls Classes/jars/*\`; do echo -n $x:; done` PCA/PCAClassifier.java
javac: invalid flag: Classes/jars/Jama.jar:
Usage: javac <options> <source files>
use -help for a list of possible options
make: * [Classes/RobotSuite/PCA/PCAClassifier.class] Error 2

I am so confused. Anyone have a solution?

Make version info:

GNU Make 3.81 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

This program built for i386-apple-darwin10.0

Background: Working on a group project. I'm running Ubuntu, my partner is running Mac OS X. For whatever reason, This makefile works just fine on my computer, but not on his. Even though the command works in his BASh terminal, somehow Make isn't sending it correctly.

1
Since you don't show us the makefile, it is going to be difficult to help. The first fragment is compiling PCA/PCAClassifier.java and the complaining version is compiling PCA/PCAHelper.java - is that difference a problem?Jonathan Leffler
No, it fails no matter which argument I'm running.FrankieTheKneeMan

1 Answers

7
votes

You have given us almost no information to go on. Nonetheless, you are in luck!

On Mac OS X, bash has been built with --enable-strict-posix-default and hence the xpg_echo shell option defaults to being on in POSIX mode. POSIX mode is on when the shell has been invoked as /bin/sh, as it has been when it is invoked by Make, unless you instruct it otherwise by setting the $(SHELL) make variable (which you probably shouldn't).

This is the difference between Linux and Mac OS that is killing your makefile. When xpg_echo is on, the shell's built-in echo treats -n as just another argument to be printed (and hence also prints a newline). So the single classpath argument that you're trying to construct ends up as a bunch of separate arguments (half of which are "-n") and javac gets confused.

(This doesn't happen on the command line, even on Mac OS X, because then the shell has been invoked as /bin/bash, so it's not in POSIX mode and xpg_echo is off.)

So you have a number of options for fixing this:

  1. Use /bin/echo -n in your shell snippet; unlike the built-in one, the real echo command these days mostly always understands -n;

  2. Construct the classpath argument in a less roundabout way than your shell for loop; for example

    ... -classpath `ls Classes/jars/* | tr '\n' :` ...
    

    or, if you are already assuming GNU Make, using make wildcards and functions instead of a shell snippet;

  3. Have your colleague add shopt -u xpg_echo to an appropriate bash startup file on their machine (however this will just lead to future confusion when your next Mac OS-using colleague comes along and you've all long since forgotten how you fixed this this time).

Finally, a general note about debugging makefiles: when a javac ... command in a makefile recipe is giving incomprehensible error messages, change it to echo javac ... instead. Then you'll be able to see exactly how it's being invoked -- which, as seen here, may not be what you intended.