Add MinGW option -mcrtdll= for choosing C RunTime DLL library

Message ID 20230527101412.19562-1-pali@kernel.org
State New
Headers
Series Add MinGW option -mcrtdll= for choosing C RunTime DLL library |

Commit Message

Pali Rohár May 27, 2023, 10:14 a.m. UTC
  It adjust preprocess, compile and link flags, which allows to change
default -lmsvcrt library by another provided by MinGW runtime.

gcc/
     * config/i386/mingw-w64.h (CPP_SPEC): Adjust for -mcrtdll=.
     (REAL_LIBGCC_SPEC): New define.
     * config/i386/mingw.opt: Add mcrtdll=
     * config/i386/mingw32.h (CPP_SPEC): Adjust for -mcrtdll=.
     (REAL_LIBGCC_SPEC): Adjust for -mcrtdll=.
     (STARTFILE_SPEC): Adjust for -mcrtdll=.
     * doc/invoke.texi: Add mcrtdll= documentation.
---
 gcc/config/i386/mingw-w64.h | 22 +++++++++++++++++++++-
 gcc/config/i386/mingw.opt   |  4 ++++
 gcc/config/i386/mingw32.h   | 28 ++++++++++++++++++++++++----
 gcc/doc/invoke.texi         | 21 ++++++++++++++++++++-
 4 files changed, 69 insertions(+), 6 deletions(-)
  

Comments

