Make file empty dependency - makefile

This is make file snippen:
SECONDEXPANSION:
/tmp/foo.o:
%.o: $$(addsuffix /%.c,foo bar) foo.h
#echo $^
My question was if a target has an empty list and no explicit rule then the next line following a pattern rule, like in this case "the target foo.o : has no dependency list and no explicit rule " then the make will automatically goes for %.o: rule or it ignores. This is what I want to know please explain?

Related

Behavior of Match-Anything Pattern Rules in makefile

Let's say my source is test.c:
#include <stdio.h>
int main()
{
printf("%s\n", "hi");
}
I want the executable called test to be created in a folder called bin. So my makefile is:
all:bin/test
When I execute make, I expect the following built-in rule to happen:
%: %.c
# recipe to execute (built-in):
$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $#
because the target % should match bin/test and since test.c exists, it should execute the recipe. However, make says: No rule to make target 'bin/test', needed by 'all'. Stop.
Why does this happen?
If % matches bin/test, then the prerequisite is bin/test.c, which does not exist. So Make rejects that implicit rule in its search for a rule to build bin/test. It finds no other rule which fits the bill, and tells you so.
If you try to build test, or move test.c into bin/, then Make will use this rule.
If you want to build binaries in bin/ from sources in the working directory, you can write your own pattern rule, something that looks like:
bin/%: %.c
...

Is my understanding correct for the first rule of the makefile?

