modules: store configure args during build (#11084)
This change stores packages' configure arguments during build and makes use of them while refreshing module files. This fixes problems such as in #10716.
This commit is contained in:
		| @@ -463,6 +463,10 @@ def log(pkg): | |||||||
|     # Archive the environment used for the build |     # Archive the environment used for the build | ||||||
|     install(pkg.env_path, pkg.install_env_path) |     install(pkg.env_path, pkg.install_env_path) | ||||||
| 
 | 
 | ||||||
|  |     if os.path.exists(pkg.configure_args_path): | ||||||
|  |         # Archive the args used for the build | ||||||
|  |         install(pkg.configure_args_path, pkg.install_configure_args_path) | ||||||
|  | 
 | ||||||
|     # Finally, archive files that are specific to each package |     # Finally, archive files that are specific to each package | ||||||
|     with working_dir(pkg.stage.path): |     with working_dir(pkg.stage.path): | ||||||
|         errors = six.StringIO() |         errors = six.StringIO() | ||||||
| @@ -1013,6 +1017,18 @@ def build_process(): | |||||||
|                         # Save the build environment in a file before building. |                         # Save the build environment in a file before building. | ||||||
|                         dump_environment(pkg.env_path) |                         dump_environment(pkg.env_path) | ||||||
| 
 | 
 | ||||||
|  |                         for attr in ('configure_args', 'cmake_args'): | ||||||
|  |                             try: | ||||||
|  |                                 configure_args = getattr(pkg, attr)() | ||||||
|  |                                 configure_args = ' '.join(configure_args) | ||||||
|  | 
 | ||||||
|  |                                 with open(pkg.configure_args_path, 'w') as args_file: | ||||||
|  |                                     args_file.write(configure_args) | ||||||
|  | 
 | ||||||
|  |                                 break | ||||||
|  |                             except Exception: | ||||||
|  |                                 pass | ||||||
|  | 
 | ||||||
|                         # cache debug settings |                         # cache debug settings | ||||||
|                         debug_enabled = tty.is_debug() |                         debug_enabled = tty.is_debug() | ||||||
| 
 | 
 | ||||||
|   | |||||||
| @@ -623,16 +623,9 @@ def configure_options(self): | |||||||
|             msg = 'unknown, software installed outside of Spack' |             msg = 'unknown, software installed outside of Spack' | ||||||
|             return msg |             return msg | ||||||
| 
 | 
 | ||||||
|         # This is quite simple right now, but contains information on how |         if os.path.exists(pkg.install_configure_args_path): | ||||||
|         # to call different build system classes. |             with open(pkg.install_configure_args_path, 'r') as args_file: | ||||||
|         for attr in ('configure_args', 'cmake_args'): |                 return args_file.read() | ||||||
|             try: |  | ||||||
|                 configure_args = getattr(pkg, attr)() |  | ||||||
|                 return ' '.join(configure_args) |  | ||||||
|             except (AttributeError, IOError, KeyError): |  | ||||||
|                 # The method doesn't exist in the current spec, |  | ||||||
|                 # or it's not usable |  | ||||||
|                 pass |  | ||||||
| 
 | 
 | ||||||
|         # Returning a false-like value makes the default templates skip |         # Returning a false-like value makes the default templates skip | ||||||
|         # the configure option section |         # the configure option section | ||||||
|   | |||||||
| @@ -68,6 +68,9 @@ | |||||||
| # Filename for the Spack build/install environment file. | # Filename for the Spack build/install environment file. | ||||||
| _spack_build_envfile = 'spack-build-env.txt' | _spack_build_envfile = 'spack-build-env.txt' | ||||||
| 
 | 
 | ||||||
|  | # Filename for the Spack configure args file. | ||||||
|  | _spack_configure_argsfile = 'spack-configure-args.txt' | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class InstallPhase(object): | class InstallPhase(object): | ||||||
|     """Manages a single phase of the installation. |     """Manages a single phase of the installation. | ||||||
| @@ -896,6 +899,18 @@ def install_log_path(self): | |||||||
|         # Otherwise, return the current install log path name. |         # Otherwise, return the current install log path name. | ||||||
|         return os.path.join(install_path, _spack_build_logfile) |         return os.path.join(install_path, _spack_build_logfile) | ||||||
| 
 | 
 | ||||||
|  |     @property | ||||||
|  |     def configure_args_path(self): | ||||||
|  |         """Return the configure args file path associated with staging.""" | ||||||
|  |         return os.path.join(self.stage.path, _spack_configure_argsfile) | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def install_configure_args_path(self): | ||||||
|  |         """Return the configure args file path on successful installation.""" | ||||||
|  |         install_path = spack.store.layout.metadata_path(self.spec) | ||||||
|  | 
 | ||||||
|  |         return os.path.join(install_path, _spack_configure_argsfile) | ||||||
|  | 
 | ||||||
|     def _make_fetcher(self): |     def _make_fetcher(self): | ||||||
|         # Construct a composite fetcher that always contains at least |         # Construct a composite fetcher that always contains at least | ||||||
|         # one element (the root package). In case there are resources |         # one element (the root package). In case there are resources | ||||||
|   | |||||||
| @@ -15,7 +15,8 @@ | |||||||
| import spack.repo | import spack.repo | ||||||
| import spack.store | import spack.store | ||||||
| from spack.spec import Spec | from spack.spec import Spec | ||||||
| from spack.package import _spack_build_envfile, _spack_build_logfile | from spack.package import (_spack_build_envfile, _spack_build_logfile, | ||||||
|  |                            _spack_configure_argsfile) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def test_install_and_uninstall(install_mockery, mock_fetch, monkeypatch): | def test_install_and_uninstall(install_mockery, mock_fetch, monkeypatch): | ||||||
| @@ -410,6 +411,9 @@ def test_pkg_install_paths(install_mockery): | |||||||
|     env_path = os.path.join(spec.prefix, '.spack', _spack_build_envfile) |     env_path = os.path.join(spec.prefix, '.spack', _spack_build_envfile) | ||||||
|     assert spec.package.install_env_path == env_path |     assert spec.package.install_env_path == env_path | ||||||
| 
 | 
 | ||||||
|  |     args_path = os.path.join(spec.prefix, '.spack', _spack_configure_argsfile) | ||||||
|  |     assert spec.package.install_configure_args_path == args_path | ||||||
|  | 
 | ||||||
|     # Backward compatibility checks |     # Backward compatibility checks | ||||||
|     log_dir = os.path.dirname(log_path) |     log_dir = os.path.dirname(log_path) | ||||||
|     mkdirp(log_dir) |     mkdirp(log_dir) | ||||||
| @@ -448,6 +452,7 @@ def test_pkg_install_log(install_mockery): | |||||||
|     with working_dir(log_dir): |     with working_dir(log_dir): | ||||||
|         touch(log_path) |         touch(log_path) | ||||||
|         touch(spec.package.env_path) |         touch(spec.package.env_path) | ||||||
|  |         touch(spec.package.configure_args_path) | ||||||
| 
 | 
 | ||||||
|     install_path = os.path.dirname(spec.package.install_log_path) |     install_path = os.path.dirname(spec.package.install_log_path) | ||||||
|     mkdirp(install_path) |     mkdirp(install_path) | ||||||
| @@ -456,6 +461,7 @@ def test_pkg_install_log(install_mockery): | |||||||
| 
 | 
 | ||||||
|     assert os.path.exists(spec.package.install_log_path) |     assert os.path.exists(spec.package.install_log_path) | ||||||
|     assert os.path.exists(spec.package.install_env_path) |     assert os.path.exists(spec.package.install_env_path) | ||||||
|  |     assert os.path.exists(spec.package.install_configure_args_path) | ||||||
| 
 | 
 | ||||||
|     # Cleanup |     # Cleanup | ||||||
|     shutil.rmtree(log_dir) |     shutil.rmtree(log_dir) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Michael Kuhn
					Michael Kuhn