How do I get buildr to put dependencies on subprojects into the POM? - pom.xml

One of my Buildr buildfiles is structured like this:
require 'buildr/custom_pom'
# Omitting a lot of off-topic header stuff.
# Full version of the file is at GitHub.
desc 'Main project'
define 'hex' do
project.version = VERSION_NUMBER
project.group = 'org.trypticon.hex'
pom.add_lgpl_v3_license
pom.add_github_project('trejkaz/hex-components')
pom.add_developer('trejkaz', 'Trejkaz', 'trejkaz#trypticon.org')
desc 'Hex Utilities'
define 'util' do
pom.description = 'Utilities used by other hex components'
compile.with INTELLIJ_ANNOTATIONS
compile.with ICU4J
compile.with SWINGX
package :jar
package :sources
package :javadoc
end
#... omitting more ...
desc 'Hex Viewer'
define 'viewer' do
pom.description = 'Hex viewer and related components'
compile.with projects('anno', 'binary', 'interpreter', 'util')
compile.with INTELLIJ_ANNOTATIONS
compile.with SWINGX
package :jar
package :sources
package :javadoc
end
end
hex-viewer depends on hex-util. Yet when Buildr creates the POM, the POM is missing these dependencies between the subprojects.
Reading the source of Buildr itself, it seems that they deliberately omit all dependencies which are not an Artifact for some reason. Subprojects not being artifacts, they naturally get omitted from the POM.
Is there a workaround to get them back in?

Related

How to add do_populate_sdk task to avro-c BitBake recipe?

This question is specific to avro-c, but the solution may be generalized to other packages in the OpenEmbedded BitBake system.
How do I create a do_populate_sdk task for avro-c?
I want to generate a Yocto SDK which includes avro-c. The avro-c layer in meta-openembedded is very small:
avro
├── avro-c
│   └── 0001-avro-c-Fix-build-with-clang-compiler.patch
└── avro-c_1.8.1.bb
The avro-c_1.8.1.bb recipe is only 20 lines:
SUMMARY = "Apache Avro data serialization system."
HOMEPAGE = "http://apr.apache.org/"
SECTION = "libs"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=73bdf70f268f0b3b9c5a83dd7a6f3324"
DEPENDS = "jansson zlib xz"
PV .= "+git${SRCPV}"
SRCREV = "4b3677c32b879e0e7f717eb95f9135ac654da760"
SRC_URI = "git://github.com/apache/avro \
file://0001-avro-c-Fix-build-with-clang-compiler.patch;patchdir=../../ \
"
S = "${WORKDIR}/git/lang/c"
LDFLAGS_append_libc-uclibc = " -lm"
inherit cmake
A target image which includes avro-c builds successfully, and ls /usr/bin/avro* lists the Avro functions.
However, avro-c is not included in the host SDK build. One way to troubleshoot this is to try the two commands:
$ bitbake avro-c
$ bitbake avro-c -c populate_sdk
The first command completes successfully. The second command fails with the following error messages:
ERROR: Task do_populate_sdk does not exist for target avro-c (/home/rdepew/workspace/clean1/build/../layers/meta-sporian/recipes-support/avro/avro-c_1.8.1.bb:do_populate_sdk). Close matches:
do_populate_lic
do_populate_sysroot
ERROR: Command execution failed: 1
I looked for clues in the other layers in my build system. It appeared that creating the file avro-c_%.bbappend, containing the single line
inherit nativesdk
might do the trick, but that generated two more BitBake error messages:
ERROR: Nothing PROVIDES 'virtual/x86_64-pokysdk-linux-compilerlibs' (but /home/rdepew/workspace/clean1/build/../layers/meta-sporian/recipes-support/avro/avro-c_1.8.1.bb DEPENDS on or otherwise requires it). Close matches:
virtual/nativesdk-x86_64-pokysdk-linux-compilerlibs
virtual/x86_64-pokysdk-linux-go-crosssdk
virtual/x86_64-pokysdk-linux-gcc-crosssdk
ERROR: Required build target 'avro-c' has no buildable providers.
Missing or unbuildable dependency chain was: ['avro-c', 'virtual/x86_64-pokysdk-linux-compilerlibs']
... and that's where I'm stuck. I'm not sure where to go from here.
Online places that I have researched:
I don't know if it's appropriate to list the URLS of places where I have looked for the answer. They include the GitHub repository for Avro, the Yocto Project ADT manual, and four related questions on StackOverflow. If it's appropriate, I will edit this question to include the URLs.
The right way to add something to SDK (or eSDK - Extended SDK) is via the image of your choice. So, the steps are:
Add a package to the image:
IMAGE_INSTALL_append = " avro-c"
Create Yocto SDK for an image of your choice:
bitbake core-image-full-cmdline -c populate_sdk
Create Yocto eSDK for an image of your choice:
bitbake core-image-full-cmdline -c populate_sdk_ext
Have fun! :-)
You need the following line in your recipe
BBCLASSEXTEND = "nativesdk"
This extends the same recipe to build for sdk as well. See here for more details.
EDIT:
do_populate_sdk: This task applies only for the image recipe. This handles two operations.
Target part: Compiles and installs the header and libraries for the target platform.
Host part: Installs the host part of the library and header based on SDKMACHINE
During these operations, it finds the list of packages needed for the SDK by examining the BBCLASSEXTEND variable and builds the nativesdk-<recipe_name> for combines them together in SDK.
So you have do_populate_sdk for image recipe which bundles the packages together.
See yocto manual here for more details.

