Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get filename from $@ in Makefile

Tags:

c++

bash

makefile

this makefile works great when all the cpp files are in one directory. upon creating subdirectories it fails to create the *.o files because its missing subdirectories:

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. using the special variable $@.

(basename $@) returned build/Board/Board but need it to be board.o

=============== Solution ===============

The Makefile was failing because the subdirectories were not created. the line @mkdir -p $(BUILDDIR) needed to become @mkdir -p $(dir $@) to remedy this.

like image 461
jcjunction Avatar asked Nov 06 '25 03:11

jcjunction


1 Answers

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?

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.

In any event the functions GNU make supports are available here. The one you want is $(notdir $@). However you don't even need that, because there are variants of the automatic variables for the directory ($(@D)) and file ($(@F)).

like image 109
MadScientist Avatar answered Nov 08 '25 19:11

MadScientist



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!