Skip to content

Commit

Permalink
CLI library rework (JetBrains#3215)
Browse files Browse the repository at this point in the history
  • Loading branch information
LepilkinaElena authored Sep 6, 2019
1 parent 51d03ec commit 8e0e346
Show file tree
Hide file tree
Showing 66 changed files with 1,495 additions and 1,100 deletions.
2 changes: 1 addition & 1 deletion Interop/StubGenerator/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ dependencies {
compile "org.jetbrains.kotlin:kotlin-compiler:$kotlinVersion"
compile project(':Interop:Indexer')
compile "org.jetbrains.kotlin:kotlin-native-shared:$konanVersion"
compile project(path: ":endorsedLibraries:kliopt", configuration: "jvmRuntimeElements")
compile project(path: ":endorsedLibraries:kotlinx.cli", configuration: "jvmRuntimeElements")
}

compileKotlin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import org.jetbrains.kotlin.native.interop.gen.jvm.prepareTool
import org.jetbrains.kotlin.native.interop.indexer.NativeLibraryHeaders
import org.jetbrains.kotlin.native.interop.indexer.getHeaderPaths
import org.jetbrains.kotlin.native.interop.tool.CInteropArguments
import org.jetbrains.kliopt.ArgParser
import kotlinx.cli.ArgParser
import java.io.File

fun defFileDependencies(args: Array<String>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,85 +16,83 @@

package org.jetbrains.kotlin.native.interop.tool

import org.jetbrains.kliopt.*
import kotlinx.cli.ArgParser
import kotlinx.cli.ArgType
import kotlinx.cli.*

const val HEADER_FILTER_ADDITIONAL_SEARCH_PREFIX = "headerFilterAdditionalSearchPrefix"
const val NODEFAULTLIBS = "nodefaultlibs"
const val NODEFAULTLIBS_DEPRECATED = "nodefaultlibs"
const val NODEFAULTLIBS = "no-default-libs"
const val NOENDORSEDLIBS = "no-endorsed-libs"
const val PURGE_USER_LIBS = "Xpurge-user-libs"
const val TEMP_DIR = "Xtemporary-files-dir"

// TODO: unify camel and snake cases.
// Possible solution is to accept both cases
open class CommonInteropArguments(val argParser: ArgParser) {
val verbose by argParser.option(ArgType.Boolean, description = "Enable verbose logging output", defaultValue = false)
val flavor by argParser.option(ArgType.Choice(listOf("jvm", "native", "wasm")), description = "Interop target",
defaultValue = "jvm")
val verbose by argParser.option(ArgType.Boolean, description = "Enable verbose logging output").default(false)
val flavor by argParser.option(ArgType.Choice(listOf("jvm", "native", "wasm")), description = "Interop target")
.default("jvm")
val pkg by argParser.option(ArgType.String, description = "place generated bindings to the package")
val output by argParser.option(ArgType.String, shortName = "o", description = "specifies the resulting library file",
defaultValue = "nativelib")
val libraryPath by argParser.options(ArgType.String, description = "add a library search path",
multiple = true, delimiter = ",")
val staticLibrary by argParser.options(ArgType.String, description = "embed static library to the result",
multiple = true, delimiter = ",")
val generated by argParser.option(ArgType.String, description = "place generated bindings to the directory",
defaultValue = System.getProperty("user.dir"))
val natives by argParser.option(ArgType.String, description = "where to put the built native files",
defaultValue = System.getProperty("user.dir"))
val library by argParser.options(ArgType.String, shortName = "l", description = "library to use for building",
multiple = true)
val repo by argParser.options(ArgType.String, shortName = "r", description = "repository to resolve dependencies",
multiple = true)
val output by argParser.option(ArgType.String, shortName = "o", description = "specifies the resulting library file")
.default("nativelib")
val libraryPath by argParser.option(ArgType.String, description = "add a library search path")
.multiple().delimiter(",")
val staticLibrary by argParser.option(ArgType.String, description = "embed static library to the result")
.multiple().delimiter(",")
val generated by argParser.option(ArgType.String, description = "place generated bindings to the directory")
.default(System.getProperty("user.dir"))
val natives by argParser.option(ArgType.String, description = "where to put the built native files")
.default(System.getProperty("user.dir"))
val library by argParser.option(ArgType.String, shortName = "l", description = "library to use for building")
.multiple()
val repo by argParser.option(ArgType.String, shortName = "r", description = "repository to resolve dependencies")
.multiple()
val nodefaultlibs by argParser.option(ArgType.Boolean, NODEFAULTLIBS,
description = "don't link the libraries from dist/klib automatically").default(false)
val nodefaultlibsDeprecated by argParser.option(ArgType.Boolean, NODEFAULTLIBS_DEPRECATED,
description = "don't link the libraries from dist/klib automatically",
defaultValue = false)
deprecatedWarning = "Old form of flag. Please, use $NODEFAULTLIBS.").default(false)
val noendorsedlibs by argParser.option(ArgType.Boolean, NOENDORSEDLIBS,
description = "don't link the endorsed libraries from dist automatically").default(false)
val purgeUserLibs by argParser.option(ArgType.Boolean, PURGE_USER_LIBS,
description = "don't link unused libraries even explicitly specified", defaultValue = false)
description = "don't link unused libraries even explicitly specified").default(false)
val tempDir by argParser.option(ArgType.String, TEMP_DIR,
description = "save temporary files to the given directory")
}

