## page was renamed from CMakeLists == Writing a ROS CMakeLists.txt file == This page documents the CMake API provided by [[rosbuild]]. You might first want to see some [[/Examples|examples]]. We use [[http://www.cmake.org|CMake]] to build ROS packages. You need to [[ROS/Installation|install CMake]] on your system. Each package requires a file, called `CMakeLists.txt` to tell CMake how to build it. This file is analogous to a `Makefile` as used by `make`. If you're unfamiliar with `CMakeLists.txt`, that's ok, because most ROS packages follow a very simple pattern that is described below. Of course, you can always use the full power of CMake, for which you may want to consult the [[http://www.cmake.org/Wiki/CMake_2.4.6_Docs|CMake documentation]]. '''NOTE''': To support older platforms, we use '''only''' features that are available in CMake 2.4.6. Check the [[http://www.cmake.org/Wiki/CMake_2.4.6_Docs|2.4.6 docs]] to verify the availability of a feature you want to use. <> == API documentation == === rosbuild.cmake === To use any of the ROS macros, you must first do this: {{{ include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake) }}} This line brings in the '''`rosbuild.cmake`''' file, which defines the macros described below. === Global variables === Some variables can be set before calling `rosbuild_init()`: * `ROSBUILD_DONT_REDEFINE_PROJECT` (new in 1.3.1): If `TRUE`, don't infer the project name from the current working directory. Instead, inherit the existing `PROJECT_NAME`. Useful for complex projects in which a ROS package is just one part. === rosbuild_init === {{{ rosbuild_init() }}} This macro should be called first. It does the following (assume ${pkg} is the name of the package, and ${dir} is the package directory): * Configure default output locations: * executables go in ${dir} * libraries go in ${dir}/lib * Add ${dir}/include to the search path for include files * Invoke [[rospack]] to get compile and link flags, storing the result in several variables (but you don't need to access them directly if you're using th '''`rosbuild_add_executable`''' an '''`rosbuild_add_library`''' macros): * -I compile flags go in ${pkg}_INCLUDE_DIRS * other compile flags go in ${pkg}_CFLAGS_OTHER * -L link flags go in ${pkg}_LIBRARY_DIRS * -l link flags go in ${pkg}_LIBRARIES * other link flags go in ${pkg}_LDFLAGS_OTHER Note that you are free to override the default output locations after invoking '''`rosbuild_init().`''' E.g., if you want your binaries in ${pkg}/bin, you might do this: {{{ rosbuild_init() set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) }}} To put your libraries somewhere strange: {{{ set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/libraries) }}} '''NOTE''': the '''`rosbuild_init()`''' macro does '''NOT''' bring in the compile or link flags that are exported by the package presently being built. It '''ONLY''' brings in the flags exported by the present package's dependencies. The flags in the export section of your `manifest.xml` are for use by others, not by you. If you need some of your package's exported flags when building the package itself, use the appropriate CMake calls in your `CMakeLists.txt`, such as `include_directories()` and `target_link_libraries()`. But see [[/Examples#Linking_against_libraries_built_by_other_ROS_packages|Linking against libraries built by other ROS packages]] for when '''not''' to use '''`target_link_libraries()`'''. === Build macros === ==== rosbuild_add_executable ==== {{{ rosbuild_add_executable(exe src1 src2...) }}} This macro declares an executable that is to be built. It is a simple wrapper around the standard CMake command add_executable(), and takes exactly the same arguments. In addition to invoking add_executable(), this macro invokes set_target_properties() and target_link_libraries() to incorporate the compile and link flags found by th '''`rosbuild_init()`''' macro. '''NOTE''': Do not call your executable '''test'''. This target name is reserved for unit testing, and CMake will fail if you try it. If you really want your executable to be called '''test''', you can do it like so: {{{ rosbuild_add_executable(mytest src/test.cpp) set_target_properties(mytest PROPERTIES OUTPUT_NAME test) }}} But if you're building test programs, you should do it with '''`rosbuild_add_gtest()`'''; see below. If you're building an executable that shouldn't be built in the '''make all''' step (e.g., if you intend to use '''`rosbuild_add_gtest_build_flags()`'''), then use CMake's '''EXCLUDE_FROM_ALL''' option, e.g.: {{{ rosbuild_add_executable(mytest EXCLUDE_FROM_ALL src/test.cpp) rosbuild_add_gtest_build_flags(mytest) }}} ==== rosbuild_add_library ==== {{{ rosbuild_add_library(lib src1 src2...) }}} This macro declares a library that is to be built. It is a simple wrapper around the standard CMake command add_library(), and takes exactly the same arguments. In addition to invoking add_library(), this macro invokes set_target_properties() to incorporate the compile flags found by the '''`rosbuild_init()`''' macro. Example usage: {{{ cmake_minimum_required(VERSION 2.4.6) include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake) rosbuild_init() rosbuild_add_library(XmlRpc src/XmlRpcClient.cpp src/XmlRpcDispatch.cpp src/XmlRpcServer.cpp src/XmlRpcServerConnection.cpp src/XmlRpcServerMethod.cpp src/XmlRpcSocket.cpp src/XmlRpcSource.cpp src/XmlRpcUtil.cpp src/XmlRpcValue.cpp) }}} '''NOTE''': Do not call your library '''test'''. This target name is reserved for unit testing, and CMake will fail if you try it. ==== rosbuild_add_swigpy_library ==== New in 0.11 {{{ rosbuild_add_swigpy_library(target lib src1 src2...) }}} This macro is a variation o '''`rosbuild_add_library()`''' that should be used when building a SWIG-generated library that will be imported by Python. The first argument is a unique target name, which you can pass to things like target_link_libraries(). The rest of the arguments are the same as you would normally pass to rosbuild_add_library(). This macro will generate a library called '''_.''', where is what you passed in, and is the appropriate extension for a shared library. On OS X, the extension is forced to '''.so''', to allow module imports to work with the MacPorts version of Python. Example usage: {{{ cmake_minimum_required(VERSION 2.4.6) include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake) rosbuild_init() find_package(PythonLibs REQUIRED) rosbuild_add_swigpy_library(python_foo foo foo_swig_generated.cpp bar.cpp) target_link_libraries(python_foo ${PYTHON_LIBRARIES}) }}} This example will produce a library named '''_foo.so''' on most platforms. '''NOTE''': Do not call your target '''test'''. This target name is reserved for unit testing, and CMake will fail if you try it. ==== rosbuild_add_compile_flags ==== {{{ rosbuild_add_compile_flags(target flags) }}} This macro adds compile flags for the given target. You can use it to add things like warning or optimization settings, but don't use it to add library/include search paths, '''`-D`''' definitions, or libraries to link against. Use CMake builtin commands ('''`link_directories()`, `include_directories()`, `add_definitions()`, `target_link_libraries()`''') for those cases. But see [[/Examples#Linking_against_libraries_built_by_other_ROS_packages|Linking against libraries built by other ROS packages]] for when '''not''' to use '''`target_link_libraries()`'''. ==== rosbuild_remove_compile_flags ==== {{{ rosbuild_remove_compile_flags(target flags) }}} This macro removes compile flags for the given target. ==== rosbuild_add_link_flags ==== {{{ rosbuild_add_link_flags(target flags) }}} This macro adds link flags for the given target. You can use it to add things like profiling settings, but don't use it to add library/include search paths, '''-D''' definitions, or libraries to link against. Use CMake builtin commands ('''link_directories() include_directories(), add_definitions(), target_link_libraries()''') for those cases. But see [[/Examples#Linking_against_libraries_built_by_other_ROS_packages|Linking against libraries built by other ROS packages]] for when '''not''' to use '''`target_link_libraries()`'''. ==== rosbuild_remove_link_flags ==== {{{ rosbuild_remove_link_flags(target flags) }}} This macro removes link flags for the given target. ==== rosbuild_add_boost_directories ==== {{{ rosbuild_add_boost_directories() }}} This macro adds the boost include/library directories to your search paths. You must call this macro if any of your code includes boost headers. ==== rosbuild_link_boost ==== {{{ rosbuild_link_boost(target lib1 lib2 lib3 ...) }}} This macro adds the boost link flags to a target, given some boost libraries you want to link against. You must call this macro for each of your library and executable that uses one or more libraries from boost. Example: {{{ rosbuild_link_boost(my_exe thread regex) }}} ==== rosbuild_add_openmp_flags ==== {{{ rosbuild_add_openmp_flags(target) }}} This macro adds the necessary compile and link flags to a target so that OpenMP can be used. ==== rosbuild_invoke_rospack ==== {{{ rosbuild_invoke_rospack(pkg prefix varname rospack_args) }}} This macro invokes rospack. Specifically, it invokes: {{{ rospack ${rospack_args) ${pkg} }}} It stores the result in the variable ${prefix}_${varname}. Failure to invoke rospack is fatal. ==== rosbuild_find_ros_package ==== {{{ rosbuild_find_ros_package(pkg) }}} This macro searches for the given ROS package. If the package is found, then the variable ${pkg_PACKAGE_PATH} is set to the absolute path to the package. If the package is not found, the variable is not set. ==== rosbuild_find_ros_stack ==== (New in 1.6.0) {{{ rosbuild_find_ros_stack(stack) }}} This macro searches for the given ROS stack. If the stack is found, then the variable ${stack_STACK_PATH} is set to the absolute path to the stack. If the stack is not found, the variable is not set. ==== rosbuild_check_for_sse ==== (New in 1.1.8) {{{ rosbuild_check_for_sse() }}} This macro determines the level of SSE support in the compiler. If SSE support is found, `HAS_SSE_EXTENSIONS` is set to True. Similarly, SSE2 and SSE3 support cause `HAS_SSE2_EXTENSIONS` and `HAS_SSE3_EXTENSIONS` to be set to True, respectively. If any level of SSE support is found, `SSE_FLAGS` will contain the flags required to use the highest level available. For example, to compile a library with the highest level of SSE available: {{{ rosbuild_check_for_sse() rosbuild_add_library(foo foo.cpp) rosbuild_add_compile_flags(foo ${SSE_FLAGS}) }}} To check for SSE2 specifically: {{{ rosbuild_check_for_sse() if(HAS_SSE2_EXTENSIONS) endif(HAS_SSE2_EXTENSIONS) }}} ==== rosbuild_include ==== (New in 1.1.8) {{{ rosbuild_include(package module) }}} This macro includes CMake code exported by another package. Specifically, it includes a file called `module.cmake` from a directory exported by `package`. This mechanism allows you to extend the build system by providing your own CMake code to be used in other packages. The package calling `rosbuild_include()` must depend on `package`. That package must depend directly on `rosbuild` and must export a directory to search for CMake files. E.g., if package `dynamic_reconfigure` wants to allow other packages to include the file `dynamic_reconfigure/cmake/cfgbuild.cmake`, then its manifest should contain: {{{ ... ... }}} Then package `hokuyo_node`, which depends on `dynamic_reconfigure`, can include that file like so: {{{ rosbuild_include(dynamic_reconfigure cfgbuild) }}} ==== rosbuild_add_lisp_executable ==== {{{ rosbuild_add_lisp_executable(output system_name entry_point) }}} Used to create a standalone Lisp executable. Your package must depend on `roslisp_runtime`. The executable will be called `output`. Running it will start the SBCL runtime, load in the ASDF system `system_name`, then call the function named by `entry_point`. See the [[roslisp]] documentation for more details. === Test macros === [[rosbuild]] provides a number macros to support testing. These macros allow you to define test programs that should be compiled (if necessary) and run during `make test` in your package. See [[UnitTesting]] for more information on testing. ==== rosbuild_add_gtest ==== (TIMEOUT option new in 1.1.8) {{{ rosbuild_add_gtest(testexe src1 src2 ... [TIMEOUT timeout_secs]) }}} This macro declares a [[gtest|Google Test (gtest) executable]] that is to be built. The arguments are the same a '''`rosbuild_add_executable`''' (in fact this macro calls through to '''`rosbuild_add_executable).`''' The named executable is built from the sources, and added as a dependency to the '''test''' target. This macro invokes '''`rosbuild_add_gtest_build_flags()`''', which adds the gtest build flags to the named executable. To build the executable, use '''make tests'''. If a test doesn't complete within a certain amount of time, it will be killed, and a test failure will be synthesized. By default, the time limit is 60 seconds. To set a different timeout, use the `TIMEOUT` option, e.g.: {{{ # Give a slow test 3 minutes (180 seconds) to complete rosbuild_add_gtest(myslowtest myslowtest.cpp TIMEOUT 180.0) }}} When '''make test''' is run, each gtest executable is run like so: {{{ testexe --gtest_output=xml:${rosbuild_test_results_dir}/${PROJECT_NAME}/${_testname}.xml }}} The current working directory is the top of the package's source tree. Test output is printed to the console, and also stored in XML format in $ROS_ROOT/test/test_results/${project}, where ${project} is the name of the ROS package. Multiple tests may be declared. '''NOTE''': Do not call your test '''test'''. This target name is reserved for unit testing, and CMake will fail if you try it. ==== rosbuild_add_gtest_labeled ==== (`TIMEOUT` option new in 1.1.8) {{{ rosbuild_add_gtest_labeled(label testexe src1 src2 ... [TIMEOUT timeout_secs]) }}} This macro is the same a '''`rosbuild_add_gtest(),`''' except that it only declares the test if EITHER: * the environment variable '''ROS_BUILD_TEST_LABEL''' is unset; OR * the '''label''' argument is equal to the environment variable '''ROS_BUILD_TEST_LABEL'''. Use this macro to declare tests that should not run in certain situations. Most commonly used with a continuous integration system. ==== rosbuild_add_gtest_future ==== '''DEPRECATED and rendered non-functional in 1.7. Instead of using this macro, simply comment out tests that don't yet pass.''' {{{ rosbuild_add_gtest_future(testexe src1 src2 ... [TIMEOUT timeout_secs]) }}} This macro is the same a '''`rosbuild_add_gtest(),`''' except that the resulting test will be only be run during '''make test-future'''. Use this macro to declare tests that fail now, but should pass in the future, after an existing bug is fixed or missing feature implemented. We segregate ''future'' tests from current tests so that the automated build and test system can accurately report health of the system, including giving meaningful email notification on test failure. ==== rosbuild_add_gtest_build_flags ==== {{{ rosbuild_add_gtest_build_flags(testexe) }}} This macro adds the build flags necessary to compile and link an executable against gtest. Use this macro when you want to build a gtest exectuable, but '''not''' declare it to be a test on its own. This commonly occurs when you're using [[rostest]] and your test executable uses gtest. In this case you want the test executable to be run via rostest, not on its own. This macro also invokes '''`rosbuild_declare_test()`''', which adds a dependency from the '''tests''' target on the executable. To build the executable, use '''make tests'''. E.g., here we build an executable called '''rtest''' that uses gtest, and declare a '''rostest''' that uses it: {{{ rosbuild_add_executable(rtest test/rtest.cpp test/test_constants.cpp) rosbuild_add_gtest_build_flags(rtest) rosbuild_add_rostest(test/rtest.xml) }}} The accompanying rostest XML file might look like this: {{{ }}} ==== rosbuild_add_pyunit ==== (`TIMEOUT` option new 1.1.8) {{{ rosbuild_add_pyunit(file [TIMEOUT timeout_secs]) }}} This macro declares a [[unittest|Python unittest executable]] that is to be run. Make sure you consult the [[unittest|ROS unittest documentation]] as there are some additional items your unittest script needs to call. If a test doesn't complete within a certain amount of time, it will be killed, and a test failure will be synthesized. By default, the time limit is 60 seconds. To set a different timeout, use the `TIMEOUT` option, e.g.: {{{ # Give a slow test 3 minutes (180 seconds) to complete rosbuild_add_pyunit(myslowtest.py TIMEOUT 180.0) }}} When '''make test''' is run, each Python unit test is run like so: {{{ python file --gtest_output=xml:${rosbuild_test_results_dir}/${PROJECT_NAME}/${_testname}.xml }}} The current working directory is the top of the package's source tree. ==== rosbuild_add_pyunit_labeled ==== (`TIMEOUT` option new in 1.1.8.) {{{ rosbuild_add_pyunit_labeled(label file [TIMEOUT timeout_secs]) }}} This macro is the same a '''`rosbuild_add_pyunit(),`''' except that it only declares the test if EITHER: * the environment variable '''ROS_BUILD_TEST_LABEL''' is unset; OR * the '''label''' argument is equal to the environment variable '''ROS_BUILD_TEST_LABEL'''. Use this macro to declare tests that should not run in certain situations. Most commonly used with a continuous integration system. ==== rosbuild_add_pyunit_future ==== '''DEPRECATED and rendered non-functional in 1.7. Instead of using this macro, simply comment out tests that don't yet pass.''' (`TIMEOUT` option new in 1.1.8) {{{ rosbuild_add_pyunit_future(file [TIMEOUT timeout_secs]) }}} This macro is the same a '''`rosbuild_add_pyunit(),`''' except that the resulting test will be only be run during '''make test-future'''. Use this macro to declare tests that fail now, but should pass in the future, after an existing bug is fixed or missing feature implemented. We segregate ''future'' tests from current tests so that the automated build and test system can accurately report health of the system, including giving meaningful email notification on test failure. ==== rosbuild_add_rostest ==== {{{ rosbuild_add_rostest(xmlfile) }}} This macro declares a [[rostest]] test that is to be run when testing the package. When '''make test''' is run on the package, the given '''xmlfile''' will be passed to [[rostest]]. Output goes in $ROS_ROOT/test/test_results/${project}, where ${project} is the name of the ROS package. ==== rosbuild_add_rostest_labeled ==== {{{ rosbuild_add_rostest_labeled(label file) }}} This macro is the same a '''`rosbuild_add_rostest(),`''' except that it only declares the test if EITHER: * the environment variable '''ROS_BUILD_TEST_LABEL''' is unset; OR * the '''label''' argument is equal to the environment variable '''ROS_BUILD_TEST_LABEL'''. Use this macro to declare tests that should not run in certain situations. Most commonly used with a continuous integration system. ==== rosbuild_add_rostest_future ==== '''DEPRECATED and rendered non-functional in 1.7. Instead of using this macro, simply comment out tests that don't yet pass.''' {{{ rosbuild_add_rostest_future(xmlfile) }}} This macro is the same a '''`rosbuild_add_rostest(),`''' except that the resulting test will be only be run during '''make test-future'''. Use this macro to declare tests that fail now, but should pass in the future, after an existing bug is fixed or missing feature implemented. We segregate ''future'' tests from current tests so that the automated build and test system can accurately report health of the system, including giving meaningful email notification on test failure. ==== rosbuild_add_roslaunch_check ==== (New in ROS 1.1.2) {{{ rosbuild_add_roslaunch_check(file_or_directory [var1=val] [var2=val2] ...) }}} This macro declares as a unit test a parse check of one or more [[roslaunch]] files. The parser (`roslaunch/scripts/roslaunch-check`) checks a number of aspects of launch files, in a manner similar to [[roswtf]]. The first argument should be either a [[roslaunch]] file, or a directory. If it's a directory, then all `*.launch` files in that directory are checked. Following the required first argument, you can optionally specify environment variables that will be set before running the parser. This feature is useful if you use `$(env)` in your roslaunch files. E.g., to test a roslaunch file with the environment variable `ROBOT` set to `sim`: {{{ rosbuild_add_roslaunch_check(foo.launch ROBOT=sim) }}} '''NOTE''': Do not call your file or directory '''test'''. This target name is reserved for unit testing, and CMake will fail if you try it. Instead, put your launch files into a directory with a different name, e.g., '''tests'''. ==== rosbuild_declare_test ==== {{{ rosbuild_declare_test(exe) }}} This macro declares that an executable is a test harness, which adds it to the '''make tests''' build. Use this macro to declare that an executable is only used in testing. This macro is automatically invoked for any executable that is declared via '''`rosbuild_add_gtest()`''', '''`rosbuild_add_gtest_future()`''', or '''`rosbuild_add_gtest_build_flags()`'''. So you only need to use this macro for an executable that is used in testing, but isn't a test itself; e.g., a node that is used in setting up a [[rostest]]. This macro does '''not''' exclude building the executable from the '''make all''' build. To do this, you must supply the '''EXCLUDE_FROM_ALL''' option when calling '''`rosbuild_add_executable()`'''. ==== rosbuild_count_cores ==== {{{ rosbuild_count_cores(num) }}} This macro calls out to Python to determine the number of physical cores on your machine, and writes this number into '''num'''. It's intended for use in gating tests that require a lot of processing. E.g., if you want to run a test only when you have at least 4 cores: {{{ rosbuild_count_cores(cores) if(cores GREATER 4 OR cores EQUAL 4) rosbuild_add_rostest(my_crazy_test.xml) endif(cores GREATER 4 OR cores EQUAL 4) }}} ==== rosbuild_check_for_display ==== {{{ rosbuild_check_for_display(var) }}} This macro checks for the presence of an X display (currently by looking at the exit status from calling `xdpyinfo`). It sets '''var''' to 1 if there is a display, and 0 otherwise. It's intended for us in gating tests that require an X display, e.g.: {{{ rosbuild_check_for_display(disp) if(disp) rosbuild_add_rostest(my_graphical_test.xml) endif(disp) }}} ==== rosbuild_check_for_vm ==== {{{ rosbuild_check_for_vm(result) }}} This macro determines whether the build is happening on a virtual machine. Currently, it just looks for "/proc/xen". The intended use is gating tests that have strict timing requirements. The assumption is that a non-VM will have low load. E.g., to only run a test on a non-VM: {{{ rosbuild_check_for_vm(vm) if(NOT vm) rosbuild_add_rostest(my_strict_timing_test.xml) endif(NOT vm) }}} === Message / service macros === ==== rosbuild_gensrv ==== {{{ rosbuild_gensrv() }}} This macro processes service specifications that defined locally in a package. It runs [[Client Libraries|client library]]-specific code generators over all '''*.srv''' files found in the '''srv''' subdirectory of the package. Example usage: {{{ cmake_minimum_required(VERSION 2.4.6) include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake) rosbuild_init() rosbuild_gensrv() # the service provider rosbuild_add_executable(deadreckon deadreckon.cpp) # a dumb test client rosbuild_add_executable(test_deadreckon_service test_deadreckon_service.cpp) }}} ==== rosbuild_genmsg ==== {{{ rosbuild_genmsg() }}} This macro processes message specifications that defined locally in a package. It runs [[Client Libraries|client library]]-specific code generators over all '''*.msg''' files found in the '''msg''' subdirectory of the package. ==== rosbuild_add_generated_msgs ==== {{{ rosbuild_add_generated_msgs(AutoGen1.msg AutoGen2.msg) }}} This macro sets up for auto-generation of one or more messages. It creates an expectation that the message files passed as arguments will be created during the build. This macro may be called more than once. Through CTurtle, this macro must be called '''before''' rosbuild_init(). Starting with Diamondback, it must be called '''before''' rosbuild_genmsg(). Auto-generating messages is an advanced topic; see the code in [[actionlib]] for an example. ==== rosbuild_add_generated_srvs ==== {{{ rosbuild_add_generated_srvs(AutoGen1.srv AutoGen2.srv) }}} This macro sets up for auto-generation of one or more services. It creates an expectation that the service files passed as arguments will be created during the build. This macro may be called more than once. Through CTurtle, this macro must be called '''before''' rosbuild_init(). Starting with Diamondback, it must be called '''before''' rosbuild_gensrv(). Auto-generating services is an advanced topic; see the code in [[actionlib]] for an example. === Version macros === ==== rosbuild_get_stack_version ==== (New in ROS 1.3.1) {{{ rosbuild_get_stack_version(var stackname) }}} This macro fetches the name of the stack `stackname` and puts it into `var`. If the version cannot be determined, it is a fatal error. This macro works by calling `rosversion`. ==== rosbuild_get_package_version ==== (New in ROS 1.3.1) {{{ rosbuild_get_package_version(var pkgname) }}} This macro fetches the version of the stack that contains the package `pkgname`, and puts it into `var`. If the package is not in a stack, or if the stack's version cannot be determined, it is a fatal error. This macro works by calling `rosbuild_get_stack_version()`, with the output of `rosstack contains pkgname`. === Downloading files during the build === It is sometimes necessary to download files during the build. This is usually done to avoid checking large, often binary, files into Subversion. Some macros are provided to help in these cases ==== rosbuild_download_data ==== (New in 0.8; 3-argument form new in 0.9) {{{ rosbuild_download_data(url filename md5sum) }}} DEPRECATED 2-argument form, without an md5sum: {{{ rosbuild_download_data(url filename) }}} This macro sets up a target for downloading a file from '''url''' and saving it locally with the name '''filename''', and checking the resulting file's md5 hash against '''md5sum'''. The target will fire on the '''all''' target, which means that it will happen during the main build of the package. There are no guarantees on ordering of steps within the '''all''' target (e.g., the download is not guaranteed to happen before a particular compilation step). The '''url''' should be fully-qualified (e.g., don't leave out the domain name), and the '''filename''' should be relative to your package directory. The md5 hash is checked on every build; if it doesn't match, '''filename''' is deleted, and one attempt is made to re-download the file; if it still doesn't match, the build is aborted with an error. If you're pulling from a web-accessible Subversion repository and want a particular revision of a file, you can use the standard Subversion URL syntax, `!svn/bc//`. E.g., to download revision 6 of a map: {{{ rosbuild_download_data(https://code.ros.org/svn/data/!svn/bc/6/trunk/willow_maps/willow-2010-02-18-0.025.pgm willow-2010-02-18-0.025.pgm b9c44f1d528c1ebd6a3f5b6720a5b8df) }}} '''Note for Willow Garage people:''' You should put your data at ipr:/var/www/pr.willowgarage.com/html/data, in a directory with the same name as your package. ==== rosbuild_download_test_data ==== (3-argument form new in 0.9) {{{ rosbuild_download_test_data(url filename md5sum) }}} DEPRECATED 2-argument form, without an md5sum: {{{ rosbuild_download_test_data(url filename) }}} This macro is the same as '''`rosbuild_download_data()`''', except that it will fire on the '''tests''' target, which happens during the build of test programs, prior to running any tests. '''Note for Willow Garage people''': You should put your data at '''ipr''':/var/www/pr.willowgarage.com/html/data, in a directory with the same name as your package. ==== rosbuild_untar_file ==== (new in 1.1.8) {{{ rosbuild_untar_file(tarfile unpacked_name [target]) }}} This macro sets up rules to unpack the file `tarfile`, using the command `tar xf`. The rule expects the file or directory `unpacked_name` to exist after unpacking; you would normally set this equal to the name of the top-level directory contained in `tarfile`. The optional `target` is a target that should be made to depend on the unpacking of `tarfile`. Common values for `target` are `ALL` (unpack during `make`) and `tests` (unpack during `make test`, prior to running any tests). For example, to download a tar file of test data, and make sure that it's unpacked before running tests on it: {{{ rosbuild_download_test_data(http://pr.willowgarage.com/data/${PROJECT_NAME}/test_session_results_fixture.tgz test_data/test_session_results_fixture.tgz a15e52b7b827ab7560bd42c98e7c5a93) rosbuild_untar_file(test_data/test_session_results_fixture.tgz test_data/session_results_gold tests) }}} === Special targets === rosbuild defines some special targets that you can use to encode dependencies in the build process. ==== rosbuild_premsgsrvgen ==== The `rosbuild_premsgsrvgen` target fires before doing message or service generation. By making this target depend on one of your targets, you can do work beforehand. A simple example, which will generate a file before message or service generation: {{{ # Generate the file foo add_custom_command(OUTPUT foo COMMAND touch foo) # Create a target that depends on the generation of foo add_custom_target(foo_target DEPENDS foo) # Make message service generation depend on our target: add_dependencies(rosbuild_premsgsrvgen foo) }}} ==== rosbuild_precompile ==== The `rosbuild_precompile` target fires before compiling any C/C++ programs. By making this target depend on one of your targets, you can do work beforehand. A simple example, which will generate a file before compiling: {{{ # Generate the file foo add_custom_command(OUTPUT foo COMMAND touch foo) # Create a target that depends on the generation of foo add_custom_target(foo_target DEPENDS foo) # Make compilation depend on our target: add_dependencies(rosbuild_precompile foo) }}} === Making stack distributions === The release unit in ROS is a [[Stacks|stack]]. `rosbuild` offers support for making source distributions of stacks ([[StackBuildFiles|more information]]). ==== rosbuild_make_distribution ==== {{{ rosbuild_make_distribution(version) }}} This macro performs the set up necessary to produce a source tarball of the stack, at the given version.