tags:

views:

246

answers:

3

I have a makefile to build some transducers using Xerox' finite state tools (xfst in this case), which I invoke in my makefile like so (except with a hard tab instead of spaces in the actual makefile, of course):

latin.fst: nouns.fst verbs.fst
    xfst -f build/latin.fst.build

On my laptop (a Mac with OS X 10.6.2) this works just fine, but on my university's Linux machines I get this error:

make: xfst: Command not found
make: *** [nouns.fst] Error 127

After some debugging I've found two ways to fix this problem. The first is to quote the -f argument to xfst: "-f", the other is to say SHELL=/bin/bash at the top of the makefile.

From the second fix (and how make works) it looks like the problem is with how /bin/sh executes the command. Now, /bin/sh is linked to /bin/bash, so it's not because of some kind of weird shell being installed as /bin/sh. Also, invoking /bin/sh and running the commands, or invoking /bin/sh -c "xfst -f build/latin.fst.build" works just dandy.

Make is GNU Make 3.81, bash is GNU bash, version 3.2.25(1)-release.

Does anyone have any idea what's going on here?

A: 

Perhaps you modified a bash-specific startup file (.bashrc or .bash_profile) to change your $PATH on the Linux machines to include the directory where xfst is located. In that case, running under /bin/sh would not invoke .bash* so the correct directory would not be on your path.

Ned Deily
I have customized my path. But if I add `env` as a command before the offending one, PATH does contain all the values I want. Also, if it's dependent on PATH, why does quoting the -f argument fix it?
arnsholt
Odd. Perhaps you could try `make -d` on both machines to see what's going on under the covers.
Ned Deily
Unfortunately `make -d` doesn't really say how the shell invoked. Basically, it just says "I'm gonna execute the command `xfst -f build/latin.fst.build' now", but no specifics about how it goes about doing that.
arnsholt
A: 

Any time you move between systems that use different line endings, it's always a good idea to check whether that's a culprit in problems you encounter. As I'm sure you know, Linux and Unix use 0x0a, DOS and Windows use 0x0d 0x0a and Macs use 0x0d. Try looking at the file with hd filename to see what style line endings you have (they may even vary within the file).

Dennis Williamson
How does line endings explain that quoting fixes the problem? Besides OS X is UNIX these days, so the file has 0x0a line endings (I checked).
arnsholt
+2  A: 

This a weird error and I don't know what's causing it, but here's what I'd try:

.PHONY: experiment
experiment:
    @echo make's SHELL variable: $(SHELL)
    @echo the actual shell: $$SHELL
    which xfst

Edit:
Wait a second... the error message says that Make failed while trying to make nouns.fst, not latin.fst. Is that right? (If it is, then this problem just got weirder.)

EDIT:
All right, now I'm clutching at straws. I'd broaden the search, try running other programs that take options, try aliasing "xfst -f", try making a local symbolic link to xfst, try enclosing the whole command in quotes or backticks... and then just admit that I was totally stumped.

Beta
Good suggestions. Here's the output I get (after removing the genitive quote that made sh cry =): makes SHELL variable: /bin/sh the actual shell: /local/gnu/bin/bash which xfst /uio/arkimedes/s11/arnskj/sw/bin/xfstInvoking /local/gnu/bin/bash as a shell and executing `xfst -f build/latin.fst.build` works just fine. Same for `/local/gnu/bin/bash -c 'xfst -f build/latin.fst.build'`
arnsholt
Er, right. I messed up the formatting of the output from `make experiment`. $(SHELL) is `/bin/sh`, the actual shell i `/local/gnu/bin/bash`, and which finds the correct path to xfst.
arnsholt
Oh, sorry for the weird error. nouns.fst is made in the same way that latin.fst, just with a different build file. There are several FSTs that are built in the same way (and fail in the same way). For simplicity's sake I just listed one of the rules and forgot to mention that there are more.
arnsholt