Files
kotlin-fork/build.gradle
T
Vasily Levchenko 89ebbaeb6c DEBUGINFO: initial C bindings to debug info llvm
- support DICompileUnit
- support DIFIle
- support DISubroutine
- support DIBasicType
- support DILocation
- added gradle build
- debug info bindings are involved in kotlin build
- added binding to DIGetSubprogramLinkName
- added binding to LLVMBuilderGetCurrentFunction
- added reset location
- simple demo added (buildable with gradle)
  produces folowing output:
    Following pseudo code in sources.
     0:123456789012345678901
     1: fun main():Int {
     2:   {foo()}()
     3:   return 0
     4: }
     5  fun foo() {}

    0:b-backend-dwarf:minamoto@unit-703(0)# ./demo
    ; ModuleID = 'test'
    source_filename = "test"

    define i32 @foo(i32) !dbg !3 {
    entry:
      ret i32 %0, !dbg !7
    }

    !llvm.dbg.cu = !{!0}

    !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "konanc", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
    !1 = !DIFile(filename: "1.kt", directory: "src")
    !2 = !{}
    !3 = distinct !DISubprogram(name: "foo", linkageName: "foo:link", scope: null, file: !1, line: 66, type: !4, isLocal: false, isDefinition: true, isOptimized: false, unit: !0, variables: !2)
    !4 = !DISubroutineType(types: !5)
    !5 = !{!6}
    !6 = !DIBasicType(name: "int", size: 32, align: 4)
    !7 = !DILocation(line: 42, column: 15, scope: !3)
- demo sharing debug information between several bitcode artifacts
    0:b-backend-dwarf:minamoto@unit-703(0)# llvmDebugInfoC/build/exe/demogenerated/demogenerated
    ; ModuleID = 'test'
    source_filename = "test"

    define void @foo() !dbg !3 {
    entry:
      ret void, !dbg !5
    }

    define void @"main$caller$foo"() !dbg !6 {
    entry:
      call void @foo(), !dbg !7
      ret void
    }

    define void @main() !dbg !8 {
    entry:
      call void @"main$caller$foo"(), !dbg !9
      ret void, !dbg !10
    }

    !llvm.dbg.cu = !{!0}

    !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "konanc", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
    !1 = !DIFile(filename: "<stdin>", directory: "")
    !2 = !{}
    !3 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 5, type: !4, isLocal: false, isDefinition: true, isOptimized: false, unit: !0, variables: !2)
    !4 = !DISubroutineType(types: !2)
    !5 = !DILocation(line: 5, column: 14, scope: !3)
    !6 = distinct !DISubprogram(name: "main$caller$foo", linkageName: "main$caller$foo", scope: null, file: !1, line: 2, type: !4, isLocal: false, isDefinition: true, isOptimized: false, unit: !0, variables: !2)
    !7 = !DILocation(line: 5, column: 2, scope: !6)
    !8 = distinct !DISubprogram(name: "main", linkageName: "main", scope: null, file: !1, line: 1, type: !4, isLocal: false, isDefinition: true, isOptimized: false, unit: !0, variables: !2)
    !9 = !DILocation(line: 2, column: 12, scope: !8)
    !10 = !DILocation(line: 3, column: 4, scope: !8)
- local variables support
- demo for local variable suppor (TBD some out put here).
    ; ModuleID = 'test'
    source_filename = "test"

    define i32 @main() !dbg !3 {
    entry:
    %0 = alloca i32
    call void @llvm.dbg.declare(metadata i32* %0, metadata !5, metadata !7), !dbg !8
    store i32 42, i32* %0, !dbg !8
    %1 = load i32, i32* %0, !dbg !8
    ret i32 %1, !dbg !8
    }

    ; Function Attrs: nounwind readnone
    declare void @llvm.dbg.declare(metadata, metadata, metadata) #0

    attributes #0 = { nounwind readnone }

    !llvm.dbg.cu = !{!0}

    !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "konanc", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
    !1 = !DIFile(filename: "<stdin>", directory: "")
    !2 = !{}
    !3 = distinct !DISubprogram(name: "main", linkageName: "main", scope: null, file: !1, line: 1, type: !4, isLocal: false, isDefinition: true, isOptimized: false, unit: !0, variables: !2)
    !4 = !DISubroutineType(types: !2)
    !5 = !DILocalVariable(name: "a", scope: !3, file: !1, line: 2, type: !6)
    !6 = !DIBasicType(name: "int", size: 32, align: 4)
    !7 = !DIExpression()
    !8 = !DILocation(line: 2, column: 1, scope: !3)
