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

War*_*voy 0 c gcc makefile gnu-make

我正在尝试制作一个尽可能简单的使用数学库的 make 文件(下面是 fmax,其余的是本次考试的 C cruft):

简单.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;
}
Run Code Online (Sandbox Code Playgroud)

生成文件:

CFLAGS=-g
LDFLAGS=-lm

easy : easy.c
Run Code Online (Sandbox Code Playgroud)

然而,这会产生链接错误(缺少 fmax)。这是因为 make 将 LDFLAGS 首先放置在编译行中:

#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;
}
Run Code Online (Sandbox Code Playgroud)

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

CFLAGS=-g
LDFLAGS=-lm

easy : easy.c
    $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
Run Code Online (Sandbox Code Playgroud)

当然,现在理解 Makefile 并不是那么容易了。有谁知道默认规则不将链接线放在最后的原因吗?或者是否有一种“简单”的 make 允许新手将多个源文件链接到一个可执行文件中(没有挥之不去的 .o 文件)?

Mad*_*ist 5

你应该使用LDLIBSnot 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 $@
Run Code Online (Sandbox Code Playgroud)

(忽略LOADLIBES,因为这是一个已弃用的名称)。另请参阅和的文档LDLIBSLDFLAGS