On 01/12/2012 03:58 PM, Svante Signell wrote: > Hello. > > Consider the code snippet below. How to modify it to get the GNU version > of baseline if defined (in my case GNU/Hurd). The macro > AC_USE_SYSTEM_EXTENSIONS is stated earlier in configure.ac. First, I'd suggest that you _don't_ use basename(); it has severe portability problems (POSIX allows, but does not require, it to modify its incoming argument; worse, POSIX states that these functions need not be thread-safe, rendering them useless in multithreaded programs) - mere existence of the function in libgen.h does not tell you whether you will be encountering those subtle differences as you port to other platforms. Besides, on glibc, there are two flavors of basename(), and which version you get depends on your compile-time options - I guess this is a case where you were probing for the GNU behavior rather than the POSIX behavior. Your test program didn't test for those particular subtleties. The gnulib module dirname provides functions dir_name, base_name, and last_component, which have saner semantics that are uniform to all platforms and not dependent on POSIX vagaries. But, if I can't convince you to use gnulib and either base_name() or last_component(), I can still advise you on how to better use autoconf. > >>From configure.ac: > # COMPAT_FUNC_BASENAME > # -------------------- > # Check for working basename() function. > AC_CHECK_HEADERS([libgen.h]) This is an unconditional check; did you mean for it to be inside the body of your COMPAT_FUNC_BASENAME? > AC_DEFUN([COMPAT_FUNC_BASENAME], [ > AC_DEFINE([NEED_BASENAME], 1, > [Define if you want to use the basename function]) This unconditionally defines NEED_BASENAME. You should instead defer this line of code until after you have done the cache check. > AC_CHECK_HEADERS([libgen.h]) I'd suggest using AC_CHECK_HEADERS_ONCE, as it is more efficient. > AC_CACHE_CHECK([for working basename], > [compat_cv_func_basename_works], > > [AC_TRY_RUN([ AC_TRY_RUN is deprecated; also, instead of open-coding your program, I'd use AC_LANG_PROGRAM. > #include <stdio.h> > #include <stdlib.h> > #ifdef HAVE_LIBGEN_H > # include <libgen.h> For this particular test, there's no need to probe for HAVE_LIBGEN_H - since you are probing for a working basename(), it's perfectly find to ditch all platforms that lack <libgen.h> with a compiler error. > if (strcmp(basename(test1), tests[i].result) || > strcmp(test1, tests[i].test)) > exit(1); > } It is actually more portable to use 'return 1' than 'exit(1)' in configure checks, as then you don't have to worry about <stdlib.h> working right. Also, strcmp() requires the use of <string.h>. > ], > [compat_cv_func_basename_works=yes], > [compat_cv_func_basename_works=no], > [compat_cv_func_basename_works=no] Good, you provided a sane default for cross compilation. > )] > ) > if test "$compat_cv_func_basename_works" = "yes"; then > AC_DEFINE([HAVE_BASENAME], 1, > [Define if your system has a working basename]) > else > AC_LIBOBJ([basename]) > fi Yes, this looks like the correct conditional. In other words, you were already pretty close - reusing your main() method as-is, I would have written: AC_DEFUN([COMPAT_FUNC_BASENAME], [ AC_CHECK_HEADERS([libgen.h]) AC_CACHE_CHECK([for working basename], [compat_cv_func_basename_works], [AC_RUN_IFELSE([[ #include <string.h> #include <libgen.h> typedef struct { char *test; char *result; } test_t; const test_t tests[] = { { "/usr/local/foo", "foo" }, { "/usr/local/foo/", "foo" }, { NULL, NULL } }; ]], [[ char test1[1024]; int i; for (i = 0; tests[i].test; i++) { strcpy(test1, tests[i].test); if (strcmp(basename(test1), tests[i].result) || strcmp(test1, tests[i].test)) return 1; } ]], [compat_cv_func_basename_works=yes], [compat_cv_func_basename_works=no], [compat_cv_func_basename_works=no] )] ) if test "$compat_cv_func_basename_works" = "yes"; then AC_DEFINE([HAVE_BASENAME], 1, [Define if your system has a working basename]) else AC_LIBOBJ([basename]) fi ]) -- Eric Blake eblake@xxxxxxxxxx +1-919-301-3266 Libvirt virtualization library http://libvirt.org
Attachment:
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Autoconf mailing list Autoconf@xxxxxxx https://lists.gnu.org/mailman/listinfo/autoconf