r313270 - [lit] Force site configs to be run before source-tree configs

Zachary Turner via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 14 09:47:58 PDT 2017


Author: zturner
Date: Thu Sep 14 09:47:58 2017
New Revision: 313270

URL: http://llvm.org/viewvc/llvm-project?rev=313270&view=rev
Log:
[lit] Force site configs to be run before source-tree configs

This patch simplifies LLVM's lit infrastructure by enforcing an ordering
that a site config is always run before a source-tree config.

A significant amount of the complexity from lit config files arises from
the fact that inside of a source-tree config file, we don't yet know if
the site config has been run.  However it is *always* required to run
a site config first, because it passes various variables down through
CMake that the main config depends on.  As a result, every config
file has to do a bunch of magic to try to reverse-engineer the location
of the site config file if they detect (heuristically) that the site
config file has not yet been run.

This patch solves the problem by emitting a mapping from source tree
config file to binary tree site config file in llvm-lit.py. Then, during
discovery when we find a config file, we check to see if we have a
target mapping for it, and if so we use that instead.

This mechanism is generic enough that it does not affect external users
of lit. They will just not have a config mapping defined, and everything
will work as normal.

On the other hand, for us it allows us to make many simplifications:

* We are guaranteed that a site config will be executed first
* Inside of a main config, we no longer have to assume that attributes
  might not be present and use getattr everywhere.
* We no longer have to pass parameters such as --param llvm_site_config=<path>
  on the command line.
* It is future-proof, meaning you don't have to edit llvm-lit.in to add
  support for new projects.
* All of the duplicated logic of trying various fallback mechanisms of
  finding a site config from the main config are now gone.

One potentially noteworthy thing that was required to implement this
change is that whereas the ninja check targets previously used the first
method to spawn lit, they now use the second. In particular, you can no
longer run lit.py against the source tree while specifying the various
`foo_site_config=<path>` parameters.  Instead, you need to run
llvm-lit.py.

Differential Revision: https://reviews.llvm.org/D37756

Modified:
    cfe/trunk/test/Unit/lit.cfg
    cfe/trunk/test/lit.cfg

Modified: cfe/trunk/test/Unit/lit.cfg
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Unit/lit.cfg?rev=313270&r1=313269&r2=313270&view=diff
==============================================================================
--- cfe/trunk/test/Unit/lit.cfg (original)
+++ cfe/trunk/test/Unit/lit.cfg Thu Sep 14 09:47:58 2017
@@ -17,14 +17,11 @@ config.suffixes = []
 
 # test_source_root: The root path where tests are located.
 # test_exec_root: The root path where tests should be run.
-clang_obj_root = getattr(config, 'clang_obj_root', None)
-if clang_obj_root is not None:
-    config.test_exec_root = os.path.join(clang_obj_root, 'unittests')
-    config.test_source_root = config.test_exec_root
+config.test_exec_root = os.path.join(config.clang_obj_root, 'unittests')
+config.test_source_root = config.test_exec_root
 
 # testFormat: The test format to use to interpret tests.
-llvm_build_mode = getattr(config, 'llvm_build_mode', "Debug")
-config.test_format = lit.formats.GoogleTest(llvm_build_mode, 'Tests')
+config.test_format = lit.formats.GoogleTest(config.llvm_build_mode, 'Tests')
 
 # Propagate the temp directory. Windows requires this because it uses \Windows\
 # if none of these are present.
