Easy gnu make makefile 规则从多个源文件构建 GCC 可执行文件

Easy gnu make makefile rule to build of GCC executable from multiple source files

我正在尝试制作一个尽可能简单的 make 文件,该文件使用数学库(下面是 fmax,其余的是 C cruft 对于这个例子):

easy.c:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, const char *argv[]) {
  double x=atof(argv[1]);
  double y=atof(argv[2]);
  double z=fmax(x,y);
  printf("max(%f,%f)=%f\n",x,y,z);
  return 0;
}

生成文件:

CFLAGS=-g
LDFLAGS=-lm

easy : easy.c

然而,这会产生 link 错误(缺少 fmax)。这是因为 make 将 LDFLAGS 放在编译行的第一位:

 > make easy
cc -g  -lm  easy.c   -o easy
/usr/bin/ld: /tmp/ccmN5G9c.o: in function `main':
/home/user/projects/easy/easy.c:8: undefined reference to `fmax'
collect2: error: ld returned 1 exit status
make: *** [<builtin>: easy] Error 1

当然,如果我使用显式规则明确地将 LDFLAGS 放在末尾,它会起作用:

CFLAGS=-g
LDFLAGS=-lm

easy : easy.c
    $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)

当然,现在理解Makefile并不是那么容易。有没有人知道默认规则不将 link 行放在末尾的原因?或者是否有一种“简单”的方法允许新手 link 将多个源文件合并到一个可执行文件中(没有挥之不去的 .o 文件)?

您应该使用 LDLIBS 而不是 LDFLAGSLDFLAGS 用于链接器标志(例如 -L)。 LDLIBS 用于链接器库(例如 -lm)。

如果您调查默认规则 (make -pf/dev/null),您会发现这条规则:

LINK.o = $(CC) $(LDFLAGS) $(TARGET_ARCH)

%: %.o
#  recipe to execute (built-in):
        $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@

(忽略 LOADLIBES,因为这是一个已弃用的名称)。 LDLIBSLDFLAGS.

另见 the documentation