Rework cinterop linkerOpts/compilerOpts (KT-29970) (#2841)

This commit is contained in:
LepilkinaElena
2019-04-02 16:56:01 +03:00
committed by GitHub
parent de90535386
commit 5a80eafec3
15 changed files with 99 additions and 34 deletions
@@ -59,10 +59,20 @@ fun getCInteropArguments(): List<OptionDescriptor> {
isMultiple = true, delimiter = ",", deprecatedWarning = "Option -h is deprecated. Please use -header."),
OptionDescriptor(ArgType.String(), HEADER_FILTER_ADDITIONAL_SEARCH_PREFIX, "hfasp",
"header file to produce kotlin bindings for", isMultiple = true, delimiter = ","),
OptionDescriptor(ArgType.String(), "compilerOpts", "copt",
"additional compiler options", isMultiple = true, delimiter = " "),
OptionDescriptor(ArgType.String(), "linkerOpts", "lopt",
"additional linker options", isMultiple = true, delimiter = " "),
OptionDescriptor(ArgType.String(), "compilerOpts",
description = "additional compiler options (allows to add several options separated by spaces)",
isMultiple = true, delimiter = " "),
OptionDescriptor(ArgType.String(), "linkerOpts",
description = "additional linker options (allows to add several options separated by spaces)",
isMultiple = true, delimiter = " "),
OptionDescriptor(ArgType.String(), "compilerOpt",
description = "additional compiler option", isMultiple = true),
OptionDescriptor(ArgType.String(), "linkerOpt",
description = "additional linker option", isMultiple = true),
OptionDescriptor(ArgType.String(), "copt", description = "additional compiler options (allows to add several options separated by spaces)",
isMultiple = true, delimiter = " ", deprecatedWarning = "Option -copt is deprecated. Please use -compilerOpts."),
OptionDescriptor(ArgType.String(), "lopt", description = "additional linker options (allows to add several options separated by spaces)",
isMultiple = true, delimiter = " ", deprecatedWarning = "Option -lopt is deprecated. Please use -linkerOpts."),
OptionDescriptor(ArgType.String(), "linker", description = "use specified linker")
)
return (options + getCommonInteropArguments())
@@ -176,12 +176,15 @@ private fun processCLib(args: Array<String>, additionalArgs: Map<String, Any> =
val tool = prepareTool(argParser.get<String>("target"), flavor)
val def = DefFile(defFile, tool.substitutions)
if (flavorName == "native" && argParser.getOrigin("linkerOpts") == ArgParser.ValueOrigin.SET_BY_USER) {
warn("-linkerOpts/-lopt option is not supported by cinterop. Please add linker options to .def file or binary compilation instead.")
val isLinkerOptsSetByUser = (argParser.getOrigin("linkerOpts") == ArgParser.ValueOrigin.SET_BY_USER) ||
(argParser.getOrigin("linkerOpt") == ArgParser.ValueOrigin.SET_BY_USER) ||
(argParser.getOrigin("lopt") == ArgParser.ValueOrigin.SET_BY_USER)
if (flavorName == "native" && isLinkerOptsSetByUser) {
warn("-linkerOpt(s)/-lopt option is not supported by cinterop. Please add linker options to .def file or binary compilation instead.")
}
val additionalLinkerOpts = argParser.getValuesAsArray("linkerOpts")
val additionalLinkerOpts = argParser.getValuesAsArray("linkerOpts") + argParser.getValuesAsArray("linkerOpt") +
argParser.getValuesAsArray("lopt")
val verbose = argParser.get<Boolean>("verbose")!!
val language = selectNativeLanguage(def.config)
@@ -302,7 +305,8 @@ internal fun buildNativeLibrary(
imports: ImportsImpl
): NativeLibrary {
val additionalHeaders = arguments.getValuesAsArray("header") + arguments.getValuesAsArray("h")
val additionalCompilerOpts = arguments.getValuesAsArray("compilerOpts")
val additionalCompilerOpts = arguments.getValuesAsArray("compilerOpts") + arguments.getValuesAsArray("compilerOpt") +
arguments.getValuesAsArray("copt")
val headerFiles = def.config.headers + additionalHeaders
val language = selectNativeLanguage(def.config)
@@ -121,8 +121,8 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
put(NOMAIN, arguments.nomain)
put(LIBRARY_FILES,
arguments.libraries.toNonNullList())
put(LINKER_ARGS, arguments.linkerArguments.toNonNullList())
put(LINKER_ARGS, arguments.linkerArguments.toNonNullList() +
arguments.singleLinkerArguments.toNonNullList())
arguments.moduleName ?. let{ put(MODULE_NAME, it) }
arguments.target ?.let{ put(TARGET, it) }
@@ -66,6 +66,9 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
@Argument(value="-linker-options", deprecatedName = "-linkerOpts", valueDescription = "<arg>", description = "Pass arguments to linker", delimiter = " ")
var linkerArguments: Array<String>? = null
@Argument(value="-linker-option", valueDescription = "<arg>", description = "Pass argument to linker", delimiter = "")
var singleLinkerArguments: Array<String>? = null
@Argument(value = "-nostdlib", description = "Don't link with stdlib")
var nostdlib: Boolean = false
+32
View File
@@ -2894,6 +2894,20 @@ task inline_defaultArgs_linkTest(type: LinkKonanTest) {
lib = "codegen/inline/defaultArgs_linkTest_lib.kt"
}
def generateWithSpaceDefFile() {
def file = new File("${buildDir}/withSpaces.def")
file.write """
headers = stdio.h "${projectDir}/interop/basics/custom headers/custom.h"
linkerOpts = -map "${buildDir}/cutom map.map"
---
int customCompare(const char* str1, const char* str2) {
return custom_strcmp(str1, str2);
}
"""
return file.absolutePath
}
kotlinNativeInterop {
target project.testTarget ?: 'host'
flavor 'native'
@@ -3050,6 +3064,24 @@ task interop_callbacksAndVarargs(type: RunInteropKonanTest) {
interop = 'ccallbacksAndVarargs'
}
task interop_withSpaces() {
dependsOn 'build'
konanArtifacts {
interop('withSpacesInterop') {
defFile generateWithSpaceDefFile()
}
program("withSpaces") {
srcDir "interop/basics/withSpaces.kt"
libraries {
artifact 'withSpacesInterop'
}
}
}
doLast {
assert file("${buildDir}/cutom map.map").exists()
}
}
task interop_echo_server(type: RunInteropKonanTest) {
disabled = isWasmTarget(project) || isWindowsTarget(project)
run = false
@@ -0,0 +1,7 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int custom_strcmp(const char* str1, const char* str2) {
return strcmp(str1, str2);
}
@@ -0,0 +1,12 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the LICENSE file.
*/
import kotlin.test.*
import kotlinx.cinterop.*
import withSpaces.*
fun main(args: Array<String>) {
customCompare("first", "second")
}
@@ -247,8 +247,8 @@ class NamedNativeInteropConfig implements Named {
environment['PATH'] = project.files(project.hostPlatform.clang.clangPaths).asPath +
File.pathSeparator + environment['PATH']
args compilerOpts.collectMany { ['-copt', it] }
args linkerOpts.collectMany { ['-lopt', it] }
args compilerOpts.collectMany { ['-compilerOpt', it] }
args linkerOpts.collectMany { ['-linkerOpt', it] }
headers.each {
args '-header', it
+2 -2
View File
@@ -21,8 +21,8 @@ remoteRoot=konan_tests
kotlinCompilerRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_dev_Compiler),number:1.3.40-dev-1234,branch:default:true,pinned:true/artifacts/content/maven
kotlinVersion=1.3.40-dev-1234
testKotlinVersion=1.3.40-dev-1234
sharedRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_KotlinNativeShared_BuildAndTest),number:1.0-dev-23,branch:default:true,pinned:true/artifacts/content/maven
sharedVersion=1.0-dev-23
sharedRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_KotlinNativeShared_BuildAndTest),number:1.0-dev-28,branch:default:true,pinned:true/artifacts/content/maven
sharedVersion=1.0-dev-28
konanVersion=1.3.0
org.gradle.jvmargs='-Dfile.encoding=UTF-8'
org.gradle.workers.max=4
+5 -5
View File
@@ -21,17 +21,17 @@ if (MPPTools.isMacos()) {
'-headerFilterAdditionalSearchPrefix', '/usr/include/x86_64-linux-gnu',
'-headerFilterAdditionalSearchPrefix', '/usr/include/ffmpeg']
} else if (MPPTools.isWindows()) {
includeDirsFfmpeg += ['-copt', "-I${MPPTools.mingwPath()}/include"]
includeDirsFfmpeg += ['-compilerOpt', "-I${MPPTools.mingwPath()}/include"]
}
def includeDirsSdl = []
if (MPPTools.isMacos()) {
includeDirsSdl += ['-copt', '-I/opt/local/include/SDL2',
'-copt', '-I/usr/local/include/SDL2']
includeDirsSdl += ['-compilerOpt', '-I/opt/local/include/SDL2',
'-compilerOpt', '-I/usr/local/include/SDL2']
} else if (MPPTools.isLinux()) {
includeDirsSdl += ['-copt', '-I/usr/include/SDL2']
includeDirsSdl += ['-compilerOpt', '-I/usr/include/SDL2']
} else if (MPPTools.isWindows()) {
includeDirsSdl += ['-copt', "-I${MPPTools.mingwPath()}/include/SDL2"]
includeDirsSdl += ['-compilerOpt', "-I${MPPTools.mingwPath()}/include/SDL2"]
}
project.ext {
@@ -98,14 +98,14 @@ open class CInteropTask @Inject constructor(val settings: CInteropSettingsImpl):
addFileArgs("-header", headers)
compilerOpts.forEach {
addArg("-copt", it)
addArg("-compilerOpt", it)
}
linkerOpts.forEach {
addArg("-lopt", it)
addArg("-linkerOpt", it)
}
addArgs("-copt", allHeadersDirs.map { "-I${it.absolutePath}" })
addArgs("-compilerOpt", allHeadersDirs.map { "-I${it.absolutePath}" })
addArgs("-headerFilterAdditionalSearchPrefix", headerFilterDirs.map { it.absolutePath })
libraries.files.filter {
@@ -196,7 +196,9 @@ open class KotlinNativeCompile @Inject constructor(internal val binary: Abstract
else -> { /* Do nothing. */ }
}
addListArg("-linker-options", linkerOpts)
linkerOpts.forEach {
addArg("-linker-option", it)
}
addAll(sources.files.map { it.absolutePath })
commonSources.files.mapTo(this) { "-Xcommon-sources=${it.absolutePath}" }
@@ -203,12 +203,6 @@ internal fun MutableList<String>.addFileArgs(parameter: String, values: Collecti
}
}
internal fun MutableList<String>.addListArg(parameter: String, values: List<String>) {
if (values.isNotEmpty()) {
addArg(parameter, values.joinToString(separator = " "))
}
}
// endregion
internal fun dumpProperties(task: Task) {
@@ -122,8 +122,9 @@ abstract class KonanCompileTask: KonanBuildingTask(), KonanCompileSpec {
addFileArgs("-native-library", nativeLibraries)
addArg("-produce", produce.name.toLowerCase())
addListArg("-linker-options", linkerOpts)
linkerOpts.forEach {
addArg("-linker-option", it)
}
addArgIfNotNull("-target", konanTarget.visibleName)
addArgIfNotNull("-language-version", languageVersion)
@@ -93,10 +93,10 @@ open class KonanInteropTask @Inject constructor(val workerExecutor: WorkerExecut
linkerOpts.addAll(it.files.map { it.canonicalPath })
}
linkerOpts.forEach {
addArg("-lopt", it)
addArg("-linkerOpt", it)
}
addArgs("-copt", includeDirs.allHeadersDirs.map { "-I${it.absolutePath}" })
addArgs("-compilerOpt", includeDirs.allHeadersDirs.map { "-I${it.absolutePath}" })
addArgs("-headerFilterAdditionalSearchPrefix", includeDirs.headerFilterDirs.map { it.absolutePath })
addArgs("-repo", libraries.repos.map { it.canonicalPath })