2017-04-14 11:39:51 +03:00

341 lines
9.3 KiB
Groovy

/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import groovy.io.FileType
//ant.importBuild 'backend.native/kotlin-ir/build.xml'
defaultTasks 'clean', 'demo'
convention.plugins.platformInfo = new PlatformInfo()
allprojects {
if (path != ":dependencies") {
evaluationDependsOn(":dependencies")
}
repositories {
mavenCentral()
}
loadCommandLineProperties()
loadLocalProperties()
setupCompilationFlags()
setupClang(project)
}
void setupClang(Project project) {
project.convention.plugins.execClang = new org.jetbrains.kotlin.ExecClang(project)
project.plugins.withType(NativeComponentPlugin) {
project.model {
toolChains {
clang(Clang) {
clangPath.each {
path it
}
eachPlatform { // TODO: will not work when cross-compiling
[cCompiler, cppCompiler, linker].each {
it.withArguments { it.addAll(hostClangArgs) }
}
}
}
}
}
}
}
void setupCompilationFlags() {
ext.clangPath = ["$llvmDir/bin"]
ext.clangArgs = []
ext.targetArgs = [:]
final String binDir
if (isLinux()) {
ext.targetArgs <<
["host":
["--sysroot=${gccToolchainDir}/${gnuTriplet}/sysroot"],
"raspberrypi":
["-target", "armv7-unknown-linux-gnueabihf",
"-mfpu=vfp", "-mfloat-abi=hard",
"--sysroot=$raspberryPiSysrootDir",
// TODO: those two are hacks.
"-I$raspberryPiSysrootDir/usr/include/c++/4.8.3",
"-I$raspberryPiSysrootDir/usr/include/c++/4.8.3/arm-linux-gnueabihf"]
]
} else {
ext.targetArgs <<
["host":
["--sysroot=$hostSysrootDir", "-mmacosx-version-min=$minMacOsVersion"],
"iphone":
["-stdlib=libc++", "-arch", "arm64", "-isysroot", "$iphoneSysrootDir",
"-miphoneos-version-min=8.0.0"]
// TODO: re-enable after simulator sysroot is available in the dependencies
// "iphone_sim":
// ["-stdlib=libc++", "-isysroot", "$iphoneSimSysrootDir", "-miphoneos-version-min=8.0.0"],
]
}
ext.targetList = ext.targetArgs.keySet() as List
if (isLinux()) {
binDir = "$gccToolchainDir/$gnuTriplet/bin"
ext.clangArgs.addAll([
"--gcc-toolchain=$gccToolchainDir",
"-L$llvmDir/lib"
])
} else {
binDir = "$hostSysrootDir/usr/bin"
}
ext.clangArgs << "-B$binDir"
ext.hostClangArgs = ext.clangArgs.clone()
ext.hostClangArgs.addAll(ext.targetArgs['host'])
ext.clangPath << binDir
ext.jvmArgs = ["-ea"]
}
void loadLocalProperties() {
if (new File("$project.rootDir/local.properties").exists()) {
Properties props = new Properties()
props.load(new FileInputStream("$project.rootDir/local.properties"))
props.each {prop -> project.ext.set(prop.key, prop.value)}
}
}
void loadCommandLineProperties() {
if (project.hasProperty("konanc_flags")) {
throw new Error("Specify either -Ptest_flags or -Pbuild_flags.")
}
ext.globalBuildArgs = project.hasProperty("build_flags")
? ext.build_flags.split(' ') : []
ext.globalTestArgs = project.hasProperty("test_flags")
? ext.test_flags.split(' ') : []
ext.testTarget = project.hasProperty("test_target")
? ext.test_target : null
}
class PlatformInfo {
private final String osName = System.properties['os.name']
private final String osArch = System.properties['os.arch']
boolean isMac() {
return osName == 'Mac OS X'
}
boolean isLinux() {
return osName == 'Linux'
}
boolean isAmd64() {
return osArch in ['x86_64', 'amd64']
}
String getGnuTriplet() {
if (isLinux() && isAmd64()) {
return "x86_64-unknown-linux-gnu"
} else {
throw unsupportedPlatformException()
}
}
String simpleOsName() {
if (isMac()) return 'macos'
if (isLinux()) return 'linux'
throw unsupportedPlatformException()
}
Throwable unsupportedPlatformException() {
return new Error("unsupported platform: $osName/$osArch")
}
}
task dist_compiler(type: Copy) {
dependsOn ':backend.native:jars'
dependsOn ':tools:helpers:jar'
destinationDir file('dist')
from(project(':backend.native').file('build/libs')) {
into('konan/lib')
}
from(project('Interop').file('Runtime/build/libs')) {
into('konan/lib')
}
from(project('Interop').file('Indexer/build/libs')) {
into('konan/lib')
}
from(project('Interop').file('StubGenerator/build/libs')) {
into('konan/lib')
}
from(project(':backend.native').file('build/external_jars')) {
into('konan/lib')
}
from(project(':backend.native').file('build/nativelibs')) {
into('konan/nativelib')
}
from(project(':Interop').file('Indexer/build/nativelibs')) {
into('konan/nativelib')
}
from(project(':Interop').file('Runtime/build/nativelibs')) {
into('konan/nativelib')
}
from(project(':llvmDebugInfoC').file('build/libs/debugInfo/shared')) {
into('konan/nativelib')
}
from(file('cmd')) {
fileMode(0755)
into('bin')
}
from(project(':backend.native').file('konan.properties')) {
into('konan')
}
from("$llvmDir/lib") {
into('konan/nativelib')
include '**/libclang.*'
includeEmptyDirs = false
}
// TODO: check if we use native libraries copied to dist (see above) or not.
from(project(':tools:helpers').file('build/libs')) {
into('konan/lib')
}
doLast {
// MacOS System Integrity Protection strips DYLD_LIBRARY_PATH from
// environment of all the binaries residing in /bin /usr/bin etc.
// That means /usr/bin/java can't use DYLD_LIBRARY_PATH to pick up
// rpath'ed libraries.
// See dyld(1), install_name_tool(1) for rpath details.
if (isMac()) {
exec {
commandLine "install_name_tool"
args '-add_rpath', '@loader_path/',
'dist/konan/nativelib/libclangstubs.dylib'
}
exec {
commandLine "install_name_tool"
args '-add_rpath', '@loader_path/',
'dist/konan/nativelib/libdebugInfostubs.dylib'
}
}
}
}
task list_dist(type: Exec) {
commandLine 'find', 'dist'
}
task dist_runtime(type: Copy) {
dependsOn ':runtime:hostRuntime'
dependsOn ':backend.native:hostStdlib'
dependsOn ':backend.native:hostStart'
destinationDir file('dist')
from(project(':runtime').file('build')) {
include('*/*.bc')
into('lib')
}
}
task cross_dist_runtime(type: Copy) {
dependsOn.addAll(targetList.collect { ":runtime:${it}Runtime" })
dependsOn.addAll(targetList.collect { ":backend.native:${it}Stdlib" })
dependsOn.addAll(targetList.collect { ":backend.native:${it}Start" })
destinationDir file('dist')
from(project(':runtime').file('build')) {
include('*/*.bc')
into('lib')
}
}
task dist {
dependsOn 'dist_compiler', 'dist_runtime'
}
task cross_dist {
dependsOn 'cross_dist_runtime', 'dist_compiler'
}
task bundle(type: Tar) {
dependsOn('cross_dist')
baseName = "kotlin-native-${simpleOsName()}-${project.konanVersion}"
from("$project.rootDir/dist") {
include '**'
exclude 'dependencies'
into baseName
}
from(project.rootDir) {
include 'DISTRO_README.md'
rename {
return "README.md"
}
into baseName
}
from(project.rootDir) {
include 'samples/**'
include 'INTEROP.md'
include 'RELEASE_NOTES.md'
include 'GRADLE_PLUGIN.md'
exclude '**/gradle.properties'
exclude '**/build'
exclude '**/.gradle'
rename { String fileName ->
if (fileName == "gradle.properties.for_bundle") {
return "gradle.properties"
} else {
return fileName
}
}
into baseName
}
destinationDir = file('.')
extension = 'tar.gz'
compression = Compression.GZIP
}
task demo(type: Exec) {
dependsOn 'dist'
commandLine './dist/bin/konanc', 'backend.native/tests/runtime/collections/moderately_large_array.kt', '-o', 'build/demo.kexe'
}
task clean {
doLast {
file('dist').traverse(type: FileType.ANY, excludeNameFilter: "dependencies", maxDepth: 0) {
delete it
}
delete bundle.outputs.files
}
}