rrn/rd/KT-55578 User-provided hints for linker errors
[K/N] KT-55578 Show customized user suggestions on linkage errors Merge-request: KT-MR-9636 Merged-by: Gleb Lukianets <Gleb.Lukianets@jetbrains.com>
This commit is contained in:
committed by
Space Team
parent
1e0115aef8
commit
242ca73d83
+4
@@ -34,6 +34,7 @@ const val SHORT_MODULE_NAME = "Xshort-module-name"
|
|||||||
const val FOREIGN_EXCEPTION_MODE = "Xforeign-exception-mode"
|
const val FOREIGN_EXCEPTION_MODE = "Xforeign-exception-mode"
|
||||||
const val DUMP_BRIDGES = "Xdump-bridges"
|
const val DUMP_BRIDGES = "Xdump-bridges"
|
||||||
const val DISABLE_EXCEPTION_PRETTIFIER = "Xdisable-exception-prettifier"
|
const val DISABLE_EXCEPTION_PRETTIFIER = "Xdisable-exception-prettifier"
|
||||||
|
const val USER_SETUP_HINT = "Xuser-setup-hint"
|
||||||
|
|
||||||
// TODO: unify camel and snake cases.
|
// TODO: unify camel and snake cases.
|
||||||
// Possible solution is to accept both cases
|
// Possible solution is to accept both cases
|
||||||
@@ -138,6 +139,9 @@ open class CInteropArguments(argParser: ArgParser =
|
|||||||
|
|
||||||
val disableExceptionPrettifier by argParser.option(ArgType.Boolean, DISABLE_EXCEPTION_PRETTIFIER,
|
val disableExceptionPrettifier by argParser.option(ArgType.Boolean, DISABLE_EXCEPTION_PRETTIFIER,
|
||||||
description = "Don't hide exceptions with user-friendly ones").default(false)
|
description = "Don't hide exceptions with user-friendly ones").default(false)
|
||||||
|
|
||||||
|
val userSetupHint by argParser.option(ArgType.String, USER_SETUP_HINT,
|
||||||
|
description = "A suggestion that is displayed to the user if produced lib fails to link")
|
||||||
}
|
}
|
||||||
|
|
||||||
class JSInteropArguments(argParser: ArgParser = ArgParser("jsinterop",
|
class JSInteropArguments(argParser: ArgParser = ArgParser("jsinterop",
|
||||||
|
|||||||
+6
@@ -388,6 +388,12 @@ private fun processCLib(
|
|||||||
ForeignExceptionMode.byValue(it).value // may throw IllegalArgumentException
|
ForeignExceptionMode.byValue(it).value // may throw IllegalArgumentException
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cinteropArguments.userSetupHint?.let {
|
||||||
|
def.manifestAddendProperties.put("userSetupHint", it)?.also {
|
||||||
|
warn("User setup hint provided in .def file will be shadowed by command line argument")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
manifestAddend?.parentFile?.mkdirs()
|
manifestAddend?.parentFile?.mkdirs()
|
||||||
manifestAddend?.let { def.manifestAddendProperties.storeProperties(it) }
|
manifestAddend?.let { def.manifestAddendProperties.storeProperties(it) }
|
||||||
|
|
||||||
|
|||||||
+31
-11
@@ -9,6 +9,8 @@ import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
|||||||
import org.jetbrains.kotlin.konan.target.Family
|
import org.jetbrains.kotlin.konan.target.Family
|
||||||
import org.jetbrains.kotlin.konan.target.LinkerOutputKind
|
import org.jetbrains.kotlin.konan.target.LinkerOutputKind
|
||||||
import org.jetbrains.kotlin.konan.target.presetName
|
import org.jetbrains.kotlin.konan.target.presetName
|
||||||
|
import org.jetbrains.kotlin.library.isInterop
|
||||||
|
import org.jetbrains.kotlin.library.uniqueName
|
||||||
|
|
||||||
internal fun determineLinkerOutput(context: PhaseContext): LinkerOutputKind =
|
internal fun determineLinkerOutput(context: PhaseContext): LinkerOutputKind =
|
||||||
when (context.config.produce) {
|
when (context.config.produce) {
|
||||||
@@ -144,15 +146,33 @@ internal fun runLinkerCommands(context: PhaseContext, commands: List<Command>, c
|
|||||||
it.execute()
|
it.execute()
|
||||||
}
|
}
|
||||||
} catch (e: KonanExternalToolFailure) {
|
} catch (e: KonanExternalToolFailure) {
|
||||||
val extraUserInfo =
|
val extraUserInfo = if (cachingInvolved)
|
||||||
if (cachingInvolved)
|
"""
|
||||||
"""
|
Please try to disable compiler caches and rerun the build. To disable compiler caches, add the following line to the gradle.properties file in the project's root directory:
|
||||||
Please try to disable compiler caches and rerun the build. To disable compiler caches, add the following line to the gradle.properties file in the project's root directory:
|
|
||||||
|
kotlin.native.cacheKind.${context.config.target.presetName}=none
|
||||||
kotlin.native.cacheKind.${context.config.target.presetName}=none
|
|
||||||
|
Also, consider filing an issue with full Gradle log here: https://kotl.in/issue
|
||||||
Also, consider filing an issue with full Gradle log here: https://kotl.in/issue
|
""".trimIndent()
|
||||||
""".trimIndent()
|
else null
|
||||||
else ""
|
|
||||||
context.reportCompilationError("${e.toolName} invocation reported errors\n$extraUserInfo\n${e.message}")
|
val extraUserSetupInfo = run {
|
||||||
|
context.config.resolvedLibraries.getFullResolvedList()
|
||||||
|
.filter { it.library.isInterop }
|
||||||
|
.mapNotNull { library ->
|
||||||
|
library.library.manifestProperties["userSetupHint"]?.let {
|
||||||
|
"From ${library.library.uniqueName}:\n$it".takeIf { it.isNotEmpty() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mapIndexed { index, message -> "$index. $message" }
|
||||||
|
.takeIf { it.isNotEmpty() }
|
||||||
|
?.joinToString(separator = "\n\n")
|
||||||
|
?.let {
|
||||||
|
"It seems your project produced link errors.\nProposed solutions:\n\n$it\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val extraInfo = listOfNotNull(extraUserInfo, extraUserSetupInfo).joinToString(separator = "\n")
|
||||||
|
|
||||||
|
context.reportCompilationError("${e.toolName} invocation reported errors\n$extraInfo\n${e.message}")
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
headerFilter = **/userSetupHint.h
|
||||||
|
userSetupHint = 🤌\t\u2115ever put ketchup on-a 🍝\
|
||||||
|
\nℕ = `\u2115` = "\u2115" = \\u2115\
|
||||||
|
\n🇮🇹
|
||||||
|
---
|
||||||
|
void foo();
|
||||||
|
|
||||||
|
void test() {
|
||||||
|
foo();
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import userSetupFancyHint.*
|
||||||
|
|
||||||
|
fun userSetupHint(args: Array<String>) {
|
||||||
|
test()
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define EXPORT extern "C"
|
||||||
|
#else
|
||||||
|
#define EXPORT
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import userSetupHint1.*
|
||||||
|
import userSetupHint2.*
|
||||||
|
|
||||||
|
fun userSetupHint(args: Array<String>) {
|
||||||
|
testFoo()
|
||||||
|
testBar()
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#import "userSetupHint.h"
|
||||||
|
|
||||||
|
EXPORT void foo() {
|
||||||
|
// this just needs to exist
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
headerFilter = **/userSetupHint.h
|
||||||
|
userSetupHint = <<HINT1>>
|
||||||
|
---
|
||||||
|
void foo(void);
|
||||||
|
|
||||||
|
void testFoo() {
|
||||||
|
foo();
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#import "userSetupHint.h"
|
||||||
|
|
||||||
|
EXPORT void bar() {
|
||||||
|
// this just needs to exist
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
headerFilter = **/userSetupHint.h
|
||||||
|
userSetupHint = <<HINT2>>
|
||||||
|
---
|
||||||
|
void bar(void);
|
||||||
|
|
||||||
|
void testBar() {
|
||||||
|
bar();
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
headerFilter = **/userSetupHint.h
|
||||||
|
userSetupHint = <<HINT_MISSING_LIBRARY>>
|
||||||
|
linkerOpts = -lNonExistant
|
||||||
|
---
|
||||||
|
void test() { }
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
import userSetupHintLinkingMissingLibrary.*
|
||||||
|
|
||||||
|
fun userSetupHint(args: Array<String>) {
|
||||||
|
test()
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
headerFilter = **/userSetupHint.h
|
||||||
|
---
|
||||||
|
void foo(void);
|
||||||
|
|
||||||
|
void test() {
|
||||||
|
foo();
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import userSetupNoHint.*
|
||||||
|
|
||||||
|
fun userSetupHint(args: Array<String>) {
|
||||||
|
test()
|
||||||
|
}
|
||||||
+54
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.konan.blackboxtest
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.*
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.*
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.runner.TestRunChecks
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.KotlinNativeTargets
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.settings.Timeouts
|
||||||
|
|
||||||
|
@EnforcedProperty(ClassLevelProperty.COMPILER_OUTPUT_INTERCEPTOR, "NONE")
|
||||||
|
abstract class AbstractNativeLinkerOutputTest : AbstractNativeCInteropBaseTest() {
|
||||||
|
private fun createTestCaseNoTestRun(module: TestModule.Exclusive, compilerArgs: TestCompilerArgs) = TestCase(
|
||||||
|
id = TestCaseId.Named(module.name),
|
||||||
|
kind = TestKind.STANDALONE_NO_TR,
|
||||||
|
modules = setOf(module),
|
||||||
|
freeCompilerArgs = compilerArgs,
|
||||||
|
nominalPackageName = PackageName.EMPTY,
|
||||||
|
checks = TestRunChecks.Default(testRunSettings.get<Timeouts>().executionTimeout),
|
||||||
|
extras = TestCase.NoTestRunnerExtras(".${module.name}")
|
||||||
|
).apply {
|
||||||
|
initialize(null, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun compileToExecutable(
|
||||||
|
module: TestModule.Exclusive,
|
||||||
|
dependencies: List<TestCompilationDependency<*>>,
|
||||||
|
args: List<String> = emptyList()
|
||||||
|
) = compileToExecutable(
|
||||||
|
createTestCaseNoTestRun(module, TestCompilerArgs(args)),
|
||||||
|
dependencies
|
||||||
|
)
|
||||||
|
|
||||||
|
internal fun compileToExecutable(
|
||||||
|
testCase: TestCase,
|
||||||
|
dependencies: List<TestCompilationDependency<*>>
|
||||||
|
): TestCompilationResult<out TestCompilationArtifact.Executable> {
|
||||||
|
val compilation = ExecutableCompilation(
|
||||||
|
settings = testRunSettings,
|
||||||
|
freeCompilerArgs = testCase.freeCompilerArgs,
|
||||||
|
sourceModules = testCase.modules,
|
||||||
|
extras = TestCase.NoTestRunnerExtras(".${testCase.modules.singleOrNull()!!.name}"),
|
||||||
|
dependencies = dependencies,
|
||||||
|
expectedArtifact = getExecutableArtifact()
|
||||||
|
)
|
||||||
|
return compilation.result
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getExecutableArtifact() =
|
||||||
|
TestCompilationArtifact.Executable(buildDir.resolve("app." + testRunSettings.get<KotlinNativeTargets>().testTarget.family.exeSuffix))
|
||||||
|
}
|
||||||
+177
@@ -0,0 +1,177 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.konan.blackboxtest
|
||||||
|
|
||||||
|
import com.intellij.testFramework.TestDataPath
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.*
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationArtifact
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationArtifact.KLIB
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationResult
|
||||||
|
import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationResult.Companion.assertSuccess
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import java.io.File
|
||||||
|
import kotlin.test.assertContains
|
||||||
|
import kotlin.test.assertFalse
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
@TestDataPath("\$PROJECT_ROOT")
|
||||||
|
@EnforcedProperty(ClassLevelProperty.COMPILER_OUTPUT_INTERCEPTOR, "NONE")
|
||||||
|
class LinkerOutputTestKT55578 : AbstractNativeLinkerOutputTest() {
|
||||||
|
private val testDir = File("native/native.tests/testData/CInterop/KT-55578/")
|
||||||
|
|
||||||
|
private val hint1 = "<<HINT1>>"
|
||||||
|
private val hint2 = "<<HINT2>>"
|
||||||
|
private val cliHint = "<<CLI>>"
|
||||||
|
private val hintMissingLibrary = "<<HINT_MISSING_LIBRARY>>"
|
||||||
|
private val hintFancy = "\uD83E\uDD0C\tℕever put ketchup on-a \uD83C\uDF5D\nℕ = `ℕ` = \"\\u2115\" = \\u2115\n\uD83C\uDDEE\uD83C\uDDF9\n"
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should print hints on failed linkage`() {
|
||||||
|
val targetLibrary1 = compileKlib(testDir.resolve("userSetupHint1.def"))
|
||||||
|
val targetLibrary2 = compileKlib(testDir.resolve("userSetupHint2.def"))
|
||||||
|
|
||||||
|
val compilationResult = compileExecutable(testDir.resolve("userSetupHint.kt"), targetLibrary1, targetLibrary2)
|
||||||
|
assertTrue(compilationResult is TestCompilationResult.Failure, "Compilation is expected to fail with linkage errors")
|
||||||
|
val compilationOutput = compilationResult.loggedData.toString()
|
||||||
|
|
||||||
|
for (hint in arrayOf(hint1, hint2)) {
|
||||||
|
assertContains(compilationOutput, hint, false, """
|
||||||
|
|Error output should contain provided hint "$hint"
|
||||||
|
|Actual output:
|
||||||
|
|$compilationOutput
|
||||||
|
""".trimMargin())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should print fancy hints`() {
|
||||||
|
val targetLibrary = compileKlib(testDir.resolve("userSetupFancyHint.def"))
|
||||||
|
|
||||||
|
val compilationResult = compileExecutable(testDir.resolve("userSetupFancyHint.kt"), targetLibrary)
|
||||||
|
assertTrue(compilationResult is TestCompilationResult.Failure, "Compilation is expected to fail with linkage errors")
|
||||||
|
val compilationOutput = compilationResult.loggedData.toString()
|
||||||
|
|
||||||
|
assertContains(compilationOutput, hintFancy, false, """
|
||||||
|
|Error output should contain provided hint
|
||||||
|
|Actual output:
|
||||||
|
|$compilationOutput
|
||||||
|
""".trimMargin())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should print hints on missing library`() {
|
||||||
|
val targetLibrary = compileKlib(testDir.resolve("userSetupHintLinkingMissingLibrary.def"))
|
||||||
|
|
||||||
|
val compilationResult = compileExecutable(testDir.resolve("userSetupHintLinkingMissingLibrary.kt"), targetLibrary)
|
||||||
|
assertTrue(compilationResult is TestCompilationResult.Failure, "Compilation is expected to fail with linkage errors")
|
||||||
|
val compilationOutput = compilationResult.loggedData.toString()
|
||||||
|
|
||||||
|
for (hint in arrayOf(hintMissingLibrary)) {
|
||||||
|
assertContains(compilationOutput, hint, false, """
|
||||||
|
|Error output should contain provided hint "$hint"
|
||||||
|
|Actual output:
|
||||||
|
|$compilationOutput
|
||||||
|
""".trimMargin())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun `should not print hints on successful compilation`() {
|
||||||
|
val targetLibrary1 = compileKlib(
|
||||||
|
testDir.resolve("userSetupHint1.def"),
|
||||||
|
testDir.resolve("userSetupHint1.c")
|
||||||
|
)
|
||||||
|
val targetLibrary2 = compileKlib(
|
||||||
|
testDir.resolve("userSetupHint2.def"),
|
||||||
|
testDir.resolve("userSetupHint2.c")
|
||||||
|
)
|
||||||
|
|
||||||
|
val compilationResult = compileExecutable(
|
||||||
|
testDir.resolve("userSetupHint.kt"),
|
||||||
|
targetLibrary1, targetLibrary2
|
||||||
|
)
|
||||||
|
val compilationOutput = compilationResult.assertSuccess().loggedData.toString()
|
||||||
|
|
||||||
|
for (hint in arrayOf(hint1, hint2)) {
|
||||||
|
assertFalse(compilationOutput.contains(hint), """
|
||||||
|
|Error output should *not* contain provided hint "$hint"
|
||||||
|
|Actual output:
|
||||||
|
|$compilationOutput
|
||||||
|
""".trimMargin())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should not print hints on compilation failed without linker errors`() {
|
||||||
|
val targetLibrary1 = compileKlib(
|
||||||
|
testDir.resolve("userSetupHint1.def"),
|
||||||
|
testDir.resolve("userSetupHint1.c")
|
||||||
|
)
|
||||||
|
|
||||||
|
val compilationResult = compileExecutable(testDir.resolve("userSetupHint.kt"), targetLibrary1)
|
||||||
|
assertTrue(compilationResult is TestCompilationResult.Failure, "Compilation is expected to fail")
|
||||||
|
val compilationOutput = compilationResult.loggedData.toString()
|
||||||
|
|
||||||
|
for (hint in arrayOf(hint1, hint2)) {
|
||||||
|
assertFalse(compilationOutput.contains(hint), """
|
||||||
|
|Error output should *not* contain provided hint "$hint"
|
||||||
|
|Actual output:
|
||||||
|
|$compilationOutput
|
||||||
|
""".trimMargin())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should shadow hint by cli argument`() {
|
||||||
|
val targetLibrary1 = compileKlib(testDir.resolve("userSetupHint1.def"), extraArgs = listOf("-Xuser-setup-hint", cliHint))
|
||||||
|
val targetLibrary2 = compileKlib(testDir.resolve("userSetupHint2.def"))
|
||||||
|
|
||||||
|
val compilationResult = compileExecutable(testDir.resolve("userSetupHint.kt"), targetLibrary1, targetLibrary2)
|
||||||
|
assertTrue(compilationResult is TestCompilationResult.Failure, "Compilation is expected to fail")
|
||||||
|
val compilationOutput = compilationResult.loggedData.toString()
|
||||||
|
|
||||||
|
for (hint in arrayOf(cliHint, hint2)) {
|
||||||
|
assertContains(compilationOutput, hint, false, """
|
||||||
|
|Error output should contain provided hint "$hint"
|
||||||
|
|Actual output:
|
||||||
|
|$compilationOutput
|
||||||
|
""".trimMargin())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should not print hints on compilation failed with no provided hints`() {
|
||||||
|
val targetLibrary = compileKlib(testDir.resolve("userSetupNoHint.def"))
|
||||||
|
|
||||||
|
val compilationResult = compileExecutable(testDir.resolve("userSetupNoHint.kt"), targetLibrary)
|
||||||
|
assertTrue(compilationResult is TestCompilationResult.Failure, "Compilation is expected to fail")
|
||||||
|
val compilationOutput = compilationResult.loggedData.toString()
|
||||||
|
|
||||||
|
assertFalse(compilationOutput.contains("It seems your project produced link errors."), """
|
||||||
|
|Error output should *not* contain any hints
|
||||||
|
|Actual output:
|
||||||
|
|$compilationOutput
|
||||||
|
""".trimMargin())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun compileExecutable(
|
||||||
|
file: File,
|
||||||
|
vararg libraries: KLIB,
|
||||||
|
extraArgs: List<String> = emptyList()
|
||||||
|
): TestCompilationResult<out TestCompilationArtifact.Executable> {
|
||||||
|
val module = TestModule.Exclusive("userSetupHint", emptySet(), emptySet(), emptySet()).apply {
|
||||||
|
files += TestFile.createCommitted(file, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
return compileToExecutable(module, libraries.asList().map { it.asLibraryDependency() }, extraArgs)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun compileKlib(defFile: File, sourceFile: File? = null, extraArgs: List<String> = emptyList()): KLIB {
|
||||||
|
val sourceArguments = sourceFile?.let { listOf("-Xcompile-source", sourceFile.absolutePath) } ?: emptyList()
|
||||||
|
val libraryTestCase: TestCase = generateCInteropTestCaseWithSingleDef(defFile, extraArgs + sourceArguments)
|
||||||
|
return libraryTestCase.cinteropToLibrary().assertSuccess().resultingArtifact
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -135,6 +135,10 @@ class DefFile(val file:File?, val config:DefFileConfig, val manifestAddendProper
|
|||||||
val objcClassesIncludingCategories by lazy {
|
val objcClassesIncludingCategories by lazy {
|
||||||
properties.getSpaceSeparated("objcClassesIncludingCategories")
|
properties.getSpaceSeparated("objcClassesIncludingCategories")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val userSetupHint by lazy {
|
||||||
|
properties.getProperty("userSetupHint")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user