简体   繁体   English

从 Makefile 中的 $@ 获取文件名

[英]Get filename from $@ in Makefile

this makefile works great when all the cpp files are in one directory.当所有 cpp 文件都在一个目录中时,这个 makefile 工作得很好。 upon creating subdirectories it fails to create the *.o files because its missing subdirectories:创建子目录时,它无法创建 *.o 文件,因为它缺少子目录:

Directory Structure目录结构

.
├── 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 $@ $<

an example output of this code is:此代码的示例输出是:

 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

how can the command be changed so that it is just the name of the o file and not the full path.如何更改命令,使其只是 o 文件的名称而不是完整路径。 using the special variable $@.使用特殊变量 $@。

(basename $@) returned build/Board/Board but need it to be board.o (basename $@)返回build/Board/Board但需要它是 board.o

=============== Solution =============== ============== 解决方法==============

The Makefile was failing because the subdirectories were not created. Makefile 失败,因为未创建子目录。 the line @mkdir -p $(BUILDDIR) needed to become @mkdir -p $(dir $@) to remedy this.@mkdir -p $(BUILDDIR)需要变成@mkdir -p $(dir $@)来解决这个问题。

I don't really understand what you mean by how can the command be changed so that it is just the name of the o file ... which command?我真的不明白你的意思是如何更改命令以使其只是 o 文件的名称......哪个命令?

It's not correct for a recipe to create a file which is not exactly the value of $@ .创建一个不完全是$@值的文件的配方是不正确的。 That's what make expects you to create and things won't work correctly if your recipe creates some other file.这就是 make 期望您创建的内容,如果您的配方创建了其他文件,则事情将无法正常工作。

In any event the functions GNU make supports are available here .在任何情况下,GNU make 支持的功能都可以在这里使用 The one you want is $(notdir $@) .你想要的是$(notdir $@) However you don't even need that, because there are variants of the automatic variables for the directory ( $(@D) ) and file ( $(@F) ).但是,您甚至不需要它,因为目录( $(@D) )和文件( $(@F) )有自动变量的变体。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM