Difference between revisions of "Writing Makefiles"

From Apertium
Jump to navigation Jump to search
 
(7 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
Some tips for writing clean Makefile.am's in Apertium:
 
Some tips for writing clean Makefile.am's in Apertium:
 
{{TOCD}}
 
{{TOCD}}
  +
==Use apertium-init==
  +
If you're creating a new monolingual module or pair, use [[apertium-init]]. It creates modules that Just Work. If you've got a problem with an old makefile, throw it all away and create a new one using [[apertium-init]].
  +
  +
  +
If you really want to debug your old makefile, read on for some tips.
  +
 
==Modes==
 
==Modes==
If you have <code>apertium</code> revision 51184 or higher, you can do this to simplify dealing with [[Modes]] files / modes.xml:
+
If you have <code>apertium</code> version 3.3 or higher, you can do this to simplify dealing with [[Modes]] files / modes.xml:
   
First add <code>AP_MKINCLUDE</code> to <code>configure.ac</code> in the language pair.
+
In <code>configure.ac</code>, add this:
  +
<pre>AP_MKINCLUDE</pre>
 
 
Now let your <code>Makefile.am</code> include this:
+
In <code>Makefile.am</code>, add this:
 
<pre>
 
<pre>
  +
# Only include one mode file here, the rest will be built along with it (listing several leads to problems with parallell make):
 
noinst_DATA=modes/$(PREFIX1).mode
 
noinst_DATA=modes/$(PREFIX1).mode
   
 
@ap_include@
 
@ap_include@
   
  +
# Most language pairs don't need to specify anything else for install-data-local:
 
install-data-local: install-modes
 
install-data-local: install-modes
   
 
EXTRA_DIST:
 
EXTRA_DIST:
 
modes.xml \
 
modes.xml \
# other files, typically .dix and .t1x
+
# here you'll typically also have other things, like .dix and .t1x
  +
# files that are to be included when you make a release
 
</pre>
 
</pre>
   
 
''Nowhere else should modes be mentioned in the <code>Makefile.am</code>.''
 
''Nowhere else should modes be mentioned in the <code>Makefile.am</code>.''
  +
  +
If you follow this system, the modes with install="yes" in modes.xml will be installed, and you won't end up with root-owned modes files, and make -j4 will work fine.
   
 
==Use .deps/.d to say that the .deps directory must be created==
 
==Use .deps/.d to say that the .deps directory must be created==
Line 38: Line 50:
 
.PRECIOUS: .deps/.d
 
.PRECIOUS: .deps/.d
 
</pre>
 
</pre>
  +
(If using apertium 3.3 or higher, you can just do AP_MKINCLUDE, which includes the above .deps/.d goal.)
  +
 
And then, instead of creating the dir in each goal, just depend on .deps/.d for those goals:
 
And then, instead of creating the dir in each goal, just depend on .deps/.d for those goals:
 
<pre>
 
<pre>
Line 55: Line 69:
 
-rm -rf .deps modes
 
-rm -rf .deps modes
 
</pre>
 
</pre>
  +
  +
==Where does this $AP_SRC1 stuff come from?==
  +
When you do <code>./autogen.sh --with-lang1=foo</code>, the variable AP_SRC1 will be set to "foo" in the Makefile. Your configure.ac should say something like <code>AP_CHECK_LING([1], [apertium-lol])</code> for that option to work.
  +
  +
  +
;The details: The autogen.sh script passes its arguments on to the configure script. If configure.ac says e.g. <code>AP_CHECK_LING([1], [apertium-lol])</code>, then the configure script will have a --with-lang1 option to set to the location of the package apertium-lol. If you don't pass --with-lang1 to autogen.sh, configure will attempt to find the location of an ''installed'' apertium-lol package using pkg-config.
  +
  +
:;The gory details: The actual configure code for all this checking is in apertium.m4, typically in /usr/share/aclocal/apertium.m4 or /usr/local/share/aclocal/apertium.m4 if you're very interested in reading m4sh code.
   
 
[[Category:Tools]]
 
[[Category:Tools]]

Latest revision as of 13:09, 18 February 2015

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

Use apertium-init[edit]

If you're creating a new monolingual module or pair, use apertium-init. It creates modules that Just Work. If you've got a problem with an old makefile, throw it all away and create a new one using apertium-init.


If you really want to debug your old makefile, read on for some tips.

Modes[edit]

If you have apertium version 3.3 or higher, you can do this to simplify dealing with Modes files / modes.xml:

In configure.ac, add this:

AP_MKINCLUDE

In Makefile.am, add this:

# Only include one mode file here, the rest will be built along with it (listing several leads to problems with parallell make):
noinst_DATA=modes/$(PREFIX1).mode

@ap_include@

# Most language pairs don't need to specify anything else for install-data-local:
install-data-local: install-modes

EXTRA_DIST: 
	modes.xml \
	# here you'll typically also have other things, like .dix and .t1x 
        # files that are to be included when you make a release

Nowhere else should modes be mentioned in the Makefile.am.

If you follow this system, the modes with install="yes" in modes.xml will be installed, and you won't end up with root-owned modes files, and make -j4 will work fine.

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

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

(If using apertium 3.3 or higher, you can just do AP_MKINCLUDE, which includes the above .deps/.d goal.)

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.)

Removing directories on make clean[edit]

Say you want to remove .deps and modes on "make clean". Don't do CLEANFILES=-rf .deps modes file1 file2 …, it doesn't work everywhere.

A more portable solution is this:

CLEANFILES = $(TARGETS_COMMON)
clean-local: 
	-rm -rf .deps modes

Where does this $AP_SRC1 stuff come from?[edit]

When you do ./autogen.sh --with-lang1=foo, the variable AP_SRC1 will be set to "foo" in the Makefile. Your configure.ac should say something like AP_CHECK_LING([1], [apertium-lol]) for that option to work.


The details
The autogen.sh script passes its arguments on to the configure script. If configure.ac says e.g. AP_CHECK_LING([1], [apertium-lol]), then the configure script will have a --with-lang1 option to set to the location of the package apertium-lol. If you don't pass --with-lang1 to autogen.sh, configure will attempt to find the location of an installed apertium-lol package using pkg-config.
The gory details
The actual configure code for all this checking is in apertium.m4, typically in /usr/share/aclocal/apertium.m4 or /usr/local/share/aclocal/apertium.m4 if you're very interested in reading m4sh code.