在Makefile中从$@获取文件名

3

当所有cpp文件在一个目录中时,这个makefile工作得很好。但是在创建子目录后,由于缺少子目录,它无法创建*.o文件:

目录结构

.
├── Makefile
├── README.md
├── src
│   ├── Adventurer
│   │   └── Adventurer.cpp
│   ├── Board
│   │   ├── AdventureTile.cpp
│   │   └── Board.cpp

Makefile

CC := g++ # This is the main compiler
SRCDIR := src
BUILDDIR := build
TARGET := bin/forbidden-island
 
SRCEXT := cpp
SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o))
CFLAGS := -g -Wall
LIB := -lsfml-graphics -lsfml-window -lsfml-system 
INC := -I include


$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT)
# BUILDPATH=$($(BUILDDIR)/%.o) # missing step of creating subdirectories 
# OFILE=$(basename $@)
    @mkdir -p $(BUILDDIR)
    @echo " $(CC) $(CFLAGS) $(INC) -c -o $@ $<"; $(CC) $(CFLAGS) $(INC) -c -o $@ $<

这段代码的一个示例输出如下:
 g++  -g -Wall -I include -c -o build/Board/Board.o src/Board/Board.cpp
 src/Board/Board.cpp: In member function ‘AdventureTile Board::getTile(int, int)’:
 src/Board/Board.cpp:13:1: warning: no return statement in function returning non-void [-Wreturn-type]
}
^
Assembler messages:
Fatal error: can't create build/Board/Board.o: No such file or directory
Makefile:23: recipe for target 'build/Board/Board.o' failed
make: *** [build/Board/Board.o] Error 1

如何更改命令,使其只是o文件的名称而不是完整路径。使用特殊变量$@。

(basename $@) 返回了build/Board/Board,但需要它是board.o。

=============== 解决方案 ===============

Makefile失败是因为子目录没有创建。 行@mkdir -p $(BUILDDIR)需要变成@mkdir -p $(dir $@)来解决这个问题。

1个回答

3

我不太明白你所说的“如何更改命令,使其只是o文件的名称”是什么意思...是哪个命令?

对于一个配方来说,创建的文件必须完全符合$@的值。如果您的配方创建了其他文件,则make会出现问题,无法正常工作。

无论如何,GNU make支持的函数可以在这里找到。你需要的是$(notdir $@)。但是,你甚至不需要那个,因为有目录($(@D))和文件($(@F))的自动变量的变体。


谢谢。我没有意识到这些特殊函数是为GNU make设计的。我以为它们指的是bash的特殊变量。 - jcjunction

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接