17

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.

2
  • An example where the "unexpected end of file" is caused by the different EOL formats. [link]stackoverflow.com/questions/6366530/… Commented May 23, 2015 at 12:53
  • 2
    A Makefile is not a bash script. Commented May 23, 2015 at 13:42

1 Answer 1

32

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 
Sign up to request clarification or add additional context in comments.

2 Comments

That works! Thank you for your super-fast answer and clear explanation = )
@BaoziCAI Now you should consider marking this as an accepted answer by clicking the tick at the left of this answer

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.