Repository: JetBrains/kotlin
File: kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Linker.kt (Kotlin)

Code before:
                                   libraries: List<String>, linkerArgs: List<String>,
                                   optimize: Boolean, debug: Boolean,
                                   kind: LinkerOutputKind, outputDsymBundle: String,
                                   needsProfileLibrary: Boolean, mimallocEnabled: Boolean,
                                   sanitizer: SanitizerKind?): List<Command> {
        require(sanitizer == null) {
            "Sanitizers are unsupported"
        }
        if (kind == LinkerOutputKind.STATIC_LIBRARY)
            return staticGnuArCommands(ar, executable, objectFiles, libraries)

        val dynamic = kind == LinkerOutputKind.DYNAMIC_LIBRARY
        val toolchainSysroot = "${absoluteTargetToolchain}/sysroot"
        val architectureDir = Android.architectureDirForTarget(target)
        val apiSysroot = "$absoluteTargetSysRoot/$architectureDir"
        val clangTarget = targetTriple.withoutVendor()
        val libDirs = listOf(
                "--sysroot=$apiSysroot",
                if (target == KonanTarget.ANDROID_X64) "-L$apiSysroot/usr/lib64" else "-L$apiSysroot/usr/lib",
                "-L$toolchainSysroot/usr/lib/$clangTarget/${Android.API}",
                "-L$toolchainSysroot/usr/lib/$clangTarget")
        return listOf(Command(clang).apply {
            +"-o"
            +executable
            if (dynamic) +"-fPIC" else +listOf("-fPIE", "-pie")
            if (dynamic) +"-shared"
            +"-target"
            +clangTarget
            +libDirs
            +objectFiles
            if (optimize) +linkerOptimizationFlags
            if (!debug) +linkerNoDebugFlags
            if (dynamic) +linkerDynamicFlags
            if (dynamic) +"-Wl,-soname,${File(executable).name}"
            +linkerKonanFlags
            if (mimallocEnabled) +mimallocLinkerDependencies
            +libraries
            +linkerArgs
        })
    }
}

class MacOSBasedLinker(targetProperties: AppleConfigurables)
    : LinkerFlags(targetProperties), AppleConfigurables by targetProperties {

    private val libtool = "$absoluteTargetToolchain/usr/bin/libtool"
    private val linker = "$absoluteTargetToolchain/usr/bin/ld"
    private val strip = "$absoluteTargetToolchain/usr/bin/strip"
    private val dsymutil = "$absoluteTargetToolchain/usr/bin/dsymutil"

    private val compilerRtDir: String? by lazy {

Review comment (bug):
Let's change these lines to something like this:
```kotlin
when (kind) {
    LinkerOutputKind.EXECUTABLE -> +listOf("-fPIE", "-pie")
    LinkerOutputKind.DYNAMIC_LIBRARY -> +listOf("-fPIC", "-shared")
    LinkerOutputKind.STATIC_LIBRARY -> {}
}
```
Motivation:
* It is more explicit that we add these flags only when producing executables.
* Nothing will go wrong if we add another `LinkerOutputKind`.

Code after:
                                   libraries: List<String>, linkerArgs: List<String>,
                                   optimize: Boolean, debug: Boolean,
                                   kind: LinkerOutputKind, outputDsymBundle: String,
                                   needsProfileLibrary: Boolean, mimallocEnabled: Boolean,
                                   sanitizer: SanitizerKind?): List<Command> {
        require(sanitizer == null) {
            "Sanitizers are unsupported"
        }
        if (kind == LinkerOutputKind.STATIC_LIBRARY)
            return staticGnuArCommands(ar, executable, objectFiles, libraries)

        val dynamic = kind == LinkerOutputKind.DYNAMIC_LIBRARY
        val toolchainSysroot = "${absoluteTargetToolchain}/sysroot"
        val architectureDir = Android.architectureDirForTarget(target)
        val apiSysroot = "$absoluteTargetSysRoot/$architectureDir"
        val clangTarget = targetTriple.withoutVendor()
        val libDirs = listOf(
                "--sysroot=$apiSysroot",
                if (target == KonanTarget.ANDROID_X64) "-L$apiSysroot/usr/lib64" else "-L$apiSysroot/usr/lib",
                "-L$toolchainSysroot/usr/lib/$clangTarget/${Android.API}",
                "-L$toolchainSysroot/usr/lib/$clangTarget")
        return listOf(Command(clang).apply {
            +"-o"
            +executable
            when (kind) {
                LinkerOutputKind.EXECUTABLE -> +listOf("-fPIE", "-pie")
                LinkerOutputKind.DYNAMIC_LIBRARY -> +listOf("-fPIC", "-shared")
                LinkerOutputKind.STATIC_LIBRARY -> {}
            }
            +"-target"
            +clangTarget
            +libDirs
            +objectFiles
            if (optimize) +linkerOptimizationFlags
            if (!debug) +linkerNoDebugFlags
            if (dynamic) +linkerDynamicFlags
            if (dynamic) +"-Wl,-soname,${File(executable).name}"
            +linkerKonanFlags
            if (mimallocEnabled) +mimallocLinkerDependencies
            +libraries
            +linkerArgs
        })
    }
}

class MacOSBasedLinker(targetProperties: AppleConfigurables)
    : LinkerFlags(targetProperties), AppleConfigurables by targetProperties {

    private val libtool = "$absoluteTargetToolchain/usr/bin/libtool"
    private val linker = "$absoluteTargetToolchain/usr/bin/ld"
    private val strip = "$absoluteTargetToolchain/usr/bin/strip"