[m-rev.] for review: work towards supporting 64-bit Windows with MSVC

Julien Fischer jfischer at opturion.com
Sun Jun 25 02:12:05 AEST 2023


For review by anyone.
(I intend to to commit this one this evening, since I want to continue
working on it.)

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

Work towards supporting 64-bit Windows with MSVC.

compiler/globals.m:
      Extend c_compiler_type to distinguish between versions of MSVC
      that target x86 and those that target x86_64 (x64).

compiler/handle_options.m:
      Update the list of valid C compiler types.

compiler/compile_target_code.m:
      Handle versions of MSVC that generate x86_64 code.

m4/mercury.m4:
     Distinguish between versions of MSVC that target x86 and those
     that target x86_64.

configure.ac:
     Generate the new values of --c-compiler-type for MSVC.

     Determine the CPU type to pass to boehm_gc/NT_MAKEFILE.
     (This will also require an update to boehm_gc/Mmakefile; this change does
     not do that.)

Mmake.common.in:
     Add a new variable for setting the CPU type for boehm_gc/NT_MAKEFILE.

Julien.

diff --git a/Mmake.common.in b/Mmake.common.in
index 848b376..dc162be 100644
--- a/Mmake.common.in
+++ b/Mmake.common.in
@@ -185,6 +185,10 @@ BOEHM_CFLAGS_FOR_THREADS = @BOEHM_CFLAGS_FOR_THREADS@ \
  	@ENABLE_BOEHM_THREAD_LOCAL_ALLOC@ \
  	@ENABLE_BOEHM_PARALLEL_MARK@

+# The CPU type to pass via the "cpu" argument of boehm_gc/NT_MAKEFILE.
+# (This is only relevant when using MSVC.)
+BOEHM_WINDOWS_CPU_TYPE = @BOEHM_WINDOWS_CPU_TYPE@
+
  # Do we want to deal with intermodule information when building the library?
  # By default yes, since this way we note immediately when intermodule
  # optimization breaks, and always at installation time, since we must install
diff --git a/compiler/compile_target_code.m b/compiler/compile_target_code.m
index f35957c..8d605fd 100644
--- a/compiler/compile_target_code.m
+++ b/compiler/compile_target_code.m
@@ -395,7 +395,8 @@ gather_c_compiler_flags(Globals, PIC, AllCFlags) :-
          ;
              % XXX Check whether we need to do anything for these C compilers?
              ( C_CompilerType = cc_clang(_)
-            ; C_CompilerType = cc_cl(_)
+            ; C_CompilerType = cc_cl_x86(_)
+            ; C_CompilerType = cc_cl_x64(_)
              ),
              C_FnAlignOpt = ""
          ;
@@ -835,7 +836,9 @@ gather_compiler_specific_flags(Globals, Flags) :-
          C_CompilerType = cc_clang(_),
          globals.lookup_accumulating_option(Globals, clang_flags, FlagsList)
      ;
-        C_CompilerType = cc_cl(_),
+        ( C_CompilerType = cc_cl_x86(_)
+        ; C_CompilerType = cc_cl_x64(_)
+        ),
          globals.lookup_accumulating_option(Globals, msvc_flags, FlagsList)
      ;
          C_CompilerType = cc_unknown,
