The difference between .mk file and Makefile - makefile

I've just begun to study Porting Android. And I come across a new type of file which is .mk file. It's is an extension of Makefile but I don't know what it is different from a Makefile ? So, can somebody help you clarify them. Thanks very much !

A make file can have any name. The -f option of make is used to specify which file to use:
make -f foobar
You can even use -f several times:
make -f foo -f bar
In which case make processes the files in order (or, equivalently, concatenates the files and processes the result).
makefile and Makefile are special names because if make is called without the -f option it automatically searches for them, in this order, and use the first it finds. Note that GNU make also considers GNUmakefile, and prefers it over makefile and Makefile. Other make implementations can have other default names.
The .mk extension is a more or less standard extension for make files that have other names than the defaults. It is a reasonable extension if you want humans to quickly understand what these files are: convert.mk is more informative than foobar. Some editors use this extension to identify the file type and apply syntax coloring. They usually apply the same syntax coloring to makefile and Makefile.

Related

makefile for metapost: how to compile file-N.pdf

I want to let makefile manage the compilation of figures with metapost.
The source file is file.mp. This generates .mps files file.1, file.2 etc. that are then converted to file-1.pdf, file-2.pdf etc.
Here are my rules:
export TEX = latex
%: %.1
mptopdf $*
%.1: %.mp
mpost $*
So that when I run make file it creates all the files.
However, I am not satisfied with this solution. Namely, I'd like to be able to let only one of the files be compiled (say file-2.pdf) by entering make file-2.
Unfortunately, I don't know how to write the rule for this, although I suspect it might be trivial.
I thought the problem could be solved by extracting the number from the file name given in the command line (i.e. extract 2 from file-2) but it is not clear to me how to do it either.

Finding dependencies by grep in Make

I'm working on a rather large project in pure C, and for various reasons we are not using CMake.
We have a good system which uses various shell commands to require very little maintanence. It will automatically find new headers and C files and add the headers to the dependencies and will compile the C files and include them in the output. However, we've gotten to the point where any changes we make to the header files becomes a problem because it requires a recompilation of the entire project, rather than just the C files that include it directly or indirectly.
I've worked on a system to ensure that the only header files which are added as dependencies are ones which are required by the C file itself (recursively up the tree).
I had thought I would be able to solve this myself, but it seems that make has rather inconsistent rules for expansion of variables.
The solution I came up with was to try to use ag and get all the includes out of the file. This works as intended, and I pipe it into tr so that I can ensure that no newlines are added, thereby messing up make. The issue that I'm having though is in determining which file to search in. This is the recipe that it's using for the section in question:
$(GAMEOBJDIR)/%.o : $(GAMEDIR)/%.c $(shell ag -o '(?<=(^#include "))(.*?)(?=("$$))' $(GAMEDIR)/%.c | tr '\n' ' ')
$(CC) $(CFLAGS) $(if $(RELEASE),$(RELFLAGS),$(DBFLAGS)) -c -o $# $<
The problem is that $(GAMEDIR)/%.c is expanding to src/game/%.c and not src/game/<filename>.c. I'm unsure how to fix this issue based on the expansion rules of make.
Once I can figure this out I'll be able to make sure this walks up the chain of header files too, but until I can get this figured out I have no reason to work on that.
Make's rules for expansion are completely consistent... but sometimes they aren't what people want. That's not the same thing :)
Rules for expansion are explained in the manual. In your case you're working with a prerequisite list which means the variables are expanded as the makefile is parsed. That includes the shell command and all other variables. Because you are working with a pattern rule, it means that at the time the makefile is parsed it doesn't match any particular file, it's just defining the pattern rule itself. So, % can't be expanded here. It will be expanded later, when make starts walking the dependency graph and trying to locate ways to build targets.
In general your method cannot work efficiently. You could defer the expansion of these parts of the prerequisites list using Secondary Expansion. However, that means every time make wants to TRY to use this pattern it will run these commands--that will just be slow.
Have you considered using a more standard way to manage detecting prerequisites? Try reading this description for example to see if it would work for you.

