не может получить неявные / шаблонные правила, работающие в любом качестве - PullRequest
0 голосов
/ 22 мая 2018

Итак, я пытаюсь написать этот make-файл, и у меня возникают некоторые проблемы с его работой, на самом деле у меня возникают проблемы с получением make-файлов в целом (без сомнения, из-за ошибки пользователя).

make output:

$ 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

makefile:

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 ++, я думаю).

AmЯ использую расширения GNU неправильно?Я знаю, что call является расширением GNU.

ожидаемый результат будет:

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

Этот make-файл очень похож на другие make-файлы, которые я видел плавающими на SO, например, https://stackoverflow.com/a/2484343/2717116 - однако этот make-файл при копировании дословно также не работает для меня - дословный вывод:

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

, как и ожидалось, сталкивается с той же проблемой, а именно, что make-цель никогда не достигается по одной причинеили другой.

1 Ответ

0 голосов
/ 22 мая 2018

Это неверно:

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

Имя функции patsubst, а не pathsubst.

...