From 086d380a2b2f1e4db4e0ba72118d0be186dd8ba4 Mon Sep 17 00:00:00 2001
From: Andrea Shepard <andrea@persephoneslair.org>
Date: Fri, 11 Nov 2016 02:28:16 +0000
Subject: [PATCH] Move LLVM config stuff out to SConstruct; use import/export

---
 SConstruct     | 76 +++++++++++++++++++++++++++++++++++++++
 src/SConscript | 98 +++++++++++++-------------------------------------
 2 files changed, 100 insertions(+), 74 deletions(-)

diff --git a/SConstruct b/SConstruct
index 9651ad19..0cc76d0e 100644
--- a/SConstruct
+++ b/SConstruct
@@ -6,6 +6,9 @@ import os
 import os.path
 import platform
 import sys
+from distutils.version import LooseVersion
+import re
+import subprocess
 
 default_install_dir='/usr/local'
 if platform.system() == 'Windows':
@@ -160,9 +163,82 @@ targets = ['$libpath',
            '$backendsincpath',
            '$pkgconfigpath']
 
+# Set up LLVM config stuff to export
+
+# some llvm versions are old and will not work; some require --system-libs
+# with llvm-config, and some will break if given it
+llvm_config_version = subprocess.Popen('%s --version' % env["LLVM_CONFIG"], \
+                                       shell=True, \
+                                       stdin=subprocess.PIPE, stdout=subprocess.PIPE).communicate()
+if LooseVersion(llvm_config_version[0]) < LooseVersion("3.6"):
+   print "This LLVM version %s is too old" % llvm_config_version
+   Exit(1)
+
+if LooseVersion(llvm_config_version[0]) < LooseVersion("3.9") and \
+   LooseVersion(llvm_config_version[0]) >= LooseVersion("3.5"):
+    llvm_system_libs_flag = "--system-libs"
+else:
+    llvm_system_libs_flag = ""
+
+# Only keep one copy of this
+llvm_required_components = "core executionengine mcjit analysis x86codegen x86info"
+# Stubbing this out so we can implement static-only mode if needed later
+llvm_use_shared = True
+# Can we ask for shared/static from llvm-config?
+if LooseVersion(llvm_config_version[0]) < LooseVersion("3.9"):
+    # Nope
+    llvm_linkage_type_flag = ""
+    llvm_use_computed_shared_lib_name = True
+else:
+    # Woo, they finally fixed the dumb
+    llvm_use_computed_shared_lib_name = False
+    if llvm_use_shared:
+        llvm_linkage_type_flag = "--link-shared"
+    else:
+        llvm_linkage_type_flag = "--link-static"
+
+if llvm_use_computed_shared_lib_name:
+    # Okay, pull out the major and minor version numbers (barf barf)
+    p = re.compile("^(\d+)\.(\d+).*$")
+    m = p.match(llvm_config_version[0])
+    if m:
+        llvm_computed_shared_lib_name = "LLVM-%d.%d" % ((int)(m.group(1)), (int)(m.group(2)))
+    else:
+        print "Couldn't compute shared library name from LLVM version '%s', but needed to" % \
+            llvm_config_version[0]
+        Exit(1)
+else:
+    # We won't be needing it
+    llvm_computed_shared_lib_name = None
+
+# llvm-config 'helpfully' supplies -g and -O flags; educate it with this
+# custom ParseConfig function arg; make it a class with a method so we can
+# pass it around with scons export/import
+
+class LLVMConfigSanitizer:
+    def sanitize(self, env, cmd, unique=1):
+        # cmd is output from llvm-config
+        flags = cmd.split()
+        # match -g or -O flags
+        p = re.compile("^-[gO].*$")
+        filtered_flags = [flag for flag in flags if not p.match(flag)]
+        filtered_cmd = ' '.join(filtered_flags)
+        # print "llvm_config_sanitize: \"%s\" => \"%s\"" % (cmd, filtered_cmd)
+        env.MergeFlags(filtered_cmd, unique)
+llvm_config_sanitizer = LLVMConfigSanitizer()
+
 Export('env')
 Export('testruns')
 Export('targets')
