3

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.
Blue
  • 820
  • 4
  • 17
  • What happens if you run `make test`? – jwdonahue Mar 26 '20 at 07:50
  • Try to run `make -d test` to see which targets are evaluated and why they are rejected. – raspy Mar 26 '20 at 08:55
  • As a side note -- there's a few things in the Makefile that I would consider bad practice -- first, variables that contain paths should not contain trailing slashes (Thus in the above, `PATHS` should be `src` not `src/`, and references to this should be `$(PATHS)/%.o` rather than `$(PATHS)%.o`. (the former being more readable). Next, makefiles should be used to _build_ something, but not to _run_ the result. If you want to build and run in a single step, you can create a script that calls make and then the resultant executable. – HardcoreHenry Mar 26 '20 at 14:25
  • Added more notes on `make -d test` and `make test` – austinhoang Mar 26 '20 at 18:23
  • @HardcoreHenry Some Makefiles have an `install:` target – Déjà vu Mar 27 '20 at 00:39
  • I ended up just installing ceedling and using the autogenerate ruby scripts to get me moving. I don't know why I didn't start with ceedling, such an easy tool to use. Thanks for the help guys. – austinhoang Mar 27 '20 at 07:39
  • @HardcoreHenry: Having a `test` target that builds and runs the tests is common practice. – DevSolar Jun 29 '20 at 07:34

2 Answers2

1

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!

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
0

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!

iPAS
  • 4,603
  • 1
  • 17
  • 5