Qt, Qbs: generate moc_Filename.cpp automatically - qt

So I have a Q_OBJECT tagged class, which requires pregenerated .moc to be usable.
In my .qbs file, I have a CppApplication item; this seems to be the wrong type of project, as qbs does not call moc ClassName.cpp to generate moc's for me. What should be used instead/tweaked?
-
So I knew about Qt.core dependency, but it wasn't working on my crippled install of Qt; while I was trying to fix it, these facts came up:
It was required to detect Qt toolchain (qbs-setup-qt) and call qbs-config-ui
Qbs indeed stores the build rules in core.qbs, linked in via Qt/core dependency.
it's possible to copy/paste the build rules into my own .qbs file and avoid external dependencies; I'm considering this as a dirty hack for deploying the code on really crippled build systems (now I have a word for Qt support on Gentoo).

I think you might be missing the dependency of the application on the Qt-modules.
The rule for generation of the moc files is part of the Qt.core module.
You might add this dependency with:
CppApplication {
name: "MyApp"
files: "path_to_source/**"
Depends { name: "Qt.core" } // Optional
Depends { name: "Qt.widgets" }
}
As all other Qt modules have an implicit dependency on Qt.core the explicit dependency could on Qt.core could be skipped if there is a dependency on a different Qt-module (Qt.widgets in this example).
More details could be found at http://doc.qt.io/qbs/qt-modules.html

Related

Execute sbt task without prior compiling (for generating database classes with JOOQ)

I have a PlayFramework 2.7 application which is build by sbt.
For accessing the database, I am using JOOQ. As you know, JOOQ reads my database schema and generates the Java source classes, which then are used in my application.
The application only compiles, if the database classes are present.
I am generating the classes with this custom sbt task:
// https://mvnrepository.com/artifact/org.jooq/jooq-meta
libraryDependencies += "org.jooq" % "jooq-meta" % "3.12.1"
lazy val generateJOOQ = taskKey[Seq[File]]("Generate JooQ classes")
generateJOOQ := {
(runner in Compile).value.run("org.jooq.codegen.GenerationTool",
(fullClasspath in Compile).value.files,
Array("conf/db.conf.xml"),
streams.value.log).failed foreach (sys error _.getMessage)
((sourceManaged.value / "main/generated") ** "*.java").get
}
I googled around and found the script above and modified it a little bit according to my needs, but I do not really understand it, since sbt/scala are new to me.
The problem now is, when I start the generateJOOQ, sbt tries to compile the project first, which fails, because the database classes are missing. So what I have to do is, comment all code out which uses the generated classes, execute the task which compiles my project, generates the database classes and then enable the commented out code again. This is a pain!
I guess the problem is the command (runner in Compile) but I did not find any possibility to execute my custom task WITHOUT compiling first.
Please help! Thank you!
Usually, when you want to generate sources, you should use a source generator, see https://www.scala-sbt.org/1.x/docs/Howto-Generating-Files.html
sourceGenerators in Compile += generateJOOQ
Doing that automatically causes SBT to execute your task first before trying to compile the Scala/Java sources.
Then, you should not really use the runner task, since that is used to run your project, which depends on the compile task, which needs to execute first of course.
You should add the jooq-meta library as a dependeny of the build, not of your sources. That means you should add the libraryDependencies += "org.jooq" % "jooq-meta" % "3.12.1" line e.g. to project/jooq.sbt.
Then, you can simply call the GenerationTool of jooq just as usually in your task:
// build.sbt
generateJOOQ := {
org.jooq.codegen.GenerationTool.main(Array("conf/db.conf.xml"))
((sourceManaged.value / "main/generated") ** "*.java").get
}

Gradle implementation vs compile in jar task