Automake default rule for targets with no extension?

Is there a generic was to specify a rule for something that goes from something with an extension to something with no extension? (in this case, '.in' to '')?
I have a project that's using automake. I have some config file templates that need substitutions before installing them. For example, I have a 'foo.ini.in' file that I want to use to create 'foo.ini'. I have a few of these scattered throughout the codebase. However, for each one, I need to create a custom Makefile rule to make them work. Is there a better way? I currently do this in Makefile.am:
bazdir=$(libdir)/#PACKAGE_NAME#/baz
EXTRA_DIST = foo.ini.in bar.ini.in
CLEANFILES = foo.ini bar.ini
foo.ini: foo.ini.in
sed -e 's|#LIBDIR#|$(bazdir)|g' $< > $#
bar.ini: bar.ini.in
sed -e 's|#LIBDIR#|$(bazdir)|g' $< > $#
This works fine, but I need to duplicate the rule for every file. I'd like to write one rule that will do the substitution for any 'ini.in' files to 'ini' files. I've tried:
%.ini.in: %.ini
sed ....
but autoconf complains that % pattern substitution is a non-portable gnumake-ism. It also doesn't like
.ini.in.ini:
sed .....
.. which I can't really blame it for not liking, because I can't even parse that.
Is there a way to do this?
NOTE: I can not use AC_CONFIG_FILES to do this substitution, because 'bazdir' is not fully expanded in that case.
Fortunately, there's a much better way: let the 'configured' files be generated from the templates using the configure script itself. As I mentioned in the comment, I don't see any reason to try to expand $bazdir in the Makefile.am itself. Maybe you can clear this up for me if there's some special reason for this.
In the configure.ac script, substitution variables are defined with the AC_SUBST macro. I'm guessing you want to replace LIBDIR with the value of $bazdir. Note that LIBDIR isn't a good choice of name, as libdir is already used in configure scripts; so let's use a variable name prepended with a project name: BAZ_LIBDIR
1/. set bazdir in the configure script: bazdir="${libdir}/${PACKAGE_NAME}/baz", and substitute with: AC_SUBST(BAZ_LIBDIR, $bazdir). Alternatively, just assign the value to BAZ_LIBDIR and use the single argument form of AC_SUBST. BAZ_LIBDIR is now ready for substitution...
2/. At the end of configure.ac, specify the files to be generated from their <file>.in templates, with AC_CONFIG_FILES. Typically this will list Makefile's, as well as data files, where the .in suffix is implicit.
Assuming a projectdir tree... could be any sort of tree layout of course:
BAZ_LIBDIR="${libdir}/${PACKAGE_NAME}/baz"
AC_SUBST(BAZ_LIBDIR)
...
AC_CONFIG_FILES([Makefile projectdir/Makefile])
AC_CONFIG_FILES([projectdir/foo.ini projectdir/bar.ini])
...
AC_OUTPUT
Instances of #BAZ_LIBDIR# in the <file>.ini.in files will be replaced with the substitution value. No arcane sed invocations are required to generate <file>.ini files.
Another nice feature is that you needn't add foo.ini.in or bar.ini.in to the EXTRA_DIST variable in the Makefile.am - and make distclean will clean the bar.ini and foo.ini files.

How do I use dependencies in a makefile without calling a target?