@@ -38,55 +35,6 @@ for symbolizer in ['ASAN_SYMBOLIZER_PATH
     if symbolizer in os.environ:
         config.environment[symbolizer] = os.environ[symbolizer]
 
-###
-
-# Check that the object root is known.
-if config.test_exec_root is None:
-    # Otherwise, we haven't loaded the site specific configuration (the user is
-    # probably trying to run on a test file directly, and either the site
-    # configuration hasn't been created by the build system, or we are in an
-    # out-of-tree build situation).
-
-    # Check for 'clang_unit_site_config' user parameter, and use that if available.
-    site_cfg = lit_config.params.get('clang_unit_site_config', None)
-    if site_cfg and os.path.exists(site_cfg):
-        lit_config.load_config(config, site_cfg)
-        raise SystemExit
-
-    # Try to detect the situation where we are using an out-of-tree build by
-    # looking for 'llvm-config'.
-    #
-    # FIXME: I debated (i.e., wrote and threw away) adding logic to
-    # automagically generate the lit.site.cfg if we are in some kind of fresh
-    # build situation. This means knowing how to invoke the build system
-    # though, and I decided it was too much magic.
-
-    llvm_config = lit.util.which('llvm-config', config.environment['PATH'])
-    if not llvm_config:
-        lit_config.fatal('No site specific configuration available!')
-
-    # Get the source and object roots.
-    llvm_src_root = subprocess.check_output(['llvm-config', '--src-root']).strip()
-    llvm_obj_root = subprocess.check_output(['llvm-config', '--obj-root']).strip()
-    clang_src_root = os.path.join(llvm_src_root, "tools", "clang")
-    clang_obj_root = os.path.join(llvm_obj_root, "tools", "clang")
-
-    # Validate that we got a tree which points to here, using the standard
-    # tools/clang layout.
-    this_src_root = os.path.join(os.path.dirname(__file__),'..','..')
-    if os.path.realpath(clang_src_root) != os.path.realpath(this_src_root):
-        lit_config.fatal('No site specific configuration available!')
-
-    # Check that the site specific configuration exists.
-    site_cfg = os.path.join(clang_obj_root, 'test', 'Unit', 'lit.site.cfg')
-    if not os.path.exists(site_cfg):
-        lit_config.fatal('No site specific configuration available!')
-
-    # Okay, that worked. Notify the user of the automagic, and reconfigure.
-    lit_config.note('using out-of-tree build at %r' % clang_obj_root)
-    lit_config.load_config(config, site_cfg)
-    raise SystemExit
-
 shlibpath_var = ''
 if platform.system() == 'Linux':
     shlibpath_var = 'LD_LIBRARY_PATH'
@@ -97,14 +45,7 @@ elif platform.system() == 'Windows':
 
 # in stand-alone builds, shlibdir is clang's build tree
 # while llvm_libs_dir is installed LLVM (and possibly older clang)
-llvm_shlib_dir = getattr(config, 'shlibdir', None)
-if not llvm_shlib_dir:
-    lit_config.fatal('No shlibdir set!')
-# Point the dynamic loader at dynamic libraries in 'lib'.
-llvm_libs_dir = getattr(config, 'llvm_libs_dir', None)
-if not llvm_libs_dir:
-    lit_config.fatal('No LLVM libs dir set!')
-shlibpath = os.path.pathsep.join((llvm_shlib_dir, llvm_libs_dir,
+shlibpath = os.path.pathsep.join((config.shlibdir, config.llvm_libs_dir,
                                  config.environment.get(shlibpath_var,'')))
 
 config.environment[shlibpath_var] = shlibpath

Modified: cfe/trunk/test/lit.cfg
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/lit.cfg?rev=313270&r1=313269&r2=313270&view=diff
==============================================================================
--- cfe/trunk/test/lit.cfg (original)
+++ cfe/trunk/test/lit.cfg Thu Sep 14 09:47:58 2017
@@ -55,13 +55,7 @@ config.excludes = ['Inputs', 'CMakeLists
 config.test_source_root = os.path.dirname(__file__)
 
 # test_exec_root: The root path where tests should be run.
-clang_obj_root = getattr(config, 'clang_obj_root', None)
-if clang_obj_root is not None:
-    config.test_exec_root = os.path.join(clang_obj_root, 'test')
-
-# Set llvm_{src,obj}_root for use by others.
-config.llvm_src_root = getattr(config, 'llvm_src_root', None)
-config.llvm_obj_root = getattr(config, 'llvm_obj_root', None)
+config.test_exec_root = os.path.join(config.clang_obj_root, 'test')
 
 # Clear some environment variables that might affect Clang.
 #
@@ -92,91 +86,20 @@ for name in possibly_dangerous_env_vars:
     del config.environment[name]
 
 # Tweak the PATH to include the tools dir and the scripts dir.
-if clang_obj_root is not None:
-    clang_tools_dir = getattr(config, 'clang_tools_dir', None)
-    if not clang_tools_dir:
-        lit_config.fatal('No Clang tools dir set!')
-    llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
-    if not llvm_tools_dir:
-        lit_config.fatal('No LLVM tools dir set!')
-    path = os.path.pathsep.join((
-            clang_tools_dir, llvm_tools_dir, config.environment['PATH']))
-    config.environment['PATH'] = path
-    # in stand-alone builds, llvm_shlib_dir is clang's build tree
-    # while llvm_libs_dir is installed LLVM (and possibly older clang)
-    llvm_shlib_dir = getattr(config, 'llvm_shlib_dir', None)
-    if not llvm_shlib_dir:
-        lit_config.fatal('No LLVM shlib dir set!')
-    llvm_libs_dir = getattr(config, 'llvm_libs_dir', None)
-    if not llvm_libs_dir:
-        lit_config.fatal('No LLVM libs dir set!')
-    path = os.path.pathsep.join((llvm_shlib_dir, llvm_libs_dir,
-                                 config.environment.get('LD_LIBRARY_PATH','')))
-    config.environment['LD_LIBRARY_PATH'] = path
+path = os.path.pathsep.join((
+        config.clang_tools_dir, config.llvm_tools_dir, config.environment['PATH']))
+config.environment['PATH'] = path
+path = os.path.pathsep.join((config.llvm_shlib_dir, config.llvm_libs_dir,
+                              config.environment.get('LD_LIBRARY_PATH','')))
+config.environment['LD_LIBRARY_PATH'] = path
 
 # Propagate path to symbolizer for ASan/MSan.
 for symbolizer in ['ASAN_SYMBOLIZER_PATH', 'MSAN_SYMBOLIZER_PATH']:
     if symbolizer in os.environ:
         config.environment[symbolizer] = os.environ[symbolizer]
 
-###
-
-# Check that the object root is known.
-if config.test_exec_root is None:
-    # Otherwise, we haven't loaded the site specific configuration (the user is
-    # probably trying to run on a test file directly, and either the site
-    # configuration hasn't been created by the build system, or we are in an
-    # out-of-tree build situation).
-
-    # Check for 'clang_site_config' user parameter, and use that if available.
-    site_cfg = lit_config.params.get('clang_site_config', None)
-    if site_cfg and os.path.exists(site_cfg):
-        lit_config.load_config(config, site_cfg)
-        raise SystemExit
-
-    # Try to detect the situation where we are using an out-of-tree build by
-    # looking for 'llvm-config'.
-    #
-    # FIXME: I debated (i.e., wrote and threw away) adding logic to
-    # automagically generate the lit.site.cfg if we are in some kind of fresh
-    # build situation. This means knowing how to invoke the build system though,
-    # and I decided it was too much magic. We should solve this by just having
-    # the .cfg files generated during the configuration step.
-
-    llvm_config = lit.util.which('llvm-config', config.environment['PATH'])
-    if not llvm_config:
-        lit_config.fatal('No site specific configuration available!')
-
-    # Get the source and object roots.
-    llvm_src_root = subprocess.check_output(['llvm-config', '--src-root']).strip()
-    llvm_obj_root = subprocess.check_output(['llvm-config', '--obj-root']).strip()
-    clang_src_root = os.path.join(llvm_src_root, "tools", "clang")
-    clang_obj_root = os.path.join(llvm_obj_root, "tools", "clang")
-
-    # Validate that we got a tree which points to here, using the standard
-    # tools/clang layout.
-    this_src_root = os.path.dirname(config.test_source_root)
-    if os.path.realpath(clang_src_root) != os.path.realpath(this_src_root):
-        lit_config.fatal('No site specific configuration available!')
-
-    # Check that the site specific configuration exists.
-    site_cfg = os.path.join(clang_obj_root, 'test', 'lit.site.cfg')
-    if not os.path.exists(site_cfg):
-        lit_config.fatal(
-            'No site specific configuration available! You may need to '
-            'run "make test" in your Clang build directory.')
-
-    # Okay, that worked. Notify the user of the automagic, and reconfigure.
-    lit_config.note('using out-of-tree build at %r' % clang_obj_root)
-    lit_config.load_config(config, site_cfg)
-    raise SystemExit
-
-###
-
 # Discover the 'clang' and 'clangcc' to use.
 
-import os
-
 def inferClang(PATH):
     # Determine which clang to use.
     clang = os.getenv('CLANG')
@@ -315,7 +238,7 @@ config.substitutions.append(
 # with the full path to the build directory holding that tool.  This
 # ensures that we are testing the tools just built and not some random
 # tools that might happen to be in the user's PATH.
-tool_dirs = os.path.pathsep.join((clang_tools_dir, llvm_tools_dir))
+tool_dirs = os.path.pathsep.join((config.clang_tools_dir, config.llvm_tools_dir))
 
 # Regex assertions to reject neighbor hyphens/dots (seen in some tests).
 # For example, don't match 'clang-check-' or '.clang-format'.
@@ -351,7 +274,7 @@ for pattern in tool_patterns:
     if not tool_path:
         # Warn, but still provide a substitution.
         lit_config.note('Did not find ' + tool_name + ' in ' + tool_dirs)
-        tool_path = clang_tools_dir + '/' + tool_name
+        tool_path = config.clang_tools_dir + '/' + tool_name
     config.substitutions.append((pattern, tool_pipe + tool_path))
 
 ###
@@ -451,7 +374,7 @@ def get_llvm_config_props():
 
     cmd = subprocess.Popen(
         [
-            os.path.join(llvm_tools_dir, 'llvm-config'),
+            os.path.join(config.llvm_tools_dir, 'llvm-config'),
             '--assertion-mode',
             '--targets-built',
             '--cxxflags'




More information about the cfe-commits mailing list