我如何更正我的 Makefile 以便它构建我所有的源文件? (答案:检查隐藏的选项卡)
How do I correct my Makefile so that it builds all my source files? (Answer: check for hidden tabs)
在使用 clang v7.0.2 和 make v3.81 的 OS X v10.10.5 中,我在当前项目中遇到了一些我认为是直接的 Makefile 的问题。
当我再添加一对 .h/.c 文件时出现了问题——之前一切似乎都运行良好。现在 make 不会 'pick up' 并构建新的源代码,即使我可以成功地手动构建它。 Make 似乎认为 .o 文件是最新的,即使它似乎根本不存在。
这里是我的相关项目目录的转储以供参考:
$ ls -R
.:
LICENSE Makefile README.md docs include src
./docs:
ptscheme.ebnf
./include:
lispbool.h lispchar.h lisperr.h lispint.h lisppair.h lispstr.h memmanager.h ptscheme.h
./src:
lispbool.c lispchar.c lisperr.c lispint.c lisppair.c lispstr.c memmanager.c ptscheme.c
而且,这是我的 Makefile 的内容:
$ cat Makefile
# Basic Makefile for ptscheme
# Set our paths to traditional locations for files:
# ./src - c source files
# ./include - c header files
vpath %.c src
vpath %.h include
CC = clang
CPPFLAGS = -std=c99 -Wall -g -I include
objects = ptscheme.o memmanager.o lispbool.o lispchar.o lispint.o \
lispstr.o lisperr.o lisppair.o
all: ptscheme
ptscheme: $(objects)
clang $(CPPFLAGS) -o ptscheme $(objects)
ptscheme.o: ptscheme.h memmanager.h
memmanager.o: ptscheme.h memmanager.h
lispbool.o: ptscheme.h memmanager.h lispbool.h
lispchar.o: ptscheme.h memmanager.h lispchar.h
lispint.o: ptscheme.h memmanager.h lispint.h
lispstr.o: ptscheme.h memmanager.h lispstr.h
lisperr.o: ptscheme.h memmanager.h lisperr.h
lisppair.o: ptscheme.h memmanager.h lisppair.h
# clean - Implement standard 'clean' target to clean up after ourselves
.PHONY: clean
clean:
rm -f ptscheme $(objects)
这是我尝试 运行 时发生的情况:
$ make
clang -std=c99 -Wall -g -I include -c -o ptscheme.o src/ptscheme.c
clang -std=c99 -Wall -g -I include -c -o memmanager.o src/memmanager.c
clang -std=c99 -Wall -g -I include -c -o lispbool.o src/lispbool.c
clang -std=c99 -Wall -g -I include -c -o lispchar.o src/lispchar.c
clang -std=c99 -Wall -g -I include -c -o lispint.o src/lispint.c
clang -std=c99 -Wall -g -I include -c -o lispstr.o src/lispstr.c
clang -std=c99 -Wall -g -I include -c -o lisperr.o src/lisperr.c
clang ptscheme.o memmanager.o lispbool.o lispchar.o lispint.o lispstr.o lisperr.o lisppair.o -o ptscheme
clang: error: no such file or directory: 'lisppair.o'
make: *** [ptscheme] Error 1
显然,lisppair.o 没有被构建,即使我在我的 Makefile 中有一个条目,它遵循与其他条目相同的模式。
这是一个验证文件丢失的目录:
$ ls -al *.o
-rw-r--r-- 1 ptdecker 4392 Dec 22 22:00 lispbool.o
-rw-r--r-- 1 ptdecker 3360 Dec 22 22:00 lispchar.o
-rw-r--r-- 1 ptdecker 3376 Dec 22 22:00 lisperr.o
-rw-r--r-- 1 ptdecker 3344 Dec 22 22:00 lispint.o
-rw-r--r-- 1 ptdecker 3776 Dec 22 22:00 lispstr.o
-rw-r--r-- 1 ptdecker 3244 Dec 22 22:00 memmanager.o
-rw-r--r-- 1 ptdecker 15324 Dec 22 22:00 ptscheme.o
当我尝试让 运行 只是 lisppair.o 收据时,make 告诉我它认为我想要的目标文件是最新的 (!?):
$ make lisppair.o
make: `lisppair.o' is up to date.
我可以手动编译:
$ clang -std=c99 -Wall -g -I include -c -o lisppair.o src/lisppair.c
生成目标文件:
$ ls -al *.o
-rw-r--r-- 1 ptdecker 4392 Dec 22 22:00 lispbool.o
-rw-r--r-- 1 ptdecker 3360 Dec 22 22:00 lispchar.o
-rw-r--r-- 1 ptdecker 3376 Dec 22 22:00 lisperr.o
-rw-r--r-- 1 ptdecker 3344 Dec 22 22:00 lispint.o
-rw-r--r-- 1 ptdecker 5664 Dec 22 22:03 lisppair.o
-rw-r--r-- 1 ptdecker 3776 Dec 22 22:00 lispstr.o
-rw-r--r-- 1 ptdecker 3244 Dec 22 22:00 memmanager.o
-rw-r--r-- 1 ptdecker 15324 Dec 22 22:00 ptscheme.o
然后让我重新运行 使我的最终构建和链接完成:
$ make
clang ptscheme.o memmanager.o lispbool.o lispchar.o lispint.o lispstr.o lisperr.o lisppair.o -o ptscheme
让我最终到达我想去的地方:
$ ./ptscheme
>
感谢您的帮助和反馈!显然,我遗漏了一些基本的东西。
可以找到所有这些的完整来源 in my github repository。
只有查看 github 中的原始 Makefile
,问题才会明显。第 37 行(# clean
注释之后的行)有一个错误的选项卡。删除该选项卡,您应该可以开始了。
在使用 clang v7.0.2 和 make v3.81 的 OS X v10.10.5 中,我在当前项目中遇到了一些我认为是直接的 Makefile 的问题。
当我再添加一对 .h/.c 文件时出现了问题——之前一切似乎都运行良好。现在 make 不会 'pick up' 并构建新的源代码,即使我可以成功地手动构建它。 Make 似乎认为 .o 文件是最新的,即使它似乎根本不存在。
这里是我的相关项目目录的转储以供参考:
$ ls -R
.:
LICENSE Makefile README.md docs include src
./docs:
ptscheme.ebnf
./include:
lispbool.h lispchar.h lisperr.h lispint.h lisppair.h lispstr.h memmanager.h ptscheme.h
./src:
lispbool.c lispchar.c lisperr.c lispint.c lisppair.c lispstr.c memmanager.c ptscheme.c
而且,这是我的 Makefile 的内容:
$ cat Makefile
# Basic Makefile for ptscheme
# Set our paths to traditional locations for files:
# ./src - c source files
# ./include - c header files
vpath %.c src
vpath %.h include
CC = clang
CPPFLAGS = -std=c99 -Wall -g -I include
objects = ptscheme.o memmanager.o lispbool.o lispchar.o lispint.o \
lispstr.o lisperr.o lisppair.o
all: ptscheme
ptscheme: $(objects)
clang $(CPPFLAGS) -o ptscheme $(objects)
ptscheme.o: ptscheme.h memmanager.h
memmanager.o: ptscheme.h memmanager.h
lispbool.o: ptscheme.h memmanager.h lispbool.h
lispchar.o: ptscheme.h memmanager.h lispchar.h
lispint.o: ptscheme.h memmanager.h lispint.h
lispstr.o: ptscheme.h memmanager.h lispstr.h
lisperr.o: ptscheme.h memmanager.h lisperr.h
lisppair.o: ptscheme.h memmanager.h lisppair.h
# clean - Implement standard 'clean' target to clean up after ourselves
.PHONY: clean
clean:
rm -f ptscheme $(objects)
这是我尝试 运行 时发生的情况:
$ make
clang -std=c99 -Wall -g -I include -c -o ptscheme.o src/ptscheme.c
clang -std=c99 -Wall -g -I include -c -o memmanager.o src/memmanager.c
clang -std=c99 -Wall -g -I include -c -o lispbool.o src/lispbool.c
clang -std=c99 -Wall -g -I include -c -o lispchar.o src/lispchar.c
clang -std=c99 -Wall -g -I include -c -o lispint.o src/lispint.c
clang -std=c99 -Wall -g -I include -c -o lispstr.o src/lispstr.c
clang -std=c99 -Wall -g -I include -c -o lisperr.o src/lisperr.c
clang ptscheme.o memmanager.o lispbool.o lispchar.o lispint.o lispstr.o lisperr.o lisppair.o -o ptscheme
clang: error: no such file or directory: 'lisppair.o'
make: *** [ptscheme] Error 1
显然,lisppair.o 没有被构建,即使我在我的 Makefile 中有一个条目,它遵循与其他条目相同的模式。
这是一个验证文件丢失的目录:
$ ls -al *.o
-rw-r--r-- 1 ptdecker 4392 Dec 22 22:00 lispbool.o
-rw-r--r-- 1 ptdecker 3360 Dec 22 22:00 lispchar.o
-rw-r--r-- 1 ptdecker 3376 Dec 22 22:00 lisperr.o
-rw-r--r-- 1 ptdecker 3344 Dec 22 22:00 lispint.o
-rw-r--r-- 1 ptdecker 3776 Dec 22 22:00 lispstr.o
-rw-r--r-- 1 ptdecker 3244 Dec 22 22:00 memmanager.o
-rw-r--r-- 1 ptdecker 15324 Dec 22 22:00 ptscheme.o
当我尝试让 运行 只是 lisppair.o 收据时,make 告诉我它认为我想要的目标文件是最新的 (!?):
$ make lisppair.o
make: `lisppair.o' is up to date.
我可以手动编译:
$ clang -std=c99 -Wall -g -I include -c -o lisppair.o src/lisppair.c
生成目标文件:
$ ls -al *.o
-rw-r--r-- 1 ptdecker 4392 Dec 22 22:00 lispbool.o
-rw-r--r-- 1 ptdecker 3360 Dec 22 22:00 lispchar.o
-rw-r--r-- 1 ptdecker 3376 Dec 22 22:00 lisperr.o
-rw-r--r-- 1 ptdecker 3344 Dec 22 22:00 lispint.o
-rw-r--r-- 1 ptdecker 5664 Dec 22 22:03 lisppair.o
-rw-r--r-- 1 ptdecker 3776 Dec 22 22:00 lispstr.o
-rw-r--r-- 1 ptdecker 3244 Dec 22 22:00 memmanager.o
-rw-r--r-- 1 ptdecker 15324 Dec 22 22:00 ptscheme.o
然后让我重新运行 使我的最终构建和链接完成:
$ make
clang ptscheme.o memmanager.o lispbool.o lispchar.o lispint.o lispstr.o lisperr.o lisppair.o -o ptscheme
让我最终到达我想去的地方:
$ ./ptscheme
>
感谢您的帮助和反馈!显然,我遗漏了一些基本的东西。
可以找到所有这些的完整来源 in my github repository。
只有查看 github 中的原始 Makefile
,问题才会明显。第 37 行(# clean
注释之后的行)有一个错误的选项卡。删除该选项卡,您应该可以开始了。