diff --git a/SConstruct b/SConstruct index bcb0b3f6b98ba94b8e1bb656c4d8d88558ffbd45..dc220c1d59326eaf9d54ebde05b2df41536e01a6 100644 --- a/SConstruct +++ b/SConstruct @@ -3,6 +3,9 @@ import os import os.path import platform import sys +from distutils.version import LooseVersion +import re +import subprocess vars = Variables(None, ARGUMENTS) @@ -121,9 +124,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 ea7c56ec186f7e1dabcbfb8758d3f2c2e4f6afab..d40e65258fe50bb27835e65fe4d189a689822310 100644 --- a/src/SConscript +++ b/src/SConscript @@ -5,6 +5,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", @@ -80,87 +89,28 @@ ctests = ['t_benchmark.c', 't_misc.c', 't_regression.c'] -# 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('hammer', 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) @@ -177,21 +127,21 @@ testenv.Append(LIBS=['hammer'], LIBPATH=['.']) testenv.ParseConfig('pkg-config --cflags --libs glib-2.0') # 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) + (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: 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) testenv.Append(LIBS=['stdc++'], LIBPATH=['.']) 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]))