Difference between revisions of "Writing Makefiles"

From Apertium
Jump to navigation Jump to search
(Created page with 'Some tips for writing clean Makefile.am's in Apertium: ==Avoid ending up with root-owned modes files== When you do "sudo make install", some Makefiles.am still have a bug where …')
 
Line 18: Line 18:
 
This method leaves no root-owned files hanging around.
 
This method leaves no root-owned files hanging around.
   
(It might look odd that we "rm -rf modes" there after gen-modes, but "apertium-gen-modes somedir" creates both apertium-foo-bar/foo-bar.mode and non-installable debug modes in apertium-foo-bar/modes/ – perhaps tihs could be fixed so we can avoid this makefile workaround.)
+
(It might look odd that we "rm -rf modes" there after gen-modes, but "apertium-gen-modes somedir" creates both apertium-foo-bar/foo-bar.mode and non-installable debug modes in apertium-foo-bar/modes/ – perhaps tihs could be fixed in apertium-gen-modes so we can avoid this makefile workaround.)
   
 
==Use .deps/.d to say that the .deps directory must be created==
 
==Use .deps/.d to say that the .deps directory must be created==

Revision as of 06:27, 24 October 2013

Some tips for writing clean Makefile.am's in Apertium:

Avoid ending up with root-owned modes files

When you do "sudo make install", some Makefiles.am still have a bug where they'll leave around root-owned modes files. Then on the next "make", you see a "Permission denied" error, since it tries to create the same filenames again as non-root. (The installable mode files have paths pointing to e.g. /usr/local, while the non-install mode files have paths that point to your source development directory. You want the latter to hang around so you can do apertium -d . fie-bar.)

A workaround is this: when doing make install, first stash away any already existing development modes directory, the generate the install modes, then clean up the root-owned stuff and unstash the old modes directory:

install-data-local:
	mv modes modes.bak
	apertium-gen-modes modes.xml $(BASENAME)
	rm -rf modes
	mv modes.bak modes
	test -d $(DESTDIR)$(apertium_modesdir) || mkdir $(DESTDIR)$(apertium_modesdir)
	$(INSTALL_DATA) $(PREFIX1).mode $(DESTDIR)$(apertium_modesdir)
	$(INSTALL_DATA) $(PREFIX2).mode $(DESTDIR)$(apertium_modesdir)
	rm $(PREFIX1).mode $(PREFIX2).mode

This method leaves no root-owned files hanging around.

(It might look odd that we "rm -rf modes" there after gen-modes, but "apertium-gen-modes somedir" creates both apertium-foo-bar/foo-bar.mode and non-installable debug modes in apertium-foo-bar/modes/ – perhaps tihs could be fixed in apertium-gen-modes so we can avoid this makefile workaround.)

Use .deps/.d to say that the .deps directory must be created

Say you have several goals that put temporary files in .deps/, e.g.

.deps/apertium-wat-lol.lol.dix: apertium-wat-lol.lol.dix
	test -d .deps || mkdir .deps
	xsltproc lexchoicebil.xsl $< >$@

and so on. The .deps directory has to be created for the file in .deps to be created. If you put mkdir .deps in each such goal, you can get a race condition where two goals try to make .deps at the same time.

The solution is this: if a goal needs the .deps directory to be created, let it depend on the file .deps/.d. First put this in Makefile.am:

.deps/.d:
	test -d .deps || mkdir .deps
	touch $@

.PRECIOUS: .deps/.d

And then, instead of creating the dir in each goal, just depend on .deps/.d for those goals:

.deps/apertium-wat-lol.lol.dix: apertium-wat-lol.lol.dix .deps/.d
	xsltproc lexchoicebil.xsl $< >$@

(The PRECIOUS line prevents the .d file from being cleaned up and removed automatically.)