kakts-log

programming について調べたことを整理していきます

Makefileでmake時に 「*** missing separator. Stop.」 と出たときの対処法。

概要

Makefileで処理を実行する際に下記のエラーが出ることがあります。

Makefile:8: *** missing separator.  Stop.

この場合は、下記の最後の行の先頭でスペースを使っていることにより発生するもので、その原因と対処法についてまとめます。

missing separator. Stop. エラーの原因と簡単な対処法

簡単に結論から書くと、make コマンドで実際の処理を行うブロック(recipeと呼ぶ)での先頭行で、仕様ではタブ文字を使う必要がありますが、スペースが使っているために起きていました。

PROGRAM = server_socket
OBJS    = server.o
SRCS    = $(OBJS:%.o=%.c)
CFLAGS  = -g -Wall
LDFLAGS =

$(PROGRAM):$(OBJS)
    $(CC) $(CFLAGS) $(LDFLAGS) -o $(PROGRAM) $(OBJS) $(LDLIBS)

最後の行の先頭で使われているスペースをタブに変更すれば解決します。

makeの仕様について

ここで、Makefileで書く内容の仕様を理解するため、make公式のドキュメントを参照します。

www.gnu.org

Makefile内で下記のような形式でコマンド・処理を記述していきます。

target … : prerequisites …
        recipe
        …
        …

ここで、recipe ブロックは、複数の行を記述可能です。
makeの仕様では、recipeブロックの各行の先頭では タブ文字を使う必要があると定められています。

Please note: you need to put a tab character at the beginning of every recipe line! This is an obscurity that catches the unwary.

( Make3.82以降) recipe行の先頭文字はタブ文字から他の文字に変更可能

仕様を確認したところ、make 3.82以降ではrecipeブロックの先頭文字をタブ文字以外に変更することができるようです。

https://cvs.savannah.gnu.org/viewvc/make/make/NEWS?&revision=2.109

makeでは.RECIPEPREFIX という変数があり、Makefile内で.RECIPEPREFIXの値を変更すればタブ文字から変更可能です。

  • New special variable: .RECIPEPREFIX allows you to reset the recipe introduction character from the default (TAB) to something else. The first character of this variable value is the new recipe introduction character. If the variable is set to the empty string, TAB is used again. It can be set and reset at will; recipes will use the value active when they were first parsed. To detect this feature check the value of $(.RECIPEPREFIX).

ただ、タブ文字、スペースに関してはエディタ側でMakefileの場合はタブ文字を使うような設定にできたりするので、よほどの理由がない限りこの設定を扱うのは控えたほうがよさそうです。