@@ -2368,9 +2371,7 @@ get_restricted_command_line_link_opts(Globals, LinkTargetType,
              LinkTargetType = executable,
              get_c_compiler_type(Globals, C_CompilerType),
              (
-                C_CompilerType = cc_cl(_),
-                % XXX WIN64 - this will need to be revisited when we begin
-                % supporting 64-bit Windows with MSVC.
+                C_CompilerType = cc_cl_x86(_),
                  ResCmdLinkFlags = [
                      "-nologo",
                      "-subsystem:console",
@@ -2380,6 +2381,16 @@ get_restricted_command_line_link_opts(Globals, LinkTargetType,
                  ],
                  join_string_list(ResCmdLinkFlags, "", "", " ", ResCmdLinkOpts)
              ;
+                C_CompilerType = cc_cl_x64(_),
+                ResCmdLinkFlags = [
+                    "-nologo",
+                    "-subsystem:console",
+                    "-machine:x64",
+                    "-entry:wmainCRTStartup",
+                    "-defaultlib:libcmt"
+                ],
+                join_string_list(ResCmdLinkFlags, "", "", " ", ResCmdLinkOpts)
+            ;
                  ( C_CompilerType = cc_gcc(_, _, _)
                  ; C_CompilerType = cc_clang(_)
                  ; C_CompilerType = cc_unknown
@@ -2556,10 +2567,12 @@ get_linker_output_option(Globals, LinkTargetType, OutputOpt) :-
      % NOTE: the spacing around the value of OutputOpt here is important.
      % Any changes should be reflected in predicate link_exe_or_shared_lib/9.
      (
-        C_CompilerType = cc_cl(_),
+        ( C_CompilerType = cc_cl_x86(_)
+        ; C_CompilerType = cc_cl_x64(_)
+        ),
          ( if LinkTargetType = executable then
              % NOTE: -Fe _must not_ be separated from its argument by any
-            % whitspace; the lack of a trailing space in the following
+            % whitespace; the lack of a trailing space in the following
              % is deliberate.
              OutputOpt = " -Fe"
          else
@@ -2591,7 +2604,9 @@ reserve_stack_size_flags(Globals) = Flags :-
              ),
              string.format("-Wl,--stack=%d", [i(ReserveStackSize)], Flags)
          ;
-            C_CompilerType = cc_cl(_),
+            ( C_CompilerType = cc_cl_x86(_)
+            ; C_CompilerType = cc_cl_x64(_)
+            ),
              string.format("-stack:%d", [i(ReserveStackSize)], Flags)
          )
      ).
@@ -2617,7 +2632,9 @@ process_link_library(Globals, MercuryLibDirs, LibName, LinkerOpt,
              LinkOpt = "-l",
              LibSuffix = ""
          ;
-            CCompilerType = cc_cl(_),
+            ( CCompilerType = cc_cl_x86(_)
+            ; CCompilerType = cc_cl_x64(_)
+            ),
              LinkOpt = "",
              LibSuffix = ".lib"
          )
@@ -2702,7 +2719,9 @@ create_archive(Globals, ProgressStream, ErrorStream, LibFileName, Quote,
      (
          % If we are using Visual C then we must be using the Microsoft
          % lib tool.
-        C_CompilerType = cc_cl(_),
+        ( C_CompilerType = cc_cl_x86(_)
+        ; C_CompilerType = cc_cl_x64(_)
+        ),
          ArOutputSpace = ""
      ;
          ( C_CompilerType = cc_gcc(_, _, _)
diff --git a/compiler/globals.m b/compiler/globals.m
index 0880a18..dd4599b 100644
--- a/compiler/globals.m
+++ b/compiler/globals.m
@@ -163,7 +163,8 @@
                  % This is only available since gcc 3.0.
              )
      ;       cc_clang(maybe(clang_version))
-    ;       cc_cl(maybe(int))
+    ;       cc_cl_x86(maybe(int))  % MSVC targeting x86.
+    ;       cc_cl_x64(maybe(int))  % MSVC targeting x86_64 (x64).
      ;       cc_unknown.

      % For the csharp backend, which csharp compiler are we using?
@@ -532,7 +533,11 @@ convert_c_compiler_type(CC_Str, C_CompilerType) :-

  convert_c_compiler_type_simple("gcc",      cc_gcc(no, no, no)).
  convert_c_compiler_type_simple("clang",    cc_clang(no)).
-convert_c_compiler_type_simple("msvc",     cc_cl(no)).
+% For backwards compatibility we currently recognise "msvc"
+% as a synonym for "msvc_x86".
+convert_c_compiler_type_simple("msvc",     cc_cl_x86(no)).
+convert_c_compiler_type_simple("msvc_x86", cc_cl_x86(no)).
+convert_c_compiler_type_simple("msvc_x64", cc_cl_x64(no)).
  convert_c_compiler_type_simple("unknown",  cc_unknown).

  :- pred convert_c_compiler_type_with_version(string::in, c_compiler_type::out)
@@ -544,8 +549,14 @@ convert_c_compiler_type_with_version(CC_Str, C_CompilerType) :-
          convert_gcc_version(Major, Minor, Patch, C_CompilerType)
      else if Tokens = ["clang", Major, Minor, Patch] then
          convert_clang_version(Major, Minor, Patch, C_CompilerType)
-    else if Tokens = ["msvc", Version] then
-        convert_msvc_version(Version, C_CompilerType)
+    else if Tokens = ["msvc", "x64", Version] then
+        convert_msvc_x64_version(Version, C_CompilerType)
+    else if
+        ( Tokens = ["msvc", Version]
+        ; Tokens = ["msvc", "x86", Version]
+        )
+    then
+        convert_msvc_x86_version(Version, C_CompilerType)
      else
          false
      ).
@@ -629,12 +640,19 @@ convert_clang_version(MajorStr, MinorStr, PatchStr, C_CompilerType) :-
      % The version number is an integer literal (corresponding to the value
      % of the builtin macro _MSC_VER).
      %
-:- pred convert_msvc_version(string::in, c_compiler_type::out) is semidet.
+:- pred convert_msvc_x86_version(string::in, c_compiler_type::out) is semidet.
+
+convert_msvc_x86_version(VersionStr, C_CompilerType) :-
+    string.to_int(VersionStr, Version),
+    Version > 0,
+    C_CompilerType = cc_cl_x86(yes(Version)).
+
+:- pred convert_msvc_x64_version(string::in, c_compiler_type::out) is semidet.

-convert_msvc_version(VersionStr, C_CompilerType) :-
+convert_msvc_x64_version(VersionStr, C_CompilerType) :-
      string.to_int(VersionStr, Version),
      Version > 0,
-    C_CompilerType = cc_cl(yes(Version)).
+    C_CompilerType = cc_cl_x64(yes(Version)).

  convert_csharp_compiler_type("microsoft", csharp_microsoft).
  convert_csharp_compiler_type("mono", csharp_mono).
diff --git a/compiler/handle_options.m b/compiler/handle_options.m
index 8dfe27e..007b7ff 100644
--- a/compiler/handle_options.m
+++ b/compiler/handle_options.m
@@ -522,11 +522,18 @@ check_option_values(!OptionTable, Target, WordSize, GC_Method,
          C_CompilerType = C_CompilerTypePrime
      else
          C_CompilerType = cc_unknown,   % dummy
+        ValidC_CompilerTypes = [
+            "gcc",
+            "clang",
+            "msvc_x86",
+            "msvc_x64",
+            "unknown"
+        ],
          CCTpec =
              [words("Invalid argument"), quote(C_CompilerTypeStr),
              words("to the"), quote("--c-compiler-type"), words("option;"),
              words("must be")] ++
-            list_to_quoted_pieces_or(["gcc", "clang", "msvc", "unknown"]) ++
+            list_to_quoted_pieces_or(ValidC_CompilerTypes) ++
              [suffix("."), nl],
          add_error(phase_options, CCTpec, !Specs)
      ),
diff --git a/configure.ac b/configure.ac
index c4d16e7..a01e997 100644
--- a/configure.ac
+++ b/configure.ac
@@ -170,10 +170,10 @@ case "$mercury_cv_cc_type" in
          C_COMPILER_TYPE="gcc_${mercury_cv_gcc_version}"
          ;;

-    msvc)
+    msvc_x86|msvc_x64)
          MERCURY_HAVE_MSVC=yes
          MERCURY_MSVC_VERSION
-        C_COMPILER_TYPE="msvc_${mercury_cv_msvc_version}"
+        C_COMPILER_TYPE="${mercury_cv_cc_type}_${mercury_cv_msvc_version}"
          ;;

      *)
@@ -183,6 +183,17 @@ esac

  #-----------------------------------------------------------------------------#

+# Work out what CPU type we need to pass to boehm_gc/NT_MAKEFILE.
+
+case "$mercury_cv_cc_type" in
+    msvc_64) BOEHM_WINDOWS_CPU_TYPE="x64" ;;
+    *) BOEHM_WINDOWS_CPU_TYPE="x86" ;;
+esac
+
+AC_SUBST([BOEHM_WINDOWS_CPU_TYPE])
+
+#-----------------------------------------------------------------------------#
+
  AC_CANONICAL_HOST
  FULLARCH="$host"
  AC_SUBST(FULLARCH)
