diff mbox series

[27/30] build: move compiler version check to meson

Message ID 20221209112409.184703-28-pbonzini@redhat.com
State New
Headers show
Series Meson changes for QEMU 8.0 | expand

Commit Message

Paolo Bonzini Dec. 9, 2022, 11:24 a.m. UTC
Instead of checking with preprocessor defines, use the Meson compiler object.
Because of the mess Apple does with its versioning scheme, check for an
option that was added in clang 6.0 instead of looking at the version number.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 configure   | 25 -------------------------
 meson.build | 11 +++++++++++
 2 files changed, 11 insertions(+), 25 deletions(-)

Comments

Peter Maydell Dec. 9, 2022, 11:52 a.m. UTC | #1
On Fri, 9 Dec 2022 at 11:40, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> Instead of checking with preprocessor defines, use the Meson compiler object.
> Because of the mess Apple does with its versioning scheme, check for an
> option that was added in clang 6.0 instead of looking at the version number.

> -# Check whether the compiler matches our minimum requirements:
> -cat > $TMPC << EOF
> -#if defined(__clang_major__) && defined(__clang_minor__)
> -# ifdef __apple_build_version__
> -#  if __clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 0)
> -#   error You need at least XCode Clang v10.0 to compile QEMU
> -#  endif
> -# else
> -#  if __clang_major__ < 6 || (__clang_major__ == 6 && __clang_minor__ < 0)
> -#   error You need at least Clang v6.0 to compile QEMU
> -#  endif
> -# endif
> -#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
> -# if __GNUC__ < 7 || (__GNUC__ == 7 && __GNUC_MINOR__ < 4)
> -#  error You need at least GCC v7.4.0 to compile QEMU
> -# endif
> -#else
> -# error You either need GCC or Clang to compiler QEMU
> -#endif
> -int main (void) { return 0; }
> -EOF
> -if ! compile_prog "" "" ; then
> -    error_exit "You need at least GCC v7.4 or Clang v6.0 (or XCode Clang v10.0)"
> -fi
>
> +foreach lang : all_languages
> +  compiler = meson.get_compiler(lang)
> +  if compiler.get_id() == 'gcc' and compiler.version().version_compare('>=7.4')
> +    # ok
> +  elif compiler.get_id() == 'clang' and compiler.has_argument('-Wpragma-pack')
> +    # ok
> +  else
> +    error('You either need GCC v7.4 or Clang v6.0 (or XCode Clang v10.0) to compile QEMU')
> +  endif
> +endforeach

The new code makes it much harder to move our compiler version
requirements forward in future, because there's no longer a simple
"check for normal clang X or apple clang Y" test where we can
bump up X and Y based on what's provided in the various host
platforms we have to support. Doesn't meson provide a way to do
the version check on the version number the way we were doing
previously?

thanks
-- PMM
Paolo Bonzini Dec. 9, 2022, 2:09 p.m. UTC | #2
On 12/9/22 12:52, Peter Maydell wrote:
> The new code makes it much harder to move our compiler version
> requirements forward in future, because there's no longer a simple
> "check for normal clang X or apple clang Y" test where we can
> bump up X and Y based on what's provided in the various host
> platforms we have to support. Doesn't meson provide a way to do
> the version check on the version number the way we were doing
> previously?

Yes, I could just do the check with #error just like before.

For GCC I used the nicer "compiler.version().version_compare('>=x.y')" 
check.  For clang we have to deal with both upstream and Apple version 
numbers; it's also possible to check for __apple_build_version__ to 
distinguish between the two and then do version_compare(), but at that 
point it's easier to just use cc.compiles() and #error.

While it's possible to learn the upstream version corresponding to Apple 
compilers with "c++ --verbose", it is not really machine-friendly so 
Meson does not attempt to parse it and neither did QEMU's configure script.

So I went for the trick of using -Wpragma-pack, which was extracted from 
https://github.com/simd-everywhere/simde/blob/master/simde/simde-detect-clang.h. 
  The advantage is that you only have one check, the disadvantage is of 
course that it obscures what's going on.  I can add a clearer comment 
around the check, or switch to #error and add a pointer to 
https://trac.macports.org/wiki/XcodeVersionInfo where the mapping can be 
found, or really anything else that is your preference.

