Bug 1551618 - Check for libclang >= 4.0 in configure. r=froydnj
authorEmilio Cobos Álvarez <emilio@crisal.io>
Wed, 15 May 2019 13:11:52 +0000
changeset 532747 33b8297c53bcc11843f0992e0e310c8bf9379c57
parent 532746 24a2db112eb829634b49dd178fe43a04770fffae
child 532748 f64789945bb3f49cd7ca160315d5999dbed25387
push id11272
push userapavel@mozilla.com
push dateThu, 16 May 2019 15:28:22 +0000
treeherdermozilla-beta@2265bfc5920d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1551618
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1551618 - Check for libclang >= 4.0 in configure. r=froydnj This is better than failing with obscure rust errors later on. Differential Revision: https://phabricator.services.mozilla.com/D31102
build/moz.configure/bindgen.configure
--- a/build/moz.configure/bindgen.configure
+++ b/build/moz.configure/bindgen.configure
@@ -162,19 +162,19 @@ def bindgen_config_paths(llvm_config, li
 
         if host.os == 'OpenBSD':
             libclang_choices = glob.glob(path + '/libclang.so.*.*')
 
         # At least one of the choices must be found.
         for choice in libclang_choices:
             libclang = os.path.join(path, choice)
             if os.path.exists(libclang):
-                return (True, None)
+                return (libclang, None)
         else:
-            return (False, list(set(libclang_choices)))
+            return (None, list(set(libclang_choices)))
 
     # XXX: we want this code to be run for both Gecko and JS, but we don't
     # necessarily want to force a bindgen/Rust dependency on JS just yet.
     # Actually, we don't want to force an error if we're not building the
     # browser generally.  We therefore whitelist the projects that require
     # bindgen facilities at this point and leave it at that.
     bindgen_projects = ('browser', 'mobile/android')
 
@@ -214,26 +214,27 @@ def bindgen_config_paths(llvm_config, li
 
         if not os.path.exists(libclang_path):
             die(dedent('''\
             The directory {} returned by `llvm-config {}` does not exist.
             clang is required to build Firefox.  Please install the
             necessary packages, or run `mach bootstrap`.
             '''.format(libclang_path, libclang_arg)))
 
-        (found, searched) = search_for_libclang(libclang_path)
-        if not found:
+        (libclang, searched) = search_for_libclang(libclang_path)
+        if not libclang:
             die(dedent('''\
             Could not find the clang shared library in the path {}
             returned by `llvm-config {}` (searched for files {}).
             clang is required to build Firefox.  Please install the
             necessary packages, or run `mach bootstrap`.
             '''.format(libclang_path, libclang_arg, searched)))
 
         return namespace(
+            libclang=libclang,
             libclang_path=libclang_path,
             clang_path=clang_resolved,
         )
 
     if (not libclang_path and clang_path) or \
        (libclang_path and not clang_path):
         if build_project not in bindgen_projects:
             return namespace()
@@ -246,34 +247,56 @@ def bindgen_config_paths(llvm_config, li
     clang_path = clang_path[0]
 
     if not os.path.exists(libclang_path) or \
        not os.path.isdir(libclang_path):
         die(dedent('''\
         The argument to --with-libclang-path is not a directory: {}
         '''.format(libclang_path)))
 
-    (found, searched) = search_for_libclang(libclang_path)
-    if not found:
+    (libclang, searched) = search_for_libclang(libclang_path)
+    if not libclang:
         die(dedent('''\
         Could not find the clang shared library in the path {}
         specified by --with-libclang-path (searched for files {}).
         '''.format(libclang_path, searched)))
 
     clang_resolved = find_program(clang_path)
     if not clang_resolved:
         die(dedent('''\
         The argument to --with-clang-path is not a file: {}
         '''.format(clang_path)))
 
     return namespace(
+        libclang=libclang,
         libclang_path=libclang_path,
         clang_path=clang_resolved,
     )
 
+@depends(bindgen_config_paths.libclang)
+@checking('that libclang is new enough', lambda s: 'yes' if s else 'no')
+@imports(_from='ctypes', _import='CDLL')
+@imports(_from='textwrap', _import='dedent')
+def min_libclang_version(libclang):
+    try:
+        lib = CDLL(libclang)
+        # We want at least 4.0. The API we test below is enough for that.
+        # Just accessing it should throw if not found.
+        fun = lib.clang_EvalResult_getAsLongLong
+        return True
+    except:
+        die(dedent('''\
+        The libclang located at {} is too old (need at least 4.0).
+
+        Please make sure to update it or point to a newer libclang using
+        --with-libclang-path.
+        '''.format(libclang)))
+        return False
+
+
 set_config('MOZ_LIBCLANG_PATH', bindgen_config_paths.libclang_path)
 set_config('MOZ_CLANG_PATH', bindgen_config_paths.clang_path)
 
 
 @depends(target, target_is_unix, cxx_compiler, bindgen_cflags_android,
          bindgen_config_paths.clang_path, macos_sdk)
 def basic_bindgen_cflags(target, is_unix, compiler_info, android_cflags,
                          clang_path, macos_sdk):