Hey Stéphane,
2011/1/12 Stéphane Magnenat <
stephane.magnenat@mavt.ethz.ch>:
> Hello,
>
> It happens often that one has a ROS-independent library and a campanion
> ROS wrapper. Ideally, one would like a seamless integration of this
> library with ROS while still allowing people without ROS to compile the
> library. In your opinion, what is the best practice? Is it to have a
> library in its own repository and the ROS wrapper to fetch it locally,
I definitely understand the desire to avoid this one ...
> or should the library be in the ROS stack with a parallel build system
> for ROSless usage? The former is a bit complex but the later requires
> two build paths for the library, and obfuscates the build for people not
> using ROS.
... and I'm not a fan of this one either, but here is a sketch, breaking
things up into three files CMakeLists.txt, rosbuild.cmake, and
standalone.cmake:
CMakeLists.txt:
set(mylib_SRCS src/file1.cpp src/file2.cpp)
if (BUILDING_INSIDE_ROS_TREE) # see below
include(rosbuild.cmake)
else()
include(standalone.cmake)
endif()
rosbuild.cmake:
include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)
set(ROS_BUILD_TYPE Release)
rosbuild_init()
rosbuild_add_boost_directories()
rosbuild_genmsg()
rosbuild_gensrv()
rosbuild_add_library(mylib ${mylib_SRCS})
rosbuild_link_boost(mylib thread signals)
standalone.cmake:
add_library(mylib ${mylib_SRCS})
But this BUILDING_INSIDE_ROS_TREE doesn't exist. Options:
- you could check to see if ENV{ROS_ROOT} is defined, but that might
be even if you're not building inside a ros tree. I don't know what
would happen then, but I'm sure the error message would be
misleading.
- you could drop an empty file that contains
set(BUILDING_INSIDE_ROS_TREE TRUE)
inside ROS_ROOT/rostoolchain.cmake. But then all ros users would
have to do this in order to build your package inside a ros tree.
- you could put the following in the toplevel 'Makefile' of the
package:
include $(shell rospack find mk)/cmake.mk
CMAKE_FLAGS += -DBUILDING_INSIDE_ROS_TREE=TRUE
but now non-ros users will be confused by the presence of both
Makefile and CMakeLists.txt. If they just run 'make', they will get
a (probably misleading) error, and there appears to be no way to
give them a good one. But I could be wrong.
I can think of several hacks to rosbuild/rosmake, each of which also
don't solve the problem well:
- rosmake sets BUILDING_INSIDE_ROS_TREE in environment
this doesn't work as ros packages are supposed to be buildable with
plain 'make' in the package directory.
- ros/core/mk/cmake.mk sets BUILDING_INSIDE_ROS_TREE in CMAKE_FLAGS
has the same problem as above.
Obviously, none of these help for already-released ROS versions
either. So maybe the best way is to force the user to specify:
CMakeLists.txt:
if (NOT DEFINED BUILDING_OUTSIDE_ROS)
message(FATAL_ERROR "Please set the cmake flag
BUILDING_OUTSIDE_ROS to either TRUE or FALSE")
endif()
if (BULDING_OUTSIDE_ROS)
include(standalone.cmake)
else()
include(rosbuild.cmake)
endif()
Users will still get I-dont-know-what if they attempt to build via
just typing 'make' outside of ROS. Maybe there is a way to detect
this and report something reasonable.
Troy