[Coverage]Enable code coverage for linux_x64 and mingw_x64
This commit is contained in:
committed by
Sergey Bogolepov
parent
4782c2adeb
commit
8622eb3be4
+1
-2
@@ -3,10 +3,9 @@ Kotlin/Native has a code coverage support that is based on Clang's
|
|||||||
[Source-based Code Coverage](https://clang.llvm.org/docs/SourceBasedCodeCoverage.html).
|
[Source-based Code Coverage](https://clang.llvm.org/docs/SourceBasedCodeCoverage.html).
|
||||||
|
|
||||||
**Please note**:
|
**Please note**:
|
||||||
1. Coverage support is in it's very early days and is in active development. Known issues and restrictions are:
|
1. Coverage support is in it's very early days and is in active development. Known issues are:
|
||||||
* Coverage information may be inaccurate.
|
* Coverage information may be inaccurate.
|
||||||
* Line execution counts may be wrong.
|
* Line execution counts may be wrong.
|
||||||
* Only macOS and iOS simulator binaries are supported.
|
|
||||||
|
|
||||||
2. Most of described functionality will be incorporated into Gradle plugin.
|
2. Most of described functionality will be incorporated into Gradle plugin.
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -79,6 +79,8 @@ internal class Linker(val context: Context) {
|
|||||||
executable = dylibPath.absolutePath
|
executable = dylibPath.absolutePath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val needsProfileLibrary = context.coverage.enabled
|
||||||
|
|
||||||
try {
|
try {
|
||||||
File(executable).delete()
|
File(executable).delete()
|
||||||
linker.linkCommands(objectFiles = objectFiles, executable = executable,
|
linker.linkCommands(objectFiles = objectFiles, executable = executable,
|
||||||
@@ -87,7 +89,8 @@ internal class Linker(val context: Context) {
|
|||||||
BitcodeEmbedding.getLinkerOptions(context.config) +
|
BitcodeEmbedding.getLinkerOptions(context.config) +
|
||||||
libraryProvidedLinkerFlags + frameworkLinkerArgs,
|
libraryProvidedLinkerFlags + frameworkLinkerArgs,
|
||||||
optimize = optimize, debug = debug, kind = linkerOutput,
|
optimize = optimize, debug = debug, kind = linkerOutput,
|
||||||
outputDsymBundle = context.config.outputFile + ".dSYM").forEach {
|
outputDsymBundle = context.config.outputFile + ".dSYM",
|
||||||
|
needsProfileLibrary = needsProfileLibrary).forEach {
|
||||||
it.logWith(context::log)
|
it.logWith(context::log)
|
||||||
it.execute()
|
it.execute()
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFile
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||||
import org.jetbrains.kotlin.konan.file.File
|
import org.jetbrains.kotlin.konan.file.File
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
import org.jetbrains.kotlin.konan.target.supportsCodeCoverage
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,14 +43,14 @@ internal class CoverageManager(val context: Context) {
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
if (enabled && !checkRestrictions()) {
|
if (enabled && !checkRestrictions()) {
|
||||||
context.reportCompilationError("Coverage is only supported for macOS and iOS simulator binaries for now.")
|
context.reportCompilationError("Coverage is not supported for ${context.config.target}.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkRestrictions(): Boolean {
|
private fun checkRestrictions(): Boolean {
|
||||||
val isKindAllowed = context.config.produce.involvesBitcodeGeneration
|
val isKindAllowed = context.config.produce.involvesBitcodeGeneration
|
||||||
val target = context.config.target
|
val target = context.config.target
|
||||||
val isTargetAllowed = target == KonanTarget.MACOS_X64 || target == KonanTarget.IOS_X64
|
val isTargetAllowed = target.supportsCodeCoverage()
|
||||||
return isKindAllowed && isTargetAllowed
|
return isKindAllowed && isTargetAllowed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3756,7 +3756,7 @@ KotlinNativeTestKt.createTest(project, 'harmonyRegexTest', KonanGTest) { task ->
|
|||||||
|
|
||||||
standaloneTest("coverage_basic_program") {
|
standaloneTest("coverage_basic_program") {
|
||||||
|
|
||||||
disabled = PlatformInfo.getTarget(project).name != "ios_x64" && PlatformInfo.getTarget(project).name != "macos_x64"
|
disabled = !UtilsKt.testTargetSupportsCodeCoverage(project)
|
||||||
|
|
||||||
description = "Test that `-Xcoverage` generates correct __llvm_coverage information"
|
description = "Test that `-Xcoverage` generates correct __llvm_coverage information"
|
||||||
|
|
||||||
@@ -3783,7 +3783,7 @@ standaloneTest("coverage_basic_program") {
|
|||||||
|
|
||||||
standaloneTest("coverage_basic_library") {
|
standaloneTest("coverage_basic_library") {
|
||||||
|
|
||||||
disabled = PlatformInfo.getTarget(project).name != "ios_x64" && PlatformInfo.getTarget(project).name != "macos_x64"
|
disabled = !UtilsKt.testTargetSupportsCodeCoverage(project)
|
||||||
|
|
||||||
description = "Test that `-Xlibrary-to-cover` generates correct __llvm_coverage information"
|
description = "Test that `-Xlibrary-to-cover` generates correct __llvm_coverage information"
|
||||||
|
|
||||||
|
|||||||
@@ -7,10 +7,7 @@ package org.jetbrains.kotlin
|
|||||||
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.Task
|
import org.gradle.api.Task
|
||||||
import org.jetbrains.kotlin.konan.target.AppleConfigurables
|
import org.jetbrains.kotlin.konan.target.*
|
||||||
import org.jetbrains.kotlin.konan.target.HostManager
|
|
||||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
|
||||||
import org.jetbrains.kotlin.konan.target.PlatformManager
|
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -54,6 +51,9 @@ val Project.globalTestArgs: List<String>
|
|||||||
fun Project.platformManager() = findProperty("platformManager") as PlatformManager
|
fun Project.platformManager() = findProperty("platformManager") as PlatformManager
|
||||||
fun Project.testTarget() = findProperty("target") as KonanTarget
|
fun Project.testTarget() = findProperty("target") as KonanTarget
|
||||||
|
|
||||||
|
fun Project.testTargetSupportsCodeCoverage(): Boolean =
|
||||||
|
this.testTarget.supportsCodeCoverage()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ad-hoc signing of the specified path.
|
* Ad-hoc signing of the specified path.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package org.jetbrains.kotlin.konan.target
|
||||||
|
|
||||||
|
fun KonanTarget.supportsCodeCoverage(): Boolean =
|
||||||
|
this == KonanTarget.MINGW_X64 ||
|
||||||
|
this == KonanTarget.LINUX_X64 ||
|
||||||
|
this == KonanTarget.MACOS_X64 ||
|
||||||
|
this == KonanTarget.IOS_X64
|
||||||
@@ -75,10 +75,12 @@ abstract class LinkerFlags(val configurables: Configurables)
|
|||||||
|
|
||||||
open val useCompilerDriverAsLinker: Boolean get() = false // TODO: refactor.
|
open val useCompilerDriverAsLinker: Boolean get() = false // TODO: refactor.
|
||||||
|
|
||||||
|
// TODO: Number of arguments is quite big. Better to pass args via object.
|
||||||
abstract fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
abstract fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
||||||
libraries: List<String>, linkerArgs: List<String>,
|
libraries: List<String>, linkerArgs: List<String>,
|
||||||
optimize: Boolean, debug: Boolean,
|
optimize: Boolean, debug: Boolean,
|
||||||
kind: LinkerOutputKind, outputDsymBundle: String): List<Command>
|
kind: LinkerOutputKind, outputDsymBundle: String,
|
||||||
|
needsProfileLibrary: Boolean): List<Command>
|
||||||
|
|
||||||
abstract fun filterStaticLibraries(binaries: List<String>): List<String>
|
abstract fun filterStaticLibraries(binaries: List<String>): List<String>
|
||||||
|
|
||||||
@@ -87,6 +89,16 @@ abstract class LinkerFlags(val configurables: Configurables)
|
|||||||
// Let's just pass them as absolute paths.
|
// Let's just pass them as absolute paths.
|
||||||
return libraries
|
return libraries
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open fun provideCompilerRtLibrary(libraryName: String): String? {
|
||||||
|
System.err.println("Can't provide $libraryName.")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code coverage requires this library.
|
||||||
|
protected val profileLibrary: String? by lazy {
|
||||||
|
provideCompilerRtLibrary("profile")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open class AndroidLinker(targetProperties: AndroidConfigurables)
|
open class AndroidLinker(targetProperties: AndroidConfigurables)
|
||||||
@@ -107,7 +119,8 @@ open class AndroidLinker(targetProperties: AndroidConfigurables)
|
|||||||
override fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
override fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
||||||
libraries: List<String>, linkerArgs: List<String>,
|
libraries: List<String>, linkerArgs: List<String>,
|
||||||
optimize: Boolean, debug: Boolean,
|
optimize: Boolean, debug: Boolean,
|
||||||
kind: LinkerOutputKind, outputDsymBundle: String): List<Command> {
|
kind: LinkerOutputKind, outputDsymBundle: String,
|
||||||
|
needsProfileLibrary: Boolean): List<Command> {
|
||||||
if (kind == LinkerOutputKind.STATIC_LIBRARY)
|
if (kind == LinkerOutputKind.STATIC_LIBRARY)
|
||||||
return staticGnuArCommands(ar, executable, objectFiles, libraries)
|
return staticGnuArCommands(ar, executable, objectFiles, libraries)
|
||||||
|
|
||||||
@@ -153,7 +166,7 @@ open class MacOSBasedLinker(targetProperties: AppleConfigurables)
|
|||||||
get() = this == KonanTarget.TVOS_X64 || this == KonanTarget.IOS_X64 ||
|
get() = this == KonanTarget.TVOS_X64 || this == KonanTarget.IOS_X64 ||
|
||||||
this == KonanTarget.WATCHOS_X86 || this == KonanTarget.WATCHOS_X64
|
this == KonanTarget.WATCHOS_X86 || this == KonanTarget.WATCHOS_X64
|
||||||
|
|
||||||
private fun provideCompilerRtLibrary(libraryName: String): String? {
|
override fun provideCompilerRtLibrary(libraryName: String): String? {
|
||||||
val prefix = when (target.family) {
|
val prefix = when (target.family) {
|
||||||
Family.IOS -> "ios"
|
Family.IOS -> "ios"
|
||||||
Family.WATCHOS -> "watchos"
|
Family.WATCHOS -> "watchos"
|
||||||
@@ -173,15 +186,6 @@ open class MacOSBasedLinker(targetProperties: AppleConfigurables)
|
|||||||
return if (dir != null) "$dir/lib/darwin/libclang_rt.$mangledLibraryName$prefix$suffix.a" else null
|
return if (dir != null) "$dir/lib/darwin/libclang_rt.$mangledLibraryName$prefix$suffix.a" else null
|
||||||
}
|
}
|
||||||
|
|
||||||
private val compilerRtLibrary: String? by lazy {
|
|
||||||
provideCompilerRtLibrary("")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Code coverage requires this library.
|
|
||||||
private val profileLibrary: String? by lazy {
|
|
||||||
provideCompilerRtLibrary("profile")
|
|
||||||
}
|
|
||||||
|
|
||||||
private val osVersionMinFlags: List<String> by lazy {
|
private val osVersionMinFlags: List<String> by lazy {
|
||||||
listOf(osVersionMinFlagLd, osVersionMin + ".0")
|
listOf(osVersionMinFlagLd, osVersionMin + ".0")
|
||||||
}
|
}
|
||||||
@@ -191,7 +195,8 @@ open class MacOSBasedLinker(targetProperties: AppleConfigurables)
|
|||||||
override fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
override fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
||||||
libraries: List<String>, linkerArgs: List<String>,
|
libraries: List<String>, linkerArgs: List<String>,
|
||||||
optimize: Boolean, debug: Boolean, kind: LinkerOutputKind,
|
optimize: Boolean, debug: Boolean, kind: LinkerOutputKind,
|
||||||
outputDsymBundle: String): List<Command> {
|
outputDsymBundle: String,
|
||||||
|
needsProfileLibrary: Boolean): List<Command> {
|
||||||
if (kind == LinkerOutputKind.STATIC_LIBRARY)
|
if (kind == LinkerOutputKind.STATIC_LIBRARY)
|
||||||
return listOf(Command(libtool).apply {
|
return listOf(Command(libtool).apply {
|
||||||
+"-static"
|
+"-static"
|
||||||
@@ -214,7 +219,7 @@ open class MacOSBasedLinker(targetProperties: AppleConfigurables)
|
|||||||
if (dynamic) +linkerDynamicFlags
|
if (dynamic) +linkerDynamicFlags
|
||||||
+linkerKonanFlags
|
+linkerKonanFlags
|
||||||
if (compilerRtLibrary != null) +compilerRtLibrary!!
|
if (compilerRtLibrary != null) +compilerRtLibrary!!
|
||||||
if (profileLibrary != null) +profileLibrary!!
|
if (needsProfileLibrary) +profileLibrary!!
|
||||||
+libraries
|
+libraries
|
||||||
+linkerArgs
|
+linkerArgs
|
||||||
+rpath(dynamic)
|
+rpath(dynamic)
|
||||||
@@ -231,6 +236,10 @@ open class MacOSBasedLinker(targetProperties: AppleConfigurables)
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val compilerRtLibrary: String? by lazy {
|
||||||
|
provideCompilerRtLibrary("")
|
||||||
|
}
|
||||||
|
|
||||||
private fun rpath(dynamic: Boolean): List<String> = listOfNotNull(
|
private fun rpath(dynamic: Boolean): List<String> = listOfNotNull(
|
||||||
when (target.family) {
|
when (target.family) {
|
||||||
Family.OSX -> "@executable_path/../Frameworks"
|
Family.OSX -> "@executable_path/../Frameworks"
|
||||||
@@ -295,12 +304,22 @@ open class LinuxBasedLinker(targetProperties: LinuxBasedConfigurables)
|
|||||||
private val linker = "$absoluteLlvmHome/bin/ld.lld"
|
private val linker = "$absoluteLlvmHome/bin/ld.lld"
|
||||||
private val specificLibs = abiSpecificLibraries.map { "-L${absoluteTargetSysRoot}/$it" }
|
private val specificLibs = abiSpecificLibraries.map { "-L${absoluteTargetSysRoot}/$it" }
|
||||||
|
|
||||||
|
override fun provideCompilerRtLibrary(libraryName: String): String? {
|
||||||
|
val targetSuffix = when (target) {
|
||||||
|
KonanTarget.LINUX_X64 -> "x86_64"
|
||||||
|
else -> error("$target is not supported.")
|
||||||
|
}
|
||||||
|
val dir = File("$absoluteLlvmHome/lib/clang/").listFiles.firstOrNull()?.absolutePath
|
||||||
|
return if (dir != null) "$dir/lib/linux/libclang_rt.$libraryName-$targetSuffix.a" else null
|
||||||
|
}
|
||||||
|
|
||||||
override fun filterStaticLibraries(binaries: List<String>) = binaries.filter { it.isUnixStaticLib }
|
override fun filterStaticLibraries(binaries: List<String>) = binaries.filter { it.isUnixStaticLib }
|
||||||
|
|
||||||
override fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
override fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
||||||
libraries: List<String>, linkerArgs: List<String>,
|
libraries: List<String>, linkerArgs: List<String>,
|
||||||
optimize: Boolean, debug: Boolean,
|
optimize: Boolean, debug: Boolean,
|
||||||
kind: LinkerOutputKind, outputDsymBundle: String): List<Command> {
|
kind: LinkerOutputKind, outputDsymBundle: String,
|
||||||
|
needsProfileLibrary: Boolean): List<Command> {
|
||||||
if (kind == LinkerOutputKind.STATIC_LIBRARY)
|
if (kind == LinkerOutputKind.STATIC_LIBRARY)
|
||||||
return staticGnuArCommands(ar, executable, objectFiles, libraries)
|
return staticGnuArCommands(ar, executable, objectFiles, libraries)
|
||||||
|
|
||||||
@@ -331,6 +350,9 @@ open class LinuxBasedLinker(targetProperties: LinuxBasedConfigurables)
|
|||||||
if (!debug) +linkerNoDebugFlags
|
if (!debug) +linkerNoDebugFlags
|
||||||
if (dynamic) +linkerDynamicFlags
|
if (dynamic) +linkerDynamicFlags
|
||||||
+objectFiles
|
+objectFiles
|
||||||
|
// See explanation about `-u__llvm_profile_runtime` here:
|
||||||
|
// https://github.com/llvm/llvm-project/blob/21e270a479a24738d641e641115bce6af6ed360a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp#L930
|
||||||
|
if (needsProfileLibrary) +listOf("-u__llvm_profile_runtime", profileLibrary!!)
|
||||||
+linkerKonanFlags
|
+linkerKonanFlags
|
||||||
+listOf("-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed",
|
+listOf("-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed",
|
||||||
"-lc", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed")
|
"-lc", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed")
|
||||||
@@ -352,10 +374,20 @@ open class MingwLinker(targetProperties: MingwConfigurables)
|
|||||||
|
|
||||||
override fun filterStaticLibraries(binaries: List<String>) = binaries.filter { it.isWindowsStaticLib || it.isUnixStaticLib }
|
override fun filterStaticLibraries(binaries: List<String>) = binaries.filter { it.isWindowsStaticLib || it.isUnixStaticLib }
|
||||||
|
|
||||||
|
override fun provideCompilerRtLibrary(libraryName: String): String? {
|
||||||
|
val targetSuffix = when (target) {
|
||||||
|
KonanTarget.MINGW_X64 -> "x86_64"
|
||||||
|
else -> error("$target is not supported.")
|
||||||
|
}
|
||||||
|
val dir = File("$absoluteLlvmHome/lib/clang/").listFiles.firstOrNull()?.absolutePath
|
||||||
|
return if (dir != null) "$dir/lib/windows/libclang_rt.$libraryName-$targetSuffix.a" else null
|
||||||
|
}
|
||||||
|
|
||||||
override fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
override fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
||||||
libraries: List<String>, linkerArgs: List<String>,
|
libraries: List<String>, linkerArgs: List<String>,
|
||||||
optimize: Boolean, debug: Boolean,
|
optimize: Boolean, debug: Boolean,
|
||||||
kind: LinkerOutputKind, outputDsymBundle: String): List<Command> {
|
kind: LinkerOutputKind, outputDsymBundle: String,
|
||||||
|
needsProfileLibrary: Boolean): List<Command> {
|
||||||
if (kind == LinkerOutputKind.STATIC_LIBRARY)
|
if (kind == LinkerOutputKind.STATIC_LIBRARY)
|
||||||
return staticGnuArCommands(ar, executable, objectFiles, libraries)
|
return staticGnuArCommands(ar, executable, objectFiles, libraries)
|
||||||
|
|
||||||
@@ -366,10 +398,14 @@ open class MingwLinker(targetProperties: MingwConfigurables)
|
|||||||
}.apply {
|
}.apply {
|
||||||
+listOf("-o", executable)
|
+listOf("-o", executable)
|
||||||
+objectFiles
|
+objectFiles
|
||||||
if (optimize) +linkerOptimizationFlags
|
// --gc-sections flag may affect profiling.
|
||||||
|
// See https://clang.llvm.org/docs/SourceBasedCodeCoverage.html#drawbacks-and-limitations.
|
||||||
|
// TODO: switching to lld may help.
|
||||||
|
if (optimize && !needsProfileLibrary) +linkerOptimizationFlags
|
||||||
if (!debug) +linkerNoDebugFlags
|
if (!debug) +linkerNoDebugFlags
|
||||||
if (dynamic) +linkerDynamicFlags
|
if (dynamic) +linkerDynamicFlags
|
||||||
+libraries
|
+libraries
|
||||||
|
if (needsProfileLibrary) +profileLibrary!!
|
||||||
+linkerArgs
|
+linkerArgs
|
||||||
+linkerKonanFlags
|
+linkerKonanFlags
|
||||||
})
|
})
|
||||||
@@ -386,7 +422,8 @@ open class WasmLinker(targetProperties: WasmConfigurables)
|
|||||||
override fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
override fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
||||||
libraries: List<String>, linkerArgs: List<String>,
|
libraries: List<String>, linkerArgs: List<String>,
|
||||||
optimize: Boolean, debug: Boolean,
|
optimize: Boolean, debug: Boolean,
|
||||||
kind: LinkerOutputKind, outputDsymBundle: String): List<Command> {
|
kind: LinkerOutputKind, outputDsymBundle: String,
|
||||||
|
needsProfileLibrary: Boolean): List<Command> {
|
||||||
if (kind != LinkerOutputKind.EXECUTABLE) throw Error("Unsupported linker output kind")
|
if (kind != LinkerOutputKind.EXECUTABLE) throw Error("Unsupported linker output kind")
|
||||||
|
|
||||||
// TODO(horsh): maybe rethink it.
|
// TODO(horsh): maybe rethink it.
|
||||||
@@ -433,7 +470,8 @@ open class ZephyrLinker(targetProperties: ZephyrConfigurables)
|
|||||||
override fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
override fun linkCommands(objectFiles: List<ObjectFile>, executable: ExecutableFile,
|
||||||
libraries: List<String>, linkerArgs: List<String>,
|
libraries: List<String>, linkerArgs: List<String>,
|
||||||
optimize: Boolean, debug: Boolean,
|
optimize: Boolean, debug: Boolean,
|
||||||
kind: LinkerOutputKind, outputDsymBundle: String): List<Command> {
|
kind: LinkerOutputKind, outputDsymBundle: String,
|
||||||
|
needsProfileLibrary: Boolean): List<Command> {
|
||||||
if (kind != LinkerOutputKind.EXECUTABLE) throw Error("Unsupported linker output kind: $kind")
|
if (kind != LinkerOutputKind.EXECUTABLE) throw Error("Unsupported linker output kind: $kind")
|
||||||
return listOf(Command(linker).apply {
|
return listOf(Command(linker).apply {
|
||||||
+listOf("-r", "--gc-sections", "--entry", "main")
|
+listOf("-r", "--gc-sections", "--entry", "main")
|
||||||
|
|||||||
Reference in New Issue
Block a user