+# LLVM-related flags
+Export('llvm_computed_shared_lib_name')
+Export('llvm_config_sanitizer')
+Export('llvm_config_version')
+Export('llvm_linkage_type_flag')
+Export('llvm_required_components')
+Export('llvm_system_libs_flag')
+Export('llvm_use_computed_shared_lib_name')
+Export('llvm_use_shared')
 
 if not GetOption('in_place'):
     env['BUILD_BASE'] = 'build/$VARIANT'
diff --git a/src/SConscript b/src/SConscript
index 642c4b2f..a9d2e334 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -8,6 +8,15 @@ import re
 import subprocess
 
 Import('env testruns')
+# LLVM-related flags
+Import('llvm_computed_shared_lib_name')
+Import('llvm_config_sanitizer')
+Import('llvm_config_version')
+Import('llvm_linkage_type_flag')
+Import('llvm_required_components')
+Import('llvm_system_libs_flag')
+Import('llvm_use_computed_shared_lib_name')
+Import('llvm_use_shared')
 
 dist_headers = [
     'hammer.h',
@@ -100,87 +109,28 @@ if env['PLATFORM'] == 'win32':
     # prevent collision between .lib from dll and .lib for static lib
     static_library_name = 'hammer_s'
 
-# some llvm versions are old and will not work; some require --system-libs
-# with llvm-config, and some will break if given it
-llvm_config_version = subprocess.Popen('%s --version' % env["LLVM_CONFIG"], \
-                                       shell=True, \
-                                       stdin=subprocess.PIPE, stdout=subprocess.PIPE).communicate()
-if LooseVersion(llvm_config_version[0]) < LooseVersion("3.6"):
-   print "This LLVM version %s is too old" % llvm_config_version
-   Exit(1)
-
-if LooseVersion(llvm_config_version[0]) < LooseVersion("3.9") and \
-   LooseVersion(llvm_config_version[0]) >= LooseVersion("3.5"):
-    llvm_system_libs_flag = "--system-libs"
-else:
-    llvm_system_libs_flag = ""
-
-# Only keep one copy of this
-required_llvm_components = "core executionengine mcjit analysis x86codegen x86info"
-# Stubbing this out so we can implement static-only mode if needed later
-use_shared_llvm = True
-# Can we ask for shared/static from llvm-config?
-if LooseVersion(llvm_config_version[0]) < LooseVersion("3.9"):
-    # Nope
-    llvm_linkage_type_flag = ""
-    llvm_use_computed_shared_lib_name = True
-else:
-    # Woo, they finally fixed the dumb
-    llvm_use_computed_shared_lib_name = False
-    if use_shared_llvm:
-        llvm_linkage_type_flag = "--link-shared"
-    else:
-        llvm_linkage_type_flag = "--link-static"
-
-if llvm_use_computed_shared_lib_name:
-    # Okay, pull out the major and minor version numbers (barf barf)
-    p = re.compile("^(\d+)\.(\d+).*$")
-    m = p.match(llvm_config_version[0])
-    if m:
-        llvm_computed_shared_lib_name = "LLVM-%d.%d" % ((int)(m.group(1)), (int)(m.group(2)))
-    else:
-        print "Couldn't compute shared library name from LLVM version '%s', but needed to" % \
-            llvm_config_version[0]
-        Exit(1)
-else:
-    # We won't be needing it
-    llvm_computed_shared_lib_name = None
-
-# llvm-config 'helpfully' supplies -g and -O flags; educate it with this
-# custom ParseConfig function arg
-
-def llvm_config_sanitize(env, cmd, unique=1):
-    # cmd is output from llvm-config
-    flags = cmd.split()
-    # match -g or -O flags
-    p = re.compile("^-[gO].*$")
-    filtered_flags = [flag for flag in flags if not p.match(flag)]
-    filtered_cmd = ' '.join(filtered_flags)
-    # print "llvm_config_sanitize: \"%s\" => \"%s\"" % (cmd, filtered_cmd)
-    env.MergeFlags(filtered_cmd, unique)
-
-env.ParseConfig('%s --cflags --ldflags' % env["LLVM_CONFIG"], function=llvm_config_sanitize)
+env.ParseConfig('%s --cflags --ldflags' % env["LLVM_CONFIG"], function=llvm_config_sanitizer.sanitize)
 libhammer_static = env.StaticLibrary(static_library_name, parsers + backends + misc_hammer_parts)
 
 # Use a cloned env for the shared library so we can have library dependencies
 shared_env = env.Clone()
 # Get LLVM stuff into LIBS/LDFLAGS
 shared_env.ParseConfig('%s --ldflags %s %s %s' % \
-                       (env["LLVM_CONFIG"], llvm_system_libs_flag, llvm_linkage_type_flag, required_llvm_components), \
-                       function=llvm_config_sanitize)
+                       (env["LLVM_CONFIG"], llvm_system_libs_flag, llvm_linkage_type_flag, llvm_required_components), \
+                       function=llvm_config_sanitizer.sanitize)
 # Get the right -l lines in
