diff --git a/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/NativeIndex.kt b/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/NativeIndex.kt index 80ac7d7889c..8b094d8c749 100644 --- a/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/NativeIndex.kt +++ b/kotlin-native/Interop/Indexer/src/main/kotlin/org/jetbrains/kotlin/native/interop/indexer/NativeIndex.kt @@ -16,10 +16,10 @@ package org.jetbrains.kotlin.native.interop.indexer -enum class Language(val sourceFileExtension: String) { - C("c"), - CPP("cpp"), - OBJECTIVE_C("m") +enum class Language(val sourceFileExtension: String, val clangLanguageName: String) { + C("c", "c"), + CPP("cpp", "c++"), + OBJECTIVE_C("m", "objective-c") } interface HeaderInclusionPolicy { diff --git a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt index 3a19b6ab429..bb4eeb1d096 100644 --- a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt +++ b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt @@ -105,9 +105,12 @@ private fun List?.isTrue(): Boolean { return this?.last() == "true" } -private fun runCmd(command: Array, verbose: Boolean = false) { - if (verbose) println("COMMAND: " + command.joinToString(" ")) - Command(*command).getOutputLines(true).let { lines -> +private fun runCmd(command: Array, verbose: Boolean = false, redirectInputFile: File? = null) { + if (verbose) { + val redirect = if (redirectInputFile == null) "" else " < ${redirectInputFile.path}" + println("COMMAND: " + command.joinToString(" ") + redirect) + } + Command(command.toList(), redirectInputFile = redirectInputFile).getOutputLines(true).let { lines -> if (verbose) lines.forEach(::println) } } @@ -384,9 +387,11 @@ private fun processCLib(flavor: KotlinPlatform, cinteropArguments: CInteropArgum } KotlinPlatform.NATIVE -> { val outLib = File(nativeLibsDir, "$libName.bc") + // Note that the output bitcode contains the source file path, which can lead to non-deterministc builds (see KT-54284). + // The source file is passed in via stdin to ensure the output library is deterministic. val compilerCmd = arrayOf(compiler, *compilerArgs, - "-emit-llvm", "-c", outCFile.absolutePath, "-o", outLib.absolutePath) - runCmd(compilerCmd, verbose) + "-emit-llvm", "-x", library.language.clangLanguageName, "-c", "-", "-o", outLib.absolutePath) + runCmd(compilerCmd, verbose, redirectInputFile = File(outCFile.absolutePath)) outLib.absolutePath } } diff --git a/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/exec/ExecuteCommand.kt b/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/exec/ExecuteCommand.kt index f2db585c3bf..768cb16af7f 100644 --- a/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/exec/ExecuteCommand.kt +++ b/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/exec/ExecuteCommand.kt @@ -18,12 +18,13 @@ package org.jetbrains.kotlin.konan.exec import org.jetbrains.kotlin.konan.KonanExternalToolFailure import java.io.BufferedReader +import java.io.File import java.io.InputStreamReader import java.lang.ProcessBuilder.Redirect import java.nio.file.Files -open class Command(initialCommand: List) { +open class Command(initialCommand: List, val redirectInputFile: File? = null) { constructor(tool: String) : this(listOf(tool)) constructor(vararg command: String) : this(command.toList()) @@ -58,7 +59,11 @@ open class Command(initialCommand: List) { val builder = ProcessBuilder(command) builder.redirectOutput(Redirect.INHERIT) - builder.redirectInput(Redirect.INHERIT) + if (redirectInputFile == null) { + builder.redirectInput(Redirect.INHERIT) + } else { + builder.redirectInput(redirectInputFile) + } val process = builder.start() @@ -90,7 +95,11 @@ open class Command(initialCommand: List) { try { val builder = ProcessBuilder(command) - builder.redirectInput(Redirect.INHERIT) + if (redirectInputFile == null) { + builder.redirectInput(Redirect.INHERIT) + } else { + builder.redirectInput(redirectInputFile) + } builder.redirectError(Redirect.INHERIT) builder.redirectOutput(Redirect.to(outputFile)) .redirectErrorStream(withErrors)