[m-rev.] for review: support using clang as a C compiler with Mercury

Julien Fischer juliensf at csse.unimelb.edu.au
Wed Aug 24 16:56:01 AEST 2011


For review by anyone.

The following diff is based on work by Jeremy Huddleston 
<jeremyhu at macports.org> (posted on mercury-bugs).  I have removed
the restrictions that required clang to be used in c89 mode however.

----------------------------------

Branches: main, 11.07

Support using clang as a C compiler with Mercury -- currently only
tested on Mac OS X.

Clean up the handling of C compilers in the configure script.

configure.in:
 	Improve this script's ability to distinguish between different
 	types of C compiler.  In particular, ensure that a clear
 	distinction is maintained between clang and gcc.

 	Fix an old XXX: don't rely on pattern matching on the value
 	of $CC to determine the C compiler type.  This is particularly
 	error prone now since one compiler is named "clang" and another
 	"cl".

 	Set optimization and warning flags for clang.
 	(XXX this is currently very conservative; we need to go through
 	them and work out what good defaults might be.)

 	Don't link against libgcc if we are using clang.
 	(XXX I don't think this is really necessary for gcc either in
 	the great majority of cases.)

 	Mark spots that still need updating with "XXX CLANG"; I will
 	look into these separately.

aclocal.m4:
 	Add a new macro that determines the C compiler type based
 	on what builtin macros are defined -- unlike AC_PROG_CC
 	this macro correctly distinguishes between gcc and clang.

 	Add two new macros that determine version information for
 	clang and for Visual C.

scripts/mgnuc.in:
scripts/ml.in:
 	Handle clang as a C compiler.

README.MacOS:
 	Mention that clang can be used with Mercury on Mac OS X.

Julien.

Index: README.MacOS
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/README.MacOS,v
retrieving revision 1.18
diff -u -r1.18 README.MacOS
--- README.MacOS	17 Mar 2011 05:58:05 -0000	1.18
+++ README.MacOS	24 Aug 2011 06:47:10 -0000
@@ -7,7 +7,7 @@

  Mercury should build and install "out-of-the-box" on Mac OS X 10.5 or 10.6
  using Apple's gcc version 4.2.  This version of gcc is included with the
-Developer Tools.
+Developer Tools.  On Mac OS X 10.6 you may also use clang.

  The 'asm_fast*' and 'reg*' grades are not currently available on Mac OS X 10.5
  or 10.6.  The only low-level C grades available are the 'none*' grades.  The
@@ -23,8 +23,8 @@
  By default, 64-bit versions of the executables and libraries in the Mercury
  system will be installed on x86-64 machines running Mac OS X 10.6.  To build a
  32-bit installation on such a machine, you need to arrange to have the option
-"-m32" passed to gcc.  This can be done by invoking Mercury's configure script
-with the option:
+"-m32" passed to gcc or clang.  This can be done by invoking Mercury's
+configure script with the option:

      --with-cc="gcc -m32"

@@ -47,8 +47,7 @@

      MCFLAGS = --cross-compiling

-Mercury can currently only be compiled by gcc on Mac OS X.  It cannot currently
-be compiled with llvm-gcc or clang.
+Mercury cannot currently be compiled with llvm-gcc on Mac OS X.

  If, after installing Mercury, you encounter errors about missing .mih files,
  and you have fink installed, then try removing the fink components from your
Index: aclocal.m4
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/aclocal.m4,v
retrieving revision 1.37
diff -u -r1.37 aclocal.m4
--- aclocal.m4	9 Dec 2010 06:14:14 -0000	1.37
+++ aclocal.m4	24 Aug 2011 06:47:10 -0000
@@ -524,6 +524,105 @@
  ])

  #-----------------------------------------------------------------------------#