-if use_shared_llvm:
+if llvm_use_shared:
     if llvm_use_computed_shared_lib_name:
         shared_env.Append(LIBS=[llvm_computed_shared_lib_name, ])
     else:
         shared_env.ParseConfig('%s %s --libs %s' % \
-                               (env["LLVM_CONFIG"], llvm_linkage_type_flag, required_llvm_components), \
-                               function=llvm_config_sanitize)
+                               (env["LLVM_CONFIG"], llvm_linkage_type_flag, llvm_required_components), \
+                               function=llvm_config_sanitizer.sanitize)
 else:
     # Just grab the statics regardless of version
     shared_env.ParseConfig('%s %s --libs %s' % \
-                           (env["LLVM_CONFIG"], llvm_linkage_type_flag, required_llvm_components), \
-                           function=llvm_config_sanitize)
+                           (env["LLVM_CONFIG"], llvm_linkage_type_flag, llvm_required_components), \
+                           function=llvm_config_sanitizer.sanitize)
 shared_env.Append(LIBS=['stdc++', ], LIBPATH=['.'])
 libhammer_shared = shared_env.SharedLibrary('hammer', parsers + backends + misc_hammer_parts)
 
@@ -204,21 +154,21 @@ if GetOption('with_tests'):
     # Get LLVM stuff into LIBS/LDFLAGS
     testenv.ParseConfig('%s --ldflags %s %s %s' % \
                         (env["LLVM_CONFIG"], llvm_system_libs_flag, \
-                        llvm_linkage_type_flag, required_llvm_components), \
-                        function=llvm_config_sanitize)
+                        llvm_linkage_type_flag, llvm_required_components), \
+                        function=llvm_config_sanitizer.sanitize)
     # Get the right -l lines in
-    if use_shared_llvm:
+    if llvm_use_shared:
         if llvm_use_computed_shared_lib_name:
             testenv.Append(LIBS=[llvm_computed_shared_lib_name, ])
         else:
             testenv.ParseConfig('%s %s --libs %s' % \
-                                (env["LLVM_CONFIG"], llvm_linkage_type_flag, required_llvm_components), \
-                                function=llvm_config_sanitize)
+                                (env["LLVM_CONFIG"], llvm_linkage_type_flag, llvm_required_components), \
+                                function=llvm_config_sanitizer.sanitize)
     else:
         # Just grab the statics regardless of version
         testenv.ParseConfig('%s %s --libs %s' % \
-                            (env["LLVM_CONFIG"], llvm_linkage_type_flag, required_llvm_components), \
-                            function=llvm_config_sanitize)
+                            (env["LLVM_CONFIG"], llvm_linkage_type_flag, llvm_required_components), \
+                            function=llvm_config_sanitizer.sanitize)
     ctestexec = testenv.Program('test_suite', ctests + ['test_suite.c'], LINKFLAGS='--coverage' if testenv.GetOption('coverage') else None)
     ctest = Alias('testc', [ctestexec], ''.join(['env LD_LIBRARY_PATH=', os.path.dirname(ctestexec[0].path), ' ', ctestexec[0].path]))
     AlwaysBuild(ctest)
-- 
GitLab