|
1 | 1 | # ============================================================================ |
2 | 2 | # jig_auto_package.cmake |
3 | 3 | # |
4 | | -# Automated build system for ROS 2 packages with jig nodes. Expects nodes/ directory with subdirectories containing |
5 | | -# interface.yaml and C++ or Python implementation files. |
| 4 | +# Automated build system for ROS 2 packages with jig nodes. Optionally expects a nodes/ directory with subdirectories |
| 5 | +# containing interface.yaml and C++ or Python implementation files; packages without nodes/ are also supported (e.g. |
| 6 | +# launch-only, config-only, or shared-interface metapackages). |
6 | 7 | # |
7 | 8 | # NOTE: Most internal functions are implemented as macros (not functions) for consistency with ament_cmake patterns and |
8 | 9 | # to preserve variable scope behavior. This allows macros like ament_auto_add_library() and |
@@ -47,8 +48,8 @@ function(_jig_snake_to_pascal OUTPUT_VAR INPUT_STRING) |
47 | 48 | endfunction() |
48 | 49 |
|
49 | 50 | # Main entry point for jig build system Automates the entire build process for ROS 2 packages with jig nodes. Detects |
50 | | -# languages, generates interfaces, builds libraries, and registers components. Requires: nodes/ directory with at least |
51 | | -# one .cpp or .py file |
| 51 | +# languages, generates interfaces, builds libraries, and registers components. If nodes/ is absent, all per-node steps |
| 52 | +# are skipped and only top-level interfaces/, launch/, config/, and INSTALL_TO_SHARE assets are installed. |
52 | 53 | macro(jig_auto_package) |
53 | 54 | # Parse optional arguments |
54 | 55 | set(_jig_auto_options "") |
@@ -79,31 +80,30 @@ macro(jig_auto_package) |
79 | 80 | # NOTE: JIG_NODES_DIR is part of the jig cmake API |
80 | 81 | set(JIG_NODES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/nodes") |
81 | 82 |
|
82 | | - if(NOT IS_DIRECTORY ${JIG_NODES_DIR}) |
83 | | - message(FATAL_ERROR "jig: nodes/ directory not found at ${JIG_NODES_DIR}") |
84 | | - endif() |
| 83 | + # nodes/ is optional: a jig package may exist purely for launch files, configs, or shared interface YAMLs. |
| 84 | + if(IS_DIRECTORY ${JIG_NODES_DIR}) |
| 85 | + _jig_detect_languages(${JIG_NODES_DIR} _jig_HAS_CPP _jig_HAS_PYTHON) |
85 | 86 |
|
86 | | - _jig_detect_languages(${JIG_NODES_DIR} _jig_HAS_CPP _jig_HAS_PYTHON) |
| 87 | + if(NOT _jig_HAS_CPP AND NOT _jig_HAS_PYTHON) |
| 88 | + message(FATAL_ERROR "jig: nodes/ directory has no C++ (.cpp) or Python (.py) files.") |
| 89 | + endif() |
87 | 90 |
|
88 | | - if(NOT _jig_HAS_CPP AND NOT _jig_HAS_PYTHON) |
89 | | - message(FATAL_ERROR "jig: nodes/ directory has no C++ (.cpp) or Python (.py) files.") |
90 | | - endif() |
| 91 | + if(_jig_HAS_CPP) |
| 92 | + # NOTE: JIG_CPP_PACKAGE_TARGET is part of the jig cmake API |
| 93 | + set(JIG_CPP_PACKAGE_TARGET "${PROJECT_NAME}") |
| 94 | + _jig_create_package_shared_cpp_library(${JIG_CPP_PACKAGE_TARGET}) |
| 95 | + endif() |
91 | 96 |
|
92 | | - if(_jig_HAS_CPP) |
93 | | - # NOTE: JIG_CPP_PACKAGE_TARGET is part of the jig cmake API |
94 | | - set(JIG_CPP_PACKAGE_TARGET "${PROJECT_NAME}") |
95 | | - _jig_create_package_shared_cpp_library(${JIG_CPP_PACKAGE_TARGET}) |
96 | | - endif() |
| 97 | + if(_jig_HAS_PYTHON) |
| 98 | + # set up python package |
| 99 | + find_package(ament_cmake_python REQUIRED) |
| 100 | + _ament_cmake_python_get_python_install_dir() |
| 101 | + _jig_create_top_level_python_package() |
| 102 | + endif() |
97 | 103 |
|
98 | | - if(_jig_HAS_PYTHON) |
99 | | - # set up python package |
100 | | - find_package(ament_cmake_python REQUIRED) |
101 | | - _ament_cmake_python_get_python_install_dir() |
102 | | - _jig_create_top_level_python_package() |
| 104 | + _jig_generate_nodes(${JIG_NODES_DIR}) |
103 | 105 | endif() |
104 | 106 |
|
105 | | - _jig_generate_nodes(${JIG_NODES_DIR}) |
106 | | - |
107 | 107 | # Process and install interface.yaml files with token replacement |
108 | 108 | _jig_process_and_install_interfaces(${JIG_NODES_DIR}) |
109 | 109 |
|
@@ -417,18 +417,20 @@ macro(_jig_process_and_install_interfaces NODES_DIR) |
417 | 417 | set(_jig_interfaces_output_dir "${CMAKE_CURRENT_BINARY_DIR}/interfaces") |
418 | 418 | file(MAKE_DIRECTORY ${_jig_interfaces_output_dir}) |
419 | 419 |
|
420 | | - # Collect expected generated node YAML names (for conflict checking) |
| 420 | + # Collect expected generated node YAML names (for conflict checking). Skipped when nodes/ is absent. |
421 | 421 | set(_jig_generated_node_yaml_names "") |
422 | | - file(GLOB _jig_interface_NODE_DIRS RELATIVE ${NODES_DIR} ${NODES_DIR}/*) |
423 | | - foreach(_jig_interface_NODE_ENTRY ${_jig_interface_NODE_DIRS}) |
424 | | - set(_jig_interface_NODE_PATH "${NODES_DIR}/${_jig_interface_NODE_ENTRY}") |
425 | | - if(IS_DIRECTORY ${_jig_interface_NODE_PATH}) |
426 | | - set(_jig_interface_YAML_PATH "${_jig_interface_NODE_PATH}/interface.yaml") |
427 | | - if(EXISTS ${_jig_interface_YAML_PATH}) |
428 | | - list(APPEND _jig_generated_node_yaml_names "${_jig_interface_NODE_ENTRY}.yaml") |
| 422 | + if(IS_DIRECTORY ${NODES_DIR}) |
| 423 | + file(GLOB _jig_interface_NODE_DIRS RELATIVE ${NODES_DIR} ${NODES_DIR}/*) |
| 424 | + foreach(_jig_interface_NODE_ENTRY ${_jig_interface_NODE_DIRS}) |
| 425 | + set(_jig_interface_NODE_PATH "${NODES_DIR}/${_jig_interface_NODE_ENTRY}") |
| 426 | + if(IS_DIRECTORY ${_jig_interface_NODE_PATH}) |
| 427 | + set(_jig_interface_YAML_PATH "${_jig_interface_NODE_PATH}/interface.yaml") |
| 428 | + if(EXISTS ${_jig_interface_YAML_PATH}) |
| 429 | + list(APPEND _jig_generated_node_yaml_names "${_jig_interface_NODE_ENTRY}.yaml") |
| 430 | + endif() |
429 | 431 | endif() |
430 | | - endif() |
431 | | - endforeach() |
| 432 | + endforeach() |
| 433 | + endif() |
432 | 434 |
|
433 | 435 | # Process top-level interfaces/ directory if it exists |
434 | 436 | set(_jig_toplevel_interfaces_dir "${CMAKE_CURRENT_SOURCE_DIR}/interfaces") |
|
0 commit comments