diff --git a/README.MacOS b/README.MacOS index 867c8787e..c1b0d4d40 100644 --- a/README.MacOS +++ b/README.MacOS @@ -7,7 +7,7 @@ Mercury on Mac OS X 10.5 and 10.6 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 @@ for compiling applications. 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 @@ Mmake.params at the top-level of the source tree: 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 diff --git a/aclocal.m4 b/aclocal.m4 index 43b6b221f..90c452ec7 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -523,6 +523,105 @@ else fi ]) +#-----------------------------------------------------------------------------# + +# 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 + +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 + +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 + +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. diff --git a/configure.in b/configure.in index e98bb5c4f..74ada07ea 100644 --- a/configure.in +++ b/configure.in @@ -145,8 +145,57 @@ AC_PROG_CC 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 @@ AC_DEFINE_UNQUOTED(MR_HOSTNAMECMD, "$HOSTNAMECMD") 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 @@ AC_MSG_CHECKING(whether Mercury supports shared libraries on this system) 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 @@ case "$host" in 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 @@ case "$host" in *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 @@ esac # 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= + CFLAGS_FOR_DEBUG="-g" + CFLAGS_FOR_NO_STRICT_ALIASING="-fno-strict-aliasing" + MCFLAGS_FOR_CC= + ;; - # Turn off all warnings due to spurious warnings. - CFLAGS_FOR_WARNINGS="-w" + lcc) + CFLAGS_FOR_ANSI= - CFLAGS_FOR_OPT= - CFLAGS_FOR_DEBUG="-g" - CFLAGS_FOR_NO_STRICT_ALIASING= - MCFLAGS_FOR_CC= - ;; + # Turn off all warnings due to spurious warnings. + CFLAGS_FOR_WARNINGS="-w" - *cl* | *CL*) - C_COMPILER_TYPE=cl - CFLAGS_FOR_ANSI= - CFLAGS_FOR_WARNINGS= - CFLAGS_FOR_OPT= - CFLAGS_FOR_DEBUG="-Zi" - CFLAGS_FOR_NO_STRICT_ALIASING= + CFLAGS_FOR_OPT= + CFLAGS_FOR_DEBUG="-g" + CFLAGS_FOR_NO_STRICT_ALIASING= + MCFLAGS_FOR_CC= + ;; - # 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" - ;; + 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= + ;; - 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= - ;; + msvc*) + CFLAGS_FOR_ANSI= + CFLAGS_FOR_WARNINGS= + CFLAGS_FOR_OPT= + CFLAGS_FOR_DEBUG="-Zi" + CFLAGS_FOR_NO_STRICT_ALIASING= - *) - 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 + # 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" + ;; + + *) + 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 @@ AC_SUBST([C_COMPILER_TYPE]) # 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 @@ esac # 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 "") diff --git a/scripts/mgnuc.in b/scripts/mgnuc.in index a934cdd4a..b5415ff7e 100644 --- a/scripts/mgnuc.in +++ b/scripts/mgnuc.in @@ -69,6 +69,13 @@ case "$CC" in 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. diff --git a/scripts/ml.in b/scripts/ml.in index f3342e398..0758fe5a1 100644 --- a/scripts/ml.in +++ b/scripts/ml.in @@ -2,7 +2,7 @@ # vim: ts=4 sw=4 noet # @configure_input@ #---------------------------------------------------------------------------# -# Copyright (C) 1995-2008, 2010 The University of Melbourne. +# Copyright (C) 1995-2008, 2010-2011The University of Melbourne. # This file may only be copied under the terms of the GNU General # Public License - see the file COPYING in the Mercury distribution. #---------------------------------------------------------------------------# @@ -75,6 +75,9 @@ case "$CC" in *lcc*) COMPILER=lcc ;; + *clang*) + COMPILER=clang + ;; *cl* | *CL*) COMPILER=cl ;;