I can successfully use Gradle to compile a fat JAR, but having trouble running the JAR after recently switching from the "compile" dependency specification to the "implementation/api" specification. I have isolated that the problem occurs in only one of the two following cases. The application runs in either case inside IntelliJ.
first/problem:
dependencies {implementation 'no.tornado:tornadofx:1.7.18'}
second/works:
dependencies {compile'no.tornado:tornadofx:1.7.18'}
The JAR compiles in both cases. The problem appears when I attempt to start the first case JAR on the command line and it throws the following error.
C:\aaa_eric\code\testr\mic\build\libs>java -jar mic-1.0-snapshot.jar
Error: Could not find or load main class app.MyApp
Caused by: java.lang.NoClassDefFoundError: tornadofx/App
Here is the JAR task in build.gradle. Is it possible that the tornadofx dependency is available at compile time, but not at run time? Thanks for any help.
jar {
manifest {
attributes 'Main-Class': 'app.MyApp'
}
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
Changing configurations.compile.collect to configurations.compileClasspath.collect fixed the problem for me.
I was having the same problem and stumbled across this in https://docs.gradle.org/current/javadoc/org/gradle/api/artifacts/ConfigurationContainer.html:
An example showing how to refer to a given configuration by name in
order to get hold of all dependencies (e.g. jars, but only)
apply plugin: 'java' //so that I can use 'implementation', 'compileClasspath' configuration
dependencies {
implementation 'org.slf4j:slf4j-api:1.7.26'
}
//copying all dependencies attached to 'compileClasspath' into a specific folder
task copyAllDependencies(type: Copy) {
//referring to the 'compileClasspath' configuration
from configurations.compileClasspath
into 'allLibs'
}
One thing to note is that configurations.compileClasspath.collect worked for me even when I was using the compile specification instead of implement.

How to find Libpng library used in android project

When I upload my project to google play store I am getting Libpng library error and app getting rejected. I am not sure where it been used. I been used many library might be among those. How can I find it out exactly where this been used.
Is there any way to force fully by pass this like (Just an example)-
resolutionStrategy {
force 'com.google.android.gms:play-services-vision:11.4.2'
}
To get the list of dependency you can run this from Gradle -> Dependencies
Then you can find out which library causing issue and you can exclude it like this
dependencies
{
compile 'com.android.support:support-v4:xx.0.+'
compile ("com.xxx:xxx-commons:1.+")
{
exclude group: 'junit', module: 'junit'
}
}

Can't understand gradle jar task code that creates executable fat-jar

I am learning Gradle but I don't understand the jar task code that creates a jar with all the dependencies inside ( taken from Gradle Cookbook ):
jar {
baseName = jarBaseName
manifest { attributes "Main-Class": mainClass }
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
My questions are:
1.The task name is jar. Because it's not written like jar<<{...} I'm assuming that this is run in the configuration phase, and not the execution one. Am I correct?
2.What exactly is configurations.compile? I'm assuming that some kind of dependencies classpath is queried, and each jar is zipTree-ed. Then all of this stuff is merged with the base classpath
. Please elaborate about it
3.The zipTree method, I'm assuming it kind of unarchives each jar but I'm not sure. Am I correct?
Regards,
Yes You're correct. When no action added (mostly with << see docs) the code is run at configuration phase. The code You provided is also run at configuration phase.
configurations.compile refers to a configuration named compile using configurations object (a kind of a configurations container). Prior to gradle 2.0 compile configuration is provided by default with java plugin. AFAIR now it's called javaCompile. According to zipTree You're also correct.
Yes You're.

How do you do develop an SBT project, itself?

Background: I've got a Play 2.0 project, and I am trying to add something to do aspectj weaving using aspects in a jar on some of my classes (Java). (sbt-aspectj doesn't seem to do it, or I can't see how). So I need to add a custom task, and have it depend on compile. I've sort of figured out the dependency part. However, because I don't know exactly what I'm doing, yet, I want to develop this using the IDE (I'm using Scala-IDE). Since sbt projects (and therefore Play projects) are recursively defined, I assumed I could:
Add the eclipse plugin to the myplay/project/project/plugins.sbt
Add the sbt main jar (and aspectj jar) to myplay/project/project/build.sbt:
libraryDependencies ++= Seq(
"org.scala-sbt" % "main" % "0.12.2",
"aspectj" % "aspectj-tools" % "1.0.6"
)
Drop into the myplay/project
Run sbt, run the eclipse task, then import the project into eclipse as a separate project.
I can do this, though the build.scala (and other scala files) aren't initially considered source, and I have to fiddle with the build path a bit. However, even though I've got the sbt main defined for the project, both eclipse IDE and the compile task give errors:
> compile
[error] .../myplay/project/Build.scala:2: not found: object keys
[error] import keys.Keys._
[error] ^
[error] .../myplay/project/SbtAspectJ.scala:2: object Configurations is not a member of package sbt
[error] import sbt.Configurations.Compile
[error] ^
[error] .../myplay/project/SbtAspectJ.scala:3: object Keys is not a member of package sbt
[error] import sbt.Keys._
[error] ^
[error] three errors found
The eclipse project shows neither main nor aspectj-tools in its referenced-libraries. However, if I give it a bogus version (e.g. 0.12.4), reload fails, so it appears to be using
the dependency.
So,...
First: Is this the proper way to do this?
Second: If so, why aren't the libs getting added.
(Third: please don't let this be something dumb that I missed.)
If you are getting the object Keys is not a member of package sbt error, then you should check that you are running sbt from the base directory, and not the /project directory.
sbt-aspectj
sbt-aspectj doesn't seem to do it, or I can't see how.
I think this is the real issue. There's a plugin already that does the work, so try making it work instead of fiddling with the build. Using plugins from build.scala is a bit tricky.
Luckily there are sample projects on github:
import sbt._
import sbt.Keys._
import com.typesafe.sbt.SbtAspectj.{ Aspectj, aspectjSettings, compiledClasses }
import com.typesafe.sbt.SbtAspectj.AspectjKeys.{ binaries, compileOnly, inputs, lintProperties }
object SampleBuild extends Build {
....
// precompiled aspects
lazy val tracer = Project(
"tracer",
file("tracer"),
settings = buildSettings ++ aspectjSettings ++ Seq(
// stop after compiling the aspects (no weaving)
compileOnly in Aspectj := true,
// ignore warnings (we don't have the sample classes)
lintProperties in Aspectj += "invalidAbsoluteTypeName = ignore",
// replace regular products with compiled aspects
products in Compile <<= products in Aspectj
)
)
}
How do you do develop an SBT project, itself?
If you're interested in hacking on the build still the first place to go is the Getting Started guide. Specifically, your question should be answered in .scala Build Definition page.
I think you want your build to utilize "aspectj" % "aspectj-tools" % "1.0.6". If so it should be included in myplay/project/plugins.sbt, and your code should go into myplay/project/common.scala or something. If you want to use IDE, you have have better luck with building it as a sbt plugin. That way your code would go into src/main/scala. Check out sbt/sbt-aspectj or sbt/sbt-assembly on example of sbt plugin structure.

Resources