英文:
Makefile only compiling the first item of list
问题
为什么 test.c 没有被编译?
英文:
I have this Makefile:
SRCS = ../compilation-test2/src/test2.c ./test.c
OBJS = $(foreach src,$(SRCS),$(patsubst %.c,build/%.o,$(notdir $(src))))
define build_obj
$(info $(1))
obj_file := $(patsubst %.c, build/%.o, $(notdir $(1)))
src_file := $(1)
$(info $(obj_file))
$(info $(src_file))
$(obj_file): $(src_file)
g++ -c $(src_file) -o $(obj_file)
endef
$(foreach src,$(SRCS),$(eval $(call build_obj,$(src))))
all: $(OBJS)
g++ $^ -o build/exec_file
clean:
rm -rf build/*
and this directories structures:
$ tree compilation-test
compilation-test
├── Makefile
├── build
└── test.c
1 directory, 2 files
andre:~
$ tree compilation-test2/
compilation-test2/
├── include
│ └── test2.h
└── src
└── test2.c
When I execute make
only test2.c is compiled:
andre:~/compilation-test
$ make
../compilation-test2/src/test2.c
./test.c
build/test2.o
../compilation-test2/src/test2.c
g++ -c ../compilation-test2/src/test2.c -o build/test2.o
andre:~/compilation-test
$ ls build/
test2.o
Why is test.c not compiled?
答案1
得分: 3
When you run make
without specifying any targets, it will build the first target in the makefile.
当你运行make
而不指定任何目标时,它将构建makefile中的第一个目标。
Quick solution: Move the all
target to be the first target, and that should be the default.
快速解决方案:将all
目标移到第一个目标位置,这样它就会成为默认目标。
On another note, you don't really need most of your makefile. You definitely don't need that function you define. Use the implicit rules already existing to build programs. You don't need to provide any commands to build the object files or the linking, only provide the flags through variables.
另外一点,你实际上不需要大部分的makefile。你绝对不需要你定义的那个函数。使用已经存在的隐式规则来构建程序。你不需要提供任何命令来构建目标文件或链接,只需通过变量提供标志。
Your makefile could be simplified to:
你的makefile可以简化为:
.PHONY: default
default: all
.PHONY: all
all: build/exec_file
build/exec_file: build/test2.o build/test.o
.PHONY: clean
clean:
-rm -f build/*
build/test2.o: ../compilation-test2/src/test2.c
build/test.o: test.c
I've added a "default" target to be placed as the first rule in the makefile, which will then be the default target if none is specified. I also marked it and the all
and clean
targets as phony because they don't generate any files themselves.
我添加了一个“default”目标,将其放在makefile中的第一条规则,如果没有指定目标,它将成为默认目标。我还将它和all
以及clean
目标标记为phony,因为它们本身不生成任何文件。
I also added some default compiler flags, which will add some extra warnings when you build. This is generally a good habit, and also shows you how to add flags when needed.
我还添加了一些默认的编译器标志,这将在构建时添加一些额外的警告。这通常是一个好习惯,也展示了如何在需要时添加标志。
And of course please take some time to read the full documentation to learn more about make
and how it works.
当然,请花些时间阅读完整的文档以了解更多关于make
及其工作原理的信息。
英文:
When you run make
without specifying any targets, it will build the first target in the makefile.
And the first target of your makefile is for one of your source files, to create its object file. So that's the only thing that will be built.
Quick solution: Move the all
target to be the first target, and that should be the default.
On another note, you don't really need most of your makefile. You definitely don't need that function you define. Use the implicit rules already existing to build programs. You don't need to provide any commands to build the object files or the linking, only provide the flags through variables.
Your makefile could be simplified to:
CFLAGS = -Wall -Wextra
.PHONY: default
default: all
.PHONY: all
all: build/exec_file
build/exec_file: build/test2.o build/test.o
.PHONY: clean
clean:
-rm -f build/*
build/test2.o: ../compilation-test2/src/test2.c
build/test.o: test.c
I've added a "default" target to be placed as the first rule in the makefile, which will then be the default target if none is specified. I also marked it and the all
and clean
targets as phony because they don't generate any files themselves.
I also added some default compiler flags, which will add some extra warnings when you build. This is generally a good habit, and also shows you how to add flags when needed.
And of course please take some time to read the full documentation to learn more about make
and how it works.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论