I have a working make, I have platform code and like several makes for each os in the folder. Right now I have one makefile which works. I renamed it to Makefile.ws and wrote this in Makefile
all:
make -f Makefile.w32
clean:
make -f Makefile.w32 clean
I ran it and got this error
> "make"
make -f Makefile.w32
make[1]: Entering directory `/c/nightly/test'
make -f Makefile.w32
make[3]: Makefile.w32: No such file or directory
make[3]: *** No rule to make target `Makefile.w32'. Stop.
make[2]: *** [all] Error 2
make[1]: *** [build] Error 2
make[1]: Leaving directory `/c/nightly/test'
"make": *** [all] Error 2
Oddly enough the clean works perfectly. Then I decided to write "make -f Makefile.w32 mingw32" and that did not work correctly. In fact it made a folder called mingw32 which I thought was very strange.
As for the mingw32 rule I just copy build which I suspect is the main/normal rule that is used to build
$(BUILD):
#[ -d $# ] || mkdir -p $#
#make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
mingw32:
#[ -d $# ] || mkdir -p $#
#make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
full .w32 source is here http://pastie.org/320035
First, what make are you running? Cygwin or MinGW, or something else?
make -f Makefile.w32
make[1]: Entering directory `/c/nightly/test'
make -f Makefile.w32
make[3]: Makefile.w32: No such file or directory
"Entering directory" is a hint. Why is it entering /c/nightly/test? Is there a Makefile.w32 there?
As to creating the directory "mingw32", the rule
mingw32:
#[ -d $# ] || mkdir -p $#
...
does exactly that. If "mingw32" does not exist, it creates it.
It would be easier to help you if you had a shorter example and clearly explain what you want to accomplish and what you expect to happen.
I think I see the problem in your second example. The mingw32 line should be changed so that it does not include the $(BUILD) variable:
mingw32:
#[ -d $# ] || mkdir -p $#
#make --no-print-directory -C mingw32 -f $(CURDIR)/Makefile
It is clear that he created the directory,
your first command in your given 2 rules, include a mkdir with the object name, i.e. either build or mingw32
Afterwards he changes into the current directory (i.e. no cd at all) and execute Makefile. But as you wrote you renamed Makefile into Makefile.ws, so offcourse you are getting File-Not-Found-error.
From the questions I can only recommend you to have a look at an short introduction or even better the manual for make.
Have you tried calling the secondary makefile using
$(MAKE) -f ...
instead of
make -f ...?
Related
i was compiling a kernel module thermal.c at an ARCH linux distro using Makefile
Makefile:
obj-m += thermal.o
all:
make -C /lib/modules/$(uname -r)/build/ M=$(PWD) modules
clean:
make -C /lib/modules/$(uname -r)/build/ M=$(PWD) clean
the make command output is:
make -C /lib/modules//build/ M=/home/user/dir modules
make[1]: *** /lib/modules//build/: No such file or directory. Stop.
make: *** [Makefile:4: all] Error 2
uname -r output : 5.6.8-arch1-1
make expands the recipes before passing them to the shell. In your case make replaced $(PWD) by the value of the make variable named PWD (correct) but it also replaced $(uname -r) by the value of the make variable named uname -r. As there was no such make variable defined, the result was the empty string. Using $$(uname -r) solves the problem because make expands it as $(uname -r), exactly what you want to pass to the shell.
In summary, you must escape the $ you want to preserve from the make expansion by doubling them:
all:
make -C /lib/modules/$$(uname -r)/build/ M=$(PWD) modules
clean:
make -C /lib/modules/$$(uname -r)/build/ M=$(PWD) clean
Here's a minimal example of what I'm trying to do.
Directory structure:
.
├── Makefile
└── subdir
├── a
└── Makefile
./subdir/Makefile:
a.copy: a
cp a a.copy
./Makefile:
.PHONY: build_subdir
a.copy: subdir/a.copy
cp subdir/a.copy a.copy
build_subdir:
$(MAKE) -C subdir
subdir/a.copy: build_subdir
The first time I run make, everything's fine:
$ make
make -C subdir
make[1]: Entering directory `/home/kkourt/src/tests/make/subdir'
cp a a.copy
make[1]: Leaving directory `/home/kkourt/src/tests/make/subdir'
cp subdir/a.copy a.copy
Re-runing make is also fine (nothing happens):
$ make
make -C subdir
make[1]: Entering directory `/home/kkourt/src/tests/make/subdir'
make[1]: `a.copy' is up to date.
make[1]: Leaving directory `/home/kkourt/src/tests/make/subdir'
If I update subdir/a, however, ./a is not updated:
$ touch subdir/a
$ make
make -C subdir
make[1]: Entering directory `/home/kkourt/src/tests/make/subdir'
cp a a.copy
make[1]: Leaving directory `/home/kkourt/src/tests/make/subdir'
If I run make a second time, ./a gets updated
$ make
make -C subdir
make[1]: Entering directory `/home/kkourt/src/tests/make/subdir'
make[1]: `a.copy' is up to date.
make[1]: Leaving director
Why does this happen? shouldn't the check of whether subdir/a.copy is older than a.copy happen after the build_subdir target is finished since it's its dependency? Is there a way to fix this?
Edit:
As MadScientist suggested, I added a dummy recipe and it works:
subdir/a.copy: build_subdir
#:
Because your rule subdir/a.copy: build_subdir has no recipe, make "knows" that it can't actually change the timestamp on subdir/a.copy.
You need add a dummy recipe to it, maybe like this:
subdir/a.copy: build_subdir ;
(note I can't test this right now but I think it'll work).
I am trying to link Lapack library with my Makefile and Fortran 90 code (gfortran), but every time I type : make pkr_test (pkr_test is the name of the code)
I get the following error :
make[1]: * No rule to make target '/usr/ben/models/common/src/fitting.o'. Stop.
make[1]: Leaving directory '/usr/ben/models/common/src'
Makefile:20: recipe for target '/usr/ben/models/common/src/fitting.o' failed
make: * [/usr/ben/models/common/src/fitting.o] Error 2
I can attach the Makefile and the Makefile. In case it will help you to give me a quick solution. I actually tried to attach it but I didn't manage.
Here is the Makefile:
#
# Makefile for pqr_test
#
include ../../Makefile.in
#
MODS= $(DIR_test)wrt_two.o \
$(DIR_test)ppt_one.o \
$(DIR_test)cat_one.o \
$(DIR_test)uti_test.o \
$(DIR_test)ncdf_test.o \
$(DIR_test)quick_test.o \
$(DIR_test)ovr_one.o \
$(DIR_test)row_to.o \
$(DIR_test)fitting.o
#
OBJS=pqr_test.o
#
$(MODS) :
cd $(DIR_test) && make $(MODS)
#
pqr_test : $(MODS) $(OBJS)
cd $(DIR_test) && make $(MODS)
$(FC) $(FFLAGS) -L$(XML_LIB) -L$(NC_LIB_LOC) -L$(NC_LIB_LAPACK_LOC) -I$(NC_INCLUDE) -I$(NC_LAPACK_INCLUDE) \
-Wl,-rpath,$(NC_LIB_LOC) $(NC_LIB_LAPACK_LOC) $(MODS) $(OBJS) $(NC_LIB) $(NC_LIB_LAPACK) \
-lflib -o ../bin/pqr_test
#
pqr_test.o : pqr_test.f90
cd $(DIR_test) && make $(MODS)
$(FC) $(FFLAGS) -I$(DIR_test) -I$(XML_INCLUDE) -I$(NC_INCLUDE) -I$(NC_LAPACK_INCLUDE) -c pqr_test.f90
#
cleanup:
mv $(DIR_test)*.o $(DIR_test)../obj/
mv $(DIR_test)*.mod $(DIR_test)../mod/
mv *.o ../obj/
#
clean:
rm -f $(DIR_test)*.o
rm -f $(DIR_test)../obj/*.o
rm -f $(DIR_test)*.mod
rm -f $(DIR_test)../obj/*.o
rm -f *.o
rm -f ../obj/*.o
#
I am trying to link Lapack library with my Makefile and Fortran 90 code (gfortran), but every time I type : make pkr_test (pkr_test is the name of the code) I get the following error :
make[1]: * No rule to make target '/usr/ben/models/common/src/fitting.o'. Stop.
make[1]: Leaving directory '/usr/ben/models/common/src'
Makefile:20: recipe for target '/usr/ben/models/common/src/fitting.o' failed
make: * [/usr/ben/models/common/src/fitting.o] Error 2
The Makefile tries to build the (object) modules specified in MODS variable, including the last one, $(DIR_test)fitting.o.
It does this by doing the equivalent of calling itself, make $(DIR_test)fitting.o. The problem is that your Makefile, and the included Makefile (../../Makefile.in) don't include instructions on how to generate that file, and the implicit make rules don't success either.
As the dependency ($(DIR_test)fitting.o) cannot be built, make cannot build your specified target (pkr_test).
I've gone over a number of other posts about recursive makefiles. Either I'm doing something wrong or there's a missing feature that I want. With a typical makefile I can check to see if it's out of date with -q, for example:
make -q || echo "out of date"
However, setting up a mechanism to force make to process dependent makefiles causes the root makefile to always be out of date. Here's a working example:
#./Makefile
all: myfile
myfile: dir
cp dir/myfile .
.PHONY: dir
dir:
$(MAKE) -C dir/
#./dir/Makefile
all: myfile
myfile:
touch myfile
#testing...
>>> make
make -C dir/
make[1]: Entering directory `dir'
touch myfile
make[1]: Leaving directory `dir'
cp dir/myfile .
>>> make
make -C dir/
make[1]: Entering directory `dir'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `dir'
cp dir/myfile . #<-- this shouldn't be necessary
>>> make -q || echo "out of date"
make -C dir/
out of date
Is there a mechanism that allows the recursive make call to return and say "actually everything's up to date here, no need to continue"?
There's an hacky way of doing it, maybe.
You could invoke $(MAKE) -q ... && touch something from inside the makefile, and have the something file as requisite for some rule in the outer makefile.
No, there's no way to do that. A recursive invocation of make is just another command that make invokes in a shell: the only result of that command available to make is the exit code. If we could always be sure that the command invoked was a make command, and that we were using the -q flag, then we could assume that if it exited with a 0 then nothing was done. But make does not assume those things.
You will need to rewrite your makefiles to be non-recursive to get the behavior you want.
#Dacav gave me the idea of calling make explicitly. Though without using a temporary files, target dependencies can be set dynamically using a shell-populated variable. I'm not sure the following is a good solution because even when calling make without -q it recursively calls make -q to populate OLD_CHILDREN. Moreover this will happen again unnecessarily for the child makefiles too (assuming multiple levels of recursion).
#./Makefile
CHILDREN=dir/
OLD_CHILDREN=$(foreach c, $(CHILDREN), $(shell make -q -C $(c) || echo $(c)))
all: myfile
myfile: $(OLD_CHILDREN)
cp dir/myfile .
.PHONY: $(CHILDREN)
$(CHILDREN):
$(MAKE) -C $#
Testing...
>>> make -q || echo out of date
make -C dir/
make: *** [dir/] Error 1 #huh??? whatever. still works, returning out of date
out of date
>>> make
make -C dir/
make[1]: Entering directory `dir'
touch myfile
make[1]: Leaving directory `dir'
cp dir/myfile .
>>> make
make: Nothing to be done for `all'.
>>> make -q || echo out of date
>>> #nothing. success :D
I'm trying to write a makefile to produce several output files for each of several sources, using pattern rules.
I have the following Makefile (GNU Make 3.8.1):
all : foo.all bar.all
%.all : %.pdf %.svg
#echo Made $*
%.pdf :
touch $#
%.svg :
touch $#
.PHONY: foo.all bar.all
Since *.all do not represent real output files, I tried marking them as .PHONY. However, running make then doesn't work:
$ ls
Makefile
$ make
make: Nothing to be done for `all'.
According to make -d:
No implicit rule found for `all'.
Considering target file `foo.all'.
File `foo.all' does not exist.
Finished prerequisites of target file `foo.all'.
Must remake target `foo.all'.
Successfully remade target file `foo.all'.
Considering target file `bar.all'.
File `bar.all' does not exist.
Finished prerequisites of target file `bar.all'.
Must remake target `bar.all'.
Successfully remade target file `bar.all'.
Finished prerequisites of target file `all'.
Must remake target `all'.
Successfully remade target file `all'.
make: Nothing to be done for `all'.
which seems to be pretending to run the %.all rules, but skipping the bodies.
But with the .PHONY line commented out, Make runs the targets, but then spontaneously decides to delete the output files:
$ make
touch foo.pdf
touch foo.svg
Made foo
touch bar.pdf
touch bar.svg
Made bar
rm foo.pdf foo.svg bar.pdf bar.svg
According to make -d, it says:
Removing intermediate files...
Minimal example
A minimal example giving anomalous behavior:
%.all: %.out
#echo Made $*
%.out:
touch $#
I expect running make somefile.all to cause it to create the file somefile.out, but it gets deleted:
$ make somefile.all
touch somefile.out
Made somefile
rm somefile.out
Keeping make from deleting intermediary files
I recommend against using .PRECIOUS (see below as to why). Using .SECONDARY would preserve the .out files:
TARGETS=foo bar
all: $(TARGETS:=.all)
%.all: %.out
#echo Made $*
%.out:
touch $#
.SECONDARY: $(TARGETS:=.out)
$(TARGETS:=.all) just appends .all to all names in TARGETS. $(TARGETS:=.out) appends .out. We apparently cannot use %.out as a target of .SECONDARY. These just save having to relist all targets individually.
I prefer to not use .PRECIOUS for this because the documentation says
if make is killed or interrupted during the execution of their recipes, the target is not deleted.
This can leave corrupted files in the file system. Here's an example.
all: foo.all bar.all
%.all: %.out
#echo Made $*
%.out:
sh -e -c 'echo "{1, 2, 3" > $#; FAIL!; echo "}" >> $#'
.PRECIOUS: %.out
The FAIL! command simulates a tool that crashes in the middle of its work. Here's a shell session working with the Makefile above:
$ ls
Makefile
$ make
sh -e -c 'echo "{1, 2, 3" > foo.out; FAIL!; echo "}" >> foo.out'
sh: 1: FAIL!: not found
make: *** [foo.out] Error 127
$ cat foo.out
{1, 2, 3
Yikes... my foo.out file is incomplete. Let's try making again:
$ make
Made foo
sh -e -c 'echo "{1, 2, 3" > bar.out; FAIL!; echo "}" >> bar.out'
sh: 1: FAIL!: not found
make: *** [bar.out] Error 127
$ cat *.out
{1, 2, 3
{1, 2, 3
Make is none the wiser about files left around by earlier runs so when you run make again, it will take the corrupted files at face value. foo.out was not remade (despite the "Made foo" message) because it already exists and the Makefile went straight to trying to make bar.
.SECONDARY makes it so that:
The targets which .SECONDARY depends on are treated as intermediate files, except that they are never automatically deleted.
This means they are never automatically deleted just because they are intermediate files. The default make behavior of deleting targets that were being rebuilt if the tool rebuilding them crashed is not affected.
Using .PHONY with pattern rules
It seems though that .PHONY works only for targets that are explicit, not inferred. I've not found documentation confirming this. However, this works:
TARGETS:=foo bar
TARGETS_all:=$(TARGETS:=.all)
.PHONY: all
all: $(TARGETS_all)
.PHONY: $(TARGETS_all)
$(TARGETS_all): %.all: %.out
#echo Made $*
%.out:
touch $#
.SECONDARY: $(TARGETS:=.out)
In this rule $(TARGETS_all): %.all: %.out $(TARGETS_all): gives the list of targets to which the pattern can be applied. It makes foo.all and bar.all explicit targets. Without this, they would be inferred targets.
You can test that it works by creating file called foo.all in your directory and run make over and over. The foo.all file has no effect on make.
Your somefile.out files are considered intermediate by GNU make, which is why they are automatically deleted in your example. You can instruct GNU make to preserve these files by use the of .PRECIOUS special target, like this:
%.all: %.out
#echo Made $*
%.out:
touch $#
.PRECIOUS: %.out