patsubst没有将* .c转换为* .o

时间:2014-01-23 10:34:33

标签: 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/,$(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}变量不是*.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

输出包含PATHPATH/*.c这两件事,似乎仍然不正确,因为所有obj文件仅转到文件夹c

我想我已经有了$(SRC)存储的源文件列表,因此我尝试了:

OBJ := $(patsubst %.c,%.o, $(SRC))

并输出:

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文件而不是源文件夹。

  • 如果我的第一次尝试声明不正确,问题出在哪里?

  • 如果可以改善第二种方式?获取$(OBJ)的方式最适合我的情况?

1 个答案:

答案 0 :(得分:0)

因为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/%.c,这肯定不是您想要的。尝试将patsubstforeach功能结合使用。

的内容
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))))