+
+# Work out the C compiler type using a stronger test than AC_PROG_CC to
+# distinguish between clang and gcc.
+# (We don't handle lcc here - I don't think that it's possible to.)
+
+AC_DEFUN([MERCURY_CC_TYPE], [
+AC_REQUIRE([AC_PROG_CC])
+AC_MSG_CHECKING([what the C compiler type really is])
+
+cat > conftest.c << EOF
+
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+    #if defined(__clang__)
+       printf("clang");
+    #elif defined(__GNUC__)
+       printf("gcc");
+    #elif defined(_MSC_VER)
+       printf("msvc");
+    #else
+       printf("unknown");
+    #endif
+ 
+    return 0;
+}
+EOF
+
+echo "$CC -o conftest conftests.c" >&AC_FD_CC 2>&1
+if
+    $CC -o conftest conftest.c
+then
+    mercury_cv_cc_type=`./conftest`
+else
+    # This shouldn't happen as we have already checked for this.
+    AC_MSG_ERROR([unexpected: $CC cannot create executable])
+fi
+
+AC_MSG_RESULT([$mercury_cv_cc_type])
+])
+
+#-----------------------------------------------------------------------------#
+
+AC_DEFUN([MERCURY_CLANG_VERSION], [
+AC_REQUIRE([AC_PROG_CC])
+
+cat > conftest.c << EOF
+
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+
+    printf("%d_%d_%d", __clang_major__, __clang_minor__, __clang_patchlevel__);
+    return 0;
+}
+EOF
+
+echo "$CC -o conftest contest.c" >&AC_FD_CC 2>&1
+if
+    $CC -o conftest conftest.c
+then
+    mercury_cv_clang_version=`./conftest`
+else
+    # This shouldn't happen as we have already checked for this.
+    AC_MSG_ERROR([unexpected: $CC cannot create executable])
+fi
+])
+
+#-----------------------------------------------------------------------------#
+
+AC_DEFUN([MERCURY_MSVC_VERSION], [
+AC_REQUIRE([AC_PROG_CC])
+
+cat > conftest.c << EOF
+
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+
+    printf("%d", _MSC_VER);
+    return 0;
+}
+EOF
+
+echo "$CC -o conftest contest.c" >&AC_FD_CC 2>&1
+if
+    $CC -o conftest conftest.c
+then
+    mercury_cv_msvc_version=`./conftest`
+else
+    # This shouldn't happen as we have already checked for this.
+    AC_MSG_ERROR([unexpected: $CC cannot create executable])
+fi
+])
+
+#-----------------------------------------------------------------------------#
  #
  # Check if the POSIX threads library is pthreads-win32.
  #
Index: configure.in
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/configure.in,v
retrieving revision 1.583
diff -u -r1.583 configure.in
--- configure.in	22 Jul 2011 03:34:36 -0000	1.583
+++ configure.in	24 Aug 2011 06:47:10 -0000
@@ -145,8 +145,57 @@
  AC_SUBST([CC])

  # Ensure that AC_CANONICAl_HOST uses the value of CC we just determined.
+#
  export CC

+# NOTE: AC_PROG_CC will set the variable GCC if it thinks the C compiler is
+# GCC.  However, it also sets it if the C compiler is clang -- because they
+# both define __GNUC__ -- do *NOT* use the GCC variable to check the C compiler
+# type, instead use the value of C_COMPILER_TYPE (defined below).
+#
+MERCURY_CC_TYPE
+
+MERCURY_HAVE_CLANG=no
+MERCURY_HAVE_GCC=no
+MERCURY_HAVE_MSVC=no
+MERCURY_HAVE_LCC=no
+
+case "$mercury_cv_cc_type" in
+    clang)
+        MERCURY_HAVE_CLANG=yes
+        MERCURY_CLANG_VERSION
+        C_COMPILER_TYPE="clang_${mercury_cv_clang_version}"
+    ;;
+ 
+    gcc)
+        MERCURY_HAVE_GCC=yes
+        MERCURY_GCC_VERSION
+        C_COMPILER_TYPE="gcc_${mercury_cv_gcc_version}"
+    ;;
+ 
+    msvc)
+        MERCURY_HAVE_MSVC=yes
+        MERCURY_MSVC_VERSION
+        # XXX For historical reasons msvc is identified as "cl".
+        C_COMPILER_TYPE="cl_${mercury_cv_msvc_version}"
+    ;;
+
+    *)
+        # XXX is there a better way to test for lcc other than
+        # to pattern match on its name?
+        case "$CC" in
+            *lcc*)
+                MERCURY_HAVE_LCC=yes
+                C_COMPILER_TYPE="lcc"
+            ;;
+
+            *)
+                C_COMPILER_TYPE="unknown"
+            ;;
+        esac
+    ;;
+esac
+
  #-----------------------------------------------------------------------------#

  AC_CANONICAL_HOST
@@ -830,10 +879,8 @@

  MERCURY_CHECK_CC_NEEDS_TRAD_CPP

-# AC_PROG_CC sets GCC to yes if $CC is GNU C.
-# If the C compiler is GCC try to work out what version we are using.
-if test "$GCC" = "yes"; then
-    MERCURY_GCC_VERSION
+if test "$MERCURY_HAVE_GCC" = "yes"
+then
      GCC_PROG=$CC
  else
      AC_PATH_PROG(GCC_PROG,gcc)
@@ -4054,7 +4101,8 @@
  LINK_EXE=$CC
  LINK_SHARED_OBJ="$CC -shared"
  LINK_SHARED_OBJ_SH="$CC -shared"
