首页 > 解决方案 > 编译器对 make 表现异常

问题描述

关于makefile有一个非常奇怪的问题,请让我描述一下:

我的项目中有两个文件,一个文件是makefile , makefile的内容如下:

context::
    @echo "hello makefile"

另一个是makefile.outmakefile.out文件的内容如下:

all:
    echo "hello makefile.out"

当我要编译我的项目时,我会使用make -f makefile.out替换make操作,因为我想调用makefile.out文件,但是奇怪的是发生了什么,当我执行时make -f makefile.out,我会在控制台上看到这样的操作:

cp Makefile Makefile.out
hello makefile

然后我的 makefile.out 文件被修改如下:

############################################################################
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.  The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################/


context::
    @echo "hello makefile"

如您所见,这个结果不是我想要的,但我不知道为什么会出现这个问题。

不知道有没有人和我遇到过类似的问题。如果是这样,你能告诉我解决方案代码吗?

标签: makefile

解决方案


我知道为什么会这样。

首先,GNU make 有一个内置规则,它显示了如何%.out从文件构建%文件;make -p将会呈现:

%.out: %
#  recipe to execute (built-in):
        @rm -f $@
         cp $< $@

其次,make 将始终尝试重建它加载或包含的任何 makefile;请参阅 GNU make 手册的Makefiles are Remade部分。

因此,每次运行时make -f makefile.out如果(且仅当)makefile比 更新makefile.out,make 将复制makefilemakefile.out.

您可以通过多种方式之一避免这种情况:以下任何一种方式都可以解决问题:

首先并且可能最好的方法是避免在系统中使用.out后缀命名的任何重要文件。该后缀传统上用于日志文件、输出文件等。在许多环境中,这些文件默认被视为临时文件。这只是一个坏名字。

其次,您可以创建一个显式规则来makefile.out覆盖模式规则:

makefile.out: ;

第三,您可以通过将其添加到您的 makefile 来删除该默认规则:

%.out: %

(没有其他先决条件,没有配方)。请参阅取消模式规则

-r第四,您可以通过将选项添加到您的MAKEFLAGS;来删除所有内置模式规则。像这样将它添加到您的makefile中:

MAKEFLAGS += -r

请注意,此解决方案需要 GNU make 4.0 或更高版本。


推荐阅读