Hearner
Hearner

Reputation: 2729

Creating makefile c++ that stores .o to a directory

Here is an example of how my datas are stored :

\Program
     main.cpp
     makefile
     \Part1
          file1.cpp
          file1.h
          file2.cpp
          etc
     \Part2
          file3.cpp
          file4.cpp
          file4.h
          etc..
     \Part3
          file5.cpp
          file5.h
          etc..

     \Objects
          file1.o
          file2.o
          file3.o
          file4.o

I think you understood.

My problem is that whatever I try my makefile does not work

clang: error: no input files

or

Undefined symbols for architecture x86_64:

Well, I tried to learn by myself how to build a makefile. I leant the easiest way like :

all:exe
exe: Objects/file1.o Objects/file2.o Objects/file3.o Objects/file4.o Objects/file5.o .....
     $(CPP) $(LFLAGS) Objects/file1.o Objects/file2.o Objects/file3.o ... -o exe

And then, for each .o I ask the makefile to do like :

Objects/file1.0: Part1/file1.cpp
         $(CPP) $(CFLAGS) -o $(OBJ/file1).o Part1/file1.o

But I keep having this issue :

makefile:XX: warning: overriding commands for target .o' makefile:XX: warning: ignoring old commands for target.o'

For every file

I tried to learn how to build makefile more proprelly but it's quite difficult. I tried many, many things and it doesn't work.

Here is what I mean when I say a proper way to write makefile

ALL_CPP=Part1/*.cpp, Part2/*.cpp, Part3/*.cpp, Part4/*.cpp
CPP_FILES := $(wildcard $(ALL_CPP))
OBJ_FILES = $(patsubst $(ALL_CPP),Objects/%.o,$(CPP_FILES))

main: $(OBJ_FILES)
    g++ -o $@ $^

Objects/%.o: Animal/%.cpp
    g++ $(CFLAGS) -c -o $@ $<
Objects/%.o: Enclos/%.cpp
    g++ $(CFLAGS) -c -o $@ $<
Objects/%.o: Menu/%.cpp
    g++ $(CFLAGS) -c -o $@ $<
Objects/%.o: Zoo/%.cpp
    g++ $(CFLAGS) -c -o $@ $<

But of course it doesn't work.

My question is :

How to create a makefile which would work in an environment like mine (with different subfolder) and which would store the .o in a dedicated folder.

I worked using xcode but unfortunately I want a menu where you can navigate using the arrows which doesn't work on the xcode console.

Upvotes: 2

Views: 62

Answers (1)

Etan Reisner
Etan Reisner

Reputation: 80931

Your second attempt was pretty close.

The problem is with this line

OBJ_FILES = $(patsubst $(ALL_CPP),Objects/%.o,$(CPP_FILES))

The first argument to $(patsubst) is the pattern to match but $(ALL_CPP) isn't a pattern. You want dir/%.c for each directory there. You could make that list of patterns if you really wanted to but there's a better way to do it.

You really have two transformations here. One to replace any leading directory with Objects and one to replace .cpp with .o.

So do them separately.

Use a Substitution Reference for the first part:

OBJ_FILES := $(CPP_FILES:.cpp=.o)

and the notdir and addprefix file name functions for the second part:

OBJ_FILES := $(addprefix Objects/,$(notdir $(OBJ_FILES))

and that should make things work.

Upvotes: 3

Related Questions