How do I make a makefile with a source folder? - makefile

I want to make a modular makefile with a PATH parameter but I can't figure out how.
This is what I had before:
CC=
CFLAGS=-c -stack-protect
LDFLAGS=
SOURCES=
SSOURCES=
OBJECTS=$(SOURCES:.cpp=.o)
SOBJECTS=$(SSOURCES:.s=.o)
DEBUGFLAGS=-g -DDEBUG
EXECUTABLE=
all: CC += -DNDEBUG
all: $(SOURCES) $(SSOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS) $(SOBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) $(SOBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
.s.o:
$(CC) $(CFLAGS) $< -o $#
debug: CFLAGS += $(DEBUGFLAGS)
debug: $(SOURCES) $(SSOURCES) $(LDFLAGS) $(EXECUTABLE)
$(CC) $(LDFLAGS) $(OBJECTS) $(SOBJECTS) -o $(EXECUTABLE)
clean:
rm -rf *o $(OBJECTS) $(SOBJECTS)
And this is what I'm trying to do more or less:
PATH=
CC=
CFLAGS=-c -stack-protect
LDFLAGS=
SOURCES=./src1 ./src1
SSOURCES=./src1 ./src2
FSOURCES=$(SOURCES:./=$(PATH))
FSSOURCES=$(SSOURCES:./=$(PATH))
OBJECTS=$(SOURCES:.cpp=.o)
SOBJECTS=$(SSOURCES:.s=.o)
DEBUGFLAGS=-g -DDEBUG
EXECUTABLE=
all: CC += -DNDEBUG
all: $(FSOURCES) $(FSSOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS) $(SOBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) $(SOBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
.s.o:
$(CC) $(CFLAGS) $< -o $#
debug: CFLAGS += $(DEBUGFLAGS)
debug: $(FSOURCES) $(FSSOURCES) $(LDFLAGS) $(EXECUTABLE)
$(CC) $(LDFLAGS) $(OBJECTS) $(SOBJECTS) -o $(EXECUTABLE)
clean:
rm -rf *o $(OBJECTS) $(SOBJECTS)
How can I make this work?

I am assuming that the files that the files you want to make .so are in the folder src2 and the files that you want to build and create and executable are in the in the folder src1.
VPATH = src1:src2:objects:include:libs
CFLAGS= -I ./include -Wall -g -stack-protect
LDFLAGS = -lstdc++
# You can append more libs as required.
CC = gcc
target: $(patsubst ./src1/%.c,./objects/%.o,$(wildcard ./src1/*.c)) ./libs/libmylib.so
$(CC) $(patsubst ./src/%.c,./obj_dbg/%.o,$(wildcard ./src/*.c)) $(LDFLAGS) -L ./libs -lmylib -o target
./objects/%.o: ./src/%.c ./include/*.h
#mkdir -p ./objects
$(CC) $(CFLAGS) -c $< -o $#
./libs/libmylib.so: ./src2/%.c ./include/*.h
#mkdir -p ./libs
$(CC) $(CFLAGS) -c $< -o $#
For makefile tutorial, you can check the following link.
http://www.tune2wizard.com/linux-makefiles/

Related

Makefile doesn't recompile when linker script changes

I have a Makefile as follows. make doesn't recompile the program when the linker script riscv32i.ld changes. What do I need to do to add a dependency on that file?
AS=riscv32-unknown-elf-as
CC=riscv32-unknown-elf-gcc
OC=riscv32-unknown-elf-objcopy
CFLAGS=-nostdlib -T riscv32i.ld
MAKEFLAGS += --silent
SOURCES=$(wildcard *.asm)
OBJ=$(patsubst %.asm,%.o, $(SOURCES))
ELF=$(patsubst %.asm,%.elf, $(SOURCES))
HEX=$(patsubst %.asm,%.hex, $(SOURCES))
.PHONY: all clean
all: $(HEX)
$(HEX): %.hex: %.elf
$(OC) -O binary $< $#
$(ELF): %.elf: %.o
$(CC) $(CFLAGS) -o $# $<
$(OBJ): %.o: %.asm
$(AS) -o $# $<
clean:
rm -f *.o *.elf *.hex
Okay I'm an idiot. Just adding riscv32i.ld as a prerequisite to $(ELF) works:
AS=riscv32-unknown-elf-as
CC=riscv32-unknown-elf-gcc
OC=riscv32-unknown-elf-objcopy
CFLAGS=-nostdlib -T riscv32i.ld
MAKEFLAGS += --silent
SOURCES=$(wildcard *.asm)
OBJ=$(patsubst %.asm,%.o, $(SOURCES))
ELF=$(patsubst %.asm,%.elf, $(SOURCES))
HEX=$(patsubst %.asm,%.hex, $(SOURCES))
.PHONY: all clean
all: $(HEX)
$(HEX): %.hex: %.elf
$(OC) -O binary $< $#
$(ELF): %.elf: %.o riscv32i.ld
$(CC) $(CFLAGS) -o $# $<
$(OBJ): %.o: %.asm
$(AS) -o $# $<
clean:
rm -f *.o *.elf *.hex

Why does my Makefile with pattern rules not create debugging symbols for main?

I am using this auto-generated Makefile with pattern rules, that I oviously do not understand yet. I want to create debuggins symbols and then debug main, but it doesn't work. There is a -g flag. Adding $(LDFLAGS) statement above after $(ODIR) does not print one as expcted.
IDIR =./include
CC=g++
CFLAGS = -I$(IDIR)
LDFLAGS = -g
ODIR=./
LIBS=
_OBJ = main.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/%.o: %.c
$(CC) -c -o $# $< $(CFLAGS)
main: $(OBJ)
$(CC) $(LDFLAGS) -o $# $^ $(CFLAGS) $(LIBS)
.PHONY: clean
clean:
rm -f $(ODIR)/*.o
This is the terminal output
g++ -c -o Source.o Source.cpp
g++ -g -o Source Source.o -I./include
Your sources are C++ (.cpp) but your Makefile contains explicit instructions for building C files. Make is therefore falling back to its built in implicit rules.
Also note that by convention those rules use $(CXX) to refer to the C++ compiler, with $(CXXFLAGS) replacing $(CFLAGS), and the -I flag belongs in $(CPPFLAGS):
IDIR =./include
CPPFLAGS = -I$(IDIR)
CXXFLAGS = -g
ODIR=.
LIBS=
_OBJ = main.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/%.o: %.cpp
$(CXX) -c -o $# $(CPPFLAGS) $(CXXFLAGS) $<
main: $(OBJ)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $# $^ $(LIBS)
.PHONY: clean
clean:
rm -f $(OBJ)
If you were to do away with the ODIR handling and use the conventional variable names you could do without the explicit .o: .cpp rule altogether.

How to copy object, binary and elf files to a directory in Makefile?

I am using gcc-arm and I am trying to copy the object files during the build to a separate directory.
OBJS = example.o
OBJDIR = /home/repos/build/
$(OBJDIR)/%.o: %.c
$(CC) -c $(CFLAGS) $< -o $#
$(CC) -MM $(CFLAGS) $< > $*.d
%.o: %.s
$(CC) -c $(CFLAGS) $< -o $#
ELF = main.elf
$(ELF): $(OBJS)
$(LD) $(LDFLAGS) -o $# $(OBJS) $(LDLIBS)
BIN = main.bin
%.bin: %.elf
$(OBJCOPY) -O binary $< $#
If you want to build a target in another directory you have to tell make that's what you want to do. This:
OBJS = example.o
...
$(ELF): $(OBJS)
tells make you want to build a file example.o, which is just a file in the same directory. If you want to build a file in a different directory, you have to ask for it:
OBJDIR = /home/repos/build/
OBJS = $(OBJDIR)example.o

makefile & gcc -c compilation - how to name object files

I'm playing with makefile for class project.
(1) I need to create debug rule. But I don't know how to give specific names to object files that I need (do I need?) to create that debug-enabled executable.
(2)I assume file can be further reduced to fewer lines of code. Could you suggest how?
This is my makefile:
CC = gcc
CFLAGS = -Wall -Wextra -std=c11
OBJ = hospital.o parse.o structure.o description.o patientList.o diseaseList.o
DOBJ = hospital.dbg.o parse.dbg.o structure.dbg.o description.dbg.o patientList.dbg.o diseaseList.dbg.o
all: hospital
hospital: $(OBJ)
$(CC) $^ -o $#
hospital.o: hospital.c structure.h
$(CC) $(CFLAGS) -c $^
parse.o: parse.c parse.h
$(CC) $(CFLAGS) -c $^
structure.o: structure.c structure.h
$(CC) $(CFLAGS) -c $^
patientList.o: patientList.c patientList.h
$(CC) $(CFLAGS) -c $^
diseaseList.o: diseaseList.c diseaseList.h
$(CC) $(CFLAGS) -c $^
description.o: description.c description.h
$(CC) $(CFLAGS) -c $^
debug: $(DOBJ)
$(CC) $^ -o hospital.dbg
hospital.dbg.o: hospital.c
$(CC) $(CFLAGS) -g $# $< -c
parse.dbg.o: parse.c parse.h
$(CC) $(CFLAGS) -g $# $< -c
structure.dbg.o: structure.c structure.h
$(CC) $(CFLAGS) -g $# $< -c
patientList.dbg.o: patientList.c patientList.h
$(CC) $(CFLAGS) -g $# $< -c
diseaseList.dbg.o: diseaseList.c diseaseList.h
$(CC) $(CFLAGS) -g $# $< -c
description.dbg.o: description.c description.h
$(CC) $(CFLAGS) -g $# $< -c
clean:
rm *.o hospital.dbg hospital *~
.PHONY: all clean
Thanks

How to replace parent directory in Makefile

I've the following situation:
SOURCES=home/main.cpp modelChecking/Configuracao.cpp modelChecking/Estado.cpp modelChecking/Formula.cpp modelChecking/ModelChecking.cpp lib/VisitTree.cpp
SUFIX=$(SOURCES:.cpp=.o)
OBJECTS=$(SUFIX)
all: refiner
refiner: $(OBJECTS)
$(CC) $^ -o refiner
home/main.o: home/main.cpp
$(CC) $(CFLAGS) $< -o $#
modelChecking/Configuracao.o: modelChecking/Configuracao.cpp
$(CC) $(CFLAGS) $< -o $#
modelChecking/Estado.o: modelChecking/Estado.cpp
$(CC) $(CFLAGS) $< -o $#
...
...and so on.
As you can see, I have different directories to compile my executable.
Now, I want to put every file .o in the bin/ folder and the variable OBJECT must replace the every parent directory, and I tried different ways:
OBJECTS=$(SUFIX:%/ = bin/)
OBJECTS=$(subst %/,bin/,$(SUFIX))
OBJECTS=$(patsubst %/,bin/,$(SUFIX))
When I use something like this $(subst home/,bin/,$(SUFIX)) it works, because I type the substring "home/", but I need of a regular expression to replace all directories.
And I'll need to change the target too, perhaps the code below will works:
%.o: %.cpp
$(CC) $(CFLAGS) $< -o $#
... But I prefer every target separate
You are looking for SUFIX=$(addprefix bin/,$(notdir $(SOURCES:.cpp=.o)))
The Makefile will look like:
SOURCES=home/main.cpp modelChecking/Configuracao.cpp
SUFIX=$(addprefix bin/,$(notdir $(SOURCES:.cpp=.o)))
OBJECTS=$(SUFIX)
all: refiner
refiner: $(OBJECTS)
$(CC) $^ -o refiner
bin/main.o: home/main.cpp
$(CC) $(CFLAGS) -c $< -o $#
bin/Configuracao.o: modelChecking/Configuracao.cpp
$(CC) $(CFLAGS) -c $< -o $#
However I suggest to use SUBDIRS instead. Create to Makefiles
Makefile
SUBDIRS = bin
.PHONY: subdirs $(SUBDIRS)
subdirs: $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $#
bin/Makefile
SOURCES=../home/main.cpp ../modelChecking/Configuracao.cpp
SUFIX=$(addprefix bin/,$(notdir $(SOURCES:.cpp=.o)))
OBJECTS=$(SUFIX)
all: refiner
refiner: $(OBJECTS)
$(CC) $^ -o refiner
main.o: ../home/main.cpp
$(CC) $(CFLAGS) -c $< -o $#
Configuracao.o: ../modelChecking/Configuracao.cpp
$(CC) $(CFLAGS) -c $< -o $#
This way you will not have to worry about object prefix.

Resources