@@ -2955,7 +2966,7 @@ case "$host" in
      *cygwin*)
          THREAD_LIBS=""
          case "$mercury_cv_cc_type" in
-            msvc)
+            msvc*)
                  CFLAGS_FOR_THREADS="-DGC_THREADS -MD"
                  LDFLAGS_FOR_THREADS="-MD"
                  LD_LIBFLAGS_FOR_THREADS="-MD"
@@ -2973,7 +2984,7 @@ case "$host" in
      i*86-pc-mingw*)
          THREAD_LIBS=""
          case "$mercury_cv_cc_type" in
-            msvc)
+            msvc*)
                  CFLAGS_FOR_THREADS="-DGC_THREADS -MD"
                  LDFLAGS_FOR_THREADS="-MD"
                  LD_LIBFLAGS_FOR_THREADS="-MD"
@@ -3005,7 +3016,7 @@ case "$host" in
      *-w64-mingw*|x86_64-pc-mingw*)
          THREAD_LIBS=""
          case "$mercury_cv_cc_type" in
-            msvc)
+            msvc*)
                  CFLAGS_FOR_THREADS="-DGC_THREADS -MD"
                  LDFLAGS_FOR_THREADS="-MD"
                  LD_LIBFLAGS_FOR_THREADS="-MD"
diff --git a/m4/mercury.m4 b/m4/mercury.m4
index 7a350fb..5ce50fb 100644
--- a/m4/mercury.m4
+++ b/m4/mercury.m4
@@ -686,7 +686,13 @@ int main(int argc, char **argv)
      #elif defined(__GNUC__)
         printf("gcc");
      #elif defined(_MSC_VER)
-       printf("msvc");
+       #if defined(_M_IX86)
+          printf("msvc_x86");
+       #elif defined(_M_X64)
+          printf("msvc_x64");
+       #else
+          printf("unknown");
+       #endif
      #else
         printf("unknown");
      #endif





More information about the reviews mailing list