Makefile patsubst没有将*.c转换为*.o
我的测试项目文件夹结构如下所示:Makefile patsubst没有将*.c转换为*.o,makefile,Makefile,我的测试项目文件夹结构如下所示: TOPDIR ├── a │ └── a.c ├── b │ └── b.c ├── c │ └── c.mk └── makefile 我编写了一个测试makefile: MAKE_DIR = $(PWD) MODULES := a b c SRC_DIR := $(addprefix ${MAKE_DIR}/,$(MODULES)) BUILD_DIR := $(addprefix ${MAKE_DIR}/build/,$(MODULE
TOPDIR
├── a
│ └── a.c
├── b
│ └── b.c
├── c
│ └── c.mk
└── makefile
我编写了一个测试makefile
:
MAKE_DIR = $(PWD)
MODULES := a b c
SRC_DIR := $(addprefix ${MAKE_DIR}/,$(MODULES))
BUILD_DIR := $(addprefix ${MAKE_DIR}/build/,$(MODULES))
SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c))
OBJ := $(patsubst ${SRC_DIR}/%.c,${BUILD_DIR}/%.o,$(SRC))
INCLUDES := $(addprefix -I,$(SRC_DIR))
vpath %.c $(SRC_DIR)
default:
@echo "SRC DIR: ${SRC_DIR}"
@echo "Build DIR: ${BUILD_DIR}"
@echo "Source: ${SRC}"
@echo "Obj: ${OBJ}"
@echo "Includes: ${INCLUDES}"
它的输出:
[GNU-GCC]howchen@linux:~/Work/c/c/test/test_make
-> make
SRC DIR: /home/howchen/Work/c/c/test/test_make/a /home/howchen/Work/c/c/test/test_make/b /home/howchen/Work/c/c/test/test_make/c
Build DIR: /home/howchen/Work/c/c/test/test_make/build/a /home/howchen/Work/c/c/test/test_make/build/b /home/howchen/Work/c/c/test/test_make/build/c
Source: /home/howchen/Work/c/c/test/test_make/a/a.c /home/howchen/Work/c/c/test/test_make/b/b.c /home/howchen/Work/c/c/test/test_make/c/c.c
Obj: /home/howchen/Work/c/c/test/test_make/a/a.c /home/howchen/Work/c/c/test/test_make/b/b.c /home/howchen/Work/c/c/test/test_make/c/c.c
Includes: -I/home/howchen/Work/c/c/test/test_make/a -I/home/howchen/Work/c/c/test/test_make/b -I/home/howchen/Work/c/c/test/test_make/c
Obj: /home/howchen/Work/c/c/test/test_make/a/a.o /home/howchen/Work/c/c/test/test_make/b/b.o /home/howchen/Work/c/c/test/test_make/c/c.o
${Obj}
变量不在*.o
格式上,为什么?我的makefile
中有问题吗
更新
关于Magnus Reftel的帮助,我首先尝试:
OBJ := $(foreach sdir,$(SRC_DIR),$(patsubst $(sdir)/%.c,$(BUILD_DIR)/%.o,$(filter $(sdir)/%.c,$(SRC))))
它的输出如下:
Obj:
/home/howchen/Work/c/c/test/test_make/build/a
/home/howchen/Work/c/c/test/test_make/build/b
/home/howchen/Work/c/c/test/test_make/build/c/a.o
/home/howchen/Work/c/c/test/test_make/build/a
/home/howchen/Work/c/c/test/test_make/build/b
/home/howchen/Work/c/c/test/test_make/build/c/b.o
/home/howchen/Work/c/c/test/test_make/build/a
/home/howchen/Work/c/c/test/test_make/build/b
/home/howchen/Work/c/c/test/test_make/build/c/c.o
输出同时包含PATH
和PATH/*.c
这两项内容,但似乎仍然不正确,因为所有obj文件都只进入文件夹c
我想我已经得到了源文件列表,它存储在$(SRC)
中,因此我尝试:
OBJ := $(patsubst %.c,%.o, $(SRC))
它的输出:
[GNU-GCC]howchen@linux:~/Work/c/c/test/test_make
-> make
SRC DIR: /home/howchen/Work/c/c/test/test_make/a /home/howchen/Work/c/c/test/test_make/b /home/howchen/Work/c/c/test/test_make/c
Build DIR: /home/howchen/Work/c/c/test/test_make/build/a /home/howchen/Work/c/c/test/test_make/build/b /home/howchen/Work/c/c/test/test_make/build/c
Source: /home/howchen/Work/c/c/test/test_make/a/a.c /home/howchen/Work/c/c/test/test_make/b/b.c /home/howchen/Work/c/c/test/test_make/c/c.c
Obj: /home/howchen/Work/c/c/test/test_make/a/a.c /home/howchen/Work/c/c/test/test_make/b/b.c /home/howchen/Work/c/c/test/test_make/c/c.c
Includes: -I/home/howchen/Work/c/c/test/test_make/a -I/home/howchen/Work/c/c/test/test_make/b -I/home/howchen/Work/c/c/test/test_make/c
Obj: /home/howchen/Work/c/c/test/test_make/a/a.o /home/howchen/Work/c/c/test/test_make/b/b.o /home/howchen/Work/c/c/test/test_make/c/c.o
这似乎是正确的,但不是因为我需要在我的构建文件夹而不是源文件夹中找到输出obj文件
- 如果我的first try语句不正确,问题出在哪里
- 第二种方法是否可以改进?哪种方式获取
最适合我的情况$(OBJ)
- 因为
SRC_DIR
包含一个目录列表,而不仅仅是一个。因此,您匹配的模式是/home/howchen/Work/c/test/test\u make/a/home/howchen/Work/c/test/test\u make/b/home/howchen/Work/c/test/test\u make/c/.c
,这肯定不是您想要的。尝试将patsubst
与foreach
函数组合。类似于
OBJ := $(foreach dir,$(SRC_DIR),$(patsubst $(dir)/%.c,getting/the/correct/build/dir/here/is/left/as/an/excercise/to/the/reader%.o,$(filter $(dir)/%,$(SRC))))
我尝试了你的方法,但我遇到了新问题,我在问题中更新了我的新结果。嗯,你过滤
$(dir)/%。
c,但是foreach
变量名为sdir
。可能是这样吗?我打错了,它应该是过滤器中的sdir
,但仍然存在与SRC\u DIR
相同的问题:BUILD\u DIR
包含一个目录列表。您只需要与特定的sdir
匹配的一个。我倾向于使用a_SRC
和a_BUILD
,然后使用$(每个模块,$(模块),$(patsubst$($(模块)_SRC)/%.c,$($(模块)_BUILD)/%.o,$($(模块)(文件))
或类似方法。@MagnusReftel我对过滤器的必要性有疑问。我有一个类似的规则(产生一个错误),它不是filter
,而是$(SRC)
。为什么这里需要filter
?patsubst
不应该只匹配包含$(dir)
的$(SRC)
元素吗?