0

Edit: This is the final Makefile, it build all .o files in build dir and produce one executable.

CXX         = g++
CXXFLAGS    = -g -Wall

SRC_DIR     = ./src
BUILD_DIR   = ./build
        
SRC         = $(wildcard $(SRC_DIR)/*.cpp)
OBJS        = $(SRC:$(SRC_DIR)/%.cpp=$(BUILD_DIR)/%.o)
LIBS        = -lusb-1.0 -lpulse-simple -lpulse
EXEC        = AndroidMicLinux


all: $(EXEC)

$(BUILD_DIR)/%.o : $(SRC_DIR)/%.cpp
    $(CXX) $(CXXFLAGS) -o $@ -c $<

$(EXEC) : $(OBJS)
    $(CXX) -o $(EXEC) $(OBJS) $(LIBS)

clean:
    rm -f $(OBJS) $(EXEC)
Lacoudasse
  • 19
  • 6
  • Where is `$(OBJ)` supposedly coming from ? You have it as a dependency of `$(EXEC)` – WhozCraig Sep 17 '22 at 00:10
  • @WhozCraig I want to build them in build dir. From .cpp files in src dir – Lacoudasse Sep 17 '22 at 00:22
  • Great. Didn't answer my question. Look at your post. Where is `OBJ` defined ? From what I see there is no OBJ. There is only OBJS. Granted, I don't generally keep up on the comings and goings of what 'implicit' things gnumake adds to their management tool in an attempt to dumb down the usage of said same, but I don't recall ever seeing OBJ as being implicitly defined in any circumstance. So again, where does `$(OBJ)` come from? I suspect [this question](https://stackoverflow.com/questions/5178125/how-to-place-object-files-in-separate-subdirectory) may be helpful, btw. – WhozCraig Sep 17 '22 at 00:27
  • @WhozCraig yes my bad I forgot the "'S". Now I have this result from make: "Aucune règle pour fabriquer la cible « build/accessory.o », nécessaire pour « AndroidMicLinux ». Arrêt." Thank for the question but I don't understand the syntax – Lacoudasse Sep 17 '22 at 13:38
  • It's a good idea to use `export LC_ALL=C` before invoking builds so that error messages use the default locale. – MadScientist Sep 17 '22 at 14:15

1 Answers1

1

There are many issues with this makefile. Most of them have to do with expansion of variables. If you simply visualize the expansion of variables you'll likely see the problems. Remember that make is just doing text substitution to expand variables. There's no "magic" happening here.

So for example:

SRC     = $(wildcard $(SRC_DIR)/*.cpp)

Let's suppose that you have the files ./src/foo.cpp and ./src/bar.cpp. That means that $(SRC) will expand to those two files. Fine. Then you have:

OBJS    = $(BUILD_DIR)/$(notdir $(SRC:.cpp=.o))

How does this work? First we expand BUILD_DIR:

OBJS    = ./build/$(notdir $(SRC:.cpp=.o))

Then we expand $(SRC:.cpp=.o) which gives ./src/foo.o ./src/bar.o. Then the notdir is applied which gives foo.o bar.o. That's substituted for the function, so the result is:

OBJS    = ./build/foo.o bar.o

You can see this is wrong. You can't just stick a string before a function and expect that string to be appended to every word of the function! You need to explicitly tell make that you want to do that. Probably you want something like this instead:

OBJS    = $(SRCS:$(SRC_DIR)/%.cpp=$(BUILD_DIR)/%.o)

Next this rule:

%.o : %.c
        $(CC) -o $(OBJS) -c $(SRC)

First the recipe is wrong. What does this expand to?

g++ -o ./build/foo.o ./build/bar.o -c ./src/foo.cpp ./src/bar.cpp

Clearly that's a totally invalid compile line. You want just the one object file and source file not all of them. This is what automatic variables are for:

%.o : %.c
        $(CC) -o $@ -c $<

However this is still wrong: this pattern rule will never match. Why? Because when make tries to build ./build/foo.o the % pattern matches the string ./build/foo. So when make looks to see if the prerequisite %.c exists it will check for ./build/foo.c. First, your filenames end in .cpp not .c so this should be %.cpp. But beyond that, the source files are in a different directory than the destination files so you can't just use %. You have to write it like this:

$(BUILD_DIR)/%.o : $(SRC_DIR)/%.cpp
        $(CC) -o $@ -c $<

I'll also point out that convention uses CC for the C compiler; if you're compiling C++ you should be using the CXX variable. Also you set a FLAGS variable but your compile rule doesn't actually use it; you can't just put it in the link rule. And, for C++ compiler flags the convention is to use CXXFLAGS as the variable.

MadScientist
  • 92,819
  • 9
  • 109
  • 136
  • Thank a lot for this response. I made all change and the generation of all .o file seems to went well but when it come to build the final executable, I get a lot of indefinite reference – Lacoudasse Sep 17 '22 at 15:52
  • Well, look at the link command line and see if anything is missing. If you can't figure it out, edit your question and add the link command line and at least a sampling of the errors you get. We can't help without info. – MadScientist Sep 17 '22 at 16:22
  • But did you follow my first advice, which is to _look_ at the link command line? If you compare the command line make invokes to the one that you say works you should quickly see the problem and be able to fix your makefile. – MadScientist Sep 17 '22 at 17:14
  • Damn I'm so dumb lol, but it's weird that "$(CC) $(CXXFLAGS) -o $@ -c $<" worked – Lacoudasse Sep 17 '22 at 17:18
  • I don't know what you mean. Your makefile uses `$(CXX)` in the compile line, not `$(CC)`. – MadScientist Sep 17 '22 at 18:24
  • yes because I modified the post but before, it was `$(CC)` – Lacoudasse Sep 17 '22 at 18:28
  • Yes but before you had `CC = g++` as well. Where's the confusion? – MadScientist Sep 17 '22 at 18:36
  • Well no, I retested again and it's work with `CC`. You can [test](https://github.com/wiiznokes/AndroidMicLinux/) if you want ahah. – Lacoudasse Sep 17 '22 at 19:20
  • Oh I see what you mean. You can read the man page for GCC to understand this: _GCC recognizes files with [suffixes like `.cpp`] and compiles them as C++ programs even if you call the compiler the same way as for compiling C programs (usually with the name gcc)._ That can't work for link lines because you're linking a bunch of `.o` files together and there's no way for the front-end to know what language the source files used to build these `.o` files were written in. They could even be written in multiple different languages. – MadScientist Sep 17 '22 at 20:25
  • Oh okk, that make sens – Lacoudasse Sep 17 '22 at 20:39