GNU make not working for simple test cases - makefile

First time posting on stackoverflow!
I'm just getting started on using GNU make. I'm using a simple example Makefile described here (and printed below). There are two steps to be completed by the Makefile, both of which I can complete without error without using make.
Here's the Makefile (truncated from original because I don't have topojson installed):
counties.zip:
curl -o counties.zip 'http://www2.census.gov/geo/tiger/GENZ2010/gz_2010_us_050_00_20m.zip'
gz_2010_us_050_00_20m.shp: counties.zip
unzip counties.zip
touch gz_2010_us_050_00_20m.shp
When I attempt to use make make -f Makefile or just make, I get the following:
curl -o counties.zip 'http://www2.census.gov/geo/tiger/GENZ2010/gz_2010_us_050_00_20m.zip'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1277k 100 1277k 0 0 955k 0 0:00:01 0:00:01 --:- -:-- 956k
The file successfully downloads, but is never unzipped in the next step. If I type make again, it prints:
make: `counties.zip' is up to date.
I've tried similar simple multi-step test cases and the same thing is happening - the first step is completed, but no subsequent steps are. I know I've installed programs using make in the past on this machine (Ubuntu 14.04.3 LTS).
Any help would be greatly appreciated. Apologies if I've forgotten any relevant details or this is a redundant question.

You need to add the rule at the beginning of the Makefile.
all: counties.zip gz_2010_us_050_00_20m.shp
Make sure all are the same, there is a good tutorial here, it is basic.

Related

Updating timestamp after running make recursively

My project is dependent on other projects in subfolders. I want to call make recursively to build all in one run.
My first try is like this:
.PHONY: all make_recursion
all: program
program: submake1/lib submake2/lib
submake1/lib: make_recursion
submake2/lib: make_recursion
make_recursion:
make -C submake1
make -C submake2
This does not work as intended. Each run of make both submakes are executed in case a file changed in those projects. For submake2 my program is also rebuilt if submake2/lib was updated. If only submake1/lib is updated I have to run make a second time to update program.
The reason for this is that make takes the timestamp of submake1/lib before make_recursion, but does not update it after that. How can I improve this?

In this makefile, why is the prerequisite for the target "bunzip2/data2.tar" always being remade?

I have a make file that is always re-running a rule despite the prerequisite being up-to-date:
data.tar.bz2: data.tar
bzip2 --keep data.tar
# The following rule always runs the rule for its prerequisite
# even if it is up-to-date. Note that it doesn't matter whether
# the bunzip2 directory exists or not. I suppose is has something
# to do with the dir/file naming of the rule but I haven't been
# able to decipher why.
bunzip2/data2.tar: data.tar.bz2
mkdir bunzip2 && cd bunzip2 && bzip2 -ckd ../data.tar.bz2 > data2.tar && cd ..
.PHONY: clean
clean:
rm -f data.tar.bz2
rm -Rf bunzip2
Any ideas appreciated.
The standard POSIX system calls that set timestamps on files do not support sub-second accuracy. In order for these tools to set a specific time on a file (which they try to do so that the compressed file has the same timestamp as the original file) and preserve the original accuracy they need to use different system calls; apparently they don't do so.
What you can do to work around this is change your rule like this:
data.tar.bz2: data.tar
bzip2 --keep data.tar && touch $#
so that the timestamp of the target is set to "now".
ETA The traditional system call for setting modification times on files is utime() which accepts timestamps only in increments of one second. Newer versions of the POSIX spec introduced utimensat() which allows nanosecond timestamp settings. There is also utimes() which allows microsecond accuracy but which has been considered "legacy" for a long time now.
If this behavior exists in the current latest release of bzip2, I would consider it a bug worthy of a bug report to them.
I think I figured out what was going on here.
Using #Thomas Dickey advice to try make -d, it was saying that the file data.tar.bz2 was newer than data.tar itself. That seems silly because the former is created from the later. But using ls --full-time shows bzip2 archive seems use the timestamp of the source file but it also truncates it after the second place. In my case, the timestamp 2015-03-12 09:32:02.452091888 was getting truncated to 2015-03-12 09:32:02.000000000 which makes it appear to be newer than the source. (By truncate I mean that 2015-03-12 13:10:29.681793152 goes to 2015-03-12 13:10:29.000000000... it does not round up even in that case) Seems like bzip needs to bump the accuracy of their timestamps.
It appears that lunzip also truncates the timestamp and unxz preserves the original timestamp while gzip uses the current time. In other words, be careful with your makefiles when using compression utilities because they handle things differently.
Something is missing from the example - but the process for analysis is the same, regardless: you can use the debug feature of make to see what rules it uses, e.g.,
make -d

Measuring time consumed for each make operation in recursive folders

I am very new to makefile. Here i have challenge in finding time for the compiling(c code) each module.
Operating system:Linux
make : x86_64-redhat-linux-gnu
I am using "make" with -j option.only one Makefile maintained having instruction "/usr/bin/make".
And recursivley there are multiple Components are there .For each component one Config.mk maintained.
some modules doesnt have ".mk" also
I tried to echo time in each ".mk" using "{info {shell date}),but it didn't give enough results,since they all been used in very early stage of compilation..
Could anyone help in finding time for each make operation
Cheers
Murali
You can .PHONY targets that are executed as first and last targets and print out the date
all:
echo "Component foo: build started"
date
$(MAKE) build
echo "Component foo: build finished"
date
build: ....
....

send email after `make` completes, even with failure

I have a Makefile that is organizing several steps of analysis that have to be run in a particular order. The analysis takes quite a while (a day or two) and I'd like to receive some email notifications when make completes. Is there a good way to have make automatically send an email at the end of the process so I can be alerted when it completes, especially when there is a failure with one of the steps?
I'm currently doing something like this:
# Makefile
all: results1.dat results2.dat results3.dat
python send_email_when_done.py
results1.dat: long_running_program1.py
python $< > $# # this takes ~12 hours
results2.dat: long_running_program1.py results1.dat
python $^ > $# # this takes ~2 hours
results2.dat: long_running_program1.py results2.dat
python $^ > $# # this takes ~30 hours
where the send_email_when_done.py script sends email notifications when the process has completed. But this only works if the entire process has run from start to finish without any errors. Any suggestions for a good way to do this?
+1 for suggestions that can accomplish this within the Makefile. I'm already running make in a separate session using setsid make > make.out 2>&1.
How about simply make the email sending as a separated target:
report: long_running_program1.py
python $< > $# # this takes ~12 hours
sendmail:
python send_email_when_done.py
And you call it:
make report sendmail
or
make report ; make sendmail
Let me make it more general so that it can send email for 100's of other such make. Use alias and add it in bashrc, here sagarsakre.blogspot.in is how i tried to use the alias command makes (make and send report). The added advantage would be u would get all the verbose printed regardless of worrying about rule and dependency. You can use it for all builds without really changing the makefile.
note: i used mailx, You can read this to setup mailx on ur machine
Since makepp allows you access to the underlying interpreter, you can do a little Perl programming to add an END-Handler anywhere in your makefile:
perl { END { system "python send_email_when_done.py" }}
Or more prettily layouted with an alternate direct subject-only mail
perl {
END {
system "mail -s 'Build finished with rc=$?' me#my.home <&-";
}
}
There is much more to makepp. Besides doing almost all that GNU make can, there are lots more useful things.
One way of obtaining that, would be to instruct make to ignore errors from the long-running programs. This can either be achieved by running make -i or by prepending each of the commands where failure should be ignored with a dash and just running plain make:
# Makefile
all: results1.dat results2.dat results3.dat
python send_email_when_done.py
results1.dat: long_running_program1.py
-python $< > $# # this takes ~12 hours
results2.dat: long_running_program1.py results1.dat
-python $^ > $# # this takes ~2 hours
results2.dat: long_running_program1.py results2.dat
-python $^ > $# # this takes ~30 hours
See the GNU make manual for more information on ignoring errors.

Automake: configure subdirectory only

This concerns an external project, where one OneLibrary.c and SomeLibraries.am where modified;
It would be nice to
./configure --please-configure-only-this-subdirectory=./SomeLibrariesSubdirectory
something similar to make -C ./SomeLibrariesSubdirectory
Because the whole "./configure" takes 5 minutes when only two lines have been modified ;)

Resources