0

I have some problems trying to put .o files into a separate directory (/build). Actually, my sources (in /src) contain some subdirectories, and my Makefile only create the .o of the .cpp contained at the first "level". The other .o are just ignored, so, the target cannot be created. In my /src directory, I have "three levels" (src/first/second/). Here's the code of the Makefile :

CC=g++
CFLAGS=-W -Wall -ansi -pedantic -s -O3 -Os -std=c++11 -fpermissive
LDFLAGS= -lboost_system -lboost_regex

SRCDIR=src
HEADDIR=include
LIBDIR=build
BINDIR=bin

BIN=LTN
SRC = $(wildcard src/*.cpp src/*/*.cpp src/*/*/*.cpp)
OBJ = $(patsubst %.cpp,$(LIBDIR)/%.o,$(SRC))

all: $(BIN)

LTN: $(OBJ)
    $(CC) -o $(BINDIR)/$@ $^ $(LDFLAGS)

$(LIBDIR)/$(SRCDIR)/%.o: $(SRCDIR)/%.cpp $(HEADDIR)/%.h
    $(CC) -o $@ -c $< $(CFLAGS)

.PHONY = clean
NightShadeQueen
  • 3,284
  • 3
  • 24
  • 37
Marco Montalto
  • 215
  • 5
  • 15
  • I'm assuming you mean that make doesn't know how to build the `.o` files for source files more than one level under `$(SRCDIR)`? If that's the case that's because you only have the one pattern rule for files in `$(SRCDIR)`. – Etan Reisner Mar 24 '15 at 15:30
  • Yes, that's exactly what I meant :) Do I have to write one rule for each src level? – Marco Montalto Mar 24 '15 at 19:13
  • At the simplest, yes. There are probably more complicated solutions (possibly using `vpath`) that might allow you to avoid that but whether they are worth it is a different question. – Etan Reisner Mar 24 '15 at 19:16

1 Answers1

1

You can try this:

CC=g++
CFLAGS=-W -Wall -ansi -pedantic -s -O3 -Os -std=c++11 -fpermissive
LDFLAGS= -lboost_system -lboost_regex

SRCDIR=src
HEADDIR=include
LIBDIR=build
BINDIR=bin

BIN=LTN
SRC=$(shell find . -name '*.cpp')
TMP=$(subst $(SRCDIR),$(LIBDIR), $(SRC))
OBJ=$(patsubst %.cpp,%.o,$(TMP))

all: $(BIN)

LTN: $(OBJ)
    @[ ! -d $(BINDIR) ] & mkdir -p $(BINDIR)
    $(CC) -o $(BINDIR)/$@ $^ $(LDFLAGS)

$(LIBDIR)/%.o: $(SRCDIR)/%.cpp  
    @[ ! -d $(dir $@) ] & mkdir -p $(dir $@)
    $(CC) -o $@ -c $< $(CFLAGS)

.PHONY = clean  
edwardramsey
  • 363
  • 2
  • 12
  • Thank you for your answer! I just tried it and it creates the .o in /src folder, not in /build :( – Marco Montalto Mar 24 '15 at 19:11
  • try this again and give me feedback~ – edwardramsey Mar 25 '15 at 03:13
  • Thank you again! make created all the .o at the correct place, but I obtained some errors : Undefined symbols for architecture x86_64: ...........................(a message for almost each class).................... NOTE: a missing vtable usually means the first non-inline virtual member function has no definition. "_main", referenced from: implicit entry/start for main executable ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) make: *** [LTN] Error 1 – Marco Montalto Mar 25 '15 at 07:30
  • you should use $(LIBDIR)/%.o: $(SRCDIR)/%.cpp instead. – edwardramsey Mar 25 '15 at 13:21
  • These's still just one detail I corrected in the code. At $(LIBDIR)/%.o: $(SRCDIR)/%.cpp, I added $(HEADDIR)/%.h to be sure make checks if the .h have been changed. Doing that, I got "cannot find rule for main.o" (because main.h is missing). To solve, I created an empty main.h (I know it's not the top!!) and now it nicely works :) – Marco Montalto Mar 26 '15 at 13:40