How to make N .o files from N .c files using makefile? - makefile

I have 2 .c files that defined in the makefile:
SOURCES = main.c \
memory.c
and I want to build 2 .o files using 1 command "make compile-all" (and don't link them), but can't understand how to do this.
I could create var for objective files and add .PHONY command:
OBJS=$(SOURCES:.c=.o)
.PHONY: compile-all
But what should be written next?
I guess it should be something similar with this:
%.o: %.c $(INCLUDES)
$(CC) -c $< $(CFLAGS) -o $#
But there's no way I can succeed.
Thank you in advance!

BASENAME := main
TARGET := $(BASENAME).out
OBJS=$(SOURCES:.c=.o)
%.i: %.c
$(CC) -E $< $(CFLAGS) -o $#
%.asm: %.c
$(CC) -S $< $(CFLAGS) -o $#
%.o: %.c
$(CC) -c $< $(CFLAGS) -o $#
.PHONY: build
build:$(TARGET)
$(TARGET): $(OBJS)
$(CC) $(OBJS) $(CFLAGS) $(PLATFORM_FLAGS) $(LDFLAGS) -o $#
.PHONY: clean
clean:
rm -f $(OBJS) $(TARGET) *.i *.asm $(BASENAME).map
.PHONY: compile-all
compile-all: $(OBJS)
make compile-all creates .o files from all .c files.

Related

How to copy target file to a sub folder in Makefile?

In this Makefile- I want to copy the $(TGT) binary file after compiled to a sub folder(test) in the same directory. How can I include the copy command of the compiled target file in the Makefile?
CC = g++
CFLAGS = -ansi -std=c++11
LIBS = -L/usr/lib -lstdc++
DEPS = foo.cpp
OBJ = foo.o
TGT+=foo
%.o: %.cc $(DEPS)
$(CC) -c $< $(CFLAGS) -o $#
all: $(TGT)
$(TGT): $(OBJ)
$(CC) $^ $(CFLAGS) $(LIBS) -o $#
# TODO: Need to include the copy command for copying TGT to test folder.
clean:
rm -f *.o $(TGT)
Currently the folder structure is-
<foo>
Makefile
foo.cpp
foo.h
<test>
<..Need "foo" inside this folder>
Is there some reason you can't just change the recipe to copy the file?
Change:
$(TGT): $(OBJ)
$(CC) $^ $(CFLAGS) $(LIBS) -o $#
To:
$(TGT): $(OBJ)
$(CC) $^ $(CFLAGS) $(LIBS) -o $#
cp $# test
You can easily add a rule to copy a file:
all: test/$(TGT)
test/$(TGT): $(TGT)
cp $< $#

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

How to move .o on project folder?

I wrote this Makefile to move all .o of the project inside a directory 'obj' in the main folder.
Directories
.:
actor/ lib/ Controller.cpp Controller.h Controller.o doc.txt main.cpp main.o Makefile uno VRP*
./actor:
Customer.cpp Customer.h Customer.o Depot.cpp Depot.h Depot.o Route.cpp Route.h Route.o Vehicle.cpp Vehicle.h Vehicle.o
./lib:
Search.cpp Search.h Search.o Utils.cpp Utils.h Utils.o VRP.cpp VRP.h VRP.o
Makefile
CXX=g++
RM=rm -rf
BIN_NAME=VRP
CPPFLAGS=-s -O2 -std=gnu++11 -Wall
SRCS=$(wildcard *.cpp actor/*.cpp lib/*.cpp)
OBJS=$(subst .cpp,.o,$(SRCS))
all: $(OBJS_DIR) $(BIN_NAME)
$(OBJS_DIR):
mkdir $(OBJS_DIR)
$OBJS_DIR)/%.o : $(SRCS)
$(CXX) $(CPPFLAGS) -c $< -o $#
$(BIN_NAME) : $(OBJS)
$(CXX) -o $# $^
debug:
$(CXX) -g $(CPPFLAGS) -o $(BIN_NAME) $(OBJS)
.PHONY : all clean
clean:
$(RM) $(OBJS) $(OBJS_DIR)
dist-clean: clean
$(RM) $(BIN_NAME)
How can I make it works?
This line $OBJS_DIR)/%.o : $(SRCS) sets the prerequisites of every file that matches $OBJS_DIR)/%.o to all the files in $(SRCS) that's not even close to what you want. (It is also a typo. You are missing the opening ().
You can't write a single rule for what you are trying to do here you need three pattern rules (or one with a vpath/VPATH setup).
$(OBJS_DIR)/%.o: %.cpp
$(CXX) $(CPPFLAGS) -c $< -o $#
$(OBJS_DIR)/%.o: actor/%.cpp
$(CXX) $(CPPFLAGS) -c $< -o $#
$(OBJS_DIR)/%.o: lib/%.cpp
$(CXX) $(CPPFLAGS) -c $< -o $#
That being said you don't actually have any targets that match $(OBJS_DIR)/%.o since the value of $(OBJS) is Controller.o ... actor/Customer.o ... lib/Search.o. To fix that you also need:
OBJS=$(addprefix $(OBJS_DIR)/,$(patsubst %.cpp,%.o,$(notdir $(SRCS))))
$(notdir) to get just the filename from the source files.
$(patsubst) instead of $(subst) just for correctness (subst would have modified a Bar.cpp.cpp file to Bar.o.o).
$(addprefix) to add the $(OBJS_DIR) prefix to the bare object file names.

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.

Out-of-tree build makefile without automake?

Consider the following dead-simple Makefile:
foo: foo.c
$(CC) $(CFLAGS) -o $# $<
And the following directory structure for ~/foo:
Makefile
foo.c
How can I adjust the Makefile such that I can do something like:
/tmp$ make -f ~/foo/Makefile
cc -o foo /home/me/foo/foo.c
I have tried to use $(srcdir), but that seems automake-specific. Is there any other similar variable?
This will do it:
foo: /home/me/foo/foo.c
$(CC) $(CFLAGS) -o $# $<
Or this:
foo: foo.c
$(CC) $(CFLAGS) -o $# $<
vpath %.c /home/me/foo
Or, if you don't want to hard-code the path into the makefile:
foo: foo.c
$(CC) $(CFLAGS) -o $# $<
vpath %.c $(dir $(lastword $(MAKEFILE_LIST)))

Resources