diff --git a/test/test_other.py b/test/test_other.py index 630edf777ed55..a509a9f7ed590 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -15412,3 +15412,25 @@ def test_rust_integration_basics(self): return 0; }''') self.do_runf('main.cpp', 'Hello from rust!', emcc_args=[lib]) + + @crossplatform + def test_create_cache_directory(self): + if config.FROZEN_CACHE: + self.skipTest("test doesn't work with frozen cache") + + # Test that the cache directory (including parent directories) is + # created on demand. + with env_modify({'EM_CACHE': os.path.abspath('foo/bar')}): + self.run_process([EMCC, '-c', test_file('hello_world.c')]) + self.assertExists('foo/bar/sysroot_install.stamp') + + if not WINDOWS: + # Test that we generate a nice error when we cannot create the cache + # because it is in a read-only location. + # For some reason this doesn't work on windows, at least not in CI. + os.mkdir('rodir') + os.chmod('rodir', 0o444) + self.assertFalse(os.access('rodir', os.W_OK)) + with env_modify({'EM_CACHE': os.path.abspath('rodir/foo')}): + err = self.expect_fail([EMCC, '-c', test_file('hello_world.c')]) + self.assertContained('emcc: error: unable to create cache directory', err) diff --git a/tools/cache.py b/tools/cache.py index 3a8655449447f..445de535d5683 100644 --- a/tools/cache.py +++ b/tools/cache.py @@ -75,10 +75,10 @@ def lock(reason): def ensure(): ensure_setup() if not os.path.isdir(cachedir): - parent_dir = os.path.dirname(cachedir) - if not is_writable(parent_dir): - utils.exit_with_error(f'unable to create cache directory "{cachedir}": parent directory not writable (see https://emscripten.org/docs/tools_reference/emcc.html for info on setting the cache directory)') - utils.safe_ensure_dirs(cachedir) + try: + utils.safe_ensure_dirs(cachedir) + except Exception as e: + utils.exit_with_error(f'unable to create cache directory "{cachedir}": {e} (see https://emscripten.org/docs/tools_reference/emcc.html for info on setting the cache directory)') def erase():