为Windows编写正确的Ansi C makefile

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

当我为学校项目的Windows编写C makefile时,我真的很绝望。我已经写了我的makefile并用于ubuntu,它的工作原理如下:

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。请帮助我。

c windows makefile compilation
1个回答
0
投票

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

使用相同的makefile支持不同的OS系列非常棘手,这就是为什么发明了诸如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的目标的先决条件而声明为“ 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)和所需的目标文件(这是典型的,并允许clean)引入变量。目标更精确)。您还可以考虑依赖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
© www.soinside.com 2019 - 2024. All rights reserved.