-if test "$GCC" = "yes"; then
+if test "$MERCURY_HAVE_GCC" = "yes"
+then
      SHARED_LIBS="\`$CC -print-libgcc-file-name\` \$(MATH_LIB) -lc"
      SHARED_LIBS_SH="\`$CC -print-libgcc-file-name\` \$MATH_LIB -lc"
  else
@@ -4129,8 +4177,8 @@
                  rm -f conftest*
                  ;;
              *)
-                case "$CC" in
-                    lcc*)
+                case "$C_COMPILER_TYPE" in
+                    lcc)
                          AC_MSG_RESULT(yes)
                          EXT_FOR_SHARED_LIB=so
                          EXE_RPATH_OPT="-Wl-rpath -Wl"
@@ -4332,6 +4380,7 @@
      *apple*darwin*)
          # If the compiler is gcc then use darwin style dynamic linking.
          # Otherwise use static linking.
+        # XXX CLANG
          if test "$GCC_PROG" != ""; then
              AC_MSG_RESULT(yes)
              # Check if the user has explicitly requested that flat
@@ -4430,79 +4479,72 @@
  # compiler/compile_target_code.m.

  # AC_PROG_CC sets GCC to yes if $CC is GNU C.
-if test "$GCC" = "yes"
-then
-    C_COMPILER_TYPE="gcc_${mercury_cv_gcc_version}"
-    CFLAGS_FOR_ANSI="-ansi"

-    # For a full list of the other gcc warnings that we don't
-    # enable, and why, see scripts/mgnuc.in.
-    CFLAGS_FOR_WARNINGS="-Wall -Wwrite-strings -Wshadow -Wmissing-prototypes -Wno-unused -Wno-uninitialized -Wstrict-prototypes"
+case "$C_COMPILER_TYPE" in

-    # Enabling -fomit-frame-pointer causes setjmp/longjmp to misbehave
-    # with MinGW on Windows XP.
-    case "$host" in
-        *mingw*) CFLAGS_FOR_OPT="-O2" ;;
-        *)       CFLAGS_FOR_OPT="-O2 -fomit-frame-pointer" ;;
-    esac
+    gcc*)
+        CFLAGS_FOR_ANSI="-ansi"

-    CFLAGS_FOR_DEBUG="-g"
-    CFLAGS_FOR_NO_STRICT_ALIASING="-fno-strict-aliasing"
-    MCFLAGS_FOR_CC=
-else
+        # For a full list of the other gcc warnings that we don't
+        # enable, and why, see scripts/mgnuc.in.
+        CFLAGS_FOR_WARNINGS="-Wall -Wwrite-strings -Wshadow -Wmissing-prototypes -Wno-unused -Wno-uninitialized -Wstrict-prototypes"

-    # XXX we should not rely on pattern matching against the executable name to
-    # determine the C compiler type.
+        # Enabling -fomit-frame-pointer causes setjmp/longjmp to misbehave
+        # with MinGW on Windows XP.
+        case "$host" in
+            *mingw*) CFLAGS_FOR_OPT="-O2" ;;
+            *)       CFLAGS_FOR_OPT="-O2 -fomit-frame-pointer" ;;
+        esac

