无法获得以任何身份工作的隐式/模式规则

时间:2018-05-22 01:57:31

标签: makefile gnu-make

所以我正在尝试编写这个makefile,但是我遇到了一些问题,实际上我遇到了makefile文件的问题(毫无疑问是由于用户错误)。

输出:

$ make -v
    GNU Make 4.2.1
    Built for x86_64-unknown-linux-gnu
    Copyright (C) 1988-2016 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.

$ make clean all
    rm -rf a.out  bin
    rm -rf obj
    g++ -lm  -o bin/a.out
    /usr/lib/gcc/x86_64-pc-linux-gnu/8.1.0/../../../../lib/Scrt1.o: In function `_start':
    (.text+0x20): undefined reference to `main'
    collect2: error: ld returned 1 exit status
    make: *** [makefile:32: bin/a.out] Error 1

生成文件:

CXX := g++
LXX := g++
CXXFLAGS := -m64 -std=gnu++14 -fno-enforce-eh-specs -fno-rtti -fpermissive -O3 -funswitch-loops -w
CXXDEBUG := -ggdb3 -pg
LDFLAGS  := -lm

EXE := a.out
SRC_DIR := src
BIN_DIR := bin
OBJ_DIR := obj
INCLUDE := $(addprefix -I, include)
SOURCES := $(foreach sdir, $(SRC_DIR), $(wildcard $(sdir)/*.cpp))
OBJECTS := $(pathsubst src/%.cpp, obj/%.o, $(SOURCES))
vpath %.cpp $(SRC_DIR)/

define make-goal
$1/%.o: %.cpp 
    $(CXX) $(INCLUDE) $(CXXFLAGS) -c $$< -o $$@
endef

.PHONY: clean all checkdirs $(BIN_DIR)/a.out
.SECONDARY: 

default: all

all: checkdirs $(BIN_DIR)/a.out

$(BIN_DIR)/a.out: $(OBJECTS)
    $(LXX) $(LDFLAGS) $^ -o $@

checkdirs: $(BIN_DIR) $(OBJ_DIR)

$(BIN_DIR):
    @mkdir -p $@
$(OBJ_DIR):
    @mkdir -p $@

clean: 
    rm -rf $(EXE) $(OBJECTS) bin
    @find . -name "*~" -exec rm {} \;
    @find . -name "*.o" -exec rm {} \;
    rm -rf obj

$(foreach odir,$(OBJ_DIR),$(eval $(call make-goal,$(odir))))

我的理论是,最终的$(foreach ......)永远不会被执行,或者创建的隐式模式规则没有被执行(想到它我永远不会得到%。o:%。c规则工作要么)

但老实说?我不知道,手册没有提供任何帮助 - 至少不是我能找到(或者,可能,理解)。

我的理解是没有输出任何目标文件,因为它没有找到主函数而失败了。

对我来说,这很明显且(痛苦)清楚。 (我正在用一个非常简单的例子来测试它:hello world,它干净地编译并按照预期用g ++ world.cpp -o a.out执行,所以我认为这不是g ++健全问题。)

我使用GNU扩展程序错了吗?我知道call是一个GNU扩展。

预期输出为:

├── bin
│   └── a.out
├── makefile
├── obj
│   └── world.o
└── src
    └── world.cpp

这个makefile非常类似于我在SO上看到的其他makefile,例如https://stackoverflow.com/a/2484343/2717116 - 但是这个makefile在逐字复制时似乎对我不起作用 - 逐字输出:

make all
g++  -o build/test.exe
g++: fatal error: no input files
compilation terminated.

正如预期的那样,面临同样的问题,即由于某种原因从未实现过制造目标。

1 个答案:

答案 0 :(得分:0)

这是错误的:

OBJECTS := $(pathsubst src/%.cpp, obj/%.o, $(SOURCES))

函数名称为patsubst而非pathsubst