How can I ctreate a simple makefile for minGW + gfortran - makefile

I am absolutely new in gfortran+minGW.
I need to create makefile.
When I run
$ gfortran -c q.f
All is ok!
But how can I run makefile like this?
CC = gfortran
q.o : q.f
$(CC) -c q2.o q2.f
I receive error “CC: command not found”.
(OS – Win 7 (64))
Tanks!!!

It kind of looks like you're trying to run the makefile as a regular script. Try
$ make
or
$ make -f mymakefilename
if you named the file something other than "makefile" or "Makefile".
You can potentially just execute the makefile, but if so you need a "shebang" line, something like
#!/usr/bin/make
at the top of the file, but frankly hardly anyone uses that option. Just use the make(1) command.
Update
It's because they're in the wrong order. Makefiles process (by default) the first target in the file. When you run make it sees the rule to make, q.o from q.f, it compiles it, and says, "Okay, I'm done."
If you put the q.exe target first, it says "Hmmm, I want to build q.exe and to do that I need a q.o. Do I have a q.o? No? Okay, hen I'll build a q.o. I have a rule for that -- I can build a q.o from q.f. okay, that's done. Now can I build q.exe? Oh, yes, I can. I'll build q.exe. Anything? Nope, I'm done."
If you were to use the commend
$ make q.exe
then you'd explicitly tell make to make q.exe, which would cause the same thing to happen, but better you should reorder your makefile and get used to the way they work.

Related

How to debug GNU make step by step?

I want to add a new fortran module into an existing fortran90 program. The existing fortran90 program is compiled by firstly running ./configure, then run the make and make install. If I want to define my own innovation, what else I need to do is export VER_USER=xxx, then make user and make installuser. It seems that make does the compilation job and make install does the installation job. And I need to add something like gfortran -o using_FKB using_FKB.o other.o ... -L/path_of_lib -lnewlib or path/to/libneural.a. So I need to debug the original Makefile. But I found it's difficult because the original Makefile is too long. I tried to use make -V=1 or make -d, and also make SHELL='sh -x' , but they prints so much things on my terminal...I could hardly debug. Is there anyway to debug it step by step?
By the way, there are too much $() variable in the Makefile. When I use ``make -V=1ormake -d, and also make SHELL='sh -x' , I found they hardly print the command in Makefilelike$(OBJ_PATH)=/path/obj_path...and it's quite hard for me to debug this...so is there any way to debug the Makefile``` step by step? Thanks!

Running makefile by its name

I'm learning about makefiles. I've written a simple hello world like makefile named just makefile2 but when I run mingw32-make makefile2 I get:
Nothing to be done for 'makefile2'.
When I run just only mingw32-make (without supplying the file name) it works.
My question is it a rule to have only one makefile in the folder and to run it we don't provide a file name at all?
Is it possible to run specific makefile providing it's name?
PS. I'm using MinGW on Windows 10
Usually you need the -f option to tell make to use another file than Makefile or makefile, like
make -f makefile2
Without the -f flag, you tell make to build the target named (in your case) makefile2.

Force run a recipe (--assume-old=target)

I want to force a recipe for "output.file", even though it is up-to-date.
I have already tried make --assume-old=output.file output.file, but it does not run the recipe again.
In case you are curious: use case:
I want to use this together with --dry-run to find out the command that produce a target.
I ended up hiding the file to run make --dry-run output.file, but I was hoping for something more elegant + FMI: for future debugging makefile.
I think you're misunderstanding what that option does: it does exactly the opposite of what you hoped; from the man page:
-o file, --old-file=file, --assume-old=file
Do not remake the file file even if it is older than its dependen‐
cies, and do not remake anything on account of changes in file.
Essentially the file is treated as very old and its rules are
ignored.
You want output.file to be remade, so using -o is clearly not what you want.
There is no option in GNU make to say "always rebuild this target". What you can do is tell make to pretend that some prerequisite of the target you want to be rebuilt has been updated. See this option:
-W file, --what-if=file, --new-file=file, --assume-new=file
Pretend that the target file has just been modified. When used
with the -n flag, this shows you what would happen if you were to
modify that file. Without -n, it is almost the same as running a
touch command on the given file before running make, except that
the modification time is changed only in the imagination of make.
Say for example your output.file had a prerequisite input.file. Then if you run:
make -W input.file
it will show you what rules it would run, which would include rebuilding output.file.

Ignore clean command in Makefile

I have a project to compile with a lot of makefiles including a clean command. That's why i always have to start over again if there is an error (because the clean command is called in many Makefiles)
Question:
Is there any possibility to tell make to ignore the clean command? I would have to touch > 100 Makefiles otherwise. I would like make to start on the last error, not compiling all done stuff again
Example Makefile entries:
clean: cleansubdirs $(DIR) $(DIR1)
$(DIR2)
It's possible to redefine the recipe of an explicit target as simple as that:
noclean.mk
clean:;
cleansubdirs:;
# more stuff...
Now run make -f Makefile -f noclean.mk and it will work without actual cleaning files. However, make will issue several warnings about "overriding/ignoring old recipes".

always run a script when running 'make' before compiling

I'm using automake.
I'd like to have a script run each time I run 'make'.
This script does a git diff and generates an MD5 sum of the diff.
The hash is written as a #define in repos_version.h
e.g.:
#define REPOS_DIFF "-190886e9f895e80c42cf6b426dc85afd"
The script only rewrites this file if it doesn't exist or if the diff has is different to what is in repos_version.h already. But the script needs to be run for each make.
main.c includes repos_version.h and prints out the hash when the executable is run.
Here's Attempt 1 for Makefile.am
all: config.h
#chmod +x gen_diff_hash.sh
#./gen_diff_hash.sh
$(MAKE) $(AM_MAKEFLAGS) all-recursive
This work, but I get the following error
Makefile:1234: warning: overriding recipe for target all'
Makefile:734: warning: ignoring old recipe for targetall'
Here's Attempt 2 for Makefile.am
all-local:
#chmod +x gen_diff_hash.sh
#./gen_diff_hash.sh
main.c: repos_version.h
However, this doesn't work, as all-local seems to be run too late. A second run of 'make' does get the desired result, but that's not a runner.
So neither are great.
Any ideas?
I've been reading through the automake hooks documentation, but I can't see anything that suits my needs.
You could ensure the script is always run every time Make loads the Makefile, by executing it via $(shell ./gen_diff_hash.sh) and assigning it to a throwaway variable (or using it in some other construct like an ifeq or something).
Note, that this is not POSIX, and on Make implementations other than GNU this isn't valid syntax. GNU Make 4.x supports using VAR != ./gen_diff_hash.sh as well, which is compatible with BSD Make at least.
But maybe it would be a better idea to create a .PHONY: gendiff target that runs the script, and make the header depend on this gendiff. The target would then be re-evaluated every time Make checks if repos_version.h is up-to-date, rather than every time Make is run at all.

Resources