2

I wanted to write some Makefile for testing C code via Unity test framework. However when I want to test it I get the message make: *** No rule to make target 'unity_build/results/test_unity_dumb_example.unity_res', needed by 'unity_test'. Stop. . I can not figure out what is wrong because there is the rule for files that match the pattern: $(UNITY_PATHR)%.unity_res:.

Here is beginning of my Makefile:

UNITY_PATHU = ${UNITY_INSTALL_DIR}/
UNITY_PATHS = src/
UNITY_PATHS += src/unity_dumb_example/
UNITY_PATHT = unity_test/
UNITY_PATHB = unity_build/
UNITY_PATHD = unity_build/depends/
UNITY_PATHO = unity_build/objs/
UNITY_PATHR = unity_build/results/

UNITY_BUILD_PATHS = $(UNITY_PATHB) $(UNITY_PATHD) $(UNITY_PATHO) $(UNITY_PATHR)

# Tell compiler where to look for all test files
UNITY_SRCT = $(wildcard $(UNITY_PATHT)*.c)

UNITY_COMPILER=gcc -c
UNITY_LINKER=gcc
UNITY_DEPEND=gcc -MM -MG -MF
UNITY_CFLAGS=-I. -I$(UNITY_PATHU) -I$(UNITY_PATHS) -DTEST

UNITY_RESULTS = $(patsubst $(UNITY_PATHT)test_%.c,$(UNITY_PATHR)test_%.unity_res,$(UNITY_SRCT))

unity_test: $(UNITY_BUILD_PATHS) $(UNITY_RESULTS)
    @echo "-----------------------\nIGNORES:\n-----------------------"
    @echo `grep -s IGNORE $(UNITY_PATHR)*.unity_res`
    @echo "-----------------------\nFAILURES:\n----------------------"
    @echo `grep -s FAIL $(UNITY_PATHR)*.unity_res`
    @echo "\nDONE"

$(UNITY_PATHR)%.unity_res: $(UNITY_PATHB)%.out
    ./$< > $@ 2>&1

In GNU make manual I have read

The target is a pattern for matching file names; the ‘%’ matches any nonempty substring, while other characters match only themselves.

I do not understand why make complains because there is no misspell.

EDIT: After full clean the output is as follows:

mkdir -p unity_build/
mkdir -p unity_build/depends/
mkdir -p unity_build/objs/
mkdir -p unity_build/results/
make: *** No rule to make target 'unity_build/results/test_unity_dumb_example.unity_res', needed by 'unity_test'.  Stop.

All the needed paths exist.

When I run make in debug mode -d I can see that make is trying pattern rule with stem test_test_unity_dumb_example instead of test_unity_dumb_example, for example:

Trying pattern rule with stem 'test_test_unity_dumb_example'

test_test_ was my mistake but I have fixed it. I still can't make it work.

When I run with -p I can find something like this in the output:

# Implicit Rules

unity_build/results/%.unity_res: unity_build/%.out
#  recipe to execute (from 'Makefile.unity', line 30):
    ./$< > $@ 2>&1

SOLVED

The problem was with the prerequisite of the prerequisite of the $(UNITY_PATHB)%.out. Precisely, path to one crucial source file was ${UNITY_INSTALL_DIR}/src instead of ${UNITY_INSTALL_DIR}/ . However I still find it weird that make was complaining about the rule to target that is 2 level above the target that could not be built.

SolarBear
  • 4,534
  • 4
  • 37
  • 53
Al Bundy
  • 653
  • 1
  • 6
  • 22
  • If you clean your project and remove all generated files to start from a clean slate, do you see the file `unity_build/results/test_unity_dumb_example.unity_res` being built? What happens if any of the paths in `$(UNITY_BUILD_PATHS)` doesn't exist? After a full clean, can you run `make` again and then edit your question to include the *full* output? – Some programmer dude Jun 26 '17 at 11:37
  • Also, you might consider using the `-d` option to `make` to show debug information. Using that might help you understand what happens. Perhaps also use the `-p` options to print the rule database. See e.g. [this GNU make option summary reference](https://www.gnu.org/software/make/manual/make.html#Options-Summary). – Some programmer dude Jun 26 '17 at 11:44
  • 2
    Does `unity_build/test_unity_dumb_example.out` exist before you execute Make? How about after? I see nothing in your output that indicates building it, but I see a suggestion that the `unity_build/` directory does not exist at the outset. Please give us a [minimal complete example](https://stackoverflow.com/help/mcve). (You've been here three years, has no one told you about these?) – Beta Jun 26 '17 at 13:08
  • Your paths are probably wrong, this is why `make` cannot match the rule. Print `UNITY_RESULTS` to see what it is. – Maxim Egorushkin Jun 26 '17 at 14:22
  • This question is fairly old now but you should make your solution an answer to the question: it fixed the same problem for me. – SolarBear Jan 13 '23 at 18:21

0 Answers0