Skip to content

Commit

Permalink
[K/N][tests] Stop using shared Clang module cache to improve stability
Browse files Browse the repository at this point in the history
cinterop uses Clang and libclang. When getting `-fmodules` flag, Clang
practices some caching, which is system-wide by default. Meaning, the
cache directory can be used by other Clang invocations, even at the same
time.

Clang module cache machinery has sophisticated measures to avoid any
problems with that, e.g. different compilation flags make it use
different cache sub-directories, and there are locks in place to avoid
data races. Still, sometimes we encounter problems seemingly triggered
by re-using the same cache directory.

This commit workarounds that by passing `-fmodules-cache-path=` flag
to some of the relevant `cinterop` invocations in the test
infrastructure.

^KT-68254

(cherry picked from commit 0044ca5)
  • Loading branch information
SvyatoslavScherbina committed Jul 4, 2024
1 parent b47f431 commit 275a1b5
Showing 1 changed file with 16 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -143,17 +143,31 @@ internal fun AbstractNativeSimpleTest.cinteropToLibrary(
outputDir: File,
freeCompilerArgs: TestCompilerArgs
): TestCompilationResult<out TestCompilationArtifact.KLIB> {
val testCase: TestCase = generateCInteropTestCaseFromSingleDefFile(defFile, freeCompilerArgs)
val args = freeCompilerArgs + cinteropModulesCachePathArguments(freeCompilerArgs.cinteropArgs, outputDir)
val testCase: TestCase = generateCInteropTestCaseFromSingleDefFile(defFile, args)
return CInteropCompilation(
classLoader = testRunSettings.get(),
targets = targets,
freeCompilerArgs = freeCompilerArgs,
freeCompilerArgs = args,
defFile = testCase.modules.single().files.single().location,
dependencies = emptyList(),
expectedArtifact = getLibraryArtifact(testCase, outputDir)
).result
}

private fun cinteropModulesCachePathArguments(
cinteropArgs: List<String>,
outputDir: File,
) = if (cinteropArgs.contains("-fmodules") && cinteropArgs.none { it.startsWith(FMODULES_CACHE_PATH_EQ) }) {
// Don't reuse the system-wide module cache to make the test run more predictably.
// See e.g. https://youtrack.jetbrains.com/issue/KT-68254.
TestCInteropArgs("-compiler-option", "$FMODULES_CACHE_PATH_EQ$outputDir/modulesCachePath")
} else {
TestCompilerArgs.EMPTY
}

private const val FMODULES_CACHE_PATH_EQ = "-fmodules-cache-path="

internal class CompiledExecutable(
val testCase: TestCase,
val compilationResult: TestCompilationResult.Success<out TestCompilationArtifact.Executable>
Expand Down

0 comments on commit 275a1b5

Please sign in to comment.