0
votes

Im using this code in the makefile, all is going good but the last line. My code folder looks like this:

Project/bin -> For executable files

Project/build -> For .o files

Project/include -> For .hpp files

Project/src -> For .cpp files

Makefile path: Project/Makefile

# Compiler #
CC       = g++
DEBUG    = -g
LFLAGS   =
CFLAGS   = -Wall

# Directories #
SRCDIR   = src/
INCDIR   = include/
BUILDDIR = build/
BINDIR   = bin/

# Objects #
OBJ_NAMES = main.o dfa.o dfaException.o state.o
OBJS       = $(addprefix $(BUILDDIR), $(OBJ_NAMES))

# Output #
TARGET = $(BINDIR)pract3

$(TARGET): $(OBJS)
    $(CC) $(CCFLAGS) $(LFLAGS) $(OBJS) -o $(TARGET)

$(BUILDDIR)%.o: $(SRCDIR)%.cpp
    $(CC) $(CCFLAGS)  $(LFLAGS) -c $< -o $(BUILDDIR)$($(notdir  $<):.cpp=.o)

The problem is in "$(BUILDDIR)$($(notdir $<):.cpp=.o)". What Im trying to do here is:

  1. $< contains "src/mysrc.cpp" so with $(notdir $<) I get "mysrc.cpp"
  2. Now, I want to change the file extension to .o, so I use $($(notdir $<):.cpp=.o) And I should get "mysrc.o". But this part is not working:

    g++ -c src/main.cpp -o build/

    Assembler messages:

    Fatal error: can't create build/: Permission denied

    Makefile:25: recipe for target 'build/main.o' failed

    make: *** [build/main.o] Error 1

  3. I use $(BUILDDIR) To get "build/mysrc.o"

Why does $($(notdir $<):.cpp=.o) somehow delete the file name ?

And now that Im here. I've learned to use make some days ago. Is there something that I should improve here ?

1

1 Answers

2
votes

$(notdir) operates on strings.

$(X:Y=Z) operates on the value of the X variable.

So follow your expansions when $< is src/mysrc.cpp

$($(notdir  $<):.cpp=.o)

becomes

$(mysrc.cpp:.cpp=.o)

Is that how you would write that?

No, you would write $(<:.cpp=.o).

So invert your operations.

 $(notdir  $(<:.cpp=.o))

Or, even better and simpler than that just use $@ since that's the target you are building and what you want to create.

$(CC) $(CCFLAGS)  $(LFLAGS) -c $< -o $@