Skip to content
This repository was archived by the owner on Jan 14, 2023. It is now read-only.

Commit 13a15ee

Browse files
committed
solved some hideous cmake dependency sequencing issues.
1 parent 788c1f5 commit 13a15ee

File tree

5 files changed

+93
-24
lines changed

5 files changed

+93
-24
lines changed

cmake/genjava-extras.cmake.em

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,57 +40,85 @@ endmacro()
4040
# To facilitate this, the ARG_GENERATED_FILES is actually just the underlying ARG_MSG and ARG_SRV
4141
# files which we feed the commands as DEPENDS to trigger their execution.
4242
macro(_generate_module_java ARG_PKG ARG_GEN_OUTPUT_DIR ARG_GENERATED_FILES)
43-
4443
################################
4544
# Gradle Subproject
4645
################################
4746
set(GRADLE_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/java")
4847
set(GRADLE_BUILD_FILE "${GRADLE_BUILD_DIR}/${ARG_PKG}/build.gradle")
4948
list(APPEND ALL_GEN_OUTPUT_FILES_java ${GRADLE_BUILD_FILE})
50-
49+
# a marker for the compiling script later to discover
50+
# this command will only get run when an underlying dependency changes, whereas the compiling
51+
# add_custom_target always runs (this was so we can ensure compile time dependencies are ok).
52+
# So we leave this dropping to inform it when gradle needs to run so that we can skip by
53+
# without the huge latency whenever we don't.
54+
set(DROPPINGS_FILE "${GRADLE_BUILD_DIR}/${ARG_PKG}/droppings")
5155
add_custom_command(OUTPUT ${GRADLE_BUILD_FILE}
52-
DEPENDS ${GENJAVA_BIN}
56+
DEPENDS ${GENJAVA_BIN} ${ARG_GENERATED_FILES}
5357
COMMAND ${CATKIN_ENV} ${PYTHON_EXECUTABLE} ${GENJAVA_BIN}
5458
-o ${GRADLE_BUILD_DIR}
5559
-p ${ARG_PKG}
60+
COMMAND touch ${DROPPINGS_FILE}
5661
COMMENT "Generating Java gradle project from ${ARG_PKG}"
5762
)
5863

5964
################################
6065
# Compile Gradle Subproject
6166
################################
67+
# Push the compile back to the last thing that gets done before the generate messages
68+
# is done for this package (see the PRE_LINK coupled with the TARGET option below). This
69+
# is different to genpy, gencpp since it's a compile step. If you don't force it to be
70+
# the last thing, then it may be trying to compile while dependencies are still getting
71+
# themselves ready for ${ARG_PKG}_generate_messages in parallel.
72+
# (i.e. beware of sequencing add_custom_command, it usually has to compete)
6273
set(ROS_GRADLE_VERBOSE $ENV{ROS_GRADLE_VERBOSE})
6374
if(ROS_GRADLE_VERBOSE)
64-
set(GRADLE_CMD "./gradlew")
75+
set(verbosity "--verbosity")
6576
else()
66-
set(GRADLE_CMD "./gradlew;-q")
77+
set(verbosity "")
6778
endif()
68-
set(GEN_OUTPUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/generated_java_messages.flag)
6979

70-
add_custom_command(OUTPUT ${GEN_OUTPUT_FILE}
80+
add_custom_target(${ARG_PKG}_generate_messages_java_gradle
81+
COMMAND ${CATKIN_ENV} ${PYTHON_EXECUTABLE} ${GENJAVA_BIN}
82+
${verbosity}
83+
--compile
84+
-o ${GRADLE_BUILD_DIR}
85+
-p ${ARG_PKG}
7186
DEPENDS ${GRADLE_BUILD_FILE} ${ARG_GENERATED_FILES}
72-
COMMAND ${CATKIN_ENV} ${GRADLE_CMD}
73-
COMMAND touch ${GEN_OUTPUT_FILE}
7487
WORKING_DIRECTORY ${GRADLE_BUILD_DIR}/${ARG_PKG}
75-
COMMENT "Generating Java code for ${ARG_PKG}")
76-
list(APPEND ALL_GEN_OUTPUT_FILES_java ${GEN_OUTPUT_FILE})
77-
78-
################################
79-
# Debugging
80-
################################
81-
#foreach(gen_output_file ${ALL_GEN_OUTPUT_FILES_java})
82-
# message(STATUS "ALL_GEN_OUTPUT_FILES_java..........${gen_output_file}")
83-
#endforeach()
88+
COMMENT "Compiling Java code for ${ARG_PKG}"
89+
)
90+
add_dependencies(${ARG_PKG}_generate_messages ${ARG_PKG}_generate_messages_java_gradle)
8491

8592
################################
8693
# Dependent Targets
8794
################################
95+
# This is a bad hack that needs to disappear. e.g.
96+
# - topic_tools and roscpp are both packages with a couple of msgs
97+
# - topic tools messages doesn't actually depend on roscpp messages
98+
# this is guarded, so it's not doubling up on work when called from catkin_package (roscpp does this too)
99+
# and we need it to get access to the build_depends list just in case people called generate_messages before catkin_package()
100+
if(NOT DEFINED ${ARG_PKG}_BUILD_DEPENDS)
101+
catkin_package_xml(DIRECTORY ${PROJECT_SOURCE_DIR})
102+
endif()
103+
foreach(depends ${${ARG_PKG}_BUILD_DEPENDS})
104+
if(TARGET ${depends}_generate_messages_java_gradle)
105+
message(STATUS "Adding dependency.....${depends}_generate_messages -> ${ARG_PKG}_generate_messages")
106+
add_dependencies(${ARG_PKG}_generate_messages_java_gradle ${depends}_generate_messages_java_gradle)
107+
endif()
108+
endforeach()
88109
# Make sure we have built gradle-rosjava_bootstrap if it is in the source workspace
89110
# (otherwise package.xml will make sure it has installed via rosdep/deb.
90111
#if(TARGET gradle-rosjava_bootstrap)
91112
# Preference would be to add it to ${ARG_PKG}_generate_messages_java but that
92113
# is not defined till after this module is parsed, so add it all
93114
#add_dependencies(${ARG_PKG}_generate_messages gradle-rosjava_bootstrap)
94115
#endif()
116+
117+
################################
118+
# Debugging
119+
################################
120+
#foreach(gen_output_file ${ALL_GEN_OUTPUT_FILES_java})
121+
# message(STATUS "ALL_GEN_OUTPUT_FILES_java..........${gen_output_file}")
122+
#endforeach()
95123
endmacro()
96124

src/genjava/genjava_main.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ def parse_arguments(argv):
6060
#parser.add_argument('-m', '--message', action='store', help='the message file')
6161
parser.add_argument('-p', '--package', action='store', help='package to find the message file')
6262
parser.add_argument('-o', '--output-dir', action='store', help='output directory for the java code (e.g. build/foo_msgs)')
63+
parser.add_argument('-c', '--compile', default=False, action='store_true', help='switch to compile mode (default is generating mode)')
64+
parser.add_argument('-v', '--verbosity', default=False, action='store_true', help='enable verbosity in debugging (false)')
6365
#parser.add_argument('-I', '--include-path', action='append', help="include paths to the package and deps msg files")
6466
#myargs = rospy.myargv(argv=sys.argv)
6567
#return parser.parse_args(args=myargs[1:])
@@ -73,4 +75,7 @@ def parse_arguments(argv):
7375
def main(argv):
7476
args = parse_arguments(argv[1:])
7577
#print("genjava %s/%s" % (args.package, args.message))
76-
gradle_project.create(args.package, args.output_dir)
78+
if not args.compile:
79+
gradle_project.create(args.package, args.output_dir)
80+
else:
81+
gradle_project.build(args.package, args.output_dir, args.verbosity)

src/genjava/genjava_main.pyc

331 Bytes
Binary file not shown.

src/genjava/gradle_project.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import os
1010
import shutil
11-
11+
import subprocess
1212
from catkin_pkg.packages import find_packages
1313
import rospkg
1414

@@ -98,7 +98,7 @@ def create_dependency_string(project_name, msg_package_index):
9898
dependency_package = msg_package_index[dep.name]
9999
except KeyError:
100100
continue # it's not a message package
101-
gradle_dependency_string += "compile 'org.ros.rosjava_messages:" + dependency_package.name + ":" + dependency_package.version + "'\n"
101+
gradle_dependency_string += " compile 'org.ros.rosjava_messages:" + dependency_package.name + ":" + dependency_package.version + "'\n"
102102
return gradle_dependency_string
103103

104104

@@ -120,7 +120,8 @@ def create_msg_package_index():
120120
ros_paths = [x for x in ros_paths.split(':') if x]
121121
for path in reversed(ros_paths): # make sure we pick up the source overlays last
122122
for unused_package_path, package in find_packages(path).items():
123-
if 'message_generation' in [dep.name for dep in package.build_depends]:
123+
if ('message_generation' in [dep.name for dep in package.build_depends] or
124+
'genmsg' in [dep.name for dep in package.build_depends]):
124125
# print(package.name)
125126
# print(" version: %s" % package.version)
126127
# print(" dependencies: ")
@@ -153,3 +154,17 @@ def create(msg_pkg_name, output_dir):
153154
pkg_directory = os.path.dirname(msg_package_index[msg_pkg_name].filename)
154155
msg_pkg_version = msg_package_index[msg_pkg_name].version
155156
populate_project(msg_pkg_name, msg_pkg_version, pkg_directory, genjava_gradle_dir, msg_dependencies)
157+
158+
159+
def build(msg_pkg_name, output_dir, verbosity):
160+
droppings_file = os.path.join(output_dir, msg_pkg_name, 'droppings')
161+
if not os.path.isfile(droppings_file):
162+
#print("Someone already left droppings here! %s" % droppings_file)
163+
return
164+
print("Scooping the droppings! [%s]" % droppings_file)
165+
os.remove(droppings_file)
166+
cmd = ['./gradlew']
167+
if not verbosity:
168+
cmd.append('--quiet')
169+
print("COMMAND........................%s" % cmd)
170+
subprocess.call(cmd, stderr=subprocess.STDOUT,)

src/genjava/templates/genjava_project/build.gradle.in

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,15 @@ task generateSources (type: JavaExec) {
5555
}
5656

5757
dependencies {
58-
compile 'org.ros.rosjava_bootstrap:message_generation:[0.1,)'
59-
%(msg_dependencies)s
58+
compile 'org.ros.rosjava_bootstrap:message_generation:[0.1,)'
59+
%(msg_dependencies)s
60+
}
61+
62+
jar {
63+
manifest = osgiManifest {
64+
classesDir = sourceSets.main.output.classesDir
65+
classpath = configurations.runtime
66+
}
6067
}
6168

6269
task info << {
@@ -82,4 +89,18 @@ task info << {
8289
}
8390
}
8491

92+
/* Damon's message generator doesn't catch every message. It expects everything to be nicely under 'msg'
93+
* and that directory to be under the package root. It also expects every msg it finds should be buildable.
94+
* It kinda works until now because it ignores any package which doesn't conform to this and those are just
95+
* test packages (we hope).
96+
*
97+
* Until we get this properly fixed (it fails in genjava), then we use the following bugfix to deal with the
98+
* 'Could not copy MANIFEST.MF...' error that occurs when no sources are to be made for an artifact.
99+
*/
100+
task bugfixtask << {
101+
mkdir sourceSets.main.output.classesDir
102+
}
103+
104+
jar.dependsOn(bugfixtask)
105+
85106
defaultTasks 'publishMavenJavaPublicationToMavenRepository'

0 commit comments

Comments
 (0)