15

I am writing a Makefile, which will list all headers included by a.cpp, b.cpp and c.h files. However, I got the error of unexpected EOF. Similar questions are always caused by the line terminator, like they used CRLF instead of LF for an EOL. However, my Text editor was set to using LF and I recheck this by delete all EOL and re-added. Unfortunately, the error still remains. Here are the codes:

#!/bin/bash

list-header:
    for file in a.cpp b.cpp b.h
    do
        echo "$file includes headers: "
        grep -E '^#include' $file | cut -f2
    done

I got this error message:

for file in "Bigram.cpp client.cpp Bigram.h"
/bin/sh: -c: line 1: syntax error: unexpected end of file"

Thanks in advance for any help.

Baozi CAI
  • 199
  • 1
  • 1
  • 7
  • An example where the "unexpected end of file" is caused by the different EOL formats. [link]http://stackoverflow.com/questions/6366530/bash-syntax-error-unexpected-end-of-file – Baozi CAI May 23 '15 at 12:53
  • 2
    A Makefile is not a `bash` script. – chepner May 23 '15 at 13:42

1 Answers1

30

First note you have to escape $ that you want the shell to see, otherwise make will expand them before calling the shell. However, your main problem is that every logical line in a make recipe is a separate shell command. So, this rule:

list-header:
        for file in a.cpp b.cpp b.h
        do
            echo "$file includes headers: "
            grep -E '^#include' $file | cut -f2
        done

will cause make to invoke the shell commands:

/bin/sh -c 'for file in a.cpp b.cpp b.h'
/bin/sh -c 'do'
/bin/sh -c 'echo "ile includes headers: "'
/bin/sh -c 'grep -E '^#include' ile | cut -f2'
/bin/sh -c 'done'

You need to use backslashes to "continue" a logical line across newlines if you want them all sent to the same shell, and you have to add semicolons to make that work since the newlines no longer serve as command delimiters:

list-header:
        for file in a.cpp b.cpp b.h; \
        do \
            echo "$$file includes headers: "; \
            grep -E '^#include' $$file | cut -f2; \
        done
MadScientist
  • 92,819
  • 9
  • 109
  • 136