I am using Gradle's eclipse plugin. For cross-project reference reasons, I need Eclipse's output directory to not be the default bin, rather ecbuild.
Everytime I run ./gradlew eclipse, it overwrites this output directory setting.
How to make sure it doesn't, or how to set it within gradle build script ?
Add this to the build.gradle script:
eclipse {
classpath { defaultOutputDir = file('ecbuild') }
}
This might require you to upgrade the version of your gradle wrapper.
If so, run :
./gradlew wrapper --gradle-version 3.3
In my case, seting defaultOutputDir was not enough. So I did the following:
eclipse {
classpath {
defaultOutputDir = file("build")
file.whenMerged {
entries.each { entry ->
if (entry.kind == 'src' && entry.hasProperty('output')) {
entry.output = entry.output.replace('bin/', "build/")
}
}
}
}
}
Related
Can I convince Gradle to produce multiple binaries? I have several Kotlin packages with files that have a proper "fun main(...)" but the default IntelliJ build.gradle file only allows me to specifiy one "compilations.main.entryPoint".
I could put the main functions into Kotlin classes or objects if that would help.
Changing the entryPoint argument to an array did not work :)
If it's not currently possible, is it a general limitation of Gradle or only of the "kotlin-multiplatform" plugin?
plugins {
id 'kotlin-multiplatform' version '1.3.11'
}
repositories {
mavenCentral()
}
kotlin {
targets {
// For ARM, preset should be changed to presets.iosArm32 or presets.iosArm64
// For Linux, preset should be changed to e.g. presets.linuxX64
// For MacOS, preset should be changed to e.g. presets.macosX64
fromPreset(presets.mingwX64, 'mingw')
configure([mingw]) {
// Comment to generate Kotlin/Native library (KLIB) instead of executable file:
compilations.main.outputKinds('executable')
// Change to specify fully qualified name of your application's entry point:
compilations.main.entryPoint = 'hello.main'
}
}
sourceSets {
// Note: To enable common source sets please comment out 'kotlin.import.noCommonSourceSets' property
// in gradle.properties file and re-import your project in IDE.
mingwMain {
}
mingwTest {
}
}
}
task runProgram {
def buildType = 'debug' // 'release' - Change to 'debug' to run application with debug symbols.
dependsOn "link${buildType.capitalize()}ExecutableMingw"
doLast {
def programFile = kotlin.targets.mingw.compilations.main.getBinary('EXECUTABLE', buildType)
exec {
executable programFile
args ''
}
}
}
In https://github.com/JetBrains/kotlin-native/issues/2505 I've just got the answer that this will be possible with Kotlin Native 1.3.20!
I'm trying to compile my Kotlin app and set of Kotlin libraries to JavaScript. I've got that working well, but when I try to run it it can't find kotlin.js.
So what's going on here? When I compile using IDEA (instead of Gradle), it outputs kotlin.js just fine. I tried making my build script more like an example I found, but that wouldn't compile...
Here's a link to the code and project in question: https://github.com/BlueHuskyStudios/Decision-Cruncher/blob/SO/q/53582651/1/build.gradle
This only worked for me. unzip for some reason was no working
task assembleWeb() {
configurations.implementation.setCanBeResolved(true)
configurations.implementation.each { File file ->
if (file.path.indexOf('kotlin-stdlib-js') >= 0) {
exec {
workingDir "$projectDir/web"
standardOutput = new ByteArrayOutputStream()
commandLine "7z", "e", file.absolutePath, "kotlin.js", "-aos", "-r"
}
}
}
dependsOn classes
}
assemble.dependsOn assembleWeb
Be aware of "-aos" param. This flag will prevent from overwriting of existing file
Here you can find the code snippet to extract all .js files from Kotlin/JS libraries:
task assembleWeb(type: Sync) {
configurations.compile.each { File file ->
from(zipTree(file.absolutePath), {
includeEmptyDirs = false
include { fileTreeElement ->
def path = fileTreeElement.path
path.endsWith(".js") && (path.startsWith("META-INF/resources/") ||
!path.startsWith("META-INF/"))
}
})
}
from compileKotlin2Js.destinationDir
into "${projectDir}/web"
dependsOn classes
}
assemble.dependsOn assembleWeb
For any others struggling in the future, I've had the following issue:
IntelliJ Kotlin/JS starter project has been generated with this in the gradle file:
implementation "org.jetbrains.kotlin:kotlin-stdlib-js"
which needs to be this to get the kotlin.js file
compile "org.jetbrains.kotlin:kotlin-stdlib-js"
In my Gradle build script I want to import a ZIP dependency that contains static analysis configuration (CheckStyle, PMD etc.) and then "apply from" the files in that ZIP. When anyone runs the "check" task, my custom static analysis configuration should be used then.
I've tried the somewhat convoluted solution below, but I can't get it to work. The files are retrieved and unpacked into the "config" directory, but "apply from" does not work - Gradle complains it cannot find the files; I assume this is due to "apply from" being run during the build configuration phase.
Is there a simpler way to do this?
repositories {
maven { url MY_MAVEN_REPO }
}
configurations {
staticAnalysis {
description = "Static analysis configuration"
}
}
dependencies {
staticAnalysis group:'my-group', name:'gradle-static-analysis-conf', version:'+', ext:'zip'
}
// Unzip static analysis conf files to "config" in root project dir.
// This is the Gradle default location.
task prepareStaticAnalysisConf(type: Copy) {
def confDir = new File(rootProject.projectDir, "config")
if (!confDir.exists()) {
confDir.mkdirs()
}
from {
configurations.staticAnalysis.collect { zipTree(it) }
}
into confDir
apply from: 'config/quality.gradle'
}
check.dependsOn('prepareStaticAnalysisConf')
You are perfectly right: Gradle runs apply during evaluation phase, but the prepareStaticAnalysisConf was not executed yet and the archive is not unpacked.
Instead of a task, just write some top-level code. It should do the trick. Also, you'd better use the buildscript level dependency, so that it is resolved before script is executed.
Here is the full script
buildScript {
repositories {
maven { url MY_MAVEN_REPO }
}
dependencies {
classpath group:'my-group', name:'gradle-static-analysis-conf', version:'+', ext:'zip'
}
}
def zipFile = buildscript.configurations.classpath.singleFile
copy {
from zipTree(it)
into 'config'
}
apply from: 'config/quality.gradle'
My gradle project generates some java code inside gen/main/java using annotation processor. When I import this project into Eclipse, Eclipse will not automatically add gen/main/java as source folder to buildpath. I can do it manually. But is there a way to automate this?
Thanks.
You can easily add the generated folder manually to the classpath by
eclipse {
classpath {
file.whenMerged { cp ->
cp.entries.add( new org.gradle.plugins.ide.eclipse.model.SourceFolder('gen/main/java', null) )
}
}
}
whereby null as a second constructor arg means that Eclipse should put the compiled "class" files within the default output folder. If you want to change this, just provide a String instead, e.g. 'bin-gen'.
I think it's a little bit cleaner just to add a second source directory to the main source set.
Add this to your build.gradle:
sourceSets {
main {
java {
srcDirs += ["src/gen/java"]
}
}
}
This results in the following line generated in your .classpath:
<classpathentry kind="src" path="src/gen/java"/>
I've tested this with Gradle 4.1, but I suspect it'd work with older versions as well.
Andreas' answer works if you generate Eclipse project from command line using gradle cleanEclipse eclipse. If you use STS Eclipse Gradle plugin, then you have to implement afterEclipseImport task. Below is my full working snippet:
project.ext {
genSrcDir = projectDir.absolutePath + '/gen/main/java'
}
compileJava {
options.compilerArgs += ['-s', project.genSrcDir]
}
compileJava.doFirst {
task createGenDir << {
ant.mkdir(dir: project.genSrcDir)
}
createGenDir.execute()
println 'createGenDir DONE'
}
eclipse.classpath.file.whenMerged {
classpath - >
def genSrc = new org.gradle.plugins.ide.eclipse.model.SourceFolder('gen/main/java', null)
classpath.entries.add(genSrc)
}
task afterEclipseImport(description: "Post processing after project generation", group: "IDE") {
doLast {
compileJava.execute()
def classpath = new XmlParser().parse(file(".classpath"))
new Node(classpath, "classpathentry", [kind: 'src', path: 'gen/main/java']);
def writer = new FileWriter(file(".classpath"))
def printer = new XmlNodePrinter(new PrintWriter(writer))
printer.setPreserveWhitespace(true)
printer.print(classpath)
}
}
I am trying to tell gradle that files with the *.dsl extension should be compiled as groovy files, so I have added a source set with the inclusion pattern and changed the compile task includes property:
sourceSets {
...
dsl_scripts {
groovy {
include '**/*.dsl'
}
}
}
compileDsl_scriptsGroovy.includes = ['**/*.dsl']
But when I run the build under a debug mode it skips all *.dsl files with the following message:
Skipping task ':compileDsl_scriptsGroovy' as it has no source files
The following line successfully outputs all the files I try to compile:
println sourceSets.dsl_scripts.allSource.matching({include '**/*.dsl'}).getFiles()
What do I do wrong?
EDIT:
I found the following snippet in gradle sources:
FileCollection groovyJavaOnly = spec.getSource().filter(new Spec<File>() {
public boolean isSatisfiedBy(File element) {
return element.getName().endsWith(".groovy") || element.getName().endsWith(".java");
}
});
spec.setSource(new SimpleFileCollection(groovyJavaOnly.getFiles()));
Is it possible to override?
It seems to be a gradle bug http://issues.gradle.org/browse/GRADLE-2372