Maria Ines Parnisari
Maria Ines Parnisari

Reputation: 17506

a couple of Makefile issues

I've got this Makefile:

CFLAGS = -c -Wall
CC = g++
EXEC = main
SOURCES = main.cpp listpath.cpp Parser.cpp
OBJECTS = $(SOURCES: .cpp=.o)
EXECUTABLE = tp

DIR_SRC = /src/
DIR_OBJ = /obj/

all: $(SOURCES) $(OBJECTS)

$(EXECUTABLE): $(OBJECTS)
    $(CC) $(CFLAGS) $(OBJECTS) -o $@

.cpp.o:
    $(CC) $(CFLAGS) $< -o $@

clean:
    rm $(OBJECTS) $(EXECUTABLE)

Note this:

The error I get is:

No rules to build "main.cpp", necessary for "all". Stopping.

Help!

Upvotes: 0

Views: 126

Answers (2)

Beta
Beta

Reputation: 99172

All right, from the top:

CFLAGS = -c -Wall
CC = g++
# EXEC = main never used, not needed
SOURCES = main.cpp listpath.cpp Parser.cpp

So far, so good. Note that this SOURCES doesn't mention DIR_SRC, so we'll have to make that connection later (and $(DIR_SRC)$(SOURCES) won't work, because the path must be appended to each member of the list). But OBJECTS really needs paths (e.g. /obj/main.o):

OBJECTS = $(patsubst %.cpp, $(DIR_OBJ)%.o, $(SOURCES))
EXECUTABLE = tp

DIR_SRC = /src/
DIR_OBJ = /obj/

(Personally I don't like putting the trailing slash in the variable, but it's a matter of taste.) The first target is the default target, so it should build what you actually want built:

all: $(EXECUTABLE)

Don't worry about listing the sources as prerequisites; they will sort themselves out later.

$(EXECUTABLE): $(OBJECTS)
    $(CC) $(CFLAGS) $^ -o $@  # <-- note the automatic variable $^

The .cpp.o convention doesn't really work here; we'll have to spell it out. And we must tell Make to search $(DIR_SRC) for .cpp files:

$(OBJECTS): $(DIR_OBJ)%.o: %.cpp $(DIR_OBJ)
    $(CC) $(CFLAGS) $< -o $@

$(DIR_OBJ):
    mkdir $@

vpath %.cpp $(DIR_SRC)

And tell Make that clean is not a real target, just to be safe:

.PHONY: clean
clean:
    rm $(OBJECTS) $(EXECUTABLE)

EDIT:

I shouldn't have attempted so much in one step. Let's try something simpler:

$(DIR_OBJ)%.o: $(DIR_SRC)%.cpp $(DIR_OBJ)
    $(CC) $(CFLAGS) $< -o $@

Upvotes: 1

Some programmer dude
Some programmer dude

Reputation: 409442

Edit the SOURCES to include the source directory (e.g. src/main.cpp etc.).

For the object files, consider something like this:

OBJECTS = $(subst src/,obj/,$(SOURCES:%.cpp=%.o))

# ...

all: $(SOURCES) build

.PHONY: build
build: pre_build $(EXECUTABLE)

.PHONY: pre_build
pre_build: obj

obj:
    -mkdir obj

$(EXECUTABLE): $(OBJECTS)
    $(CC) $(CFLAGS) $^ -o $@

Upvotes: 0

Related Questions