Makefile:108:***配方在第一个目标之前开始 [英] Makefile:108: *** recipe commences before first target

查看:1367
本文介绍了Makefile:108:***配方在第一个目标之前开始的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为x86_64-pc-linux-gnu构建的GNU Make 4.1

GNU Make 4.1 Built for x86_64-pc-linux-gnu

下面是Makefile:

# Project variables
PROJECT_NAME ?= todobackend
ORG_NAME ?= shamdockerhub
REPO_NAME ?= todobackend

# File names
DEV_COMPOSE_FILE := docker/dev/docker-compose.yml
REL_COMPOSE_FILE := docker/release/docker-compose.yml

# Docker compose project names
REL_PROJECT := $(PROJECT_NAME)$(BUILD_ID)
DEV_PROJECT := $(REL_PROJECT)dev

# Check and inspect logic
INSPECT := $$(docker-compose -p $$1 -f $$2 ps -q $$3 | xargs -I ARGS docker inspect -f "{{ .State.ExitCode }}" ARGS)

CHECK := @bash -c '\
    if [[ $(INSPECT) -ne 0 ]]; \
    then exit $(INSPECT); fi' VALUE

# Use these settings to specify a custom Docker registry
DOCKER_REGISTRY ?= docker.io

APP_SERVICE_NAME := app

.PHONY: test build release clean tag

test: # Run unit & integration test cases
    ${INFO} "Pulling latest images..."
    @ docker-compose -p $(DEV_PROJECT) -f $(DEV_COMPOSE_FILE) pull
    ${INFO} "Building images..."
    @ docker-compose -p $(DEV_PROJECT) -f $(DEV_COMPOSE_FILE) build cache
    @ docker-compose -p $(DEV_PROJECT) -f $(DEV_COMPOSE_FILE) build --pull test
    ${INFO} "Ensuring database is ready..."
    @ docker-compose -p $(DEV_PROJECT) -f $(DEV_COMPOSE_FILE) run --rm agent
    ${INFO} "Running tests..."
    @ docker-compose -p $(DEV_PROJECT) -f $(DEV_COMPOSE_FILE) up test
    @ docker cp $$(docker-compose -p $(DEV_PROJECT) -f $(DEV_COMPOSE_FILE) ps -q test):/reports/. reports
    ${CHECK} ${DEV_PROJECT} ${DEV_COMPOSE_FILE} test
    ${INFO} "Testing complete"

build: # Create deployable artifact and copy to ../target folder
    ${INFO} "Creating builder image..."
    @ docker-compose -p $(DEV_PROJECT) -f $(DEV_COMPOSE_FILE) build builder
    ${INFO} "Building application artifacts..."
    @ docker-compose -p $(DEV_PROJECT) -f $(DEV_COMPOSE_FILE) up builder
    ${CHECK} ${DEV_PROJECT} ${DEV_COMPOSE_FILE} builder
    ${INFO} "Copying artifacts to target folder..."
    @ docker cp $$(docker-compose -p $(DEV_PROJECT) -f $(DEV_COMPOSE_FILE) ps -q builder):/wheelhouse/. target
    ${INFO} "Build complete"

release: # Creates release environment, bootstrap the environment  
    ${INFO} "Building images..."
    @ docker-compose -p $(REL_PROJECT) -f $(REL_COMPOSE_FILE) build webroot
    @ docker-compose -p $(REL_PROJECT) -f $(REL_COMPOSE_FILE) build app
    ${INFO} "Ensuring database is ready..."
    @ docker-compose -p $(REL_PROJECT) -f $(REL_COMPOSE_FILE) run --rm agent
    ${INFO} "Collecting static files..."
    @ docker-compose -p $(REL_PROJECT) -f $(REL_COMPOSE_FILE) run --rm app manage.py collectstatic --noinput
    ${INFO} "Running database migrations..."
    @ docker-compose -p $(REL_PROJECT) -f $(REL_COMPOSE_FILE) run --rm app manage.py migrate --noinput
    ${INFO} "Pull external image and build..."
    @ docker-compose -p $(REL_PROJECT) -f $(REL_COMPOSE_FILE) build --pull nginx
    @ docker-compose -p $(REL_PROJECT) -f $(REL_COMPOSE_FILE) pull test
    ${INFO} "Running acceptance tests..."
    @ docker-compose -p $(REL_PROJECT) -f $(REL_COMPOSE_FILE) up test
    ${CHECK} $(REL_PROJECT) $(REL_COMPOSE_FILE) test
    @ docker cp $$(docker-compose -p $(REL_PROJECT) -f $(REL_COMPOSE_FILE) ps -q test):/reports/. reports
    ${INFO} "Acceptance testing complete"

