Search code examples
autoconfm4

AC_SUBST with dynamic variable name


I'm trying to create an m4 macro that basically calls AC_CHECK_SIZEOF(type) then uses AC_SUBST to define that variable for substitution. So given input of:

AX_CHECK_SIZEOF_AND_SUBST(int, 4)

I want all occurances of @SIZEOF_INT@ to be replaced with 4

This is what I came up with so far, but obviously doesn't work:

AC_DEFUN([AX_CHECK_SIZEOF_AND_SUBST], [
    AC_CHECK_SIZEOF($1, $2)
    NAME=$(echo -n "SIZEOF_$1" | tr "a-z" "A-Z" | tr '*' 'P' | tr -c 'A-Z0-9' '_')
    echo "NAME=$NAME"
    AC_SUBST($NAME, $$NAME)
])

Solution

  • The trouble with what you are trying to do is that AC_CHECK_SIZEOF does not in fact define a variable named SIZEOF_INT. In 2.68, the variable you want is named ac_cv_sizeof_int, but you should not use that as the name is subject to change in later versions. The value is also written into confdefs.h, so another way to grab it is:

    AC_PROG_AWK
    AC_CHECK_SIZEOF([int])
    SIZEOF_INT=$($AWK '/SIZEOF_INT/{print $3}' confdefs.h)
    AC_SUBST([SIZEOF_INT])
    

    (reading confdefs.h is also undocumented behavior and subject to change in future versions of autoconf, but is possibly more stable than looking at $ac_cv_sizeof_int. Possibly, less stable, too. ;) YMMV)

    To define your macro (please note my comment about the naming convention), you could do:

    AC_DEFUN([wrp_CHECK_SIZEOF_AND_SUBST], [
        AC_REQUIRE([AC_PROG_AWK])
        AC_CHECK_SIZEOF([$1])
        m4_toupper(SIZEOF_$1)=$($AWK '
            /SIZEOF_[]m4_toupper($1)/{print $[]3}' confdefs.h)
        AC_SUBST(m4_toupper(SIZEOF_$1))
    ])
    

    The version above does not handle int *, but for simplicity I will keep it there rather than replace it with the more general version:

    AC_DEFUN([wrp_CHECK_SIZEOF_AND_SUBST], [
        AC_REQUIRE([AC_PROG_AWK])
        AC_CHECK_SIZEOF([$1])
        m4_pushdef([name],SIZEOF_[]m4_toupper(m4_translit($1,[ *],[_p])))
        name=$($AWK '/name/{print $[]3}' confdefs.h)
        AC_SUBST(name)
        m4_popdef([name])
    ])
    

    Note: I believe the $() notation should be avoided in portable configure scripts, and should be replaced with backticks. However, I find backticks hideous.