I'm trying to use gradle to build simple native application. The below is an example code from Gradle documentation of native plugins.
model {
components {
main(NativeLibrarySpec) {
sources {
cpp {
source {
srcDirs "src/main/cpp", "src/shared/c++"
include "**/*.cpp"
}
exportedHeaders {
srcDirs "src/main/include", "src/shared/include"
}
}
}
}
}
}
I have several questions:
What do model, component words mean? I read about the model rules, but I don't get the idea and new syntax. Model looks like the method invocation, but there is not such method in Project class. The same for components, where is it from?
The second questions is about syntax main(NativeLibrarySpec) { .. }. What does it mean? It looks like method invocation, but why do we use the NativeLibrarySpec interface name as a parameter?
Where from does cpp name go on? I see that NativeLibrarySpec has the sources method has prototype void sources(Action<? super ModelMap<LanguageSourceSet>> action) and what does ? super .. mean? I don't understand why do we use the name cpp? How can I find out this in documentation?
Gradle is a nightmare for me..
Related
I am running assemble for my library module , I see from logs that it should generate two files myLib-release.aar and myLib-debug.aar inside the myLib/build/outputs/ folder.
However, I always only find one lib there that is myLib.aar, it doesn't matter if I run assemble for both, assembleDbug or assembleRelease.
Why is this happening?
According to this discussion it is an error (or planned feature) in gradle, up to date it is still the same.
https://github.com/gradle/gradle/issues/8328
Workaround can be to implement this:
// in library/library.gradle
afterEvaluate {
def debugFile = file("$buildDir/outputs/aar/library.aar")
tasks.named("assembleDebug").configure {
doLast {
debugFile.renameTo("$buildDir/outputs/aar/library-debug.aar")
}
}
tasks.named("assembleRelease").configure {
doLast {
debugFile.renameTo("$buildDir/outputs/aar/library-release.aar")
}
}
}
You may then implement copy tasks as desired.
I'm working on project, where we're using Stripe library for Node. We also want to use TypeScript on this project.
I've figured out that Stripe isn't providing official TypeScript definitions but I've found some community definitions #types/stripe on NPM. So I installed them and after a while I got an error:
Property 'sources' does not exist on type 'Stripe'.
Well there are missing some definitions, for example for this stripe.sources-related functionality.
I want to add missing definitions locally. So I need to extend this file:
#types/stripe/index.d.ts
I think that for the problem above I need:
to add property sources: Stripe.resources.Sources; to class Stripe,
to add class Sources to namespace resources,
to add missing function declarations to class Sources.
The problem is that I really don't know how. How should the .d.ts file with extensions look like? I've made many attempts according some examples and TypeScript docs but it always doesn't work. Do you have any idea?
I don't believe there's a way to augment the export-assigned Stripe class; the problem is similar to this open issue about augmenting a default-exported class. At this time, since you can't use augmentation, you'll have to fork the #types/stripe definitions for your project, and then you may as well make all the desired changes that way.
I think my colleague has found a solution that works for me. Here is how he made it:
import ST from 'stripe'
declare module 'stripe' {
namespace sources {
interface ISource extends IResourceObject {
...
}
interface ISourceCreationData {
...
}
}
namespace resources {
class Sources {
create(data: sources.ISourceCreationData): Promise<sources.ISource>;
retrieve(source: string, client_secret?: string): Promise<sources.ISource>;
}
}
class Stripe extends ST {
sources: ST.resources.Sources;
}
}
I would like to enforce static linking for a whole package in groovy. Static linking requires use of CompileStatic. I would like to avoid restating this on every class. How can I apply this as a package-level annotation. I have found no reference to package-level annotations in groovy.
Can you please provide a piece of code that shows how to apply the annotation to a package a.b.c?
This is untested, but I think it should be possible to create a nice combination of a configurationScript, a Source aware customizer and a AST transformation customizer explained in dsl docs.
something like:
withConfig(configuration) {
source(unitValidator: { unit -> unit.AST.classes.any { it.packageName== 'a.b.c' } }) {
ast(CompileStatic)
}
}
Given an extension registered in gradle as foo:
class Foo {
Project proj
void setProject( Project project) {
this.proj = project
}
void setProject( String project) {
// do stuff
}
}
How do I get:
foo {
project = ':random-project'
}
to call the string setter and not fail in setProperty of the decorated extension object due to GroovyCastException?
The reason for this question arose from this issue: https://github.com/Centril/gradle-plugin-robospock/issues/5
Since I don't see any better answer yet, I am trying to suggest a possible alternative.
If you can keep type of proj as a String in Foo and where you actually use the instance of Foo class, lookup the project using the findProject method on the project object available to your plugin.
class FooPlugin implements Plugin<Project> {
// ...
void apply(Project project) {
// ...
project.findProject(fooInstance.proj)
}
}
You may find more on findProject or project methods to locate a project by path at API Documentation
There might be a way to access current Project instance in your Foo class then you may use the overloaded setter.
This works in Gradle versions 2.0 and later which is likely due to the move from Groovy 1.x to 2.x. I'd suggest using a later version of Gradle if that is possible.
Luke Daley from Gradleware informed me that this is a limitation of the Groovy language: https://issues.apache.org/jira/browse/GROOVY-2500
I want to publish few artifacts using base plugin. This is how my build looks like:
apply plugin: 'base'
group = 'eu.com'
version = '0.9'
def winCdZip = file('dist/winCd.zip')
configurations {
wincd
}
repositories {
ivy {
url 'http://ivy.repo'
}
}
artifacts {
wincd winCdZip
}
buildscript {
repositories {
ivy {
url 'http://ivy.repo'
}
}
dependencies {
classpath group: 'eu.com', name:'MyCustomTask', version:'0.9-SNAPSHOT', configuration: 'runtime'
}
}
buildWincd {
// call MyCustomTask; is it possible to call it in this way?
MyCustomTask {
// pass few parameters required by this task
}
// I know that it's impossible to call zip in this way but I don't want to create another task
zip {
// build zip and save it in 'winCdZip'
}
}
uploadWincd {
repositories { add project.repositories.ivy }
}
And those are my problems to solve:
Is it possible to create nested tasks?
Is it possible to call zip without create new task but with closures?
Is it possible to call custom task using closures (the same example as at 2nd point)?
I can create zip/custom task in this way
task myZip(type: Zip) {
// do the job
}
is it possible to call it in this way?
zip {
// do the job
}
If it is not possible to call tasks using closures, how can I do it? Creating new tasks is the only way? Maybe I can create nested tasks?
The answer to your questions is 'no'. Gradle is a declarative build system. Instead of having one task call another, you declare task dependencies, which Gradle will obey during execution.
For some task types (e.g. Copy), there is an equivalent method (e.g. project.copy), but not for Zip. In most cases, it's better to use a task even if a method exists.
The first several chapters of the Gradle User Guide explain core Gradle concepts such as task dependencies in detail.