I am developing a Qt application in Python. It uses a resource file, which needs to be compiled. I am using autotools to manage compilation and installation of my projects.
Now, in order for the resource file to be usable by the application, it needs to be compiled with a certain version of the compilation program (pyrcc
). I can get the version by putting the output of pyrcc -version
in a variable in configure.ac
. But then, I don't know how to check whether the string pyrcc5
is present in the output. If it is not present, I want to tell the user that his PyRCC programm has the wrong version, and abort configure
.
Additionally, I would like to avoid the need of an extra variable for the program output, but instead do it like this (Pseudo code):
if "pyrcc5" not in output of "pyrcc -version":
say "pyrcc has wrong version"
exit 1
How can I do this ?
When writing a configure.ac
for Autoconf, always remember that you are basically writing a shell script. Autoconf provides a host of macros that afford you a lot of leverage, but you can usually at least get an idea about basic "How can I do X in Autoconf?" questions by asking instead "How would I do X in a portable shell script?"
In particular, for ...
I would like to avoid the need of an extra variable for the program output, but instead do it like this (Pseudo code):
if "pyrcc5" not in output of "pyrcc -version": say "pyrcc has wrong version" exit 1
... the usual tool for a portable shell script to use for such a task is grep
, and, happily, the easiest way to apply it to the task does not require an intermediate variable. For example, this implements exactly your pseudocode (without emitting any extraneous messaging to the console):
if ! pyrcc -version | grep pyrcc5 >/dev/null 2>/dev/null; then
echo "pyrcc has wrong version"
exit 1
fi
That pipes the output of pyrcc -version
into grep
, and relies on the fact that grep
exits with a success status if and only if it finds any matches.
You could, in fact, put exactly that in your configure.ac
, but it would be more idiomatic to
pyrcc
and grep
, and to use the versions discovered that way;AS_IF
macro to write the if
construct, instead of writing it literally;Of course, all of that makes the above considerably more complex, but also more flexible and portable. It might look like this:
AC_ARG_VAR([PYRCC], [The name or full path of pyrcc. Version 5 is required.])
# ...
AC_PROG_GREP
AC_CHECK_PROGS([PYRCC], [pyrcc5 pyrcc], [])
AS_IF([test "x${PYRCC}" = x],
[AC_MSG_ERROR([Required program pyrcc was not found])])
# ...
AC_MSG_CHECKING([whether ${PYRCC} has an appropriate version])
AS_IF([! pyrcc -version | grep pyrcc5 >/dev/null 2>/dev/null], [
AC_MSG_RESULT([no])
AC_MSG_ERROR([pyrcc version 5 is required, but ${PYRCC} is a different version])
], [
AC_MSG_RESULT([yes])
])
In addition to portability and conventional Autoconf progress messaging, that also gets the builder a way to specify a particular pyrcc
executable to configure
(by setting variable PYRCC
in its environment), documents that in configure
's help text, and exports PYRCC
as a make
variable.
Oh, and I snuck in a check for pyrcc
under the name pyrcc5
, too, though I don't know whether that's useful in practice.
The final result no longer looks much like the shell script fragment I offered first, I grant. But again, the pure shell script fragment could be used as is, and also, the fully Autoconfiscated version is derived directly from the pure script.