autotools: add -I flag when non-standard libtool (#31677)
When 1. Spack installs libtool, 2. system libtool is installed too, and 3. system automake is used Spack passes system automake's `-I <prefix>` flag to itself, even though it's a default search path. This takes precedence over spack's libtool prefix dir. This causes the wrong `libtool.m4` file to be used (since system libtool is in the same prefix as system automake). And that leads to error messages about incompatible libtool, something something LT_INIT.
This commit is contained in:
		| @@ -359,12 +359,11 @@ def autoreconf(self, spec, prefix): | ||||
| 
 | ||||
|     @property | ||||
|     def autoreconf_search_path_args(self): | ||||
|         """Arguments to autoreconf to modify the search paths""" | ||||
|         search_path_args = [] | ||||
|         for dep in self.spec.dependencies(deptype='build'): | ||||
|             if os.path.exists(dep.prefix.share.aclocal): | ||||
|                 search_path_args.extend(['-I', dep.prefix.share.aclocal]) | ||||
|         return search_path_args | ||||
|         """Search path includes for autoreconf. Add an -I flag for all `aclocal` dirs | ||||
|         of build deps, skips the default path of automake, move external include | ||||
|         flags to the back, since they might pull in unrelated m4 files shadowing | ||||
|         spack dependencies.""" | ||||
|         return _autoreconf_search_path_args(self.spec) | ||||
| 
 | ||||
|     @run_after('autoreconf') | ||||
|     def set_configure_or_die(self): | ||||
| @@ -668,3 +667,32 @@ def remove_libtool_archives(self): | ||||
| 
 | ||||
|     # On macOS, force rpaths for shared library IDs and remove duplicate rpaths | ||||
|     run_after('install')(PackageBase.apply_macos_rpath_fixups) | ||||
| 
 | ||||
| 
 | ||||
| def _autoreconf_search_path_args(spec): | ||||
|     dirs_seen = set() | ||||
|     flags_spack, flags_external = [], [] | ||||
| 
 | ||||
|     # We don't want to add an include flag for automake's default search path. | ||||
|     for automake in spec.dependencies(name='automake', deptype='build'): | ||||
|         try: | ||||
|             s = os.stat(automake.prefix.share.aclocal) | ||||
|             if stat.S_ISDIR(s.st_mode): | ||||
|                 dirs_seen.add((s.st_ino, s.st_dev)) | ||||
|         except OSError: | ||||
|             pass | ||||
| 
 | ||||
|     for dep in spec.dependencies(deptype='build'): | ||||
|         path = dep.prefix.share.aclocal | ||||
|         # Skip non-existing aclocal paths | ||||
|         try: | ||||
|             s = os.stat(path) | ||||
|         except OSError: | ||||
|             continue | ||||
|         # Skip things seen before, as well as non-dirs. | ||||
|         if (s.st_ino, s.st_dev) in dirs_seen or not stat.S_ISDIR(s.st_mode): | ||||
|             continue | ||||
|         dirs_seen.add((s.st_ino, s.st_dev)) | ||||
|         flags = flags_external if dep.external else flags_spack | ||||
|         flags.extend(['-I', path]) | ||||
|     return flags_spack + flags_external | ||||
|   | ||||
| @@ -12,6 +12,7 @@ | ||||
| 
 | ||||
| import llnl.util.filesystem as fs | ||||
| 
 | ||||
| import spack.build_systems.autotools | ||||
| import spack.environment | ||||
| import spack.platforms | ||||
| import spack.repo | ||||
| @@ -353,3 +354,67 @@ def test_autotools_args_from_conditional_variant(config, mock_packages): | ||||
|     s = Spec('autotools-conditional-variants-test').concretized() | ||||
|     assert 'example' not in s.variants | ||||
|     assert len(s.package._activate_or_not('example', 'enable', 'disable')) == 0 | ||||
| 
 | ||||
| 
 | ||||
| def test_autoreconf_search_path_args_multiple(config, mock_packages, tmpdir): | ||||
|     """autoreconf should receive the right -I flags with search paths for m4 files | ||||
|     for build deps.""" | ||||
|     spec = Spec('dttop').concretized() | ||||
|     aclocal_fst = str(tmpdir.mkdir("fst").mkdir("share").mkdir("aclocal")) | ||||
|     aclocal_snd = str(tmpdir.mkdir("snd").mkdir("share").mkdir("aclocal")) | ||||
|     build_dep_one, build_dep_two = spec.dependencies(deptype='build') | ||||
|     build_dep_one.prefix = str(tmpdir.join("fst")) | ||||
|     build_dep_two.prefix = str(tmpdir.join("snd")) | ||||
|     assert spack.build_systems.autotools._autoreconf_search_path_args(spec) == [ | ||||
|         '-I', aclocal_fst, '-I', aclocal_snd | ||||
|     ] | ||||
| 
 | ||||
| 
 | ||||
| def test_autoreconf_search_path_args_skip_automake(config, mock_packages, tmpdir): | ||||
|     """automake's aclocal dir should not be added as -I flag as it is a default | ||||
|     3rd party dir search path, and if it's a system version it usually includes | ||||
|     m4 files shadowing spack deps.""" | ||||
|     spec = Spec('dttop').concretized() | ||||
|     tmpdir.mkdir("fst").mkdir("share").mkdir("aclocal") | ||||
|     aclocal_snd = str(tmpdir.mkdir("snd").mkdir("share").mkdir("aclocal")) | ||||
|     build_dep_one, build_dep_two = spec.dependencies(deptype='build') | ||||
|     build_dep_one.name = 'automake' | ||||
|     build_dep_one.prefix = str(tmpdir.join("fst")) | ||||
|     build_dep_two.prefix = str(tmpdir.join("snd")) | ||||
|     assert spack.build_systems.autotools._autoreconf_search_path_args(spec) == [ | ||||
|         '-I', aclocal_snd | ||||
|     ] | ||||
| 
 | ||||
| 
 | ||||
| def test_autoreconf_search_path_args_external_order(config, mock_packages, tmpdir): | ||||
|     """When a build dep is external, its -I flag should occur last""" | ||||
|     spec = Spec('dttop').concretized() | ||||
|     aclocal_fst = str(tmpdir.mkdir("fst").mkdir("share").mkdir("aclocal")) | ||||
|     aclocal_snd = str(tmpdir.mkdir("snd").mkdir("share").mkdir("aclocal")) | ||||
|     build_dep_one, build_dep_two = spec.dependencies(deptype='build') | ||||
|     build_dep_one.external_path = str(tmpdir.join("fst")) | ||||
|     build_dep_two.prefix = str(tmpdir.join("snd")) | ||||
|     assert spack.build_systems.autotools._autoreconf_search_path_args(spec) == [ | ||||
|         '-I', aclocal_snd, '-I', aclocal_fst | ||||
|     ] | ||||
| 
 | ||||
| 
 | ||||
| def test_autoreconf_search_path_skip_nonexisting(config, mock_packages, tmpdir): | ||||
|     """Skip -I flags for non-existing directories""" | ||||
|     spec = Spec('dttop').concretized() | ||||
|     build_dep_one, build_dep_two = spec.dependencies(deptype='build') | ||||
|     build_dep_one.prefix = str(tmpdir.join("fst")) | ||||
|     build_dep_two.prefix = str(tmpdir.join("snd")) | ||||
|     assert spack.build_systems.autotools._autoreconf_search_path_args(spec) == [] | ||||
| 
 | ||||
| 
 | ||||
| def test_autoreconf_search_path_dont_repeat(config, mock_packages, tmpdir): | ||||
|     """Do not add the same -I flag twice to keep things readable for humans""" | ||||
|     spec = Spec('dttop').concretized() | ||||
|     aclocal = str(tmpdir.mkdir("prefix").mkdir("share").mkdir("aclocal")) | ||||
|     build_dep_one, build_dep_two = spec.dependencies(deptype='build') | ||||
|     build_dep_one.external_path = str(tmpdir.join("prefix")) | ||||
|     build_dep_two.external_path = str(tmpdir.join("prefix")) | ||||
|     assert spack.build_systems.autotools._autoreconf_search_path_args(spec) == [ | ||||
|         '-I', aclocal | ||||
|     ] | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Harmen Stoppels
					Harmen Stoppels