Skip to content
Snippets Groups Projects
Commit 13a15ee4 authored by Daniel Stonier's avatar Daniel Stonier
Browse files

solved some hideous cmake dependency sequencing issues.

parent 788c1f59
Branches
Tags 0.3.4
No related merge requests found
...@@ -40,51 +40,72 @@ endmacro() ...@@ -40,51 +40,72 @@ endmacro()
# To facilitate this, the ARG_GENERATED_FILES is actually just the underlying ARG_MSG and ARG_SRV # To facilitate this, the ARG_GENERATED_FILES is actually just the underlying ARG_MSG and ARG_SRV
# files which we feed the commands as DEPENDS to trigger their execution. # files which we feed the commands as DEPENDS to trigger their execution.
macro(_generate_module_java ARG_PKG ARG_GEN_OUTPUT_DIR ARG_GENERATED_FILES) macro(_generate_module_java ARG_PKG ARG_GEN_OUTPUT_DIR ARG_GENERATED_FILES)
################################ ################################
# Gradle Subproject # Gradle Subproject
################################ ################################
set(GRADLE_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/java") set(GRADLE_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/java")
set(GRADLE_BUILD_FILE "${GRADLE_BUILD_DIR}/${ARG_PKG}/build.gradle") set(GRADLE_BUILD_FILE "${GRADLE_BUILD_DIR}/${ARG_PKG}/build.gradle")
list(APPEND ALL_GEN_OUTPUT_FILES_java ${GRADLE_BUILD_FILE}) list(APPEND ALL_GEN_OUTPUT_FILES_java ${GRADLE_BUILD_FILE})
# a marker for the compiling script later to discover
# this command will only get run when an underlying dependency changes, whereas the compiling
# add_custom_target always runs (this was so we can ensure compile time dependencies are ok).
# So we leave this dropping to inform it when gradle needs to run so that we can skip by
# without the huge latency whenever we don't.
set(DROPPINGS_FILE "${GRADLE_BUILD_DIR}/${ARG_PKG}/droppings")
add_custom_command(OUTPUT ${GRADLE_BUILD_FILE} add_custom_command(OUTPUT ${GRADLE_BUILD_FILE}
DEPENDS ${GENJAVA_BIN} DEPENDS ${GENJAVA_BIN} ${ARG_GENERATED_FILES}
COMMAND ${CATKIN_ENV} ${PYTHON_EXECUTABLE} ${GENJAVA_BIN} COMMAND ${CATKIN_ENV} ${PYTHON_EXECUTABLE} ${GENJAVA_BIN}
-o ${GRADLE_BUILD_DIR} -o ${GRADLE_BUILD_DIR}
-p ${ARG_PKG} -p ${ARG_PKG}
COMMAND touch ${DROPPINGS_FILE}
COMMENT "Generating Java gradle project from ${ARG_PKG}" COMMENT "Generating Java gradle project from ${ARG_PKG}"
) )
################################ ################################
# Compile Gradle Subproject # Compile Gradle Subproject
################################ ################################
# Push the compile back to the last thing that gets done before the generate messages
# is done for this package (see the PRE_LINK coupled with the TARGET option below). This
# is different to genpy, gencpp since it's a compile step. If you don't force it to be
# the last thing, then it may be trying to compile while dependencies are still getting
# themselves ready for ${ARG_PKG}_generate_messages in parallel.
# (i.e. beware of sequencing add_custom_command, it usually has to compete)
set(ROS_GRADLE_VERBOSE $ENV{ROS_GRADLE_VERBOSE}) set(ROS_GRADLE_VERBOSE $ENV{ROS_GRADLE_VERBOSE})
if(ROS_GRADLE_VERBOSE) if(ROS_GRADLE_VERBOSE)
set(GRADLE_CMD "./gradlew") set(verbosity "--verbosity")
else() else()
set(GRADLE_CMD "./gradlew;-q") set(verbosity "")
endif() endif()
set(GEN_OUTPUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/generated_java_messages.flag)
add_custom_command(OUTPUT ${GEN_OUTPUT_FILE} add_custom_target(${ARG_PKG}_generate_messages_java_gradle
COMMAND ${CATKIN_ENV} ${PYTHON_EXECUTABLE} ${GENJAVA_BIN}
${verbosity}
--compile
-o ${GRADLE_BUILD_DIR}
-p ${ARG_PKG}
DEPENDS ${GRADLE_BUILD_FILE} ${ARG_GENERATED_FILES} DEPENDS ${GRADLE_BUILD_FILE} ${ARG_GENERATED_FILES}
COMMAND ${CATKIN_ENV} ${GRADLE_CMD}
COMMAND touch ${GEN_OUTPUT_FILE}
WORKING_DIRECTORY ${GRADLE_BUILD_DIR}/${ARG_PKG} WORKING_DIRECTORY ${GRADLE_BUILD_DIR}/${ARG_PKG}
COMMENT "Generating Java code for ${ARG_PKG}") COMMENT "Compiling Java code for ${ARG_PKG}"
list(APPEND ALL_GEN_OUTPUT_FILES_java ${GEN_OUTPUT_FILE}) )
add_dependencies(${ARG_PKG}_generate_messages ${ARG_PKG}_generate_messages_java_gradle)
################################
# Debugging
################################
#foreach(gen_output_file ${ALL_GEN_OUTPUT_FILES_java})
# message(STATUS "ALL_GEN_OUTPUT_FILES_java..........${gen_output_file}")
#endforeach()
################################ ################################
# Dependent Targets # Dependent Targets
################################ ################################
# This is a bad hack that needs to disappear. e.g.
# - topic_tools and roscpp are both packages with a couple of msgs
# - topic tools messages doesn't actually depend on roscpp messages
# this is guarded, so it's not doubling up on work when called from catkin_package (roscpp does this too)
# and we need it to get access to the build_depends list just in case people called generate_messages before catkin_package()
if(NOT DEFINED ${ARG_PKG}_BUILD_DEPENDS)
catkin_package_xml(DIRECTORY ${PROJECT_SOURCE_DIR})
endif()
foreach(depends ${${ARG_PKG}_BUILD_DEPENDS})
if(TARGET ${depends}_generate_messages_java_gradle)
message(STATUS "Adding dependency.....${depends}_generate_messages -> ${ARG_PKG}_generate_messages")
add_dependencies(${ARG_PKG}_generate_messages_java_gradle ${depends}_generate_messages_java_gradle)
endif()
endforeach()
# Make sure we have built gradle-rosjava_bootstrap if it is in the source workspace # Make sure we have built gradle-rosjava_bootstrap if it is in the source workspace
# (otherwise package.xml will make sure it has installed via rosdep/deb. # (otherwise package.xml will make sure it has installed via rosdep/deb.
#if(TARGET gradle-rosjava_bootstrap) #if(TARGET gradle-rosjava_bootstrap)
...@@ -92,5 +113,12 @@ macro(_generate_module_java ARG_PKG ARG_GEN_OUTPUT_DIR ARG_GENERATED_FILES) ...@@ -92,5 +113,12 @@ macro(_generate_module_java ARG_PKG ARG_GEN_OUTPUT_DIR ARG_GENERATED_FILES)
# is not defined till after this module is parsed, so add it all # is not defined till after this module is parsed, so add it all
#add_dependencies(${ARG_PKG}_generate_messages gradle-rosjava_bootstrap) #add_dependencies(${ARG_PKG}_generate_messages gradle-rosjava_bootstrap)
#endif() #endif()
################################
# Debugging
################################
#foreach(gen_output_file ${ALL_GEN_OUTPUT_FILES_java})
# message(STATUS "ALL_GEN_OUTPUT_FILES_java..........${gen_output_file}")
#endforeach()
endmacro() endmacro()
...@@ -60,6 +60,8 @@ def parse_arguments(argv): ...@@ -60,6 +60,8 @@ def parse_arguments(argv):
#parser.add_argument('-m', '--message', action='store', help='the message file') #parser.add_argument('-m', '--message', action='store', help='the message file')
parser.add_argument('-p', '--package', action='store', help='package to find the message file') parser.add_argument('-p', '--package', action='store', help='package to find the message file')
parser.add_argument('-o', '--output-dir', action='store', help='output directory for the java code (e.g. build/foo_msgs)') parser.add_argument('-o', '--output-dir', action='store', help='output directory for the java code (e.g. build/foo_msgs)')
parser.add_argument('-c', '--compile', default=False, action='store_true', help='switch to compile mode (default is generating mode)')
parser.add_argument('-v', '--verbosity', default=False, action='store_true', help='enable verbosity in debugging (false)')
#parser.add_argument('-I', '--include-path', action='append', help="include paths to the package and deps msg files") #parser.add_argument('-I', '--include-path', action='append', help="include paths to the package and deps msg files")
#myargs = rospy.myargv(argv=sys.argv) #myargs = rospy.myargv(argv=sys.argv)
#return parser.parse_args(args=myargs[1:]) #return parser.parse_args(args=myargs[1:])
...@@ -73,4 +75,7 @@ def parse_arguments(argv): ...@@ -73,4 +75,7 @@ def parse_arguments(argv):
def main(argv): def main(argv):
args = parse_arguments(argv[1:]) args = parse_arguments(argv[1:])
#print("genjava %s/%s" % (args.package, args.message)) #print("genjava %s/%s" % (args.package, args.message))
gradle_project.create(args.package, args.output_dir) if not args.compile:
gradle_project.create(args.package, args.output_dir)
else:
gradle_project.build(args.package, args.output_dir, args.verbosity)
No preview for this file type
...@@ -8,7 +8,7 @@ from __future__ import print_function ...@@ -8,7 +8,7 @@ from __future__ import print_function
import os import os
import shutil import shutil
import subprocess
from catkin_pkg.packages import find_packages from catkin_pkg.packages import find_packages
import rospkg import rospkg
...@@ -98,7 +98,7 @@ def create_dependency_string(project_name, msg_package_index): ...@@ -98,7 +98,7 @@ def create_dependency_string(project_name, msg_package_index):
dependency_package = msg_package_index[dep.name] dependency_package = msg_package_index[dep.name]
except KeyError: except KeyError:
continue # it's not a message package continue # it's not a message package
gradle_dependency_string += "compile 'org.ros.rosjava_messages:" + dependency_package.name + ":" + dependency_package.version + "'\n" gradle_dependency_string += " compile 'org.ros.rosjava_messages:" + dependency_package.name + ":" + dependency_package.version + "'\n"
return gradle_dependency_string return gradle_dependency_string
...@@ -120,7 +120,8 @@ def create_msg_package_index(): ...@@ -120,7 +120,8 @@ def create_msg_package_index():
ros_paths = [x for x in ros_paths.split(':') if x] ros_paths = [x for x in ros_paths.split(':') if x]
for path in reversed(ros_paths): # make sure we pick up the source overlays last for path in reversed(ros_paths): # make sure we pick up the source overlays last
for unused_package_path, package in find_packages(path).items(): for unused_package_path, package in find_packages(path).items():
if 'message_generation' in [dep.name for dep in package.build_depends]: if ('message_generation' in [dep.name for dep in package.build_depends] or
'genmsg' in [dep.name for dep in package.build_depends]):
# print(package.name) # print(package.name)
# print(" version: %s" % package.version) # print(" version: %s" % package.version)
# print(" dependencies: ") # print(" dependencies: ")
...@@ -153,3 +154,17 @@ def create(msg_pkg_name, output_dir): ...@@ -153,3 +154,17 @@ def create(msg_pkg_name, output_dir):
pkg_directory = os.path.dirname(msg_package_index[msg_pkg_name].filename) pkg_directory = os.path.dirname(msg_package_index[msg_pkg_name].filename)
msg_pkg_version = msg_package_index[msg_pkg_name].version msg_pkg_version = msg_package_index[msg_pkg_name].version
populate_project(msg_pkg_name, msg_pkg_version, pkg_directory, genjava_gradle_dir, msg_dependencies) populate_project(msg_pkg_name, msg_pkg_version, pkg_directory, genjava_gradle_dir, msg_dependencies)
def build(msg_pkg_name, output_dir, verbosity):
droppings_file = os.path.join(output_dir, msg_pkg_name, 'droppings')
if not os.path.isfile(droppings_file):
#print("Someone already left droppings here! %s" % droppings_file)
return
print("Scooping the droppings! [%s]" % droppings_file)
os.remove(droppings_file)
cmd = ['./gradlew']
if not verbosity:
cmd.append('--quiet')
print("COMMAND........................%s" % cmd)
subprocess.call(cmd, stderr=subprocess.STDOUT,)
...@@ -55,8 +55,15 @@ task generateSources (type: JavaExec) { ...@@ -55,8 +55,15 @@ task generateSources (type: JavaExec) {
} }
dependencies { dependencies {
compile 'org.ros.rosjava_bootstrap:message_generation:[0.1,)' compile 'org.ros.rosjava_bootstrap:message_generation:[0.1,)'
%(msg_dependencies)s %(msg_dependencies)s
}
jar {
manifest = osgiManifest {
classesDir = sourceSets.main.output.classesDir
classpath = configurations.runtime
}
} }
task info << { task info << {
...@@ -82,4 +89,18 @@ task info << { ...@@ -82,4 +89,18 @@ task info << {
} }
} }
/* Damon's message generator doesn't catch every message. It expects everything to be nicely under 'msg'
* and that directory to be under the package root. It also expects every msg it finds should be buildable.
* It kinda works until now because it ignores any package which doesn't conform to this and those are just
* test packages (we hope).
*
* Until we get this properly fixed (it fails in genjava), then we use the following bugfix to deal with the
* 'Could not copy MANIFEST.MF...' error that occurs when no sources are to be made for an artifact.
*/
task bugfixtask << {
mkdir sourceSets.main.output.classesDir
}
jar.dependsOn(bugfixtask)
defaultTasks 'publishMavenJavaPublicationToMavenRepository' defaultTasks 'publishMavenJavaPublicationToMavenRepository'
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment