从 Makefile 中的 $@ 获取文件名

Get filename from $@ in Makefile

本文关键字:获取 文件名 Makefile 中的      更新时间:2023-10-16

当所有 cpp 文件都在一个目录中时,此生成文件效果很好。 创建子目录时,它无法创建 *.o 文件,因为它缺少子目录:

目录结构

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

生成文件

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但需要它来登机。

====

=========== 解决方案 =================生成文件失败,因为未创建子目录。 这条线@mkdir -p $(BUILDDIR)需要变得@mkdir -p $(dir $@)来解决这个问题。

我真的不明白你的意思是如何更改命令,使其只是 o 文件的名称......哪个命令?

配方创建一个不完全是$@值的文件是不正确的。 这就是 make 期望您创建的内容,如果您的配方创建其他文件,则无法正常工作。

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