def test_xcode_not_available( xcode_select_output, mock_executable, monkeypatch ): # Prepare mock executables to fake the Xcode environment xcrun = mock_executable('xcrun', """ if [[ "$2" == "clang" ]] ; then echo "/Library/Developer/CommandLineTools/usr/bin/clang" fi if [[ "$2" == "clang++" ]] ; then echo "/Library/Developer/CommandLineTools/usr/bin/clang++" fi """) mock_executable('xcode-select', """ echo "{0}" """.format(xcode_select_output)) bin_dir = os.path.dirname(xcrun) monkeypatch.setenv('PATH', bin_dir, prepend=os.pathsep) # Prepare compiler apple_clang_cls = spack.compilers.class_for_compiler_name('apple-clang') compiler = apple_clang_cls( spack.spec.CompilerSpec('[email protected]'), 'catalina', 'x86_64', [ '/usr/bin/clang', '/usr/bin/clang++', None, None ] ) env = spack.util.environment.EnvironmentModifications() class MockPackage(object): use_xcode = True pkg = MockPackage() with pytest.raises(OSError): compiler.setup_custom_environment(pkg, env)
def test_apple_clang_setup_environment(mock_executable, monkeypatch): """Test a code path that is taken only if the package uses Xcode on MacOS. """ class MockPackage(object): use_xcode = False apple_clang_cls = spack.compilers.class_for_compiler_name('apple-clang') compiler = apple_clang_cls( spack.spec.CompilerSpec('[email protected]'), 'catalina', 'x86_64', [ '/usr/bin/clang', '/usr/bin/clang++', None, None ] ) env = spack.util.environment.EnvironmentModifications() # Check a package that doesn't use xcode and ensure we don't add changes # to the environment pkg = MockPackage() compiler.setup_custom_environment(pkg, env) assert not env # Prepare mock executables to fake the Xcode environment xcrun = mock_executable('xcrun', """ if [[ "$2" == "clang" ]] ; then echo "/Library/Developer/CommandLineTools/usr/bin/clang" fi if [[ "$2" == "clang++" ]] ; then echo "/Library/Developer/CommandLineTools/usr/bin/clang++" fi """) mock_executable('xcode-select', """ echo "/Library/Developer" """) bin_dir = os.path.dirname(xcrun) monkeypatch.setenv('PATH', bin_dir, prepend=os.pathsep) def noop(*args, **kwargs): pass real_listdir = os.listdir def _listdir(path): if not os.path.exists(path): return [] return real_listdir(path) # Set a few operations to noop monkeypatch.setattr(shutil, 'copytree', noop) monkeypatch.setattr(os, 'unlink', noop) monkeypatch.setattr(os, 'symlink', noop) monkeypatch.setattr(os, 'listdir', _listdir) # Qt is so far the only package that uses this code path, change # introduced in https://github.com/spack/spack/pull/1832 pkg.use_xcode = True compiler.setup_custom_environment(pkg, env) assert len(env) == 3 assert env.env_modifications[0].name == 'SPACK_CC' assert env.env_modifications[1].name == 'SPACK_CXX' assert env.env_modifications[2].name == 'DEVELOPER_DIR'