/* * 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', 'dist' convention.plugins.platformInfo = new PlatformInfo() allprojects { if (path != ":dependencies") { evaluationDependsOn(":dependencies") } repositories { mavenCentral() maven { url kotlinCompilerRepo } } 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 { if (isWindows()) { platforms { host { architecture 'x86_64' } } components { withType(NativeComponentSpec) { targetPlatform 'host' } } toolChains { gcc(Gcc) { path "$mingwWithLlvmDir/bin" } } } else { toolChains { clang(Clang) { clangPath.each { path it } eachPlatform { // TODO: will not work when cross-compiling [cCompiler, cppCompiler, linker].each { it.withArguments { it.addAll(hostClangArgs) } } } } } } } } } String getTargetArg(String target) { def result = konanProperties.getProperty("quadruple.$target") if (result == null) { throw IllegalArgumentException("konan.properties has no LLVM target args for target: $target") } return result } void setupCompilationFlags() { ext.clangPath = ["$llvmDir/bin"] ext.clangArgs = [] ext.targetArgs = [:] final String binDir if (isLinux()) { ext.host = "linux" ext.targetArgs << [(ext.host): ["--sysroot=${gccToolchainDir}/${gnuTriplet}/sysroot", "-DUSE_GCC_UNWIND=1", "-DUSE_ELF_SYMBOLS=1", "-DELFSIZE=64"], "raspberrypi": ["-target", getTargetArg("raspberrypi"), "-mfpu=vfp", "-mfloat-abi=hard", "-DUSE_GCC_UNWIND=1", "-DUSE_ELF_SYMBOLS=1", "-DELFSIZE=32", "--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 if (isWindows()) { ext.host = "mingw" ext.targetArgs << [(ext.host): ["-target", "x86_64-w64-mingw32", "--sysroot=${mingwWithLlvmDir}", "-DUSE_GCC_UNWIND=1", "-DUSE_PE_COFF_SYMBOLS=1", "-DKONAN_WINDOWS=1"]] } else { ext.host = "macbook" ext.targetArgs << [(ext.host): ["--sysroot=$macbookSysrootDir", "-mmacosx-version-min=10.11"], "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"], ] } if (isLinux() || isMac()) { ext.targetArgs << [ "android_arm32": ["-target", getTargetArg("android_arm32"), "--sysroot=$android_arm32SysrootDir", "-D__ANDROID__", "-DUSE_GCC_UNWIND=1", "-DUSE_ELF_SYMBOLS=1", "-DELFSIZE=32", // HACKS! "-I$android_arm32SysrootDir/usr/include/c++/4.9.x", "-I$android_arm32SysrootDir/usr/include/c++/4.9.x/arm-linux-androideabi"], "android_arm64": ["-target", getTargetArg("android_arm64"), "--sysroot=$android_arm64SysrootDir", "-D__ANDROID__", "-DUSE_GCC_UNWIND=1", "-DUSE_ELF_SYMBOLS=1", "-DELFSIZE=64", // HACKS! "-I$android_arm64SysrootDir/usr/include/c++/4.9.x", "-I$android_arm64SysrootDir/usr/include/c++/4.9.x/aarch64-linux-android"] ] } ext.targetList = ext.targetArgs.keySet() as List if (isLinux()) { binDir = "$gccToolchainDir/$gnuTriplet/bin" ext.clangArgs.addAll([ "--gcc-toolchain=$gccToolchainDir" ]) } else if (isWindows()) { binDir = "$mingwWithLlvmDir/bin" } else { binDir = "$macbookSysrootDir/usr/bin" } ext.clangArgs << "-B$binDir" ext.hostClangArgs = ext.clangArgs.clone() ext.hostClangArgs.addAll(ext.targetArgs[host]) ext.clangPath << binDir ext.jvmArgs = ["-ea"] File jdkHome = new File(System.getProperty('java.home')).absoluteFile.parentFile ext.hostCompilerArgsForJni = ["", jniHostPlatformIncludeDir()].collect { "-I$jdkHome/include/$it" } as String[] } 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 isWindows() { return osName.startsWith('Windows'); } 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' if (isWindows()) return 'windows' throw unsupportedPlatformException() } String jniHostPlatformIncludeDir() { if (isMac()) return "darwin" if (isLinux()) return "linux" if (isWindows()) return "win32" throw unsupportedPlatformException() } Throwable unsupportedPlatformException() { return new Error("unsupported platform: $osName/$osArch") } } task dist_compiler(dependsOn: "distCompiler") task dist_runtime(dependsOn: "distRuntime") task cross_dist(dependsOn: "crossDist") task list_dist(dependsOn: "listDist") task distCompiler(type: Copy) { dependsOn ':backend.native:jars' dependsOn ':tools:helpers:jar' dependsOn ':utilities:jar' dependsOn ':klib: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(project(':utilities').file('build/libs')) { into('konan/lib') } from(project(':klib').file('build/libs')) { into('konan/lib') } from(file('cmd')) { fileMode(0755) into('bin') if (!isWindows()) { exclude('**/*.bat') } } from(konanPropertiesFile) { into('konan') } // TODO: check if we use native libraries copied to dist (see above) or not. from(project(':tools:helpers').file('build/libs')) { into('konan/lib') } } task listDist(type: Exec) { commandLine 'find', 'dist' } task distRuntime(type: Copy) { dependsOn "${host}CrossDistRuntime" dependsOn('commonDistRuntime') } task commonDistRuntime(type: Copy) { destinationDir file('dist') // Target independant common part. from(project(':runtime').file("build/${host}Stdlib")) { include('**') into('klib/stdlib') } } task crossDistRuntime(type: Copy) { dependsOn.addAll(targetList.collect { "${it}CrossDistRuntime" }) dependsOn('commonDistRuntime') } targetList.each { target -> task("${target}CrossDistRuntime", type: Copy) { dependsOn ":runtime:${target}Runtime" dependsOn ":backend.native:${target}Stdlib" dependsOn ":backend.native:${target}Start" destinationDir file('dist') from(project(':runtime').file("build/$target")) { include("*.bc") into("klib/stdlib/targets/$target/native") } from(project(':runtime').file("build/${target}Stdlib")) { include('**') into('klib/stdlib') } from(project(':runtime').file("build/${target}Start.bc")) { rename("${target}Start.bc", 'start.bc') into("klib/stdlib/targets/$target/native") } } } task dist { dependsOn 'distCompiler', 'distRuntime' } task crossDist { dependsOn 'crossDistRuntime', 'distCompiler' } task bundle(type: Tar) { dependsOn('crossDist') 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 '**/settings.gradle' exclude '**/build' exclude '**/.gradle' rename('(.*)\\.for_bundle', '$1') into baseName } destinationDir = file('.') extension = 'tar.gz' compression = Compression.GZIP } task clean { doLast { file('dist').traverse(type: FileType.ANY, excludeNameFilter: "dependencies", maxDepth: 0) { delete it } delete bundle.outputs.files } }