set sysroot if clang version used for bindings generation cannot find stdio.h
authorSven Verdoolaege <sven.verdoolaege@gmail.com>
Sat, 4 Apr 2020 12:17:04 +0000 (4 14:17 +0200)
committerSven Verdoolaege <sven.verdoolaege@gmail.com>
Sun, 12 Apr 2020 16:47:51 +0000 (12 18:47 +0200)
For reasonably recent versions of clang, the clang driver
is used to determine the options to be used for parsing
the header file from which the bindings will be generated.
On modern version of OS X, however, mainline clang does not
appear to be set up correctly to find the standard header files.
In particular, they are not in /usr/include, since that
is completely missing.
The Xcode version of clang sets -isysroot to point
to those header files.  Try and do the same if clang
cannot find the header files by default.

Signed-off-by: Sven Verdoolaege <sven.verdoolaege@gmail.com>
interface/extract_interface.cc
m4/ax_detect_clang.m4

index 34a7f40..7384d53 100644 (file)
@@ -237,6 +237,26 @@ static void create_from_args(CompilerInvocation &invocation,
 
 #endif
 
+#ifdef CLANG_SYSROOT
+/* Set sysroot if required.
+ *
+ * If CLANG_SYSROOT is defined, then set it to this value.
+ */
+static void set_sysroot(ArgStringList &args)
+{
+       args.push_back("-isysroot");
+       args.push_back(CLANG_SYSROOT);
+}
+#else
+/* Set sysroot if required.
+ *
+ * If CLANG_SYSROOT is not defined, then it does not need to be set.
+ */
+static void set_sysroot(ArgStringList &args)
+{
+}
+#endif
+
 /* Create a CompilerInvocation object that stores the command line
  * arguments constructed by the driver.
  * The arguments are mainly useful for setting up the system include
@@ -258,10 +278,11 @@ static CompilerInvocation *construct_invocation(const char *filename,
        if (strcmp(cmd->getCreator().getName(), "clang"))
                return NULL;
 
-       const ArgStringList *args = &cmd->getArguments();
+       ArgStringList args = cmd->getArguments();
+       set_sysroot(args);
 
        CompilerInvocation *invocation = new CompilerInvocation;
-       create_from_args(*invocation, args, Diags);
+       create_from_args(*invocation, &args, Diags);
        return invocation;
 }
 
index 6466a15..d0f46f6 100644 (file)
@@ -36,6 +36,42 @@ fi
 CLANG_PREFIX=`$LLVM_CONFIG --prefix`
 AC_DEFINE_UNQUOTED(CLANG_PREFIX, ["$CLANG_PREFIX"], [Clang installation prefix])
 
+# If $CLANG_PREFIX/bin/clang cannot find the standard include files,
+# then see if setting sysroot to `xcode-select -p`/SDKs/MacOSX.sdk helps.
+# This may be required on some versions of OS X since they lack /usr/include.
+# If so, set CLANG_SYSROOT accordingly.
+SAVE_CC="$CC"
+CC="$CLANG_PREFIX/bin/clang"
+AC_MSG_CHECKING(
+       [whether $CLANG_PREFIX/bin/clang can find standard include files])
+found_header=no
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>]], [[]])],
+       [found_header=yes])
+AC_MSG_RESULT([$found_header])
+if test "x$found_header" != "xyes"; then
+       AC_CHECK_PROG(XCODE_SELECT, xcode-select, xcode-select, [])
+       if test -z "$XCODE_SELECT"; then
+               AC_MSG_ERROR([Cannot find xcode-select])
+       fi
+       sysroot=`$XCODE_SELECT -p`/SDKs/MacOSX.sdk
+       SAVE_CPPFLAGS="$CPPFLAGS"
+       CPPFLAGS="$CPPFLAGS -isysroot $sysroot"
+       AC_MSG_CHECKING(
+               [whether standard include files can be found with sysroot set])
+       found_header=no
+       AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>]], [[]])],
+               [found_header=yes])
+       AC_MSG_RESULT([$found_header])
+       CPPFLAGS="$SAVE_CPPFLAGS"
+       if test "x$found_header" != "xyes"; then
+               AC_MSG_ERROR([Cannot find standard include files])
+       else
+               AC_DEFINE_UNQUOTED([CLANG_SYSROOT], ["$sysroot"],
+                       [Define to sysroot if needed])
+       fi
+fi
+CC="$SAVE_CC"
+
 SAVE_CPPFLAGS="$CPPFLAGS"
 CPPFLAGS="$CLANG_CXXFLAGS $CPPFLAGS"
 AC_LANG_PUSH(C++)