# Issue with 'make'



## mcglk (Jan 28, 2012)

I've been revising my system administration methodology a bit, and decided that I wanted to store it all in a git repository and use Makefiles to install things that change. It's going okay, and I quite like the ability to track my changes so easily.

That said, make is complaining about something I can't seem to spot.

Each subdirectory has its own Makefile which includes the following clause:


```
install-tree: install
        @for i in $(SUBDIRS); do \
            $(ECHO) "Make all in $$i . . . "; \
            $(ECHO) "($(MAKE)" $(.MAKEFLAGS) "-C $$i install-tree)"; \
            $(MAKE) $(.MAKEFLAGS) -C $$i install-tree; \
            $(ECHO) "$Done with $$i."; \
        done
```

where

SUBDIRS = list of subdirectories
ECHO = echo (shell version)

This reads correctly, and when I run it with *make -n*, it looks correct as well, but I consistently get (for example):


```
Make all in www . . . 
(make -C www install-tree)
Syntax error: ")" unexpected (expecting "done")
```

Where is that syntax error coming from? I can't seem to spot it; can any of you? (FYI: The install: clause in each directory's Makefile is empty at the moment; it definitely seems to be coming from the install-tree: clause, and if I remove the $(MAKE) line, it works just fine, so it seems to be that line specifically.


----------



## fonz (Jan 28, 2012)

mcglk said:
			
		

> ```
> install-tree: install
> @for i in $(SUBDIRS); do \
> $(ECHO) "Make all in $$i . . . "; \
> ...


If the above was a verbatim copy, there's an unmatched right parenthesis (in red). 

Fonz


----------



## mcglk (Jan 28, 2012)

Not unmatched at all:


```
[...]
            $(ECHO) "($(MAKE)" $(.MAKEFLAGS) "-C $$i install-tree)"; \
             ^----^  ^ ^----^   ^----------^                     ^
                     `-------------------------------------------'
```
Besides, that outer pair is within quotes.


----------



## fonz (Jan 28, 2012)

My bad!
The last echo line probably should say "Done" instead of "[red]$[/red]Done", but that's unlikely to cause any errors either. Are you sure that all backslashes are immediately followed by a newline (i.e. no trailing whitespace)?

Fonz


----------



## mcglk (Jan 28, 2012)

No trailing whitespace; I checked that compulsively before I posted here. As far as the "$Done" thing . . . I have no idea how I snuck that in there; it's not what's actually in the script. In the original file, it's just "Done with $$i".


----------



## mcglk (Jan 29, 2012)

*[solved] Issue with 'make'*

So it turned out that even though the for-loop was being done correctly, and it was coming up with the right Make command, and everything looked great, the error lay in an append to .MAKEFLAGS elsewhere in the Makefile. It didn't affect any other recursive targets, not even ones that seem like they should have been affected, and it had nothing to do with an unterminated parenthesis. Ah, the arcaneness of Make. In any case, I feel much better now. Thanks for taking a look at it.


----------



## wblock@ (Jan 29, 2012)

Use curly brackets for variable substitutions, like ${ECHO}.  $() would be command substitution, but will only work with sh(1).  I think, anyway; make(1) can be weird.


----------



## mcglk (Jan 29, 2012)

My understanding is that you can use both ${} and $() syntax. From the manpage:



> ```
> Variables are expanded by surrounding the variable name with either curly
> braces (`{}') or parentheses (`()') and preceding it with a dollar sign
> (`$').  If the variable name contains only a single letter, the surround-
> ...



That said, I'm using an old convention whose origins are now lost to memory, wherein Make variables are enclosed in $(), and environment variables are enclosed in ${}. But it doesn't really matter, I suspect.


----------



## debguy (Mar 7, 2012)

```
# make sure @for is preceeded by tab not white space

SUBDIRS = bob

it:
     @for i in $(SUBDIRS) ; do \
     echo "Make all in $$i . . . " ; \
     echo "($(MAKE)" $(.MAKEFLAGS) "-C $$i it)" ; \
     ls $$i ; \
     echo "$Done with $$i." ; \
     done

# $(MAKE) $(.MAKEFLAGS) -C $$i install-tree ; \
```


----------



## debguy (Mar 7, 2012)

```
# the above is not for csh so...

SHELL = /bin/sh

# problem: sh uses ; to separate commands
#          dont' use "if [ it ];" "use if [ it ] ; "
#          some shells dont' like "];"

# note: don't confuse ; in sh with make language's
#       use of ; the end of rule line
# EXAMPLE:
target : pre-requisite ; echo "hi"
     echo "lo"
targ2 : install
     echo "ok"
```


----------



## debguy (Mar 7, 2012)

Oops, the above stripped by TAB. Preceed action lines after rules with a TAB. (or other separator make accepts)


----------



## DutchDaemon (Mar 7, 2012)

@debguy, you must start *formatting your posts* from now on.


----------