I'm learning make, and try to understand the following makefile from Prerequisite-Types
OBJDIR := objdir
OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o)
$(OBJDIR)/%.o : %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
all: $(OBJS)
$(OBJS): | $(OBJDIR)
$(OBJDIR):
mkdir $(OBJDIR)
The first rule confuses me. It's to be firstly applied. Since $(OBJDIR) is not there, the last rule will be applied to mkdir objdir. Then, since there's nothing in the newly created directory, there's no stem.o, and correspondingly, no stem.c So the prerequisites and recipes seem to be meaningless.
The only thing that the first rule does is to make a directory, which seems to be unreal.
The first rule is a pattern rule, so it cannot be the default rule; it will not be the first applied unless you specify e.g. make thing.o.
The first rule might not do what you expect. The recipe is $(COMPILE.c) $(OUTPUT_OPTION) $<, but you don't assign a value to OUTPUT_OPTION in the makefile; unless you provide a value from outside (e.g. make thing.o OPTION_OUTPUT=...) this recipe has no special instructions about where to put the file it builds, it has never heard of objdir/, and will use the compiler's default which is probably the working directory.
The last rule will build objdir (if objdir does not already exist, and if Make invokes that rule). The command make objdir will work perfectly. If you try to build one of the object files listed in OBJS, Make will construct the directory (if the directory does not exit) -- not because it needs a place to put the file, but because $(OBJDIR) is a prerequisite of every member of $(OBJS), according to the third rule. It will not construct the directory if you try to build objdir/thing.o, because $(OBJDIR) is not a prerequisite of that target. You think Make should build it because it is obviously needed? Well, Make isn't that smart.
The first rule has a prerequisite pattern %.c, and the recipe looks for the source file in the working directory, not in any newly constructed subdirectory. If there is no such source file in the working directory, Make will not run that rule.
I don't really follow your logic.
The first rule in your makefile is this:
all: $(OBJS)
so the default goal for this makefile (if you don't specify one on the command line) is all.
all depends on all the .o files. All the .o files have an order-only dependency on the directory. So, first the directory is created, then the .o files are created, then all is done (there is no recipe here to create a program or library or anything out of those .o files).

make: Reference stem of target in prerequisite without patterns

I have a project with many .c and .s files. Writing out individual rules for each is a hassle, what I had before for my .c files was this.
$(OBJ_DIR)/%.o : %.c %.h
*recipe*
While this works fine for projects with just c source files, it will not work with a project with assembly files.
I've read through the documentation for make on gnu.org and have not been able to figure out a way to reference the stem of the target name or even the whole target name in the prerequisites without using patterns. I would like to do something along these lines.
$(C_OBJ_FILES) : %.c %.h # Where % WOULD be the stem of the target name
$(AS_OBJ_FILES) : %.s # Where % WOULD be......
I currently have separate directories for objects compiled from assembly sources and objects compiled with c sources. While this works, I'd like to have them in the same directory. I also considered creating a hidden symlink that points to the objects directory that I could use to differentiate assembly and c source files, but again, that doesn't solve my question.
Edit: I am not looking for a work around that avoids referencing the target name, since being able to reference it in the prerequisites would help several other parts of my Makefiles. If this is definitely not possible, then say so and that'll answer my question.
What you are looking for is probably static pattern rules:
C_OBJ_FILES = $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard *.c))
AS_OBJ_FILES = $(patsubst %.s,$(OBJ_DIR)/%.o,$(wildcard *.s))
# static pattern rule for C files
$(C_OBJ_FILES) : $(OBJ_DIR)/%.o : %.c %.h
<recipe>
# static pattern rule for assembly files
$(AS_OBJ_FILES) : $(OBJ_DIR)/%.o : %.s
<recipe>
In your recipes you can use $#, $< and $*; they will respectively expand as the target (the object file), the first prerequisite (the C or assembly source file) and the stem (the base name of the C or assembly source file). Example:
# static pattern rule for C files
$(C_OBJ_FILES) : $(OBJ_DIR)/%.o : %.c %.h
#echo '[CC] $*' && \
$(CC) -c $(CFLAGS) $(INCLUDES) $< -o $#
The standard approach is:
all: x.o y.o z.o
%.o: %.s
*recipe*
%.o: %.c
*recipe*
And then makedepend can fill in transitive deps, such as C headers. It's not "a hassle" to "write out individual rules", you just let the program do it, automatically.
Your remark about "avoiding referencing the target name" ($#) is just bizarre, in a make context. You make it sound like you'd rather not express the DAG in a Makefile at all, that you'd rather write a tediously repetitive Bourne script that describes your build process. I encourage you to embrace make patterns, they're a natural way to express the problem, and will help you describe your requirements in just a few lines of code.

Simple Makefile reporting circular dependency -- possibly from suffix rules?

I'm using mingw32-make and attempting to create a simple rule to run windres to include an icon for a Windows executable.
The structure consists of a simple C program in a.c, an a.rs file containing only the line:
1 ICON "a.ico"
..the icon file itself, and the Makefile.
The Makefile:
CC = gcc
all: a
%.rc.o: %.rc
windres $< $#
a: a.o a.rc.o
The output I get:
>make
gcc -c -o a.o a.c
make: Circular a.rc <- a.rc.o dependency dropped.
windres a.rc a.rc.o
gcc a.o a.rc.o -o a
The output files are all created correctly, but I can't figure out how to write the .rc->.rc.o rule to get rid of the circular dependency message. From what I can tell it is interpreting it as a suffix rule where %.rc.o indicates the rule is intended to create %.rc from %.o, thus the dependency on a %.rc is circular...
I can use .rco instead of .rc.o and it doesn't generate this error, but I prefer keeping it to the compound extension if possible.
Is there any way to create a pattern rule giving outputs with an extension of the .ext1.ext2 sort, without having it be interpreted as a suffix rule?
The problem is that make has a built-in rule to build an executable file foo from an object file foo.o. In your situation make matches the rule %.rc.o for the target a.rc.o. Then it tries to find a rule that will update a.rc and when it looks it sees that a.rc.o will exist, and so it matches the rule % : %.o, but then realizes that it has a circular dependency for a.rc.o : a.rc and a.rc : a.rc.o.
The simplest thing to do is define an explicit rule for a.rc so that it won't look for a pattern rule:
a.rc : ;
Alternatively, if you don't need the built-in rule to create an executable from an object file, you can cancel it by adding:
%: %.o
with no recipe.

generating multiple executables from the same sources

To build multiple executables from the same source, I have to translate every source file with different Compiler Switches. For every variant, I have a set of defines to be set. I want to store the resulting object files into different subfolders. I have a variable, keeping all object file from all variants. Now I have problems to define a proper static rule to build the object files from the sources:
SOURCEEXT=.c
ALL_OBJECT_FILES := abcdefg/cctalkio.o tollcoll/cctalkio.o
source-from-object = $(addsuffix $(SOURCEEXT),$(basename $(notdir $(1))))
$(ALL_OBJECT_FILES): %.o: $(call source-from-object,%.o)
#echo $*.o
when I run make abcdefg/cctalkio.o, I get:
make: *** No rule to make target 'abcdefg/cctalkio.c', needed by 'abcdefg/cctalkio.o'. Schluss.
The same, when I simpify the rule to:
abcdefg/cctalkio.o: %.o: $(call source-from-object,%.o)
#echo $*.o
But when I change the rule to:
abcdefg/cctalkio.o: %.o: $(call source-from-object,abcdefg/cctalkio.o)
#echo $*.o
I get abcdefg/cctalkio.o as Output. So the stem seems to be abcdefg/cctalkio, thus %.o should be the same as abcdefg/cctalkio.o. But why is make behaving different in both cases?
When I "debug" the source-from-object function:
debug:
#echo $(call source-from-object,/abcdefg/cctalkio.o)
I get the expected result cctalkio.c, so it seem like the function is working.
Your $(call) in the prereq is happening immediately and so your function is actually being passed %.o (not the matched result as you expected).
You would have to use something like:
.SECONDEXPANSION:
abcdefg/cctalkio.o: %.o: $$(call source-from-object,%.o)
...
to get what you want I believe.
Alternatively you could probably loop over your object files and statically give them the correct prerequisites and just let the static pattern rule supply the body.

Resources