[m-rev.] for review: make gcc version information available to mmc

Julien Fischer juliensf at csse.unimelb.edu.au
Fri Jan 30 17:11:31 AEDT 2009


Extend the configuration script so that if the C compiler we are
using is GCC we also try to determine what version of GCC it is.

Make gcc version information available to mmc.

aclocal.m4:
 	Add a new macro for determining gcc version information.

configure.in:
 	Use the new macro.

 	Add a suffix to the "gcc" compiler type containing
 	the version information.  The suffix has the form:

 	    _<x>_<y>_<z>

         where x, y, and z are the major and minor
 	version numbers, and patch level respectively.

 	Conform to the above change in a couple of spots.

compiler/globals.m:
 	Store gcc version information in c_compiler_type.

 	Parse the new form of argument for the --c-compiler-type
 	option.

compiler/compile_target_code.m:
 	Conform to the above change.

Julien.

Index: aclocal.m4
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/aclocal.m4,v
retrieving revision 1.29
diff -u -r1.29 aclocal.m4
--- aclocal.m4	3 Nov 2008 11:56:16 -0000	1.29
+++ aclocal.m4	30 Jan 2009 06:02:11 -0000
@@ -431,3 +431,46 @@
  ])

  #-----------------------------------------------------------------------------#
+
+# NOTE: updates to this macro may need to be reflected in compiler/globals.m.
+
+AC_DEFUN([MERCURY_GCC_VERSION], [
+AC_REQUIRE([AC_PROG_CC])
+
+cat > conftest.c << EOF
+
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+
+#if defined(__GNUC__)
+    printf("%d_", __GNUC__);
+    #if defined(__GNUC_MINOR__)
+        printf("%d_", __GNUC_MINOR__);
+    #else
+        printf("u_");
+    #endif /* ! __GNUC_MINOR__ */
+    #if defined(__GNUC_PATCHLEVEL__)
+    	printf("%d", __GNUC_PATCHLEVEL__);
+    #else
+        printf("u");
+    #endif /* ! __GNUC_PATCHLEVEL__ */
+#endif /* __GNUC__ */
+
+	return 0;
+}
+EOF
+
+echo "$CC -o conftest contest.c" >&AC_FD_CC 2>&1
+if
+    $CC -o conftest conftest.c
+then
+    mercury_cv_gcc_version=`./conftest`
+else
+    # This shouldn't happen as we have already checked for this.
+    AC_MSG_ERROR([unexpected: $CC cannot create executable])
+fi
+])
+
+#-----------------------------------------------------------------------------#
Index: configure.in
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/configure.in,v
retrieving revision 1.535
diff -u -r1.535 configure.in
--- configure.in	8 Dec 2008 13:52:03 -0000	1.535
+++ configure.in	30 Jan 2009 03:57:09 -0000
@@ -740,6 +740,7 @@
          ;;
  esac

+
  #-----------------------------------------------------------------------------#

  cat > conftest.c << EOF
@@ -4050,11 +4051,13 @@
  #
  # Note that changes here may require changes in scripts/mgnuc.in and
  # 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
+if test "$GCC" = "yes"
+then
+
+    MERCURY_GCC_VERSION
+    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
@@ -4132,7 +4135,7 @@

  LD_STATIC_FLAGS=
  case "$C_COMPILER_TYPE" in
-    gcc|lcc)
+    gcc*|lcc)
          LD_STATIC_FLAGS=-static
          ;;
  esac
@@ -4143,7 +4146,7 @@
          # to _DYNAMIC in boehm_gc/dyn_load.c. (We might eventually need
          # similar treatment for other OSs too.)
          case "$C_COMPILER_TYPE" in
-            gcc)
+            gcc*)
                  LD_STATIC_FLAGS="-static -Wl-defsym -Wl_DYNAMIC=0"
                  ;;
              lcc)