class CInteropArguments(argParser: ArgParser =
ArgParser("cinterop", useDefaultHelpShortName = false,
ArgParser("cinterop",
prefixStyle = ArgParser.OPTION_PREFIX_STYLE.JVM)): CommonInteropArguments(argParser) {
val target by argParser.option(ArgType.String, description = "native target to compile to", defaultValue = "host")
val target by argParser.option(ArgType.String, description = "native target to compile to").default("host")
val def by argParser.option(ArgType.String, description = "the library definition file")
val header by argParser.options(ArgType.String, description = "header file to produce kotlin bindings for",
multiple = true, delimiter = ",")
val shortHeaderForm by argParser.options(ArgType.String, "h", description = "header file to produce kotlin bindings for",
multiple = true, delimiter = ",", deprecatedWarning = "Option -h is deprecated. Please use -header.")
val headerFilterPrefix by argParser.options(ArgType.String, HEADER_FILTER_ADDITIONAL_SEARCH_PREFIX, "hfasp",
"header file to produce kotlin bindings for", multiple = true, delimiter = ",")
val compilerOpts by argParser.options(ArgType.String,
description = "additional compiler options (allows to add several options separated by spaces)",
multiple = true, delimiter = " ")
val compilerOptions by argParser.options(ArgType.String, "compiler-options",
description = "additional compiler options (allows to add several options separated by spaces)",
multiple = true, delimiter = " ")
val linkerOpts by argParser.options(ArgType.String, "linkerOpts",
description = "additional linker options (allows to add several options separated by spaces)",
multiple = true, delimiter = " ")
val linkerOptions by argParser.options(ArgType.String, "linker-options",
description = "additional linker options (allows to add several options separated by spaces)",
multiple = true, delimiter = " ")
val compilerOption by argParser.options(ArgType.String, "compiler-option",
description = "additional compiler option", multiple = true)
val linkerOption by argParser.options(ArgType.String, "linker-option",
description = "additional linker option", multiple = true)
val copt by argParser.options(ArgType.String,
description = "additional compiler options (allows to add several options separated by spaces)",
multiple = true, delimiter = " ",
deprecatedWarning = "Option -copt is deprecated. Please use -compiler-options.")
val lopt by argParser.options(ArgType.String,
description = "additional linker options (allows to add several options separated by spaces)",
multiple = true, delimiter = " ",
deprecatedWarning = "Option -lopt is deprecated. Please use -linker-options.")
val header by argParser.option(ArgType.String, description = "header file to produce kotlin bindings for")
.multiple().delimiter(",")
val headerFilterPrefix by argParser.option(ArgType.String, HEADER_FILTER_ADDITIONAL_SEARCH_PREFIX, "hfasp",
"header file to produce kotlin bindings for").multiple().delimiter(",")
val compilerOpts by argParser.option(ArgType.String,
description = "additional compiler options (allows to add several options separated by spaces)")
.multiple().delimiter(" ")
val compilerOptions by argParser.option(ArgType.String, "compiler-options",
description = "additional compiler options (allows to add several options separated by spaces)")
.multiple().delimiter(" ")
val linkerOpts = argParser.option(ArgType.String, "linkerOpts",
description = "additional linker options (allows to add several options separated by spaces)")
.multiple().delimiter(" ")
val linkerOptions = argParser.option(ArgType.String, "linker-options",
description = "additional linker options (allows to add several options separated by spaces)")
.multiple().delimiter(" ")
val compilerOption by argParser.option(ArgType.String, "compiler-option",
description = "additional compiler option").multiple()
val linkerOption = argParser.option(ArgType.String, "linker-option",
description = "additional linker option").multiple()
val linker by argParser.option(ArgType.String, description = "use specified linker")
}

class JSInteropArguments(argParser: ArgParser = ArgParser("jsinterop", useDefaultHelpShortName = false,
class JSInteropArguments(argParser: ArgParser = ArgParser("jsinterop",
prefixStyle = ArgParser.OPTION_PREFIX_STYLE.JVM)): CommonInteropArguments(argParser) {
val target by argParser.option(ArgType.Choice(listOf("wasm32")),
description = "wasm target to compile to", defaultValue = "wasm32")
description = "wasm target to compile to").default("wasm32")
}

internal fun warn(msg: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import org.jetbrains.kotlin.native.interop.gen.*
import org.jetbrains.kotlin.native.interop.gen.wasm.processIdlLib
import org.jetbrains.kotlin.native.interop.indexer.*
import org.jetbrains.kotlin.native.interop.tool.*
import org.jetbrains.kliopt.ArgParser
import kotlinx.cli.ArgParser
import java.io.File
import java.lang.IllegalArgumentException
import java.nio.file.*
Expand Down Expand Up @@ -175,16 +175,15 @@ private fun processCLib(args: Array<String>, additionalArgs: Map<String, Any> =
val tool = prepareTool(cinteropArguments.target, flavor)

val def = DefFile(defFile, tool.substitutions)
val isLinkerOptsSetByUser = (cinteropArguments.argParser.getOrigin("linkerOpts") == ArgParser.ValueOrigin.SET_BY_USER) ||
(cinteropArguments.argParser.getOrigin("linker-option") == ArgParser.ValueOrigin.SET_BY_USER) ||
(cinteropArguments.argParser.getOrigin("linker-options") == ArgParser.ValueOrigin.SET_BY_USER) ||
(cinteropArguments.argParser.getOrigin("lopt") == ArgParser.ValueOrigin.SET_BY_USER)
val isLinkerOptsSetByUser = (cinteropArguments.linkerOpts.valueOrigin == ArgParser.ValueOrigin.SET_BY_USER) ||
(cinteropArguments.linkerOptions.valueOrigin == ArgParser.ValueOrigin.SET_BY_USER) ||
(cinteropArguments.linkerOption.valueOrigin == ArgParser.ValueOrigin.SET_BY_USER)
if (flavorName == "native" && isLinkerOptsSetByUser) {
warn("-linker-option(s)/-linkerOpts/-lopt option is not supported by cinterop. Please add linker options to .def file or binary compilation instead.")
warn("-linker-option(s)/-linkerOpts option is not supported by cinterop. Please add linker options to .def file or binary compilation instead.")
}

val additionalLinkerOpts = cinteropArguments.linkerOpts.toTypedArray() + cinteropArguments.linkerOption.toTypedArray() +
cinteropArguments.linkerOptions.toTypedArray() + cinteropArguments.lopt.toTypedArray()
val additionalLinkerOpts = cinteropArguments.linkerOpts.value.toTypedArray() + cinteropArguments.linkerOption.value.toTypedArray() +
cinteropArguments.linkerOptions.value.toTypedArray()
val verbose = cinteropArguments.verbose

val language = selectNativeLanguage(def.config)
Expand Down Expand Up @@ -305,10 +304,9 @@ internal fun buildNativeLibrary(
arguments: CInteropArguments,
imports: ImportsImpl
): NativeLibrary {
val additionalHeaders = (arguments.header + arguments.shortHeaderForm).toTypedArray()
val additionalHeaders = (arguments.header).toTypedArray()
val additionalCompilerOpts = (arguments.compilerOpts +
arguments.compilerOptions + arguments.compilerOption +
arguments.copt).toTypedArray()
arguments.compilerOptions + arguments.compilerOption).toTypedArray()

val headerFiles = def.config.headers + additionalHeaders
val language = selectNativeLanguage(def.config)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package org.jetbrains.kotlin.native.interop.gen.wasm
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.native.interop.gen.argsToCompiler
import org.jetbrains.kotlin.native.interop.gen.wasm.idl.*
import org.jetbrains.kliopt.ArgParser
import kotlinx.cli.ArgParser
import org.jetbrains.kotlin.native.interop.tool.JSInteropArguments

fun kotlinHeader(packageName: String): String {
Expand Down
2 changes: 1 addition & 1 deletion backend.native/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ targetList.each { target ->
"-Djava.library.path=${project.buildDir}/nativelibs/$hostName",
]

def defaultArgs = ['-nopack', '-nostdlib', '-nodefaultlibs']
def defaultArgs = ['-nopack', '-nostdlib', '-no-default-libs', '-no-endorsed-libs']
if (target != "wasm32") defaultArgs += '-g'
def konanArgs = [*defaultArgs,
'-target', target,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
with(configuration) {

put(NODEFAULTLIBS, arguments.nodefaultlibs)
put(NOENDORSEDLIBS, arguments.noendorsedlibs)
put(NOSTDLIB, arguments.nostdlib)
put(NOPACK, arguments.nopack)
put(NOMAIN, arguments.nomain)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,12 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
valueDescription = "<path>", description = "Include the native bitcode library", delimiter = "")
var nativeLibraries: Array<String>? = null

@Argument(value = "-nodefaultlibs", description = "Don't link the libraries from dist/klib automatically")
@Argument(value = "-no-default-libs", deprecatedName = "-nodefaultlibs", description = "Don't link the libraries from dist/klib automatically")
var nodefaultlibs: Boolean = false

@Argument(value = "-no-endorsed-libs", description = "Don't link the endorsed libraries from dist automatically")
var noendorsedlibs: Boolean = false

@Argument(value = "-nomain", description = "Assume 'main' entry point to be provided by external libraries")
var nomain: Boolean = false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
resolver.resolveWithDependencies(
unresolvedLibraries + includedLibraryFiles.map { UnresolvedLibrary(it.absolutePath, null) },
noStdLib = configuration.getBoolean(KonanConfigKeys.NOSTDLIB),
noDefaultLibs = configuration.getBoolean(KonanConfigKeys.NODEFAULTLIBS)
noDefaultLibs = configuration.getBoolean(KonanConfigKeys.NODEFAULTLIBS),
noEndorsedLibs = configuration.getBoolean(KonanConfigKeys.NOENDORSEDLIBS)
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ class KonanConfigKeys {
= CompilerConfigurationKey.create("native library file paths")
val NODEFAULTLIBS: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("don't link with the default libraries")
val NOENDORSEDLIBS: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("don't link with the endorsed libraries")
val NOMAIN: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("assume 'main' entry point to be provided by external libraries")
val NOSTDLIB: CompilerConfigurationKey<Boolean>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -826,7 +826,7 @@ internal val ModuleDescriptor.namePrefix: String get() {
internal fun abbreviate(name: String): String {
val normalizedName = name
.capitalize()
.replace('-', '_')
.replace("-|\\.".toRegex(), "_")

val uppers = normalizedName.filterIndexed { index, character -> index == 0 || character.isUpperCase() }
if (uppers.length >= 3) return uppers
Expand Down
1 change: 1 addition & 0 deletions backend.native/tests/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3225,6 +3225,7 @@ void createInterop(String name, Closure conf) {
interop(name, targets: [target.name]) {
conf(it)
noDefaultLibs(true)
noEndorsedLibs(true)
baseDir "$testOutputLocal/$name"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ class NativeInteropPlugin implements Plugin<Project> {

prj.dependencies {
interopStubGenerator project(path: ":Interop:StubGenerator")
interopStubGenerator project(path: ":endorsedLibraries:kliopt", configuration: "jvmRuntimeElements")
interopStubGenerator project(path: ":endorsedLibraries:kotlinx.cli", configuration: "jvmRuntimeElements")
}

// FIXME: choose tasks more wisely
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ open class BenchmarkingPlugin: Plugin<Project> {

project.configurations.getByName(nativeMain.implementationConfigurationName).apply {
// Exclude dependencies already included into K/N distribution (aka endorsed libraries).
exclude(mapOf("module" to "kliopt"))
exclude(mapOf("module" to "kotlinx.cli"))
}

repositories.maven {
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ task distCompiler(type: Copy) {
into('konan/lib')
}

from(project(':endorsedLibraries:kliopt').file('build/libs')) {
from(project(':endorsedLibraries:kotlinx.cli').file('build/libs')) {
into('konan/lib')
}

Expand Down
4 changes: 2 additions & 2 deletions cmd/run_konan
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ SHARED_JAR="${KONAN_HOME}/konan/lib/shared.jar"
EXTRACTED_METADATA_JAR="${KONAN_HOME}/konan/lib/konan.metadata.jar"
EXTRACTED_SERIALIZER_JAR="${KONAN_HOME}/konan/lib/konan.serializer.jar"
KLIB_JAR="${KONAN_HOME}/konan/lib/klib.jar"
KLIOPT_JAR="${KONAN_HOME}/konan/lib/kliopt-jvm.jar"
KOTLINX_CLI_JAR="${KONAN_HOME}/konan/lib/kotlinx.cli-jvm.jar"
UTILITIES_JAR="${KONAN_HOME}/konan/lib/utilities.jar"
NATIVE_UTILS_JAR="${KONAN_HOME}/konan/lib/kotlin-native-utils.jar"
UTIL_IO_JAR="${KONAN_HOME}/konan/lib/kotlin-util-io.jar"
UTIL_KLIB_JAR="${KONAN_HOME}/konan/lib/kotlin-util-klib.jar"
TROVE_JAR="${KONAN_HOME}/konan/lib/trove4j.jar"
KONAN_CLASSPATH="$KOTLIN_JAR:$KOTLIN_STDLIB_JAR:$KOTLIN_REFLECT_JAR:$KOTLIN_SCRIPT_RUNTIME_JAR:$INTEROP_JAR:$STUB_GENERATOR_JAR:$INTEROP_INDEXER_JAR:$KONAN_JAR:$KLIB_JAR:$UTILITIES_JAR:$SHARED_JAR:$EXTRACTED_METADATA_JAR:$EXTRACTED_SERIALIZER_JAR:$NATIVE_UTILS_JAR:$TROVE_JAR:$UTIL_IO_JAR:$UTIL_KLIB_JAR:$KLIOPT_JAR"
KONAN_CLASSPATH="$KOTLIN_JAR:$KOTLIN_STDLIB_JAR:$KOTLIN_REFLECT_JAR:$KOTLIN_SCRIPT_RUNTIME_JAR:$INTEROP_JAR:$STUB_GENERATOR_JAR:$INTEROP_INDEXER_JAR:$KONAN_JAR:$KLIB_JAR:$UTILITIES_JAR:$SHARED_JAR:$EXTRACTED_METADATA_JAR:$EXTRACTED_SERIALIZER_JAR:$NATIVE_UTILS_JAR:$TROVE_JAR:$UTIL_IO_JAR:$UTIL_KLIB_JAR:$KOTLINX_CLI_JAR"
TOOL_CLASS=org.jetbrains.kotlin.cli.utilities.MainKt

LIBCLANG_DISABLE_CRASH_RECOVERY=1 \
Expand Down
Loading

0 comments on commit 8e0e346

Please sign in to comment.