Reputation: 15
there is a very strange question about makefile, please let me describe it:
There are two files in my project, one file is makefile, the content of makefile is as follows:
context::
@echo "hello makefile"
and the other is makefile.out, the content of the makefile.out file is as follows:
all:
echo "hello makefile.out"
When I am going to compile my project, I will use make -f makefile.out
to replace the make
operation, because I want to call the makefile.out file, but it is strange What happened, when I executed make -f makefile.out
, I would see such an operation on the console:
cp Makefile Makefile.out
hello makefile
and then my makefile.out file was modified as follows:
############################################################################
#
# 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"
As you have seen, this result is not I want it, but I don't know why this problem occurs.
I don’t know if anyone has encountered a similar problem with me. If so, can you tell me the solution code?
Upvotes: 0
Views: 61
Reputation: 100876
I know why this happened.
First, there's a built-in rule for GNU make that shows how to build a %.out
file from a %
file; make -p
will show:
%.out: %
# recipe to execute (built-in):
@rm -f $@
cp $< $@
Second, make will always try to rebuild any makefile that it loads or includes; see the How Makefiles are Remade section of the GNU make manual.
So every time you run make -f makefile.out
, then IF (and only if) the makefile
is newer than makefile.out
, make will copy makefile
to makefile.out
.
You can avoid this in one of a number of ways: any one of the following will solve the problem:
First and probably the best is to avoid having any important file in your system named with a .out
suffix. That suffix is traditionally used for log files, output files, etc. There are many environments where those files are treated as temporary by default. It's just a bad name.
Second, you could create an explicit rule for makefile.out
which would override the pattern rule:
makefile.out: ;
Third, you can remove that default rule by adding this to your makefile:
%.out: %
(no other prerequisites, no recipe). See Canceling Pattern Rules.
Fourth, you could remove ALL built-in pattern rules by adding the -r
option to your MAKEFLAGS
; add it to your makefile like this:
MAKEFLAGS += -r
Note this solution requires GNU make 4.0 or better.
Upvotes: 1