Index: compiler/compile_target_code.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/compile_target_code.m,v
retrieving revision 1.136
diff -u -r1.136 compile_target_code.m
--- compiler/compile_target_code.m	28 Jan 2009 06:57:45 -0000	1.136
+++ compiler/compile_target_code.m	30 Jan 2009 03:26:11 -0000
@@ -667,7 +667,7 @@
          %
          io_get_c_compiler_type(C_CompilerType, !IO),
          (
-            C_CompilerType = cc_gcc,
+            C_CompilerType = cc_gcc(_, _, _),
              globals.io_lookup_int_option(bytes_per_word, BytesPerWord, !IO),
              C_FnAlignOpt = string.format("-falign-functions=%d ",
                  [i(BytesPerWord)])
Index: compiler/globals.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/globals.m,v
retrieving revision 1.90
diff -u -r1.90 globals.m
--- compiler/globals.m	23 Jul 2008 23:20:33 -0000	1.90
+++ compiler/globals.m	30 Jan 2009 05:38:21 -0000
@@ -122,9 +122,19 @@
      ;       norm_size_data_elems.

      % For the C backends, what type of C compiler are we using?
-    % 
+    %
  :- type c_compiler_type
-    --->    cc_gcc
+    --->    cc_gcc(
+                gcc_major_ver :: maybe(int),
+                % The major version number, if known.
+
+                gcc_minor_ver :: maybe(int),
+                % The minor version number, if known.
+ 
+                gcc_patch_level :: maybe(int)
+                % The patch level, if known.
+                % This is only available since gcc 3.0.
+            )
      ;       cc_lcc
      ;       cc_cl
      ;       cc_unknown.
@@ -302,6 +312,7 @@

  :- import_module libs.compiler_util.

+:- import_module int.
  :- import_module string.
  :- import_module univ.

@@ -353,10 +364,89 @@
  convert_maybe_thread_safe("yes", yes).
  convert_maybe_thread_safe("no",  no).

-convert_c_compiler_type("gcc",      cc_gcc).
-convert_c_compiler_type("lcc",      cc_lcc).
-convert_c_compiler_type("cl",       cc_cl).
-convert_c_compiler_type("unknown",  cc_unknown).
+convert_c_compiler_type(CC_Str, C_CompilerType) :-
+    ( convert_c_compiler_type_simple(CC_Str, C_CompilerType0) ->
+        C_CompilerType = C_CompilerType0
+    ;
+        convert_c_compiler_type_with_version(CC_Str, C_CompilerType)
+    ).
+
+:- pred convert_c_compiler_type_simple(string::in, c_compiler_type::out)
+    is semidet.
+
+convert_c_compiler_type_simple("gcc",      cc_gcc(no, no, no)).
+convert_c_compiler_type_simple("lcc",      cc_lcc).
+convert_c_compiler_type_simple("cl",       cc_cl).
+convert_c_compiler_type_simple("unknown",  cc_unknown).
+
+:- pred convert_c_compiler_type_with_version(string::in, c_compiler_type::out)
+    is semidet.
+
+convert_c_compiler_type_with_version(CC_Str, C_CompilerType) :-
+    Tokens = string.words_separator((pred(X::in) is semidet :- X = ('_')),
+        CC_Str),
+    ( Tokens = ["gcc", Major, Minor, Patch] ->
+        convert_gcc_version(Major, Minor, Patch, C_CompilerType)
+    ; 
+         false
+    ).
+
+    % Create the value of C compiler type when we have (some) version
+    % information for gcc available.
+    % We only accept version information that has the following form:
+    % 
+    %   u_u_u
+    %   <major>_u_u
+    %   <major>_<minor>_<u>
+    %   <major>_<minor>_<patch>
+    %
+    % That is setting the minor version number when the major
+    % one is unknown won't be accepted.  (It wouldn't be useful
+    % in any case.)
+    %
+    % <major> must be >= 2 (Mercury won't work with anthing older
+    % than that and <minor> and <patch> must be non-negative.
+    %
+:- pred convert_gcc_version(string::in, string::in, string::in,
+    c_compiler_type::out) is semidet.
+
+convert_gcc_version(MajorStr, MinorStr, PatchStr, C_CompilerType) :-
+    ( 
+        MajorStr = "u",
+        MinorStr = "u",
+        PatchStr = "u"
+    ->
+        C_CompilerType = cc_gcc(no, no, no)
+    ;
+        string.to_int(MajorStr, Major),
+        Major >= 2
+    ->
+        (
+            MinorStr = "u"
+        ->
+            C_CompilerType = cc_gcc(yes(Major), no, no)
+        ;
+            string.to_int(MinorStr, Minor),
+            Minor >= 0
+        ->
+            (
+                PatchStr = "u"
+            ->
+                C_CompilerType = cc_gcc(yes(Major), yes(Minor), no)
+            ;
+                string.to_int(PatchStr, Patch),
+                Patch >= 0
+            ->
+                C_CompilerType = cc_gcc(yes(Major), yes(Minor), yes(Patch))
+            ;
+                false
+            )
+        ;
+            false
+        )
+    ;
+        false
+    ).

  compilation_target_string(target_c)    = "C".
  compilation_target_string(target_il)   = "IL".

--------------------------------------------------------------------------
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