【问题标题】:Write proper Ansi C makefile for Windows [closed]为 Windows 编写正确的 Ansi C makefile [关闭]
【发布时间】:2019-12-29 14:05:45
【问题描述】:

在尝试为我的学校项目编写 Windows 的 C makefile 时,我真的很绝望。我已经为 ubuntu 编写并使用了我的 makefile,它可以像这样完美地工作:

all: clean install

install: dynarr.o broadcaster.o main.o
    gcc -o freq dynarr.o broadcaster.o main.o

clean:
    rm -f *.o

dynarr.o:
    gcc -c dynarr.c

broadcaster.o:
    gcc -c broadcaster.c

main.o:
    gcc -c main.c

我已经在不同的网站上尝试了大约 10 个教程,这让我很紧张。 我需要按照这个特定的顺序编译dynarr.c broadcaster.c main.c,输出应该是freq.exe。学校服务器上的编译器对于两个版本(linux 和 windows)都是 gcc。 请帮帮我。

编辑:出于某种原因,我们老师的在线验证器需要 windows 和 linux 的 freq.exe,他没有费心在任何地方提及它。我必须编辑的所有内容都是freqfreq.exe。感谢支持。

【问题讨论】:

  • 我们无法猜测到底出了什么问题。编辑您的问题以反映这一点,包括错误消息和/或什么是和应该是什么。
  • 好吧,问题是服务器不会给我任何比 文件freq.exe 无法创建,测试无法继续更好的线索帮助,但我找不到任何有用的东西
  • 你在运行什么命令?
  • 我真的说不出来,我看不到测试的内部。我已经联系了我的老师,等待他的回应。同时我构建了这个:CC = gcc CFLAGS = -Wall -pedantic -ansi LIBS = -lm BIN = freq.exe OBJ = dynarr.o broadcaster.o main.o $(BIN): $(OBJ) $(CC) $^ -o $@ -lm %.o: %.c $(CC) -c $(CFLAGS) $< $(LIBS) -o $@ ,它似乎应该没问题,但不是。请您检查一下是否有错误?
  • 请注意,make 和 C 是分开且独立的,除非 make 实现可以用 C 编写。因此,短语“Ansi C makefile”没有明确定义意义。我猜你只是想要一个生成文件来构建你的特定 C 程序。

标签: c windows makefile compilation


【解决方案1】:

在 Windows 上,您希望编译器生成一个名为 freq.exe 的文件(或者无论如何测试系统都会生成一个文件),但您发出的命令告诉 GCC 生成一个名为 freq 的文件,而不是。后者对于 Linux 来说似乎很自然,因此您的构建在其中按预期工作也就不足为奇了。

使用相同的 makefile 支持不同的操作系统系列是很棘手的,这就是发明 Autotools 和 CMake 等实用程序的原因。假设您只需要一个适用于 Windows 的 Makefile,这个变体就足够了:

all: clean install

install: dynarr.o broadcaster.o main.o
    gcc -o freq.exe dynarr.o broadcaster.o main.o

clean:
    rm -f *.o

dynarr.o:
    gcc -c dynarr.c

broadcaster.o:
    gcc -c broadcaster.c

main.o:
    gcc -c main.c

话虽如此,我有一些进一步改进的建议:

  1. 构建特定输出文件的规则应将该文件命名为其目标。
  2. 相反,与由该规则创建的文件不对应的规则目标应通过将它们命名为名为 .PHONY 的目标的先决条件来声明为“假”。
  3. 按照惯例,“安装”目标将构建文件从其构建位置复制到永久系统位置。您的安装规则和 makefile 中的任何其他内容都不会这样做,因此您可能不需要“安装”目标。
  4. 在构建之前清除默认目标的规则可能是故意的,但这是不正常的,因为它首先破坏了使用 make 的主要原因之一:避免不必要的工作。
  5. 这是一种很好的形式,它可以防止错误使用 Make 的自动变量来避免在规则中重复自己。
  6. 存在一些意见分歧,但我认为普遍的共识是 clean 目标应该清理所有构建的对象,而不仅仅是中间对象。

应用所有这些将产生一个像这样的makefile:

all: freq.exe

freq.exe: dynarr.o broadcaster.o main.o
    gcc -o $@ $^

clean:
    rm -f freq.exe *.o

dynarr.o:
    gcc -c dynarr.c

broadcaster.o:
    gcc -c broadcaster.c

main.o:
    gcc -c main.c

.PHONY: all clean

就个人而言,我还建议为可执行目标(这将更容易在 Windows 和 Linux / macOS 之间调整 makefile)和所需的目标文件(这是典型的,并且允许 @987654328 @target 更准确)。您还可以考虑依赖 Make 的内置规则来从 .c 文件构建 .o 文件,因为您使用的显式规则不会做任何内置规则没有完成的事情。结果可能是:

PROG = freq.exe
OBJS = dynarr.o broadcaster.o main.o

all: $(PROG)

$(PROG): $(OBJS)
    gcc -o $@ $^

clean:
    rm -f $(PROG) $(OBJS)

# Relies on the built-in rules for building object files from C sources

.PHONY: all clean

【讨论】:

  • 有一件事情要做以保持您对 makefile 的理智,请将选项卡替换为 > ,在您键入的文件顶部执行此操作:.RECIPEPREFIX= >
  • 最后发现我们的教授出于某种原因希望 linux makefile 生成名为 freq.exe 的文件。再加上没有正确的错误日志,这真的让我和我的很多同学感到困惑。谢谢,解决了。
猜你喜欢
  • 2012-02-11
  • 1970-01-01
  • 2013-12-22
  • 1970-01-01
  • 2014-10-20
  • 1970-01-01
  • 2021-07-28
  • 2015-04-24
  • 2014-03-21
相关资源
最近更新 更多