Paolo
Peter Maydell Dec. 9, 2022, 2:19 p.m. UTC | #3
On Fri, 9 Dec 2022 at 14:09, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> On 12/9/22 12:52, Peter Maydell wrote:
> > The new code makes it much harder to move our compiler version
> > requirements forward in future, because there's no longer a simple
> > "check for normal clang X or apple clang Y" test where we can
> > bump up X and Y based on what's provided in the various host
> > platforms we have to support. Doesn't meson provide a way to do
> > the version check on the version number the way we were doing
> > previously?
>
> Yes, I could just do the check with #error just like before.
>
> For GCC I used the nicer "compiler.version().version_compare('>=x.y')"
> check.  For clang we have to deal with both upstream and Apple version
> numbers; it's also possible to check for __apple_build_version__ to
> distinguish between the two and then do version_compare(), but at that
> point it's easier to just use cc.compiles() and #error.
>
> While it's possible to learn the upstream version corresponding to Apple
> compilers with "c++ --verbose", it is not really machine-friendly so
> Meson does not attempt to parse it and neither did QEMU's configure script.
>
> So I went for the trick of using -Wpragma-pack, which was extracted from
> https://github.com/simd-everywhere/simde/blob/master/simde/simde-detect-clang.h.
>   The advantage is that you only have one check, the disadvantage is of
> course that it obscures what's going on.  I can add a clearer comment
> around the check, or switch to #error and add a pointer to
> https://trac.macports.org/wiki/XcodeVersionInfo where the mapping can be
> found, or really anything else that is your preference.

I think really I just don't want a check that is "we happen to
know that this particular option switch is supported only
from these versions onward", because as soon as we say
"OK, we can move forward to a clang 7 baseline" we either
need to search around for an equivalent clever trick, or
else we need to get rid of all this code anyway and have
the version number check. So I don't mind how we do this
as long as there's a straightforward bit of code that
currently has "6 "and "10" in it and where we can change it to
"7" and "11 "in future and it does what we intend.

thanks
-- PMM
Paolo Bonzini Dec. 9, 2022, 4:21 p.m. UTC | #4
On 12/9/22 15:19, Peter Maydell wrote:
> I think really I just don't want a check that is "we happen to
> know that this particular option switch is supported only
> from these versions onward", because as soon as we say
> "OK, we can move forward to a clang 7 baseline" we either
> need to search around for an equivalent clever trick, or
> else we need to get rid of all this code anyway and have
> the version number check. So I don't mind how we do this
> as long as there's a straightforward bit of code that
> currently has "6 "and "10" in it and where we can change it to
> "7" and "11 "in future and it does what we intend.

No problem, I will keep the version number logic.

Paolo
diff mbox series

Patch

diff --git a/configure b/configure
index d5491fc3b986..a7c95535fd01 100755
--- a/configure
+++ b/configure
@@ -1033,31 +1033,6 @@  if test "$targetos" = "bogus"; then
     error_exit "Unrecognized host OS (uname -s reports '$(uname -s)')"
 fi
 
-# Check whether the compiler matches our minimum requirements:
-cat > $TMPC << EOF
-#if defined(__clang_major__) && defined(__clang_minor__)
-# ifdef __apple_build_version__
-#  if __clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 0)
-#   error You need at least XCode Clang v10.0 to compile QEMU
-#  endif
-# else
-#  if __clang_major__ < 6 || (__clang_major__ == 6 && __clang_minor__ < 0)
-#   error You need at least Clang v6.0 to compile QEMU
-#  endif
-# endif
-#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
-# if __GNUC__ < 7 || (__GNUC__ == 7 && __GNUC_MINOR__ < 4)
-#  error You need at least GCC v7.4.0 to compile QEMU
-# endif
-#else
-# error You either need GCC or Clang to compiler QEMU
-#endif
-int main (void) { return 0; }
-EOF
-if ! compile_prog "" "" ; then
-    error_exit "You need at least GCC v7.4 or Clang v6.0 (or XCode Clang v10.0)"
-fi
-
 # Resolve default for --enable-plugins
 if test "$static" = "yes" ; then
   if test "$plugins" = "yes"; then
diff --git a/meson.build b/meson.build
index 01c6ac0045bc..3316ff005cfc 100644
--- a/meson.build
+++ b/meson.build
@@ -190,6 +190,17 @@  endif
 # Compiler flags #
 ##################
 
+foreach lang : all_languages
+  compiler = meson.get_compiler(lang)
+  if compiler.get_id() == 'gcc' and compiler.version().version_compare('>=7.4')
+    # ok
+  elif compiler.get_id() == 'clang' and compiler.has_argument('-Wpragma-pack')
+    # ok
+  else
+    error('You either need GCC v7.4 or Clang v6.0 (or XCode Clang v10.0) to compile QEMU')
+  endif
+endforeach
+
 # default flags for all hosts
 # We use -fwrapv to tell the compiler that we require a C dialect where
 # left shift of signed integers is well defined and has the expected