Bazel Maven migration Transitive Dependencies Scope

I am trying to use the generate_workspace on one of the project which has deps and transitive dependencies. Once thegenerate_workspace.bzl has been generated and I copied it to the WORKSPACE and followed the instruction in the bazel docs. Though I see the deps and their transitive deps listed in the generate_workspace.bzl my project during java_library phase is not able resolve transitive deps.. when I import the same project in IDEA I don't see the jars correctly loaded.
My doubt is for the deps I see the generate_workspace.bzl is adding its transitve deps as runtime_deps which means they are available only during runtenter code hereime
I have created gist of all the files here
https://gist.github.com/kameshsampath/8a4bdc8b22d85bbe3f243fa1b816e464
Ideally in my maven project I just need https://gist.github.com/kameshsampath/8a4bdc8b22d85bbe3f243fa1b816e464#file-src_main_build-L8-L9, though generate_workspace.bzl has resolved rightly i thought its enough if my src/main/BUILD looks like
java_binary(
name = "main",
srcs = glob(["java/**/*.java"]),
resources = glob(["resources/**"]),
main_class = "com.redhat.developers.DemoApplication",
# FIXME why I should import all the jars when they are transitive to spring boot starter
deps = [
"//third_party:org_springframework_boot_spring_boot_starter_actuator",
"//third_party:org_springframework_boot_spring_boot_starter_web",
],
)
But sadly that gives lots of compilation errors as transitive deps are not getting loaded as part the above declaration. eventually I have to define like how I did in the https://gist.github.com/kameshsampath/8a4bdc8b22d85bbe3f243fa1b816e464#file-src_main_build
src_main_build is BUILD file under package src/main/BUILD
third_party_BUILD is the BUILD under package third_party/BUILD
Bazel expects you to declare all your direct dependencies. I.e. if you directly use a class from jar A, you need to have it in your direct dependencies.
What you are looking for is a deploy jar. This is a bit hacky but you can actually do it that way (in third_party/BUILD):
java_binary(
name = "org_springframework_boot_spring_boot_starter_actuator_bin",
main_class = "not.important",
runtime_deps = [":org_springframework_boot_spring_boot_starter_actuator"], )
java_import(
name = "springframework_actuator",
jars = [":org_springframework_boot_spring_boot_starter_actuator_bin_deploy.jar"],
)
This will bundle all dependencies except the neverlink one in a jar (the _deploy.jar) and reexpose it.
An update: rules_jvm_external is the officially maintained ruleset by the Bazel team to fetch and resolve artifacts transitively.
You can find the example for Spring Boot here. The declaration in the WORKSPACE file looks something like this:
load("#rules_jvm_external//:defs.bzl", "maven_install")
maven_install(
artifacts = [
"org.hamcrest:hamcrest-library:1.3",
"org.springframework.boot:spring-boot-autoconfigure:2.1.3.RELEASE",
"org.springframework.boot:spring-boot-test-autoconfigure:2.1.3.RELEASE",
"org.springframework.boot:spring-boot-test:2.1.3.RELEASE",
"org.springframework.boot:spring-boot:2.1.3.RELEASE",
"org.springframework.boot:spring-boot-starter-web:2.1.3.RELEASE",
"org.springframework:spring-beans:5.1.5.RELEASE",
"org.springframework:spring-context:5.1.5.RELEASE",
"org.springframework:spring-test:5.1.5.RELEASE",
"org.springframework:spring-web:5.1.5.RELEASE",
],
repositories = [
"https://jcenter.bintray.com",
]
)