I'm using makefiles to convert an internal file format to an XML file which is sent to other colleagues. They would make changes to the XML file and send it back to us (Don't ask, this needs to be this way ;)). I'd like to use my makefile to update the internal files when this XML changes.
So I have these rules:
%.internal: $(DATAFILES)
# Read changes from XML if any
# Create internal representation here
%.xml: %.internal
# Convert to XML here
Now the XML could change because of the workflow described above. But since no data files have changed, make would tell me that file.internal is up-to-date. I would like to avoid making %.internal target phony and a circular dependency on %.xml obviously doesn't work.
Any other way I could force make to check for changes in the XML file and re-build %.internal?
You want to allow two different actions: making the xml file from the internal file, and making the internal file from the xml file. Since Make knows only the modification times, it knows which target is older but not whether it should be remade. So put in another file as a flag to record when either action was last taken, and make that your primary target; if either target is newer than the flag, it has been modified by something other than these actions, and make should rebuild the older target (and then touch the flag).
There are several ways to implement this. In some versions of Make (such as recent versions of GNUMake) you can write double-colon rules, so that Make will rebuild a target differently, based on which preq triggered it:
%.flag:: %.internal
# convert $*.internal to $*.xml
touch $#
%.flag:: %.xml
# rewrite $*.internal based on $*.xml
touch $#
A less elegant but more portable way is to look at $? and rebuild the other file:
%.flag: %.xml %.internal
ifeq ($?,$*.internal)
# convert $*.internal to $*.xml
else
# rewrite $*.internal based on $*.xml
endif
touch $#
I think you could do something like this:
all: .last-converted-xml .last-converted-internal
.last-converted-internal: *.internal
./internal-2-xml $?
touch $# .last-converted-xml
.last-converted-xml: *.xml
./xml-2-internal $?
touch $# .last-converted-internal
This runs "xml-convert" on any .xml files newer than an arbitrary marker file, ".last-converted". The $? should give you a list of all dependencies (*.xml) that are newer than the marker file.
Of course, the xml-convert program will have to be written to take a list of xml files and process each one.
I'm not sure from the question whether you actually need the .internal file, or if that was just an attempt to get the makefile working. So, either your "xml-convert" program can convert each .xml file in place, or it can also generate file.internal as well if you need it.
Use the -W option of make to have make think one of the data files has changed:
make -W somedatafile
This will cause make to think somedatafile has been modified without actually changing it's modification time.
Would it be possible to use different names for the XML file? The file you create from the internal format would have one name and the file your colleagues send you another? If they used different names there would be no circular dependency.

Using make to add m4 preprocessing to an arbitrary language

We have an ActionScript (Flex) project that we build using GNU make. We would like to add an M4 preprocessing step to the build process (e.g., so that we can create an ASSERT() macro that includes file and line numbers).
We are having remarkable difficulty.
Our current strategy is:
Create a directory "src/build" (assuming source code is in src/ and subdirectories).
Within src/build, create a Makefile.
Run make inside src/build.
The desired behavior is, make would then use the rules we write to send the *.as files src/ and its subdirs, creating new *.as files under build. For example:
src/bar.as -> m4 -> src/build/bar.as
src/a/foo.as -> m4 -> src/build/a/foo.as
The obvious make rule would be:
%.as : ../%.as
echo "m4 --args < $< > $#"
This works for bar.as but not a/foo.as, apparently because make is being "smart" about splitting and re-packing directories. make -d reveals:
Trying implicit prerequisite `a/../foo.as'.
Looking for a rule with intermediate file `a/../foo.as'.
but we want the prerequisite to be "../a/foo.as". This (what we don't want) is apparently documented behavior (http://www.gnu.org/software/make/manual/make.html#Pattern-Match).
Any suggestions? Is it possible to write a pattern rule that does what we want?
We've tried VPATH also and it does not work because the generated .as files are erroneously satisfying the dependency (because . is searched before the contents of VPATH).
Any help would be greatly appreciated.
One option is to use a different extension for files that haven't been preprocessed. Then you can have them in the same directory without conflict.
As Anon also said, your source code is no longer Flex - it is 'to be preprocessed Flex'. So, use an extension such as '.eas' (for Extended ActionScript) for the source code, and create a 'compiler' script that converts '.eas' into '.as' files, which can then be processed as before.
You may prefer to have the Extended ActionScript compiler do the whole compilation job - taking the '.eas' direct to the compiled form.
The main thing to be wary of is ensuring that '.eas' files are considered before the derived '.as' files. Otherwise, your changes in the '.eas' files will not be picked up, leading to hair-tearing and other undesirable behaviours (head banging, as in 'banging head against wall', for example) as you try to debug code that hasn't changed even though the source has.

Resources