I'm writing a library of MySQL UDF. The build system is based on GNU Autotools
. The compilation and installation of the shared library itself works well.
However to use the UDF, we need to execute some SQL statements as explained here:
CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so';
The current Makefile.am
contains an explicit rule:
installdb:
$(MYSQL) <./installdb.sql
where ./installdb.sql
contains the CREATE FUNCTION
statements.
However, it doesn't work when building outside of source tree and the user must call make installdb
explicitly (while I would like it to be part of make install
).
Any idea on how to do that ?
The current Makefile.am contains an explicit rule:
installdb: $(MYSQL) <./installdb.sql
where
./installdb.sql
contains theCREATE FUNCTION
statements. However, it doesn't work when building outside of source tree
Supposing that installdb.sql
is a file included in the package distribution, not a built one, no, that wouldn't work in an out-of-source build, because "./installdb.sql
" would not then refer to an existing file. If you want a build recipe to refer to a file that is neither a rule prerequisite nor a target built by some other rule, then you cannot expect magic -- you need to specify the wanted file via a usable path. The same applies even to prerequisites if you refer to them explicitly in your build rules. VPATH
builds operate via make
's automatic variables, such as $<
and $^
.
And GNU make
has a solution to that. The path to the source-tree directory corresponding to the current make
's working directory is always available via the $(srcdir)
variable. Using that, your recipe would look more like this:
installdb:
$(MYSQL) < $(srcdir)/installdb.sql
For an in-source build, $(srcdir)
will evaluate to .
, so in that case the above is equivalent to what you started with. For an out-of-source build, $(srcdir)
will contain the appropriate path.
Occasionally, it is also useful to reference the root of the source tree. For instance, you might want to refer to files in a direct subdirectory of the source root, without introducing other dependencies on source-tree structure. For that, you can use $(top_srcdir)
to refer to the source tree root.
These details are not clearly covered in the current Automake docs, but you can find them in other GNU documentation.
and the user must call
make installdb
explicitly (while I would like it to be part ofmake install
).
Well, yes, Automake does not assume that every target for which you provide a rule has to be exercised by a make install
. Not even all the targets it generates itself are exercised that way. But Automake does have mechanisms for indicating which user-provided rules should be included, and at what point. The current manual covers this in section 23.1.
In your case, I would use an installation hook, either by renaming your target to install-data-hook
or by declaring a new target of that name, and making your installdb
target a prerequisite. The latter would look like this:
install-data-hook: installdb
The former has stronger promises about timing, however, so if it were critical that the database initialization be performed near the end of the installation, then it would be better to do the target name change in the hook's own recipe:
install-data-hook:
$(MYSQL) < $(srcdir)/installdb.sql
Either way, do also consider what, if any, corresponding uninstallation rules may be needed. Also, if you retain your separate installdb
target, then it would be good form to mark it as phony:
PHONY = installdb
That avoids breakage in the event that an actual file of that name happens to be in the build directory for some reason.