hi,

i have the following structure in the "simple application":

application_folder
|
|--makefile
|
+-headers
| |
| +----func.h
|
|
+src
| |
| +------ func.c
| +------ main.c
|
|

and here are the contents of the files:

*func.h

float hey(float a, float b);

*func.c

#include "func.h"

float hey(float a, float b)
{
	return a+b;
}

*main.c

#include "func.h"
#include <stdio.h>

int main()
{
	printf("%f\n", hey(4.4,4.4) );


	return 0;
}

and here is the makefile, where i try to use builtin rules to
reduce the size of it

vpath %.c src
vpath %.h headers

CPPFLAGS = -I headers

simple: main.o func.o

main.o: func.h

func.o: func.h

the problem is that when i run gnu-make i only get:

cc  -I headers  -c -o main.o src/main.c
cc  -I headers  -c -o func.o src/func.c

so basically the built in rule for simple is never run.

To verify that there is a default rule for such cases,
i type gmake --print-data-base > gmake.database.txt
and when i read gmake.database.txt i find

# Implicit Rules

%.out:

%.a:

%.ln:

%.o:

%: %.o
#  commands to execute (built-in):
	$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@

so this should work but it doesn't.....:(

any ideas will be appreciated
-nicolas

Dani AI

Generated

Short answer: make did exactly what the manual (and ) says — the built‑in link rule only applies when one of the object files has the same basename as the executable. Your output shows the implicit compile rule ran (make found src/main.c and src/func.c via vpath and produced the .o files), but there was no object named simple.o, so the built‑in “%: %.o” link pattern did not match and no implicit link command was executed.

Fixes (pick one):

  • Add an explicit link recipe so you control how the .o files become the executable. For example, replace the implicit expectation with a small rule (replace names with yours):
OBJS = foo.o bar.o

program: $(OBJS)
    $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)
  • Rename the source that provides the “main” object so it produces simple.o (then the “%: %.o” implicit link rule will apply).
  • Create a rule that produces simple.o (e.g., a tiny wrapper or a symlink), but that is the least recommended approach.

Notes and tips:

  • Prefer the explicit link recipe for multi‑object programs — it makes flags and library order explicit and portable.
  • Use automatic variables ($@, $^, $<) as above to keep recipes compact.
  • To inspect what make would do without running commands, use make -n and to see rule selection use make --debug=v (or make --print-data-base as you already tried).
  • Thanks to for pointing toward the manual — that paragraph explains the implicit rule behavior you observed.

Recommended Answers

All 2 Replies

n is made automatically from n.o by running the linker (usually called ld) via the C compiler. The precise command used is ...

This rule does the right thing for a simple program with only one source file. It will also do the right thing if there are multiple object files (presumably coming from various other source files), one of which has a name matching that of the executable file....

In more complicated cases, such as when there is no object file whose name derives from the executable file name, you must write an explicit command for linking.

from http://www.gnu.org/software/make/manual/make.html#Implicit-Rules

thanks vijayan for your assistance!
sorry for asking the RTFM kind of question...:(

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.