G. Ramistella
G. Ramistella

Reputation: 1397

Understanding and modifying slightly this makefile

I have been editing this makefile but it's mostly trial and error.

Basically I have n .c files in the same directory. I want the first one (that has a fixed name) to be compiled and linked using my makefile hacks, that incorporate different .o files in the linking step, and all the other ones to be compiled and linked using only the LIBS (without the other .o files).

This is the 'main' makefile:

MAKEFILE_BASE = ./Build-Assets/Makefile
MAKEFILE_CONTROLLERS = ./Controllers/Makefile

.PHONY: default clean release release-clean

default: release

clean: release-clean

release:
    $(MAKE) -f $(MAKEFILE_CONTROLLERS) # This generates the .o files, and it works well
    $(MAKE) -f $(MAKEFILE_BASE).Release

release-clean:
    $(MAKE) -f $(MAKEFILE_BASE).Release clean

And this is the 'Makefile.Release' that handles the compilation/linking of those .c files.

TARGET = $(notdir $(shell pwd))

LIBS = -lm -lev3dev-c -pthread
D_BIN = Build-Assets

ifeq ($(OS),Windows_NT)
LIBS := $(LIBS) -lws2_32
D_BIN := $(D_BIN)/mingw
endif

D_H = ../../source/ev3
CFLAGS = $(addprefix -I, $(D_H)) -O2 -std=gnu99 -W -Wall -Wno-comment

ifeq ($(OS),Windows_NT)
CC = gcc
else
CC = arm-linux-gnueabi-gcc
endif

ifeq ($(OS),Windows_NT)
E_BIN = .exe
else
E_BIN =
endif

F_BIN = $(TARGET)$(E_BIN)

OBJECTS = $(addprefix $(D_BIN)/, $(patsubst %.c, %.o, $(wildcard *.c))) $(addprefix $(D_BIN)/, $(patsubst %.c, %.o, $(wildcard Controllers/*.c)))

.PHONY: default all clean

default: $(F_BIN)
all: default

$(OBJECTS): $(D_BIN)/%.o: %.c
    $(CC) $(CFLAGS) -c $< -o $@

.PRECIOUS: $(F_BIN) $(OBJECTS)

$(F_BIN): $(OBJECTS)
    $(info    VAR is $@)
    $(CC) $(OBJECTS) -Wall $(LIBS) -o $@

clean:
    -rm -f $(D_BIN)/*.o
    -rm -f $(F_BIN)

This also gives the output file the name of the main folder (though I don't understand where he does that?).

When linking this throws the 'multiple main' error (I don't have the ARM device at hand, so I can't provide the full error).

This is the folder hierarchy so that hopefully I can solve all your doubts..

# Main folder (This is the name that the compiled exe has) 
## Controllers
-- .c & .h files
-- Makefile
## Build-Assets
-- all .o go here to clean up the folders
- Makefile (The one I call)
- main.c (this needs to be compiled with the .o in build-assets, name can be either main or main folder)
- gcheck.c (this needs to be compiled with only the LIBS, name of executable should be filename) 
- ... other .c files, same as gcheck.c 

Upvotes: 0

Views: 37

Answers (1)

MadScientist
MadScientist

Reputation: 100781

Regarding "where the target name as the name of the directory" comes from, it's here:

TARGET = $(notdir $(shell pwd))

This runs the shell command pwd to get the full path of the current directory, then uses notdir to strip off the parent directory. Then the rule to link the executable uses this:

F_BIN = $(TARGET)$(E_BIN)
  ...
$(F_BIN): $(OBJECTS)

Regarding why you get multiple main errors, it's because you added your new .c file with the new main to the same directory and rather than the makefile listing a specific set of source files to compile and link, it uses wildcard to grab all the source files:

OBJECTS = $(addprefix $(D_BIN)/, $(patsubst %.c, %.o, $(wildcard *.c))) $(addprefix $(D_BIN)/, $(patsubst %.c, %.o, $(wildcard Controllers/*.c)))

These $(wildcard *.c) functions will expand to all the *.c files in these directories including any new ones you added. Then they will all be linked into the target, which gives you two different object files containing main.

You'll have to change this to list just the files you want, or put your files somewhere else, or remove your files from the list using make's filter-out function, or something like that.

Upvotes: 1

Related Questions