Jonathan Yong June 11, 2023, 11:08 p.m. UTC | #1
On 5/27/23 10:14, Pali Rohár wrote:
> It adjust preprocess, compile and link flags, which allows to change
> default -lmsvcrt library by another provided by MinGW runtime.
> 
> gcc/
>       * config/i386/mingw-w64.h (CPP_SPEC): Adjust for -mcrtdll=.
>       (REAL_LIBGCC_SPEC): New define.
>       * config/i386/mingw.opt: Add mcrtdll=
>       * config/i386/mingw32.h (CPP_SPEC): Adjust for -mcrtdll=.
>       (REAL_LIBGCC_SPEC): Adjust for -mcrtdll=.
>       (STARTFILE_SPEC): Adjust for -mcrtdll=.
>       * doc/invoke.texi: Add mcrtdll= documentation.
> ---
>   gcc/config/i386/mingw-w64.h | 22 +++++++++++++++++++++-
>   gcc/config/i386/mingw.opt   |  4 ++++
>   gcc/config/i386/mingw32.h   | 28 ++++++++++++++++++++++++----
>   gcc/doc/invoke.texi         | 21 ++++++++++++++++++++-
>   4 files changed, 69 insertions(+), 6 deletions(-)
> 
> diff --git a/gcc/config/i386/mingw-w64.h b/gcc/config/i386/mingw-w64.h
> index 3a21cec3f8cd..0146ed4f793e 100644
> --- a/gcc/config/i386/mingw-w64.h
> +++ b/gcc/config/i386/mingw-w64.h
> @@ -25,7 +25,27 @@ along with GCC; see the file COPYING3.  If not see
>   #define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT} " \
>   		 "%{municode:-DUNICODE} " \
>   		 "%{" SPEC_PTHREAD1 ":-D_REENTRANT} " \
> -		 "%{" SPEC_PTHREAD2 ":-U_REENTRANT} "
> +		 "%{" SPEC_PTHREAD2 ":-U_REENTRANT} " \
> +		 "%{mcrtdll=crtdll*:-U__MSVCRT__ -D__CRTDLL__} " \
> +		 "%{mcrtdll=msvcrt10*:-D__MSVCRT_VERSION__=0x100} " \
> +		 "%{mcrtdll=msvcrt20*:-D__MSVCRT_VERSION__=0x200} " \
> +		 "%{mcrtdll=msvcrt40*:-D__MSVCRT_VERSION__=0x400} " \
> +		 "%{mcrtdll=msvcrt-os*:-D__MSVCRT_VERSION__=0x700} " \
> +		 "%{mcrtdll=msvcr70*:-D__MSVCRT_VERSION__=0x700} " \
> +		 "%{mcrtdll=msvcr71*:-D__MSVCRT_VERSION__=0x701} " \
> +		 "%{mcrtdll=msvcr80*:-D__MSVCRT_VERSION__=0x800} " \
> +		 "%{mcrtdll=msvcr90*:-D__MSVCRT_VERSION__=0x900} " \
> +		 "%{mcrtdll=msvcr100*:-D__MSVCRT_VERSION__=0xA00} " \
> +		 "%{mcrtdll=msvcr110*:-D__MSVCRT_VERSION__=0xB00} " \
> +		 "%{mcrtdll=msvcr120*:-D__MSVCRT_VERSION__=0xC00} " \
> +		 "%{mcrtdll=ucrt*:-D_UCRT} "
> +
> +#undef REAL_LIBGCC_SPEC
> +#define REAL_LIBGCC_SPEC \
> +  "%{mthreads:-lmingwthrd} -lmingw32 \
> +   " SHARED_LIBGCC_SPEC " \
> +   -lmingwex %{!mcrtdll=*:-lmsvcrt} %{mcrtdll=*:-l%*} \
> +   -lkernel32 " MCFGTHREAD_SPEC
>   
>   #undef STARTFILE_SPEC
>   #define STARTFILE_SPEC "%{shared|mdll:dllcrt2%O%s} \
> diff --git a/gcc/config/i386/mingw.opt b/gcc/config/i386/mingw.opt
> index 0ae026a66bd6..dd66a50aec00 100644
> --- a/gcc/config/i386/mingw.opt
> +++ b/gcc/config/i386/mingw.opt
> @@ -18,6 +18,10 @@
>   ; along with GCC; see the file COPYING3.  If not see
>   ; <http://www.gnu.org/licenses/>.
>   
> +mcrtdll=
> +Target RejectNegative Joined
> +Preprocess, compile or link with specified C RunTime DLL library.
> +
>   pthread
>   Driver
>   
> diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h
> index 6a55baaa4587..a1ee001983a7 100644
> --- a/gcc/config/i386/mingw32.h
> +++ b/gcc/config/i386/mingw32.h
> @@ -89,7 +89,20 @@ along with GCC; see the file COPYING3.  If not see
>   #undef CPP_SPEC
>   #define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT} " \
>   		 "%{" SPEC_PTHREAD1 ":-D_REENTRANT} " \
> -		 "%{" SPEC_PTHREAD2 ": } "
> +		 "%{" SPEC_PTHREAD2 ": } " \
> +		 "%{mcrtdll=crtdll*:-U__MSVCRT__ -D__CRTDLL__} " \
> +		 "%{mcrtdll=msvcrt10*:-D__MSVCRT_VERSION__=0x100} " \
> +		 "%{mcrtdll=msvcrt20*:-D__MSVCRT_VERSION__=0x200} " \
> +		 "%{mcrtdll=msvcrt40*:-D__MSVCRT_VERSION__=0x400} " \
> +		 "%{mcrtdll=msvcrt-os*:-D__MSVCRT_VERSION__=0x700} " \
> +		 "%{mcrtdll=msvcr70*:-D__MSVCRT_VERSION__=0x700} " \
> +		 "%{mcrtdll=msvcr71*:-D__MSVCRT_VERSION__=0x701} " \
> +		 "%{mcrtdll=msvcr80*:-D__MSVCRT_VERSION__=0x800} " \
> +		 "%{mcrtdll=msvcr90*:-D__MSVCRT_VERSION__=0x900} " \
> +		 "%{mcrtdll=msvcr100*:-D__MSVCRT_VERSION__=0xA00} " \
> +		 "%{mcrtdll=msvcr110*:-D__MSVCRT_VERSION__=0xB00} " \
> +		 "%{mcrtdll=msvcr120*:-D__MSVCRT_VERSION__=0xC00} " \
> +		 "%{mcrtdll=ucrt*:-D_UCRT} "
>   
>   /* For Windows applications, include more libraries, but always include
>      kernel32.  */
> @@ -184,11 +197,18 @@ along with GCC; see the file COPYING3.  If not see
>   #define REAL_LIBGCC_SPEC \
>     "%{mthreads:-lmingwthrd} -lmingw32 \
>      " SHARED_LIBGCC_SPEC " \
> -   -lmoldname -lmingwex -lmsvcrt -lkernel32 " MCFGTHREAD_SPEC
> +   %{mcrtdll=crtdll*:-lcoldname} %{!mcrtdll=crtdll*:-lmoldname} \
> +   -lmingwex %{!mcrtdll=*:-lmsvcrt} %{mcrtdll=*:-l%*} \
> +   -lkernel32 " MCFGTHREAD_SPEC
>   
>   #undef STARTFILE_SPEC
> -#define STARTFILE_SPEC "%{shared|mdll:dllcrt2%O%s} \
> -  %{!shared:%{!mdll:crt2%O%s}} %{pg:gcrt2%O%s} \
> +#define STARTFILE_SPEC " \
> +  %{shared|mdll:%{mcrtdll=crtdll*:dllcrt1%O%s}} \
> +  %{shared|mdll:%{!mcrtdll=crtdll*:dllcrt2%O%s}} \
> +  %{!shared:%{!mdll:%{mcrtdll=crtdll*:crt1%O%s}}} \
> +  %{!shared:%{!mdll:%{!mcrtdll=crtdll*:crt2%O%s}}} \
> +  %{pg:%{mcrtdll=crtdll*:gcrt1%O%s}} \
> +  %{pg:%{!mcrtdll=crtdll*:gcrt2%O%s}} \
>     crtbegin.o%s \
>     %{fvtable-verify=none:%s; \
>       fvtable-verify=preinit:vtv_start.o%s; \
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index b92b85760279..32e3f504b22a 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -1458,7 +1458,7 @@ See RS/6000 and PowerPC Options.
>   -munroll-only-small-loops -mlam=@var{choice}}
>   
>   @emph{x86 Windows Options}
> -@gccoptlist{-mconsole  -mcygwin  -mno-cygwin  -mdll
> +@gccoptlist{-mconsole  -mcrtdll=@var{library}  -mcygwin  -mno-cygwin  -mdll
>   -mnop-fun-dllimport  -mthread
>   -municode  -mwin32  -mwindows  -fno-set-stack-executable}
>   
> @@ -34202,6 +34202,25 @@ required for console applications.
>   This option is available for Cygwin and MinGW targets and is
>   enabled by default on those targets.
>   
> +@opindex mcrtdll
> +@item -mcrtdll=@var{library}
> +Preprocess, compile or link with specified C RunTime DLL @var{library}.
> +This option adjust predefined macros @code{__CRTDLL__}, @code{__MSVCRT__}
> +and @code{__MSVCRT_VERSION__} for specified CRT @var{library}, choose
> +start file for CRT @var{library} and link with CRT @var{library}.
> +Recognized CRT library names for proprocessor are:
> +@code{crtdll}, @code{msvcrt10}, @code{msvcrt20}, @code{msvcrt40},
> +@code{msvcrt-os}, @code{msvcr70}, @code{msvcr80}, @code{msvcr90},
> +@code{msvcr100}, @code{msvcr110}, @code{msvcr120} and @code{ucrt}.
> +If this options is not specified then the default MinGW import library
> +@code{msvcrt} is used for linking and no other adjustment for
> +preprocessor is done. MinGW import library @code{msvcrt} is just a
> +symlink (or file copy) to the other MinGW CRT import library
> +chosen during MinGW compilation. MinGW import library @code{msvcrt-os}
> +is for Windows system CRT DLL library @code{msvcrt.dll} and
> +in most cases is the default MinGW import library.
> +This option is available for MinGW targets.
> +
>   @opindex mdll
>   @item -mdll
>   This option is available for Cygwin and MinGW targets.  It

LH, Jacek, NS, any thoughts on this patch?
  
LIU Hao June 12, 2023, 1:26 a.m. UTC | #2
在 2023/6/12 07:08, Jonathan Yong 写道:
> +preprocessor is done. MinGW import library @code{msvcrt} is just a
> +symlink (or file copy) to the other MinGW CRT import library 

I suggest a change to this line:

    symlink to (or a copy of) another MinGW CRT import library


Also, as discussed earlier, linking against a CRT version different from the value of 
`__MSVCRT_VERSION__` in _mingw.h is not officially supported and should be warned. So maybe we can 
append a paragraph to the documentation:

    Generally speaking, changing the CRT DLL requires recompiling
    the entire MinGW CRT. This option is for experimental and testing
    purposes only.



-- 
Best regards,
LIU Hao
  
Jonathan Yong June 12, 2023, 11:13 p.m. UTC | #3
On 6/12/23 01:26, LIU Hao wrote:
> 在 2023/6/12 07:08, Jonathan Yong 写道:
>> +preprocessor is done. MinGW import library @code{msvcrt} is just a
>> +symlink (or file copy) to the other MinGW CRT import library 
> 
> I suggest a change to this line:
> 
>     symlink to (or a copy of) another MinGW CRT import library
> 
> 
> Also, as discussed earlier, linking against a CRT version different from 
> the value of `__MSVCRT_VERSION__` in _mingw.h is not officially 
> supported and should be warned. So maybe we can append a paragraph to 
> the documentation:
> 
>     Generally speaking, changing the CRT DLL requires recompiling
>     the entire MinGW CRT. This option is for experimental and testing
>     purposes only.
> 
> 
> 

Pali, mind updating the patch?
  
Pali Rohár June 13, 2023, 6:29 a.m. UTC | #4
On Monday 12 June 2023 23:13:00 Jonathan Yong wrote:
> On 6/12/23 01:26, LIU Hao wrote:
> > 在 2023/6/12 07:08, Jonathan Yong 写道:
> > > +preprocessor is done. MinGW import library @code{msvcrt} is just a
> > > +symlink (or file copy) to the other MinGW CRT import library
> > 
> > I suggest a change to this line:
> > 
> >     symlink to (or a copy of) another MinGW CRT import library
> > 
> > 
> > Also, as discussed earlier, linking against a CRT version different from
> > the value of `__MSVCRT_VERSION__` in _mingw.h is not officially
> > supported and should be warned. So maybe we can append a paragraph to
> > the documentation:
> > 
> >     Generally speaking, changing the CRT DLL requires recompiling
> >     the entire MinGW CRT. This option is for experimental and testing
> >     purposes only.
> > 
> > 
> > 
> 
> Pali, mind updating the patch?
> 

Of course, just I'm not sure where to put the new paragraph. At the
beginning? Or after the text? What do you think?
  
LIU Hao June 13, 2023, 8:40 a.m. UTC | #5
在 2023/6/13 14:29, Pali Rohár 写道:
> Of course, just I'm not sure where to put the new paragraph. At the
> beginning? Or after the text? What do you think?

Maybe just in front of 'This option is available for MinGW targets.' Also you may reword it as you like.



-- 
Best regards,
LIU Hao
  

Patch

diff --git a/gcc/config/i386/mingw-w64.h b/gcc/config/i386/mingw-w64.h
index 3a21cec3f8cd..0146ed4f793e 100644
--- a/gcc/config/i386/mingw-w64.h
+++ b/gcc/config/i386/mingw-w64.h
@@ -25,7 +25,27 @@  along with GCC; see the file COPYING3.  If not see
 #define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT} " \
 		 "%{municode:-DUNICODE} " \
 		 "%{" SPEC_PTHREAD1 ":-D_REENTRANT} " \
-		 "%{" SPEC_PTHREAD2 ":-U_REENTRANT} "
+		 "%{" SPEC_PTHREAD2 ":-U_REENTRANT} " \
+		 "%{mcrtdll=crtdll*:-U__MSVCRT__ -D__CRTDLL__} " \
+		 "%{mcrtdll=msvcrt10*:-D__MSVCRT_VERSION__=0x100} " \
+		 "%{mcrtdll=msvcrt20*:-D__MSVCRT_VERSION__=0x200} " \
+		 "%{mcrtdll=msvcrt40*:-D__MSVCRT_VERSION__=0x400} " \
+		 "%{mcrtdll=msvcrt-os*:-D__MSVCRT_VERSION__=0x700} " \
+		 "%{mcrtdll=msvcr70*:-D__MSVCRT_VERSION__=0x700} " \
+		 "%{mcrtdll=msvcr71*:-D__MSVCRT_VERSION__=0x701} " \
+		 "%{mcrtdll=msvcr80*:-D__MSVCRT_VERSION__=0x800} " \
+		 "%{mcrtdll=msvcr90*:-D__MSVCRT_VERSION__=0x900} " \
+		 "%{mcrtdll=msvcr100*:-D__MSVCRT_VERSION__=0xA00} " \
+		 "%{mcrtdll=msvcr110*:-D__MSVCRT_VERSION__=0xB00} " \
+		 "%{mcrtdll=msvcr120*:-D__MSVCRT_VERSION__=0xC00} " \
+		 "%{mcrtdll=ucrt*:-D_UCRT} "
+
+#undef REAL_LIBGCC_SPEC
+#define REAL_LIBGCC_SPEC \
+  "%{mthreads:-lmingwthrd} -lmingw32 \
+   " SHARED_LIBGCC_SPEC " \
+   -lmingwex %{!mcrtdll=*:-lmsvcrt} %{mcrtdll=*:-l%*} \
+   -lkernel32 " MCFGTHREAD_SPEC
 
 #undef STARTFILE_SPEC
 #define STARTFILE_SPEC "%{shared|mdll:dllcrt2%O%s} \
diff --git a/gcc/config/i386/mingw.opt b/gcc/config/i386/mingw.opt
index 0ae026a66bd6..dd66a50aec00 100644
--- a/gcc/config/i386/mingw.opt
+++ b/gcc/config/i386/mingw.opt
@@ -18,6 +18,10 @@ 
 ; along with GCC; see the file COPYING3.  If not see
 ; <http://www.gnu.org/licenses/>.
 
+mcrtdll=
+Target RejectNegative Joined
+Preprocess, compile or link with specified C RunTime DLL library.
+
 pthread
 Driver
 
diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h
index 6a55baaa4587..a1ee001983a7 100644
--- a/gcc/config/i386/mingw32.h
+++ b/gcc/config/i386/mingw32.h
@@ -89,7 +89,20 @@  along with GCC; see the file COPYING3.  If not see
 #undef CPP_SPEC
 #define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT} " \
 		 "%{" SPEC_PTHREAD1 ":-D_REENTRANT} " \
-		 "%{" SPEC_PTHREAD2 ": } "
+		 "%{" SPEC_PTHREAD2 ": } " \
+		 "%{mcrtdll=crtdll*:-U__MSVCRT__ -D__CRTDLL__} " \
+		 "%{mcrtdll=msvcrt10*:-D__MSVCRT_VERSION__=0x100} " \
+		 "%{mcrtdll=msvcrt20*:-D__MSVCRT_VERSION__=0x200} " \
+		 "%{mcrtdll=msvcrt40*:-D__MSVCRT_VERSION__=0x400} " \
+		 "%{mcrtdll=msvcrt-os*:-D__MSVCRT_VERSION__=0x700} " \
+		 "%{mcrtdll=msvcr70*:-D__MSVCRT_VERSION__=0x700} " \
+		 "%{mcrtdll=msvcr71*:-D__MSVCRT_VERSION__=0x701} " \
+		 "%{mcrtdll=msvcr80*:-D__MSVCRT_VERSION__=0x800} " \
+		 "%{mcrtdll=msvcr90*:-D__MSVCRT_VERSION__=0x900} " \
+		 "%{mcrtdll=msvcr100*:-D__MSVCRT_VERSION__=0xA00} " \
+		 "%{mcrtdll=msvcr110*:-D__MSVCRT_VERSION__=0xB00} " \
+		 "%{mcrtdll=msvcr120*:-D__MSVCRT_VERSION__=0xC00} " \
+		 "%{mcrtdll=ucrt*:-D_UCRT} "
 
 /* For Windows applications, include more libraries, but always include
    kernel32.  */
@@ -184,11 +197,18 @@  along with GCC; see the file COPYING3.  If not see
 #define REAL_LIBGCC_SPEC \
   "%{mthreads:-lmingwthrd} -lmingw32 \
    " SHARED_LIBGCC_SPEC " \
-   -lmoldname -lmingwex -lmsvcrt -lkernel32 " MCFGTHREAD_SPEC
+   %{mcrtdll=crtdll*:-lcoldname} %{!mcrtdll=crtdll*:-lmoldname} \
+   -lmingwex %{!mcrtdll=*:-lmsvcrt} %{mcrtdll=*:-l%*} \
+   -lkernel32 " MCFGTHREAD_SPEC
 
 #undef STARTFILE_SPEC
-#define STARTFILE_SPEC "%{shared|mdll:dllcrt2%O%s} \
-  %{!shared:%{!mdll:crt2%O%s}} %{pg:gcrt2%O%s} \
+#define STARTFILE_SPEC " \
+  %{shared|mdll:%{mcrtdll=crtdll*:dllcrt1%O%s}} \
+  %{shared|mdll:%{!mcrtdll=crtdll*:dllcrt2%O%s}} \
+  %{!shared:%{!mdll:%{mcrtdll=crtdll*:crt1%O%s}}} \
+  %{!shared:%{!mdll:%{!mcrtdll=crtdll*:crt2%O%s}}} \
+  %{pg:%{mcrtdll=crtdll*:gcrt1%O%s}} \
+  %{pg:%{!mcrtdll=crtdll*:gcrt2%O%s}} \
   crtbegin.o%s \
   %{fvtable-verify=none:%s; \
     fvtable-verify=preinit:vtv_start.o%s; \
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index b92b85760279..32e3f504b22a 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1458,7 +1458,7 @@  See RS/6000 and PowerPC Options.
 -munroll-only-small-loops -mlam=@var{choice}}
 
 @emph{x86 Windows Options}
-@gccoptlist{-mconsole  -mcygwin  -mno-cygwin  -mdll
+@gccoptlist{-mconsole  -mcrtdll=@var{library}  -mcygwin  -mno-cygwin  -mdll
 -mnop-fun-dllimport  -mthread
 -municode  -mwin32  -mwindows  -fno-set-stack-executable}
 
@@ -34202,6 +34202,25 @@  required for console applications.
 This option is available for Cygwin and MinGW targets and is
 enabled by default on those targets.
 
+@opindex mcrtdll
+@item -mcrtdll=@var{library}
+Preprocess, compile or link with specified C RunTime DLL @var{library}.
+This option adjust predefined macros @code{__CRTDLL__}, @code{__MSVCRT__}
+and @code{__MSVCRT_VERSION__} for specified CRT @var{library}, choose
+start file for CRT @var{library} and link with CRT @var{library}.
+Recognized CRT library names for proprocessor are:
+@code{crtdll}, @code{msvcrt10}, @code{msvcrt20}, @code{msvcrt40},
+@code{msvcrt-os}, @code{msvcr70}, @code{msvcr80}, @code{msvcr90},
+@code{msvcr100}, @code{msvcr110}, @code{msvcr120} and @code{ucrt}.
+If this options is not specified then the default MinGW import library
+@code{msvcrt} is used for linking and no other adjustment for
+preprocessor is done. MinGW import library @code{msvcrt} is just a
+symlink (or file copy) to the other MinGW CRT import library
+chosen during MinGW compilation. MinGW import library @code{msvcrt-os}
+is for Windows system CRT DLL library @code{msvcrt.dll} and
+in most cases is the default MinGW import library.
+This option is available for MinGW targets.
+
 @opindex mdll
 @item -mdll
 This option is available for Cygwin and MinGW targets.  It