如何在 Linux 上为 gcc 制作一个简单的 makefile?

Posted

技术标签:

【中文标题】如何在 Linux 上为 gcc 制作一个简单的 makefile?【英文标题】:How do I make a simple makefile for gcc on Linux? 【发布时间】:2010-12-01 20:56:15 【问题描述】:

我有三个文件:program.cprogram.hheaders.h

program.c 包括program.hheaders.h

我需要在 Linux 上使用 gcc 编译器来编译它。我不知道该怎么做。 Netbeans 为我创建了一个,但它是空的。

【问题讨论】:

spin.atomicobject.com/2016/08/26/makefile-c-projects 有一个非常优雅(并且有据可查)的解决方案。 【参考方案1】:

有趣的是,我不知道 make 会默认使用 C 编译器给定有关源文件的规则。

无论如何,演示简单 Makefile 概念的简单解决方案是:

HEADERS = program.h headers.h

default: program

program.o: program.c $(HEADERS)
    gcc -c program.c -o program.o

program: program.o
    gcc program.o -o program

clean:
    -rm -f program.o
    -rm -f program

(请记住,make 需要制表符而不是空格缩进,因此请务必在复制时修复该问题)

但是,要支持更多 C 文件,您必须为每个文件制定新规则。因此,要改进:

HEADERS = program.h headers.h
OBJECTS = program.o

default: program

%.o: %.c $(HEADERS)
    gcc -c $< -o $@

program: $(OBJECTS)
    gcc $(OBJECTS) -o $@

clean:
    -rm -f $(OBJECTS)
    -rm -f program

我试图通过省略通常在 makefile 中看到的 $(CC) 和 $(CFLAGS) 等变量来尽可能简单地做到这一点。如果您有兴趣弄清楚这一点,我希望我已经为您提供了一个良好的开端。

这是我喜欢用于 C 源代码的 Makefile。随意使用它:

TARGET = prog
LIBS = -lm
CC = gcc
CFLAGS = -g -Wall

.PHONY: default all clean

default: $(TARGET)
all: default

OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
HEADERS = $(wildcard *.h)

%.o: %.c $(HEADERS)
    $(CC) $(CFLAGS) -c $< -o $@

.PRECIOUS: $(TARGET) $(OBJECTS)

$(TARGET): $(OBJECTS)
    $(CC) $(OBJECTS) -Wall $(LIBS) -o $@

clean:
    -rm -f *.o
    -rm -f $(TARGET)

它使用 make 实用程序的通配符和 patsubst 功能在当前目录中自动包含 .c 和 .h 文件,这意味着当您向目录中添加新代码文件时,您无需更新 Makefile。但是,如果要更改生成的可执行文件、库或编译器标志的名称,只需修改变量即可。

在任何一种情况下,请不要使用 autoconf。我求你! :)

【讨论】:

为了技术上正确,我相信您应该将.PHONY: clean all default 用于那些打算从命令行使用的目标。此外,Autoconf/Automake 也不错。当然,它们感觉很糟糕,习惯它们就像强迫你的头穿过一堵砖墙一样有趣,但它们确实有效,而且它们发展良好,它们将覆盖你的大部分基础,就便携性而言,一旦你习惯了他们糟糕的设计,最终会让你的生活变得更轻松。 我想这是可行的,但我想如果我在终端上输入“make”,程序应该会运行。这是我得到的: gcc statsh.o -Wall -lm -o prog 是否可以只输入 make 并执行程序? 为什么不使用 autoconf joey-adams ? 如果有人想知道为什么rm前面有破折号:***.com/questions/2989465/rm-rf-versus-rm-rf 最好使用:= 而不是=。使用:=wildcard 函数只运行一次,以后可以附加/扩展变量OBJS := $(OBJS) other.o。使用=这是不可能的,它会导致变量扩展的无限循环!请参阅:The Two Flavors of Variables。【参考方案2】:

例如这个简单的 Makefile 就足够了:

抄送=gcc CFLAGS=-墙 全部:程序 程序:program.o program.o:program.c program.h headers.h 干净的: rm -f 程序 program.o 运行:程序 。/程序

注意清理运行后的下一行必须有&lt;tab&gt;,而不是空格。

更新以下评论已应用

【讨论】:

@user69514: make 没有参数通常只构建你的软件。要运行它,要么使用make run(在这个答案中可用,但不一定在所有Makefiles),或者直接运行它:./program【参考方案3】:
all: program
program.o: program.h headers.h

就够了。其余的都是隐含的

【讨论】:

如果你的整个程序是一个单一的.c文件,那么只有program:是必要的。甜:) 虽然这肯定很简单,但毫无疑问,匿名和@MestreLion,我是 C 新手,最近才将一个大型项目拆分为 2 个源文件和一个标头,我是 使用makefile,而是一个非常简单的C程序,基本上只使用stdlib.h中的system()...这种方法没有缺点,有吗? @APJo:对于简单的项目,您可以不用Makefile 直接调用gcc *.c *.h -o program,可能添加-Wall -O2 等选项。【参考方案4】:

最简单的make文件可以是

all : test

test : test.o
        gcc -o test test.o 

test.o : test.c
        gcc -c test.c

clean :
        rm test *.o

【讨论】:

您可以添加更多细节来解释您的 Makefile 的作用 您实际上可以更简单。见@anonymous 1 班轮【参考方案5】:

根据标头的数量和您的开发习惯,您可能需要研究 gccmakedep。该程序检查您的当前目录并将每个 .c/cpp 文件的头依赖项添加到 makefile 的末尾。当您有 2 个标头和一个程序文件时,这是矫枉过正的。但是,如果您有 5 个以上的小测试程序并且您正在编辑 10 个标头之一,那么您可以信任 make 来准确重建那些因您的修改而更改的程序。

【讨论】:

以上是关于如何在 Linux 上为 gcc 制作一个简单的 makefile?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Windows 上为 NetBeans 和 gcc 添加库包含路径?

如何在同一页面上为 2 个无线电流制作播放/停止按钮?

如何在 iOS 8 上为 superview 制作 clearColor

markdown 在Windows上为GCC(MinGW)安装boost库

arm-linux-gcc交叉编译器的制作,以及版本选择问题。

分段错误:在 Mac 上为 11,但在 Linux 上没有,同时在 C 中创建数组