【问题标题】:GNU Make Pattern Rules on WindowsWindows 上的 GNU Make 模式规则
【发布时间】:2017-12-09 22:57:56
【问题描述】:

我最近在使用我在 Linux 上使用的 makefile 时遇到了一些麻烦,现在我已经使用了很长一段时间了。 它的逻辑在于生成带有用于编译过程的所有对象、源文件和头文件的字符串;但我只为需要某种特殊处理的对象编写了特定规则,其余部分我使用了以下模式规则:

obj/%.o:    src/%.c
    $(CC) $(CFLAGS) $< -o $@

在 Linux 上它可以工作,但是当我尝试在 Windows 上使用时,当然做了一些更改,它没有,我收到以下错误:

make: *** 没有规则来制作目标 'obj\battle.o','programa' 需要。停止

我一直试图独自解决,但很难。

Linux 的生成文件:

SOURCES := $(shell ls src/*.c)
SUBST1  := $(subst src/,obj/,$(SOURCES))
OBJECTS := $(subst .c,.o,$(SUBST1))
HEADERS := $(shell ls headers/*.h)
CC = gcc
LFLAGS   = -g -I headers/ -o programa -Wall -pedantic
CFLAGS   = -g -I headers/ -c -Wall -pedantic

programa:    $(OBJECTS) $(HEADERS)
    $(CC) $(LFLAGS) $(OBJECTS) -lm

obj/arvore.o:   src/arvore.c
    $(CC) $(CFLAGS) -lm $< -o $@

obj/main.o: $(HEADERS)

obj/%.o:    src/%.c
    $(CC) $(CFLAGS) $< -o $@

clean:

ifneq ($(shell ls obj/*.o),)
    rm obj/*.o
endif

ifneq ($(findstring ./programa, $(shell find . -maxdepth 1 -perm -111 -type f)),)
    rm programa
endif

##############################################################
.PHONY = programa organize clean

Windows 的生成文件:

AA = aa
SOURCES := $(shell dir /b /s src\*.c)
SUBST1  := $(subst $(shell cd)\, ,$(SOURCES))
SUBST2  := $(subst src\,obj\,$(SUBST1))
OBJECTS := $(subst .c,.o,$(SUBST2))
HEADERS := $(shell dir /b /s headers\*.h)
CC = gcc
LFLAGS   = -g -o jogo -Wall -pedantic
CFLAGS   = -g -c -Wall -pedantic

programa: $(OBJECTS) $(HEADERS)
    $(CC) $(LFLAGS) $(OBJECTS) -lm

obj\main.o: src\main.c $(HEADERS)
    $(CC) $(CFLAGS) $< -o $@

obj\arvore.o: src\arvore.c
    $(CC) $(CFLAGS) -lm $< -o $@

obj\%.o: src\%.c;
    $(CC) $(CFLAGS) $< -o $@

clean:
ifneq ($(findstring .o, $(shell dir /b obj\*.o)),)
    del obj\*.o
endif

ifneq ($(findstring jogo.exe, $(shell dir /b *.exe)),)
    del jogo.exe
endif

PS:windows 的 makefile 上的变量 AA,它是一个临时修复,因为没有它,它通常会从第一个变量中“吃掉”一个字符,例如,假设 CC = gcc 它是第一个,cmd 上的命令是“ cc -g [...]" 如果你知道为什么会这样,我也想知道。

提前致谢。

【问题讨论】:

  • 我怀疑这是这里的原因,但是在 SUBST1 中删除目录前缀的subst 可以使用,, 作为替换,而不是, ,...可能有空格留在一个糟糕的地方。

标签: c windows makefile gnu


【解决方案1】:
  • 您在模式规则之后有一个虚假的;
  • 如果您在内部使用反斜杠,则 Windows 上的 make 将无法正常工作,使用正斜杠并替换要容易得多,只有在没有它们无法使用的 Windows 工具(例如 del)时才需要。

  • 你不需要使用 windows shell 来处理很多文件,make 有这方面的内部功能。

  • 链接时编译标志无效(-Wall等),编译时链接标志无效(-lm
  • 您已经强制最终的可执行文件依赖于所有的头文件,而目标文件应该完全依赖于他们需要的头文件。使用 gcc 的依赖生成功能 -MMD 等,并改用 make 的 -include 功能。
  • CC 默认扩展为 cc,这应该是默认编译器的链接或副本,在您的情况下,只需将 bin 目录中的 gcc 复制到 cc 即可
  • make 内置了很多常用操作的规则和配方,回收它们

您的 makefile 可以压缩如下:

sources := $(wildcard src/*.c)
objects := $(sources:src/%.c=obj/%.o)
deps    := $(objects:.o=.d)

CPPFLAGS := -MMD -MP
CFLAGS   := -g -Wall -pedantic
LDLIBS   := -lm

jogo.exe: $(objects)
    $(LINK.o) $^ $(LDLIBS) -o $@

obj/%.o: src/%.c
    $(COMPILE.c) $(OUTPUT_OPTION) $<

clean:
    -del $(subst /,\,$(objects) $(deps)) jogo.exe

-include $(deps)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    • 1970-01-01
    • 1970-01-01
    • 2014-05-05
    • 1970-01-01
    • 2017-09-26
    相关资源
    最近更新 更多