자동 종속성 생성 기능이 있는 Makefile

자동 종속성 생성 기능이 있는 Makefile

미칠 것 같아, 누가 좀 도와줘...

내가 원하는 것: src의 .c 파일은 .h 파일의 .o 파일을 포함합니다. 빌드 빌드 바이너리 실행 파일의 .d 파일은

OSDev 위키에서 영감을 얻었지만 디렉토리 구조에서 작동하도록 할 수는 없습니다.

나는 bin에 별도의 단위 테스트 파일을 갖고 싶습니다(예: %_t).

(현재) 다음 오류가 발생합니다.

/usr/bin/ld: /tmp/cc0HW3O2.o: in function `outstr':
outstr.c:(.text+0x174): undefined reference to `kstrlen'
collect2: error: ld returned 1 exit status
make: *** [Makefile:38: bin/outstr_t] Error 1

src: 'kstrlen.c' 'outstr.c' 포함: 'kstrlen.h' 'outstr.h' 'test.h'

test.h에는 Test Anything 프로토콜을 사용하는 매크로가 포함되어 있습니다.

src 파일에는 다음이 포함됩니다.

#include "kstrlen.h"

#ifdef TEST
#include "test.h"
int test_string (char *str, int len);

int main () {
    PLAN(8);
    OK("One word", test_string("abcde", 5));
    OK("Zero-length", test_string("", 0));
    OK("Single char", test_string("a", 1));
    OK("Spaces", test_string("   ", 3));
    OK("Multiline", test_string("First Line\nSecond Line\nThird Line", 33));
    OK("Non-printable characters", test_string("\x01\x02\x03\x04\x05", 5));
    OK("End with null", test_string("End with null\0", 13));
    OK("Embedded null", test_string("This\0 is embedded", 4));
    GRADE();
}

int test_string (char *str, int len) {
    return kstrlen(str) == len ? 1 : 0;
}
#endif

int kstrlen (char *str) {
    if (*str == 0) {
        return 0;
    }
    int len = 0;
    while (*str) {
        len++;
        str++;
    }
    return len;
}

이 Makefile을 사용하면:

    SRCDIR := src
BINDIR := bin
INCDIR := include
BUILDDIR := build

SRCFILES := $(shell find $(SRCDIR) -type f -name "*.c")
HDRFILES := $(shell find $(INCDIR) -type f -name "*.h")
OBJFILES := $(patsubst $(SRCDIR)/%.c,$(BUILDDIR)/%.o,$(SRCFILES))
DEPFILES := $(patsubst $(SRCDIR)/%.c,$(BUILDDIR)/%.d,$(SRCFILES))
TSTFILES := $(patsubst $(SRCDIR)/%.c,$(BINDIR)/%_t,$(SRCFILES))
TSTDEPFILES := $(patsubst $(BINDIR)/%_t, $(BUILDDIR)/%.d, $(TSTFILES))

MKDIR := mkdir -p
RM := rm -rf

CC := gcc
WARNINGS := -Wextra -Werror -Wall
CFLAGS := $(WARNINGS) -I $(INCDIR)

check: testdrivers
    -@rc=0; count=0; \
        for file in $(notdir $(TSTFILES)); do \
            echo " TST     $(BINDIR)/$$file"; $(BINDIR)/$$file; \
            rc=`expr $$rc + $$?`; count=`expr $$count + 1`; \
        done; \
    echo; echo "Tests executed: $$count  Tests failed: $$rc"

testdrivers: $(TSTFILES)

-include $(DEPFILES) $(TSTDEPFILES)

$(BUILDDIR)/%.o: $(SRCDIR)/%.c Makefile | $(BUILDDIR)
    @$(CC) $(CFLAGS) -MMD -MP -c $< -o $@

$(BINDIR)/%_t: $(SRCDIR)/%.c Makefile | $(BINDIR)
    @$(CC) $(CFLAGS) -MMD -MP -MF $(BUILDDIR)/$(@F).d -DTEST $< -o $@

$(BUILDDIR):
    $(MKDIR) $@

$(BINDIR):
    $(MKDIR) $@

clean:
    $(RM) $(BUILDDIR) $(BINDIR)

관련 정보