diff --git a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt index 300289aa0da..e8b30bf7b2c 100644 --- a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt +++ b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt @@ -72,6 +72,7 @@ class K2Native : CLICompiler() { put(NOSTDLIB, arguments.nostdlib) put(COMPILE_AS_STDLIB, arguments.compileAsStdlib) put(NOLINK, arguments.nolink) + put(NOMAIN, arguments.nomain) put(LIBRARY_FILES, arguments.libraries.toNonNullList()) diff --git a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.java b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.java index 3235edf2871..2e5213ed762 100644 --- a/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.java +++ b/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.java @@ -28,6 +28,9 @@ public class K2NativeCompilerArguments extends CommonCompilerArguments { @Argument(value = "nolink", description = "Don't link, just produce a bitcode file") public boolean nolink; + @Argument(value = "nomain", description = "Assume 'main' entry point to be provided by external libraries") + public boolean nomain; + @Argument(value = "linkerArgs", description = "Pass arguments to linker", delimiter = " ") @ValueDescription("") public String[] linkerArguments; diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt index 6eb75c50d78..f4992550f39 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt @@ -27,6 +27,8 @@ class KonanConfigKeys { = CompilerConfigurationKey.create("compile the module as stdlib") val NOLINK: CompilerConfigurationKey = CompilerConfigurationKey.create("don't link, only produce a bitcode file ") + val NOMAIN: CompilerConfigurationKey + = CompilerConfigurationKey.create("assume 'main' entry point to be provided by external libraries") val LINKER_ARGS: CompilerConfigurationKey> = CompilerConfigurationKey.create("additional linker arguments") val TARGET: CompilerConfigurationKey diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LinkStage.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LinkStage.kt index 5aae08e5d25..12021253dc0 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LinkStage.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LinkStage.kt @@ -144,6 +144,7 @@ internal class LinkStage(val context: Context) { val optimize = config.get(KonanConfigKeys.OPTIMIZATION) ?: false val emitted = config.get(KonanConfigKeys.BITCODE_FILE)!! val nostdlib = config.get(KonanConfigKeys.NOSTDLIB) ?: false + val nomain = config.get(KonanConfigKeys.NOMAIN) ?: false val libraries = context.config.librariesToLink fun llvmLto(files: List): ObjectFile { @@ -188,11 +189,22 @@ internal class LinkStage(val context: Context) { return result } + // Ideally we'd want to have + // #pragma weak main = Konan_main + // in the launcher.cpp. + // Unfortunately, anything related to weak linking on MacOS + // only seems to be working with dynamic libraries. + // So we stick to "-alias _main _konan_main" on Mac. + // And just do the same on Linux. + val entryPointSelector: List + get() = if (nomain) listOf() + else properties.propertyList("entrySelector.$suffix") + fun link(objectFiles: List): ExecutableFile { val executable = config.get(KonanConfigKeys.EXECUTABLE_FILE)!! - val linkCommand = platform.linkCommand(objectFiles, executable, optimize) + - asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS)) + asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS)) + + entryPointSelector runTool(*linkCommand.toTypedArray()) diff --git a/backend.native/konan.properties b/backend.native/konan.properties index d9e6c3796e1..c86b20e2c0f 100644 --- a/backend.native/konan.properties +++ b/backend.native/konan.properties @@ -11,6 +11,7 @@ llvmLlcFlags.osx = -mtriple=x86_64-apple-macosx10.10.0 --disable-fp-elim linkerKonanFlags.osx = -lc++ linkerOptimizationFlags.osx = -dead_strip osVersionMin.osx = -macosx_version_min 10.10.0 +entrySelector.osx = -alias _Konan_main _main // iphone arch.osx-ios = arm64 @@ -22,6 +23,7 @@ llvmLlcFlags.osx-ios = -mtriple=arm64-apple-ios5.0.0 --disable-fp-elim linkerKonanFlags.osx-ios = -lc++ linkerOptimizationFlags.osx-ios = -dead_strip osVersionMin.osx-ios = -iphoneos_version_min 5.0.0 +entrySelector.osx-ios = -alias _Konan_main _main // iphone_sim arch.osx-ios-sim = x86_64 @@ -33,6 +35,7 @@ llvmLlcFlags.osx-ios-sim = -mtriple=x86_64-apple-ios5.0.0 --disable-fp-elim linkerKonanFlags.osx-ios-sim = -lc++ linkerOptimizationFlags.osx-ios-sim = -dead_strip osVersionMin.osx-ios-sim = -ios_simulator_version_min 5.0.0 +entrySelector.osx-ios-sim = -alias _Konan_main _main // linux sysRoot.linux = target-gcc-toolchain-3-linux-x86-64/x86_64-unknown-linux-gnu/sysroot @@ -44,4 +47,5 @@ llvmLlcFlags.linux = -march=x86-64 linkerKonanFlags.linux = -Bstatic -lstdc++ -Bdynamic -ldl -lm -lpthread linkerOptimizationFlags.linux = --gc-sections pluginOptimizationFlags.linux = -plugin-opt=mcpu=x86-64 -plugin-opt=O3 +entrySelector.linux = --defsym main=Konan_main diff --git a/runtime/src/launcher/cpp/main.cpp b/runtime/src/launcher/cpp/main.cpp deleted file mode 100644 index 34f3545e7f1..00000000000 --- a/runtime/src/launcher/cpp/main.cpp +++ /dev/null @@ -1,5 +0,0 @@ -extern "C" int Konan_main(int argc, char** argv); - -int main(int argc, char** argv) { - return Konan_main(argc, argv); -}