"make: *** No rule to make target" Using Unity Unit Testing

1k views Asked by At

I ended up installing ceedling which uses ruby code to auto-generate test runs. Much better tool set for learning imo. I'm going to leave the question open in case anybody else has the same issue and someone else has the answer.

Hi StackOverflow family,

I'm currently in the process of reading through "Test-Driven Development for Embedded C" and am attempting to get Unity (unit tester) to work. I am able to compile some example code using gcc.

When I try to follow the make tutorial and run 'make' in my command line:

make: *** No rule to make target 'build/results/TestEx.txt', needed by 'test'.  Stop.

I tried to follow the tree outline from throwtheswitch, and my personal tree is below (removed Unity's files for clarity):

.
├── build
│   ├── depends
│   ├── objs
│   └── results
├── makefile
├── src
│   ├── ex.c
│   └── ex.h
├── test
│   └── TestEx.c
├── testex
└── Unity
.

.

.

My makefile looks as such (Remember, it's copied):

ifeq ($(OS),Windows_NT)
  ifeq ($(shell uname -s),) # not in a bash-like shell
    CLEANUP = del /F /Q
    MKDIR = mkdir
  else # in a bash-like shell, like msys
    CLEANUP = rm -f
    MKDIR = mkdir -p
  endif
    TARGET_EXTENSION=.exe
else
    CLEANUP = rm -f
    MKDIR = mkdir -p
    TARGET_EXTENSION=out
endif

.PHONY: clean
.PHONY: test

PATHU = Unity/src/
PATHS = src/
PATHT = test/
PATHB = build/
PATHD = build/depends/
PATHO = build/objs/
PATHR = build/results/

BUILD_PATHS = $(PATHB) $(PATHD) $(PATHO) $(PATHR)

SRCT = $(wildcard $(PATHT)*.c)

COMPILE=gcc -c
LINK=gcc
DEPEND=gcc -MM -MG -MF
CFLAGS=-I. -I$(PATHU) -I$(PATHS) -DTEST

RESULTS = $(patsubst $(PATHT)Test%.c,$(PATHR)Test%.txt,$(SRCT) )

PASSED = `grep -s PASS $(PATHR)*.txt`
FAIL = `grep -s FAIL $(PATHR)*.txt`
IGNORE = `grep -s IGNORE $(PATHR)*.txt`

test: $(BUILD_PATHS) $(RESULTS)
    @echo "-----------------------\nIGNORES:\n-----------------------"
    @echo `grep -s IGNORE $(PATHR)*.txt`
    @echo "-----------------------\nFAILURES:\n-----------------------"
    @echo `grep -s FAIL $(PATHR)*.txt`
    @echo "-----------------------\nPASSED:\n-----------------------"
    @echo "$(PASSED)"
    @echo "\nDONE"

$(PATHR)%.txt: $(PATHB)%.$(TARGET_EXTENSION)
    -./$< > $@ 2>&1

$(PATHB)Test%.$(TARGET_EXTENSION): $(PATHO)Test%.o $(PATHO)%.o $(PATHU)unity.o #$(PATHD)Test%.d
    $(LINK) -o $@ $^

$(PATHO)%.o:: $(PATHT)%.c
    $(COMPILE) $(CFLAGS) $< -o $@

$(PATHO)%.o:: $(PATHS)%.c
    $(COMPILE) $(CFLAGS) $< -o $@

$(PATHO)%.o:: $(PATHU)%.c $(PATHU)%.h
    $(COMPILE) $(CFLAGS) $< -o $@

$(PATHD)%.d:: $(PATHT)%.c
    $(DEPEND) $@ $<

$(PATHB):
    $(MKDIR) $(PATHB)

$(PATHD):
    $(MKDIR) $(PATHD)

$(PATHO):
    $(MKDIR) $(PATHO)

$(PATHR):
    $(MKDIR) $(PATHR)

clean:
    $(CLEANUP) $(PATHO)*.o
    $(CLEANUP) $(PATHB)*.$(TARGET_EXTENSION)
    $(CLEANUP) $(PATHR)*.txt

.PRECIOUS: $(PATHB)Test%.$(TARGET_EXTENSION)
.PRECIOUS: $(PATHD)%.d
.PRECIOUS: $(PATHO)%.o
.PRECIOUS: $(PATHR)%.txt

Running make -d test (removed text to fit in body, but condensed to the important bits):

    Trying pattern rule with stem 'TestEx'.
    Trying implicit prerequisite 'build/TestEx'.
    Looking for a rule with intermediate file 'build/TestEx'.
     Avoiding implicit rule recursion.
     Avoiding implicit rule recursion.
     Trying pattern rule with stem 'TestEx'.
     Trying implicit prerequisite 'build/TestEx,v'.
     Trying pattern rule with stem 'TestEx'.
     Trying implicit prerequisite 'build/RCS/TestEx,v'.
     Trying pattern rule with stem 'TestEx'.
     Trying implicit prerequisite 'build/RCS/TestEx'.
     Trying pattern rule with stem 'TestEx'.
     Trying implicit prerequisite 'build/s.TestEx'.
     Trying pattern rule with stem 'TestEx'.
     Trying implicit prerequisite 'build/SCCS/s.TestEx'.
   No implicit rule found for 'build/results/TestEx.txt'.
   Finished prerequisites of target file 'build/results/TestEx.txt'.
  Must remake target 'build/results/TestEx.txt'.
make: *** No rule to make target 'build/results/TestEx.txt', needed by 'test'.  Stop.
2

There are 2 answers

0
Federico David Ceccarelli On

Ill re-open the thread because i wasn't able to find a solution to the same issue.

Are you using GNU make built for GNUWin32?

I found that GNUWin32 make uses Unix style filenames for the targets and dependencies but as I had edited makefile's PATHS to Windows style filenames to use the windows mkdir command then makefile wasn't able to find recipes.

You should edit your makefile if you are running it with GNU Makefile built for GNUWin32

Makefile rules paths should be like this:

test/build/objs/%.o: test/%.c

and mkdir command should be like this:

mkdir test\build\objs

This worked for me. Hopes it helps!

0
iPAS On

I added Unity as submodule, but did not clone it at the first place. So, I revised ".github/workflows/makefile.yml" as the following:

- uses: actions/checkout@v3
  with:
      submodules: recursive

Then, it work!