Makefile文件编译所有的文件,每次

问题描述 投票:0回答:2

我的Makefile文件编译所有的文件,每次我运行它虽然文件没有改变。我知道,这个问题已经被问了几次,但没有提供的解决方案似乎为我工作。我是新来的和makefile大多数时候我不明白,在解决方案中使用的术语。另外,我想所有生成的.o文件保存的文件夹下的“OBJ”

这里是我的文件夹结构

project (-)
        gen (-)
            display (-)
                .c and .h files
            logic (-)
                .c and .h files
        lib (-)
            include (-)
                .h files
            .lib files  
        man (-)
            .c and .h files
        obj (-)
            want to save all the .o files here

我使用的MinGW在Windows操作系统上运行此

这里是我的Makefile:

ALL: demo

SRCS:= filename1.o filename2.o filename3.o filename4.o and so on till filename27.o

demo: display.o logic.o man.o
    gcc $(SRCS) -lglut32 -loglx -lopengl32 -Llib -o demo

display.o:
    gcc -Igen/display -Igen/logic -Iman -Ilib/include gen/display/*.c -lglut32 -loglx -lopengl32 -Llib -c

logic.o:
    gcc -Igen/display -Igen/logic -Iman -Ilib/include gen/logic/*.c -lglut32 -loglx -lopengl32 -Llib -c

man.o:
    gcc -Igen/display -Igen/logic -Iman -Ilib/include man/*.c -lglut32 -loglx -lopengl32 -Llib -c

clean:
    @echo "Cleaning up.."
    -rm -rf *.o
    -rm *.exe

注:过剩和oglx文件存在lib文件夹中。 Display.o,lib.o和man.o没有相应的.c文件。他们是在他们许多的C文件只是文件夹名称。

我理解这可能是问题。由于没有display.o,logic.o创造man.o文件,请遵从它eveytime相关联的规则。让我怎么告诉它来检查实际的.o filename1.o,filename2.o等的时间戳和重新编译,只有当他们比相应的C文件和h文件日期早的甚至它们所依赖的LIB文件。

我尝试以下创建的依赖,避免每次文件的编制。但是,这并没有帮助。

%.d: %.c
     @set -e; rm -f $@; \
     $(CC) -M $(CFLAGS) $< > $@.$$$$; \
     sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
     rm -f $@.$$$$
gcc makefile compilation
2个回答
1
投票

在一个基本水平,make正在寻找像行:

target: dependency
    command

如果target不存在,它要求dependency规则,然后运行command。如果target确实存在,它测试,如果dependency是新的或不存在。如果是这样,它要求dependency规则,然后运行command。否则,它停止。

显著,为dependency规则将仅在(一)dependency不存在,或(b)dependencytarget新的调用。

在这个问题中,假设我们运行make demo。然后make查找开头demo:并注意到它声明了依赖行。因此,它看起来在每个反过来依赖,看看他们是否需要采取行动。它首先发现display.o。它注意到display.o:不存在,所以它运行的相关规则。它为其他*.o相同。

为了避免总是被运行,因为没有相关的文件存在*.o规则,你可以重写,如:

ALL: demo

SRCS:= filename1.o filename2.o filename3.o filename4.o and so on till filename27.o

demo: display.ts logic.ts man.ts
    gcc $(SRCS) -lglut32 -loglx -lopengl32 -Llib -o demo

display.ts: gen/display/*.c
    gcc -Igen/display -Igen/logic -Iman -Ilib/include gen/display/*.c -lglut32 -loglx -lopengl32 -Llib -c
    echo . > display.ts

logic.ts: gen/logic/*.c
    gcc -Igen/display -Igen/logic -Iman -Ilib/include gen/logic/*.c -lglut32 -loglx -lopengl32 -Llib -c
    echo . > logic.ts

man.ts: man/*.c
    gcc -Igen/display -Igen/logic -Iman -Ilib/include man/*.c -lglut32 -loglx -lopengl32 -Llib -c
    echo . > man.ts

clean:
    @echo "Cleaning up.."
    -rm -rf *.o *.ts
    -rm *.exe

1
投票

问题是,你的二进制对象的目标(如display.o)实际上不匹配他们的规则生成的文件。如果你告诉make它需要使目标display.o,它(通常,除了伪目标,但那些始终重新运行),预计该规则的配方来生产相应的文件,如果目标需要返工它可以跟踪。如果没有这样的文件被产生,这个目标始终评估为过时和需要重塑。

这样一个愚蠢的例子的位将是以下三种:

.
├── Makefile
├── main.c
└── test
    └── file.c

和Makefile:

main: test.o main.o
    $(CC) -o main *.o

test.o:
    $(CC) $(CFLAGX) -c test/*.c

没有test.o文件和目标需要返工......的规则运行,(再)产生file.o。由于此的目标是重拍,是main前提...一切总是被重拍。

现在有了这个小改动:

main: test.o main.o
    $(CC) -o main *.o

test.o:
    $(CC) $(CFLAGX) -o $@ -c test/*.c

test.o目标确实产生test.o文件和规则不需要再造如果test.c不会改变......与test.o不变,main.c或许还有,我们得到:

$ make
make: 'main' is up to date.

它仍然是不完全正确的,因为它确实应该阅读:

main: test.o main.o
    $(CC) -o main $+

test.o: test/*.c
    $(CC) $(CFLAGX) -o $@ -c $^

当我宣布取决于test.o的先决条件,并在规则的食谱自动变量引用他们和目标。和同去的先决条件链接。当然,在这个简单的例子,我可以只依靠隐含模式规则和做到这一点:

main: test/file.o main.c

test/file.o: test/*.c

这是什么意思为您的makefile?当您编译目标文件,看看他们是怎么实际产生和你的目标到或匹配(与-o $@例如)告诉他们产生精确匹配您的目标文件。


我已经延长了愚蠢的例子了一下,现在有在test/两个文件:

.
├── Makefile
├── main.c
└── test
    ├── file.c
    └── other.c

和Makefile文件可以是这个样子:

main: obj/file.o obj/other.o main.c

obj/%.o: test/%.c
    mkdir -p obj
    $(CC) $(CFLAGS) -c -o $@ $^

现在存储对象中obj/文件,并仍然明白什么需要的东西,可以跟踪更改。当然,你的设置更复杂,将需要更多的规则,或许也是占卜实际源或中介目标从目录树,并定义几个变量与信息,e.g工作:

OBJS := $(patsubst test/%.c,obj/%.o,$(wildcard test/*.c))

main: $(OBJS) main.c

obj/%.o: test/%.c
        mkdir -p obj
        $(CC) $(CFLAGS) -c -o $@ $^

但原理是相同的。

© www.soinside.com 2019 - 2024. All rights reserved.