-    case "$CC" in
-        *lcc*)
-            C_COMPILER_TYPE=lcc
-            CFLAGS_FOR_ANSI=
-
-            # Turn off all warnings due to spurious warnings.
-            CFLAGS_FOR_WARNINGS="-w"
-
-            CFLAGS_FOR_OPT=
-            CFLAGS_FOR_DEBUG="-g"
-            CFLAGS_FOR_NO_STRICT_ALIASING=
-            MCFLAGS_FOR_CC=
-            ;;
-
-        *cl* | *CL*)
-            C_COMPILER_TYPE=cl
-            CFLAGS_FOR_ANSI=
-            CFLAGS_FOR_WARNINGS=
-            CFLAGS_FOR_OPT=
-            CFLAGS_FOR_DEBUG="-Zi"
-            CFLAGS_FOR_NO_STRICT_ALIASING=
-
-            # Using the MSVC compiler implies that we must use
-            # a maximum jump table size of 512 to avoid a fixed limit
-            # in the compiler.
-            MCFLAGS_FOR_CC="--max-jump-table-size 512"
-            ;;
-
-        cc* | */cc*)
-            C_COMPILER_TYPE=unknown
-            CFLAGS_FOR_ANSI=
-            CFLAGS_FOR_OPT="-O"
-            CFLAGS_FOR_WARNINGS=
-            CFLAGS_FOR_DEBUG="-g"
-            CFLAGS_FOR_NO_STRICT_ALIASING=
-            MCFLAGS_FOR_CC=
-            ;;
+        CFLAGS_FOR_DEBUG="-g"
+        CFLAGS_FOR_NO_STRICT_ALIASING="-fno-strict-aliasing"
+        MCFLAGS_FOR_CC=
+        ;;
+
+    lcc)
+        CFLAGS_FOR_ANSI=
+
+        # Turn off all warnings due to spurious warnings.
+        CFLAGS_FOR_WARNINGS="-w"
+
+        CFLAGS_FOR_OPT=
+        CFLAGS_FOR_DEBUG="-g"
+        CFLAGS_FOR_NO_STRICT_ALIASING=
+        MCFLAGS_FOR_CC=
+        ;;
+
+    clang*)
+        # XXX we need go through the warning and optimization options for clang
+        # more carefully.
+        CFLAGS_FOR_WARNINGS="-w"
+        CFLAGS_FOR_OPT="-fomit-frame-pointer"
+        CFLAGS_FOR_DEBUG="-g"
+        CFLAGS_FOR_NO_STRICT_ALIASING="-fno-strict-aliasing"
+        MCFLAGS_FOR_CC=
+        ;;
+
+    msvc*)
+        CFLAGS_FOR_ANSI=
+        CFLAGS_FOR_WARNINGS=
+        CFLAGS_FOR_OPT=
+        CFLAGS_FOR_DEBUG="-Zi"
+        CFLAGS_FOR_NO_STRICT_ALIASING=
+
+        # Using the MSVC compiler implies that we must use
+        # a maximum jump table size of 512 to avoid a fixed limit
+        # in the compiler.
+        MCFLAGS_FOR_CC="--max-jump-table-size 512"
+        ;;

-        *)
-            C_COMPILER_TYPE=unknown
-            CFLAGS_FOR_ANSI=
-            CFLAGS_FOR_OPT="-O"
-            CFLAGS_FOR_WARNINGS=
-            CFLAGS_FOR_DEBUG="-g"
-            CFLAGS_FOR_NO_STRICT_ALIASING=
-            MCFLAGS_FOR_CC=
-            ;;
-    esac
-fi
+    *)
+        CFLAGS_FOR_ANSI=
+        CFLAGS_FOR_OPT="-O"
+        CFLAGS_FOR_WARNINGS=
+        CFLAGS_FOR_DEBUG="-g"
+        CFLAGS_FOR_NO_STRICT_ALIASING=
+        MCFLAGS_FOR_CC=
+        ;;
+esac

  CFLAGS_FOR_OPT="$CFLAGS_FOR_OPT $CFLAGS_FOR_NO_STRICT_ALIASING"

@@ -4521,6 +4563,8 @@

  # Note that changes here may require changes in scripts/ml.in.

+# XXX Do we also need -static for clang?
+#
  LD_STATIC_FLAGS=
  case "$C_COMPILER_TYPE" in
      gcc*|lcc)
@@ -4577,7 +4621,7 @@
  # We can't put the call to MSG_CHECKING at the start of the case statement
  # above, because of the nested check in the lcc case.  So we just put it
  # here immediately before the MSG_RESULT call.
-AC_MSG_CHECKING(options for static linking)
+AC_MSG_CHECKING([options for static linking])
  AC_MSG_RESULT($LD_STATIC_FLAGS)
  case "$LD_STATIC_FLAGS" in
      "")
Index: scripts/mgnuc.in
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/scripts/mgnuc.in,v
retrieving revision 1.136
diff -u -r1.136 mgnuc.in
--- scripts/mgnuc.in	15 Jul 2011 08:10:43 -0000	1.136
+++ scripts/mgnuc.in	24 Aug 2011 06:47:11 -0000
@@ -69,6 +69,13 @@
          DEBUG_OPT="-g"
          COMPILER=gcc
          ;;
+    *clang*)
+        ANSI_OPTS="-ansi"
+        CHECK_OPTS="-w"
+        OPT_OPTS="-O0 $CFLAGS_FOR_NO_STRICT_ALIASING -fomit-frame-pointer"
+        DEBUG_OPT="-g"
+        COMPILER=clang
+        ;;
      *lcc*)
          ANSI_OPTS=
          CHECK_OPTS="-w"     # turn off all warnings due to spurious warnings.
Index: scripts/ml.in
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/scripts/ml.in,v
retrieving revision 1.123
diff -u -r1.123 ml.in
--- scripts/ml.in	11 Feb 2010 04:36:11 -0000	1.123
+++ scripts/ml.in	24 Aug 2011 06:47:11 -0000
@@ -75,6 +75,9 @@
  	*lcc*)
  		COMPILER=lcc
  		;;
+	*clang*)
+		COMPILER=clang
+		;;
  	*cl* | *CL*)
  		COMPILER=cl
  		;;
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list