[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