通用 Makefile 不适用于 FreeBSD

Generic Makefile not working on FreeBSD

请注意,这不是名为通用 makefile 的其他问题的重复。

我已按照有关通用 makefile 的其他问题的所有说明进行操作,这是我从中得出的代码:

CFLAGS = -c
CC = cc
SOURCES = $(wildcard *.cc)
OBJECTS = $(patsubst %.cc,%.o,%(SOURCES))
EXEC = run

all: build clean

build: $(OBJECTS)
    $(CC) $(OBJECTS) -o $(EXEC)

%.o: %.cc
    $(CC) $(CFLAGS) $<

clean:
    rm *.o

但是,当我在目录中使用名为 test.cc 的文件执行 make 时,出现以下错误:

cc    -o run
cc: error: no input files
*** Error code 1

Stop.
make: stopped in /somewhere

请注意,我使用的是 FreeBSD,makecc 命令是 OS.

附带的命令
FreeBSD 上的

make 不同于 GMake(大多数 linux 系统上的 make 命令),这些功能需要 GMake。 运行 命令 gmake 代替。

我不完全了解哪些功能需要 GMake。

线条

SOURCES = $(wildcard *.cc)
OBJECTS = $(patsubst %.cc,%.o,%(SOURCES))

是 GNU make 语法,FreeBSD 的 make 无法理解,它有自己的方言(特别是 $(wildcard)$(patsubst))。如果您需要编写可移植到许多系统的 makefile,要么要求存在 gmake 并使用 GNUmakefile,要么坚持使用 features of POSIX make.

您可以使用

在 FreeBSD 上安装 GNU make (gmake)
cd /usr/ports/devel/gmake
make install clean

在 FreeBSD 的 make 中,你可以这样做:

SOURCES!= ls *.cc
OBJECTS = ${SOURCES:.cc=.o}

第一行使用了变量赋值修饰符。将值展开后传给shell执行,并将结果赋值给变量。结果中的任何换行符都将替换为空格。这是一个非常强大的机制。你应该例如使用 find 而不是 ls 也可以在子目录中搜索;

SOURCES!= find . -type f -name '*.cc'

第二行使用 变量修饰符 来执行 AT&T System V UNIX 风格的变量替换。它将后缀 .cc 替换为 .o 后缀。