Makefile无法编译已更改的主程序文件

makefile not compiling changed main program file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
ALLSRCS := $(wildcard *.c)
OTHERSRCS := testRWdata.c testddb.c testsuite.c driver.c DumpAFile.c testavl.c tester.c
SRCS := $(filter-out $(OTHERSRCS),$(ALLSRCS))
OBJS := $(addprefix obj/,$(SRCS:.c=.o))
PROGS = testRWdata testddb testsuite driver DumpAFile testavl tester


OTHER_LIBS =
OTHER_PRODUCT_DEPENDS = buffer.h dbinfo.h avl.h
TEST_OUT = nextdb.test.out
DATA_FILES = test.dfd test.input.test test.input.full test.input tstavl.input $(TEST_OUT)
HELP_FILES = README
OTHER_GARBAGE = test.asc test.dat test.wrk test.log test.dump

.PHONY: all clean

doall : $(PROGS)

obj/%.o: %.c | obj
    $(COMPILE.c) $< -o $@

obj:
    mkdir -p $@

testsuite: $(OBJS)
    $(CC) -o $@ $^ $(CFLAGS) $(LIBS) [email protected]
    -chmod a+x $@

如果obj目录为空或OBJS中包含的文件之一,则

make testsuite可以工作。完成一次之后,然后编辑文件
testsuite.c,让testsuite表示没有更改。如何使文件检测到testsuite.c已更改或.h文件之一已更改?


testsuite必须依赖于testsuite.otestsuite.c。可能的解决方法:

1
2
testsuite: obj/testsuite.o $(OBJS)
    $(CC) -o $@ $^ $(LDFLAGS) $(LIBS)

请注意,chmod是不必要的,生成的可执行文件是可执行文件。

您可能还希望自动生成标头依赖项。


如果我对您的理解正确,这是我为您的特定情况制作的示例[完整代码]。

据我了解,您有一个main.c文件,它是主程序的主文件。您也有一些test.c文件,其中包含其他电源。而且您还有其他源文件,我称之为SHARED_SRC,其中不包含带有main-s的.c文件。这些SHARED_SRC文件用于编译主程序和测试。

要运行此生成文件,请运行makemake tests

要在修改头文件时重新编译,我只添加了:
obj/%.o: %.c $(HEADERS)-每个.o对象的规则

我为测试创建了单独的规则。注意:测试文件名必须以" test"前缀开头。

希望它能回答您的问题。

编辑:在此处添加了整个示例。

Makefile:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#We suppose that the program with the main main function is in main.c

NAME        =   JWooten

ALLSRCS     :=  $(wildcard *.c)
OTHERSRCS   :=  testMain1.c testMain2.c
SHARED_SRC  :=  $(filter-out main.c $(OTHERSRCS),$(ALLSRCS))

ALL_OBJS    :=  $(addprefix obj/,$(ALLSRCS:.c=.o))
SHARED_OBJS :=  $(addprefix obj/,$(SHARED_SRC:.c=.o))
OTHER_OBJS  :=  $(addprefix obj/,$(OTHERSRCS:.c=.o))
MAIN_OBJ    :=  obj/main.o

TEST_NAMES  :=  $(OTHERSRCS:.c=)

HEADERS     :=  $(wildcard *.h)

all: $(NAME)


#Adding the $(HEADERS) to the rule, makes it recompile the object whenever the
#header is modified
obj/%.o: %.c $(HEADERS)
    gcc -c $< -o $@

#Rules for the tests.
test%: test%.c $(HEADERS)
    gcc $(SHARED_OBJS) obj/[email protected] -o $@
    -chmod a+x $@

make_obj_dir:
    @mkdir -p obj

#Rule to make the tests
tests: make_obj_dir $(SHARED_OBJS) $(OTHER_OBJS) $(TEST_NAMES)

$(NAME): make_obj_dir $(SHARED_OBJS) $(MAIN_OBJ)
    gcc $(SHARED_OBJS) $(MAIN_OBJ) -o $(NAME)
    -chmod a+x $(NAME)

clean:
    rm -f *.o
    rm -rf obj

fclean: clean
    rm -f $(TEST_NAMES)
    rm -f $(NAME)

re: fclean all

main.c:

1
2
3
4
5
6
7
8
#include"header.h"

int     main(void)
{
    some_function1();
    some_function2();
    return (0);
}

file1.c

1
2
3
4
5
6
7
#include"header.h"

void    some_function1(void)
{
    printf("Function 1\
");
}

file2.c

1
2
3
4
5
6
7
#include"header.h"

void    some_function2(void)
{
    printf("Function 2\
");
}

testMain1.c:

1
2
3
4
5
6
7
#include"header.h"

int     main(void)
{
    some_function1();
    return (0);
}

testMain2.c:

1
2
3
4
5
6
7
#include"header.h"

int     main(void)
{
    some_function2();
    return (0);
}

header.h:

1
2
3
4
5
6
7
8
9
#ifndef HEADER_H
# define HEADER_H

# include <stdio.h>

void    some_function1(void);
void    some_function2(void);

#endif