clean:
    ${INFO} "Destroying development environment..."
    @ docker-compose -p $(DEV_PROJECT) -f $(DEV_COMPOSE_FILE) kill
    @ docker-compose -p $(DEV_PROJECT) -f $(DEV_COMPOSE_FILE) rm -f -v
    @ docker-compose -p $(REL_PROJECT) -f $(REL_COMPOSE_FILE) kill
    @ docker-compose -p $(REL_PROJECT) -f $(REL_COMPOSE_FILE) rm -f -v
    @ docker images -q -f dangling=true -f label=application=$(REPO_NAME) | xargs -I ARGS docker rmi -f ARGS
    ${INFO} "Clean complete"

tag:
    $(INFO) "Tagging release image with tags $(TAG_ARGS)"
    @ $(foreach tag, $(TAG_ARGS), docker tag $(IMAGE_ID) $(DOCKER_REGISTRY)/$(ORG_NAME)/$(REPO_NAME):$(tag);)
    ${INFO} "Tagging complete"


# Cosmetics 
YELLOW := "\e[1;33m"
NC := "\e[0m"

# Shell functions
INFO := @bash -c '\
    printf $(YELLOW); \
    echo "=> $$1"; \
    printf $(NC)' VALUE

# Get container id of application service container
APP_CONTAINER_ID := $$(docker-compose -p $(REL_PROJECT) -f $(REL_COMPOSE_FILE) ps -q $(APP_SERVICE_NAME))

# Get image id of application service
IMAGE_ID := $$(docker inspect -f '{{ .Image }}' $(APP_CONTAINER_ID))

# Extract tag arguments
ifeq (tag, $(firstword $(MAKECMDGOALS)))
    TAG_ARGS := $(wordlist 2, $(words $(MAKECMDGOALS)), $(MAKECMDGOALS))
    ifeq ($(TAG_ARGS),)
        $(error You must specify a tag)
    endif
    $(eval $(TAG_ARGS):;@:) # line 108 Do not interpret "0.1 latest whatever" as make target files 
endif


以下是在运行make命令时出现的错误:


Below is the error on running make command:

$ make tag 0.1 latest $(git rev-parse --short HEAD)
Makefile:108: *** recipe commences before first target.  Stop.

第108行,$(eval $(TAG_ARGS):;@:)的目的是传达0.1 latest $(git rev-parse --short HEAD)不是make目标.

Line 108, purpose of $(eval $(TAG_ARGS):;@:) to convey that 0.1 latest $(git rev-parse --short HEAD) are not make targets.

为什么$(eval $(TAG_ARGS):;@:)提供错误?

推荐答案

发生此特定错误是因为您的$(eval ...)行被TAB缩进了(某些东西被这个可怕的Web界面隐藏了).

That particular error happens because your $(eval ...) line is indented by a TAB (something that it's hidden by this horribly broken web interface).

示例:

$ make -f <(printf '\t$(eval foo:;echo yup)')
/dev/fd/63:1: *** recipe commences before first target.  Stop.

# now with spaces instead of TAB
$ make -f <(printf '    $(eval foo:;echo yup)')
echo yup
yup

该错误记录在make

recipe commences before first target. Stop.

这意味着makefile中的第一件事似乎是 食谱:以食谱前缀字符开头,没有出现 成为合法的make指令(例如变量分配). 食谱必须始终与目标关联.

This means the first thing in the makefile seems to be part of a recipe: it begins with a recipe prefix character and doesn't appear to be a legal make directive (such as a variable assignment). Recipes must always be associated with a target.

食谱前缀字符"默认为TAB.

The "recipe prefix character" is TAB by default.

$ make -f <(printf '\tfoo')
/dev/fd/63:1: *** recipe commences before first target.  Stop.

不过,它不必一定是"makefile中的第一件事":如果在多个规则之后(如果前面带有诸如宏赋值之类的指令之类的指令),则会触发相同的错误:

It doesn't have to be the "first thing in the makefile", though: the same error will trigger after a number of rules, if preceded by a directive like a macro assignment or such:

$ make -f <(printf 'all:;\nkey=val\n\tfoo')
/dev/fd/63:3: *** recipe commences before first target.  Stop.

即使宏扩展为空字符串,GNU make也不会考虑仅包含宏扩展为空字符串的行为空:

And even if a macro expands to an empty string, GNU make will not consider empty a line containing just macros expanding to empty strings:

$ make -f <(printf '\t\nfoo:;@:')
$ make -f <(printf '\t$(info foo)\nfoo:;@:')
/dev/fd/63:1: *** recipe commences before first target.  Stop.
$ make -f <(printf '   $(info foo)\nfoo:;@:')
foo

这篇关于Makefile:108:***配方在第一个目标之前开始的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