Building a Jar of a Frege project using Gradle

I would like to:
use the Frege programming language to write a simple "Hello World" piece of code,
then using the Frege compiler generating the equivalent Java source code,
then building an executable Jar file to run from the command line,
all the previous steps should be "controlled" by Gradle.
I am able to generate the source code (items 1. and 2. from the previous list), but I am not able to specify a "package" structure of the Java source code in output, i.e. I can not see the package Java statement as the first line of code in the generate Java source code. I can specify to the Frege compiler where to put the generated code though (via the -d argument).
I think this is the reason why when building an executable Jar, then launching it, I am seeing similar errors (according to different attempts on Gradle tasks) e.g.: no main manifest attribute.
The Frege source code is saved in a file named HelloFrege.fr, the generated Java source code is in a file named HelloFrege.java (I verified the file contains the expected main method).
Here there's a version of the Gradle "Jar task":
//create a single Jar with all dependencies
task fatJar(type: Jar) {
manifest {
attributes 'Implementation-Title': 'Hello Frege Jar Example',
'Implementation-Version': version,
'Main-Class': 'HelloFrege'
}
baseName = project.name + '-all'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
Here there's another version of the Gradle "Jar" task:
jar {
manifest {
attributes 'Main-Class': 'HelloFrege'
}
}
How can I solve this problem? I would like to avoid to manually add the package reference to the automatically generated Java source code file.
If your module name in Frege is unqualified such as HelloWorld, you will not see the package statement generated in Java. The module name will become the class name and the package will be empty or default package.
If your module name is qualified such as foo.bar.HelloWorld, then foo.bar will be the package name and HelloWorld will be the class name in the generated Java source.
The rule is that the last part of the module name becomes the class name and the qualifiers form the package name in the generated Java source.
I am not sure what gradle can do for you in this regard, but without gradle, the following should at least be possible:
... build your jar, as before ...
jar -uvfe project-all.jar HelloFrege
java -jar project-all.jar # run it
This, of course, is just another way to create a manifest. If this works, then it would be time to investigate why gradle refuses to do it.
Postscriptum: After thinking another minute about what the problem might be, it occurs to me that you may think that the source file name/path has anything to do with the java package name. This is not so in Frege, though it is good practice to have the file path match the package name, and the file base name match the class name (just like in Java). In addition, to remove some confusion, use the module keyword in frege. As explained by Marimuthu, the Java package and class name is derived from the frege module name.
Example:
$ cat Foo.fr
module my.org.Baz where
...
$ java -jar fregec.jar -d bin Foo.fr
This generates the Baz class in package my.org, and creates the class file in bin/my/org/Baz.class
I am posting here my findings so far. The combination of Gradle commands that works for me is the following one (calling it from the command line typing gradle clean generateJavaSrcFromFregeSrc fatJar):
task generateJavaSrcFromFregeSrc {
ant.java(jar:"lib/frege3.21.586-g026e8d7.jar",fork:true) {
arg(value: "-j") // do not run the java compiler
arg(value: "-d")
arg(value: "src/main/java") // the place where to put the generated source code (paired to the -d argument)
arg(value: "src/main/frege/HelloFrege.fr")
}
}
jar {
manifest {
attributes 'Main-Class': 'org.wathever.HelloFrege'
}
}
task fatJar(type: Jar) {
from files(sourceSets.main.output.classesDir)
from files(sourceSets.main.output.resourcesDir)
//from {configurations.compile.collect {zipTree(it)}} // this does not include the autogenerated source code
baseName = project.name + '-fatJar'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
The manifest details need to be specified in the jar block of code, if I specify them in the task fatJar then when running the jar I get no main manifest attribute, in [...].
If I use just the block of code jar with the property from("$projectDir") { include 'lib/**'} to include the Frege jar, then I get errors like java.lang.ClassNotFoundException (I think because the Jar is included as it is and not as a set of .class files).
The folder src/main/java/org/wathever needs to be there before running Gradle (additional info: the Maven convention prefix src/main/java with as a suffix the "Java package" as specified inside the HelloFrege.fr source code: module org.wathever.HelloFrege where)
Some useful details I found:
How to build a fat Jar
Another how to build a fat Jar
An "Hello Frege" example without the Gradle management
The Gradle documentation on how to use the Jar task

CMake Generated Eclipse CDT Project Does Not Have System Includes

My problem is similar with this: http://www.eclipse.org/forums/index.php/m/649323/
I created a cmake project, and used
cmake .. -G "Eclipse CDT4 - Unix Makefiles"
to create a Eclipse CDT4 project.
But in the CDT IDE, the standard include paths are not listed, and all STL or system build-in header files include directives are marked as "cannot be resolved", so the "Open Declaration" or other a lot of operation cannot be done.
However, I could compile it without any problems.
My co-worker also has a cmake project, but it's very complicated. The CDT project generated from his cmake project DOES have the system includes. But his cmake is way too complicated, and he told me that he didn't do anything special to include the system paths.
Can anyone help me out? Thanks.
My Main CMakeLists.txt:
CMake_Minimum_Required(VERSION 2.8)
# Some settings
Set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
CMake_Policy(SET CMP0015 NEW)
#Include(CMakeProcedures.cmake)
#CheckEnvironment()
# Set the compiler and its version if needed
# Create the project
Project(MyProjectName CXX)
# Set the compiler
Set(CMAKE_CXX_COMPILER /usr/bin/g++)
# Detect whether we are in-source
If (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
Message(FATAL_ERROR "In-source building is not allowed! Please create a 'build' folder and then do 'cd build; cmake ..'")
EndIf()
# Set the output dirs
Set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
Set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
# Add source subdirs to the build
Add_Subdirectory(src)
# Add_Subdirectory(test EXCLUDE_FROM_ALL)
Peter
One workaround is to manually add these to the CDT IDE:
/usr/include/c++/4.5
/usr/include/c++/4.5/backward
/usr/include/c++/4.5/i686-linux-gnu
/usr/include/i386-linux-gnu
/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/include
/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5.2/include-fixed
/usr/local/include
But it's not the solution.
I finally figured out that this line is causing the problem:
Project(MyProjectName CXX)
If we remove the optional paramter CXX, life is good.
Can anyone tell me why?
Peter

How to Integrate Qt4 qm files into binary using cmake and QRC?

I have a Qt4 CMake project and I'd like to integrate the QM files for i18n into the output binary. These are the rules I have so far for generating the TS and QM files:
set(myapp_TRANSLATIONS
i18n/myapp_de.ts
)
set(FILES_TO_TRANSLATE
${myapp_SRCS}
${myapp_MOC_HDRS}
)
QT4_CREATE_TRANSLATION(QM_FILES ${FILES_TO_TRANSLATE} ${myapp_TRANSLATIONS})
QT4_ADD_TRANSLATION(QM ${myapp_TRANSLATIONS})
I tried the following to add the QM files to the executable:
add_executable(myapp ${myapp_SRCS} ${myapp_MOC_SRCS} ${myapp_RCC_SRCS} ${QM})
This is the initialization from main.cpp:
QTranslator qtTranslator;
qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
app.installTranslator(&qtTranslator);
QTranslator appTranslator;
appTranslator.load("myapp_" + QLocale::system().name());
app.installTranslator(&appTranslator);
However, strings mypp shows that the translations are not going into the binary.
Update: I added each qm file to a i18n/translations.qrc:
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/resources">
<file>myapp_de.qm</file>
<file> ... .qm</file>
</qresource>
</RCC>
and using
QT4_ADD_RESOURCES(myapp_QM_RCC_SRCS i18n/translations.qrc)
and adding myapp_QM_RCC_SRCS to the executable dependencies.
But this fails during build time thanks to the fact that CMake does a shadow build (building outside the source dir) but parses the QRC files for dependencies expecting the referenced files relative to the QRC file (nice feature but there's no make rule how to build the QM file at that location). The QM files are in ${CMAKE_CURRENT_BINARY_DIR} (where they belong using shadow building) but expects it in ${CMAKE_CURRENT_SOURCE_DIR} (where non-generated files should be - so both locations would be correct, depending on situation).
I had the exact same problem. I came up with the following solution:
Create a QRC file that contains only the expected QM files, and give it a different prefix so it won't conflict with your other resources:
<RCC>
<qresource prefix="/translators">
<file>myapp_en.qm</file>
</qresource>
</RCC>
Add a CMake rule to copy the QRC file to the output directory and then another rule to run the resource compiler:
# Change 'myapp_en' to be the base file name of the qrc file.
SET( trans_file myapp_en )
SET( trans_srcfile ${CMAKE_CURRENT_SOURCE_DIR}/${trans_file}.qrc)
SET( trans_infile ${CMAKE_CURRENT_BINARY_DIR}/${trans_file}.qrc)
SET( trans_outfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${trans_file}.cxx)
# Copy the QRC file to the output directory, because the files listed in the
# qrc file are relative to that directory.
ADD_CUSTOM_COMMAND(
OUTPUT ${trans_infile}
COMMAND ${CMAKE_COMMAND} -E copy ${trans_srcfile} ${trans_infile}
MAIN_DEPENDENCY ${trans_srcfile}
)
# Run the resource compiler (rcc_options should already be set). We can't
# use QT4_ADD_RESOURCES because the qrc file may not exist yet.
ADD_CUSTOM_COMMAND(
OUTPUT ${trans_outfile}
COMMAND ${QT_RCC_EXECUTABLE}
ARGS ${rcc_options} -name ${trans_file} -o ${trans_outfile} ${trans_infile}
MAIN_DEPENDENCY ${trans_infile}
DEPENDS ${qm_files}
)
# Add compiled resources to executable dependency list
ADD_EXECUTABLE( ${APP_NAME} ... ${trans_outfile} )
Use ${Qt5Core_RCC_EXECUTABLE} instead of ${QT_RCC_EXECUTABLE} if you use Qt 5.
I have found a very simple way to do it in CMake 3.0 (and, maybe, earlier) without ADD_CUSTOM_COMMAND and other complications.
First, you should create a QRC file with all .qm files listed ( thanks, the_fly_123 ):
<RCC>
<qresource prefix="/translators">
<file>myapp_en.qm</file>
</qresource>
</RCC>
Then you can copy this QRC file into the output directory using configure_file and use standard Qt routines to build and add it:
# Change lang.qrc to the name of QRC file, created on the previous step
set(lang_qrc "lang.qrc")
configure_file(${lang_qrc} ${lang_qrc} COPYONLY)
qt5_add_translation(myapp_QM ${myapp_TRANSLATIONS})
qt5_add_resources(myapp_QM_RC ${CMAKE_CURRENT_BINARY_DIR}/${lang_qrc})
Then include ${myapp_QM_RC} in add_executable along with other sources.
Note: For Qt4 replace all qt5_ prefixes with qt4_
My solution is to generate ts.qrc XML file with compiled translations from scratch and then complie it with app.
Here is example:
file(GLOB QRC_FILES *.qrc)
file(GLOB TS_FILES ts/*.ts)
...
# Option for updating translations
option(UPDATE_TRANSLATIONS "Update source translation ts/*.ts files (WARNING: make clean will delete the source *.ts files. Danger!)" OFF)
if(UPDATE_TRANSLATIONS)
qt4_create_translation(QM_FILES ${TS_FILES})
endif()
...
# Compiling translations *.ts -> *.qm
qt4_add_translation(QM_FILES ${TS_FILES})
...
# Create translations QRC file - ts.qrc
set(TRANSLATIONS_QRC "${CMAKE_CURRENT_BINARY_DIR}/ts.qrc")
file(WRITE ${TRANSLATIONS_QRC} "<RCC>\n\t<qresource prefix=\"/ts\">")
foreach(QM_FILE ${QM_FILES})
get_filename_component(QM_FILE_NAME ${QM_FILE} NAME)
file(APPEND ${TRANSLATIONS_QRC} "\n\t\t<file alias=\"${QM_FILE_NAME}\">${QM_FILE_NAME}</file>")
endforeach()
file(APPEND ${TRANSLATIONS_QRC} "\n\t</qresource>\n</RCC>")
list(APPEND QRC_FILES ${TRANSLATIONS_QRC})
...
# Compiling *.qrc files
qt4_add_resources(QRC_SRCS ${QRC_FILES})
...
# Add compiled resources to executable dependency list
add_executable(${APP_NAME} ... ${QRC_SRCS})
File tree:
/ - source code root
/rc.qrc - contains app icons etc.
/ts/appname_*.ts - application translations
...
/build - build root
/build/appname_*.qm - compiled translations
/build/ts.qrc - translations rescources
/build/Release/qrc_rc.cxx - compiled icon etc. resources
/build/Release/qrc_ts.cxx - compiled translation resources
Files in ts dir initially generated by lupdate tool.
You need to use Qt resources system to include your translation directly into your application binary. Use QT4_ADD_RESOURCES macro to do this. There is some example how to use it: http://www.qtcentre.org/wiki/index.php?title=Compiling_Qt4_apps_with_CMake

Resources