【问题标题】:can't get implicit/pattern rules working in any capacity无法获得以任何身份工作的隐式/模式规则
【发布时间】:2018-05-22 01:57:31
【问题描述】:

所以我正在尝试编写这个 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 规则工作要么)

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

我的理解是没有输出目标文件,ergo ld 失败,因为它没有找到主要功能。

这对我来说是显而易见且(痛苦地)清楚的。 (我用一个非常简单的例子来测试这个: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.

正如预期的那样,同样的问题也面临着,即由于某种原因永远无法达到目标。

【问题讨论】:

    标签: makefile gnu-make


    【解决方案1】:

    这是错误的:

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

    函数名是patsubst而不是pathsubst

    【讨论】:

    • 好吧,现在我只是觉得自己很愚蠢,它可以完美地修复错字 - 接受并赞成,谢谢。 (我是认真的,我自己从来没有发现过)
    • 是的,这很棘手。您可以在运行 make 时启用 --warn-undefined-variables 选项,它应该会发出警告。除此之外,您只需要意识到如果 make 没有构建您的先决条件,它 必须 意味着 $(OBJECTS) 变量正在扩展为空字符串并盯着它直到一分钱下降(那是我做了什么:))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多