Out-of-tree build makefile without automake? - makefile

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)))

Related

How to make N .o files from N .c files using 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.

Makefile multiple targets from same source file, with different flags

I have a binary that I need to build multiple times with different compiler flags. Therefore, I have a Makefile that states something like:
OBJECTS_A := $(addprefix $(OBJFOLDER)/, $(SOURCES:.cpp=.a.o))
OBJECTS_B := $(addprefix $(OBJFOLDER)/, $(SOURCES:.cpp=.b.o))
OBJECTS_C := $(addprefix $(OBJFOLDER)/, $(SOURCES:.cpp=.c.o))
I also define a rule to change the flags for each OBJECTS_x:
$(OBJECTS_B): DEFINES+=-D_B
$(OBJECTS_C): DEFINES+=-D_C
And this is where the problem happens: If I state the targets separately, as:
$(OBJFOLDER)/%.a.o: %.cpp
$(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o $#
$(OBJFOLDER)/%.b.o: %.cpp
$(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o $#
$(OBJFOLDER)/%.c.o: %.cpp
$(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o $#
All works. However, if I merge all rules into one, only the first is evaluated:
$(OBJFOLDER)/%.a.o $(OBJFOLDER)/%.b.o $(OBJFOLDER)/%.c.o: %.cpp
$(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o $#
What I get on a dry run is that only $(OBJFOLDER)/%.a.o objects are build, but on the linking rule each binary requires its objects (and b and c binaries fail to build, therefore).
Any ideas?
Thank you!
You can achieve this using secondary expansion :
.SECONDEXPANSION:
$(OBJFOLDER)/%.o: $$(basename $$*).cpp
$(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c $< -o $#
Note that this is not a very idiomatic way of doing this, a more usual define / call / eval combo can be used to generate rules as in your first solution :
VARIANTS=a b c
DEFINES_FOR_a=
DEFINES_FOR_b=-D_B
DEFINES_FOR_c=-D_C
define make_target =
$$(OBJFOLDER)/%.$(1).o: %.cpp
$$(COMPILER) $$(CFLAGS) $$(INCFOLDER) $$(DEFINES_FOR_$(1)) -c $$< -o $$#
endef
$(eval $(foreach variant,$(VARIANTS),$(call make_target,$(variant))))
Another way is to create symlinks to your source files and compile those with different flags. This way the same one generic pattern rule (OBJFOLDER)/%.o: %.cpp can build all of your targets:
OBJECTS_A := $(SOURCES:%.cpp=$(OBJFOLDER)/%.a.o)
OBJECTS_B := $(SOURCES:%.cpp=$(OBJFOLDER)/%.b.o)
OBJECTS_B := $(SOURCES:%.cpp=$(OBJFOLDER)/%.c.o)
$(OBJECTS_B): DEFINES+=-D_B
$(OBJECTS_C): DEFINES+=-D_C
%.a.cpp : %.cpp
ln -s $< $#
%.b.cpp : %.cpp
ln -s $< $#
%.c.cpp : %.cpp
ln -s $< $#
$(OBJFOLDER)/%.o: %.cpp
$(COMPILER) $(CFLAGS) $(INCFOLDER) $(DEFINES) -c -o $# $<

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.

Makefile static rule syntax explaination

This is a snippet of the makefile code example of static rule :
objects = foo.o bar.o
all: $(objects)
$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $#
what does this means like:
target : %.o : %.c
does this means that target : %.o and %.o : %.c explaining that all the dependency of the target would be generated by %.o rule and the recipe is applied on that and all the dependencies of %.o would be generated by %.c rule and recipe is applied?
Please somebody clarify it:
1.What are the static rule in makefile explain the syntax?
2.Does the recipe is applies on both the %.o and %.c rules?
3.Is it concatenation of target : $(all).o and $(all).o : $(all).c where all contains all the file names without any extension?
Your snippet:
objects = foo.o bar.o
all: $(objects)
$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $#
expands to (after expanding variables):
all: foo.o bar.o
foo.o bar.o: %.o: %.c
$(CC) -c $(CFLAGS) $< -o $#
This is a shorthand for writing:
foo.o: foo.c
$(CC) -c $(CFLAGS) $< -o $#
bar.o: bar.c
$(CC) -c $(CFLAGS) $< -o $#
So, in short, for each target in the target list apply the pattern and create a static rule for the result.

Makefile: Same Rule for multiple Targets

I've some targets (lets say 3). So after the makefile has run, I want to have 3 executable files.
Here's what I've done by now:
CC = gcc
CFLAGS = -Wall -pedantic -ansi
ECHO = server_echo
ECHO_O = echo.o
FOO = server_foo
FOO_O = foo.o
ALL = $(ECHO) $(FOO)
ALL_O = ECHO_O FOO_O
all: $(ALL)
$(ECHO): $(ECHO_O)
$(CC) $(CFLAGS) -o $(ECHO) $(ECHO_O)
$(FOO): $(FOO_O)
$(CC) $(CFLAGS) -o $(FOO) $(FOO_O)
.PHONY: clean
clean:
- rm -f $(ALL)
- rm -f *.o
- rm -f core
%.o: %.c
$(CC) $(CFLAGS) -c $<
.PHONY: mci
mci: clean $(ALL)
There I've a duplicate of rules for the targets $(ECHO) and $(FOO). Is there any way, that I can eliminate the duplication? Something like:
for target, target_o in $(ALL), $(ALL_O)
target: target_o
$(CC) $(CFLAGS) -o target target_o
end for
Or is there another way to solve my Problem?
Thanks for your help
Nothing easier:
$(ECHO): $(ECHO_O)
$(FOO): $(FOO_O)
$(ECHO) $(FOO):
$(CC) $(CFLAGS) -o $# $^
Or you can do away with the variables ECHO_O and FOO_O entirely with a static pattern rule:
$(ECHO) $(FOO): % : %.o
$(CC) $(CFLAGS) -o $# $^
For a bit larger rules, the call function or canned recipes can be useful.
Here is an untested example with the call function:
define COMPILE =
$(CC) $(CFLAGS) -o $(2) $(1)
endef
$(ECHO): $(ECHO_O)
$(call COMPILE,$^,$#)
$(FOO): $(FOO_O)
$(call COMPILE,$^,$#)
Here is an untested example with a canned recipe:
define COMPILE =
$(CC) $(CFLAGS) -o $# $^
endef
$(ECHO): $(ECHO_O)
$(COMPILE)
$(FOO): $(FOO_O)
$(COMPILE)
The examples contain multi-line variables as well as automatic variables.
Just in case, here is a link to the tutorial that I find useful: link.

Resources