diff --git a/.github/actions/setup-bsk/action.yml b/.github/actions/setup-bsk/action.yml index d9c75a5..4aecf69 100644 --- a/.github/actions/setup-bsk/action.yml +++ b/.github/actions/setup-bsk/action.yml @@ -1,6 +1,6 @@ name: Set up Basilisk description: > - Clones the Basilisk source tree and installs the BSK Python package, + Clones the Basilisk source tree and installs the BSK Python package set, beta/alpha => develop branch clone + nightly wheel index rc => release tag clone + TestPyPI release => release tag clone + PyPI @@ -15,7 +15,7 @@ inputs: description: Clone Basilisk source to external/basilisk (needed for sync_all.py) default: "true" install-package: - description: pip-install the BSK Python package into the current environment + description: pip-install the BSK Python package set into the current environment default: "true" runs: @@ -34,7 +34,7 @@ runs: git clone --depth 1 --branch "$REF" \ https://github.com/AVSLab/basilisk.git external/basilisk - - name: Install BSK Python package + - name: Install BSK Python package set if: inputs.install-package == 'true' shell: bash run: | @@ -43,12 +43,12 @@ runs: pip install --pre \ --index-url https://avslab.github.io/basilisk/nightly/ \ --extra-index-url https://pypi.org/simple/ \ - bsk + "bsk[all]" elif [[ "$BSK" =~ rc ]]; then pip install --pre \ --index-url https://test.pypi.org/simple/ \ --extra-index-url https://pypi.org/simple/ \ - "bsk==${BSK}" + "bsk[all]==${BSK}" else - pip install "bsk==${BSK}" + pip install "bsk[all]==${BSK}" fi diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 1f3ac8b..ed41d31 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -47,7 +47,7 @@ jobs: pip install --pre \ --index-url https://avslab.github.io/basilisk/nightly/ \ --extra-index-url https://pypi.org/simple/ \ - bsk + "bsk[all]" - name: Sync and build SDK run: | diff --git a/build_backend.py b/build_backend.py index e2e98d9..d1bc778 100644 --- a/build_backend.py +++ b/build_backend.py @@ -60,6 +60,7 @@ def _required_sync_files(repo_root: Path) -> list[Path]: msg_auto = repo_root / "tools" / "msgAutoSource" return [ repo_root / "src" / "bsk_sdk" / "_bsk_version.txt", + msg_auto / "generatePayloadEqualityHeader.py", msg_auto / "generatePayloadMetaJson.py", msg_auto / "generateSWIGModules.py", msg_auto / "msgInterfacePy.i.in", diff --git a/cmake/bsk-sdkConfig.cmake.in b/cmake/bsk-sdkConfig.cmake.in index daf2bd6..204ad36 100644 --- a/cmake/bsk-sdkConfig.cmake.in +++ b/cmake/bsk-sdkConfig.cmake.in @@ -75,7 +75,7 @@ function(_bsk_sdk_check_basilisk_version) " Installed Basilisk is ${_bsk_installed_version}\n\n" "Plugins compiled against mismatched headers will have ABI incompatibilities.\n" "Either install the matching Basilisk version or re-sync the SDK:\n" - " pip install bsk==${BSK_SDK_BSK_VERSION}\n" + " pip install \"bsk[all]==${BSK_SDK_BSK_VERSION}\"\n" " # or: cd external/basilisk && git checkout v${_bsk_installed_version} && cd ../.. && python3 tools/sync_all.py" ) endif() diff --git a/cmake/bsk_add_swig_module.cmake b/cmake/bsk_add_swig_module.cmake index a8dff25..b6dab04 100644 --- a/cmake/bsk_add_swig_module.cmake +++ b/cmake/bsk_add_swig_module.cmake @@ -107,7 +107,21 @@ macro(_bsk_find_build_deps) find_package(SWIG REQUIRED COMPONENTS python) include(${SWIG_USE_FILE}) find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module NumPy) - find_package(Eigen3 CONFIG REQUIRED) + + if(NOT TARGET Eigen3::Eigen) + find_package(Eigen3 CONFIG QUIET) + endif() + if(NOT TARGET Eigen3::Eigen) + if(DEFINED BSK_SDK_INCLUDE_DIR + AND EXISTS "${BSK_SDK_INCLUDE_DIR}/eigen3/Eigen/Core") + add_library(Eigen3::Eigen IMPORTED INTERFACE GLOBAL) + set_target_properties(Eigen3::Eigen PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${BSK_SDK_INCLUDE_DIR}/eigen3" + ) + else() + find_package(Eigen3 CONFIG REQUIRED) + endif() + endif() endmacro() # Collect SDK implementation sources to compile directly into the plugin. diff --git a/cmake/bsk_generate_messages.cmake b/cmake/bsk_generate_messages.cmake index 6fbc8b4..41417c7 100644 --- a/cmake/bsk_generate_messages.cmake +++ b/cmake/bsk_generate_messages.cmake @@ -22,13 +22,14 @@ if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/bsk_add_swig_module.cmake") include("${CMAKE_CURRENT_LIST_DIR}/bsk_add_swig_module.cmake") endif() -# Locate the msgAutoSource directory that ships generateSWIGModules.py and -# generatePayloadMetaJson.py. Both scripts must be present — the JSON -# generator was added in BSK 2.11 and is required by bsk_generate_messages(). +# Locate the msgAutoSource directory that ships the message generators. These +# scripts must be present — the JSON and equality generators were added in BSK +# 2.11 and are required by bsk_generate_messages(). function(_bsk_resolve_msg_autosource_dir out_var) if(DEFINED BSK_SDK_MSG_AUTOSOURCE_DIR AND EXISTS "${BSK_SDK_MSG_AUTOSOURCE_DIR}/generateSWIGModules.py" - AND EXISTS "${BSK_SDK_MSG_AUTOSOURCE_DIR}/generatePayloadMetaJson.py") + AND EXISTS "${BSK_SDK_MSG_AUTOSOURCE_DIR}/generatePayloadMetaJson.py" + AND EXISTS "${BSK_SDK_MSG_AUTOSOURCE_DIR}/generatePayloadEqualityHeader.py") set(${out_var} "${BSK_SDK_MSG_AUTOSOURCE_DIR}" PARENT_SCOPE) return() endif() @@ -48,7 +49,8 @@ function(_bsk_resolve_msg_autosource_dir out_var) foreach(_cand IN LISTS _candidates) if(EXISTS "${_cand}/generateSWIGModules.py" - AND EXISTS "${_cand}/generatePayloadMetaJson.py") + AND EXISTS "${_cand}/generatePayloadMetaJson.py" + AND EXISTS "${_cand}/generatePayloadEqualityHeader.py") set(${out_var} "${_cand}" PARENT_SCOPE) return() endif() @@ -57,7 +59,8 @@ function(_bsk_resolve_msg_autosource_dir out_var) string(JOIN "\n " _cand_list ${_candidates}) message(FATAL_ERROR "bsk-sdk message generators not found.\n\n" - "Looked for generateSWIGModules.py and generatePayloadMetaJson.py under:\n" + "Looked for generateSWIGModules.py, generatePayloadMetaJson.py, and " + "generatePayloadEqualityHeader.py under:\n" " ${_cand_list}\n\n" "Re-sync the SDK tools (requires BSK >= 2.11):\n" " python3 tools/sync_all.py --sync-submodules\n\n" @@ -89,6 +92,7 @@ function(bsk_generate_messages) set(_gen_swig "${_msg_autosrc}/generateSWIGModules.py") set(_gen_meta "${_msg_autosrc}/generatePayloadMetaJson.py") + set(_gen_eq "${_msg_autosrc}/generatePayloadEqualityHeader.py") set(_auto_root "${CMAKE_CURRENT_BINARY_DIR}/autoSource") set(_json_dir "${_auto_root}/cMsgMeta") file(MAKE_DIRECTORY "${_json_dir}") @@ -131,6 +135,32 @@ function(bsk_generate_messages) VERBATIM ) + # Generate the per-payload equality traits header included by the SWIG + # template. Basilisk's generator includes payload headers below + # "architecture/${_eq_payload_search_dir}", so create a forwarding include + # tree in autoSource that points back to the plugin's real payload header. + set(_eq_payload_search_dir "bskSdkPluginPayloads") + file(TO_CMAKE_PATH "${_hdr_abs}" _hdr_include) + set(_eq_forward_dir "${_auto_root}/architecture/${_eq_payload_search_dir}") + set(_eq_forward_hdr "${_eq_forward_dir}/${_payload_name}.h") + file(MAKE_DIRECTORY "${_eq_forward_dir}") + file(WRITE "${_eq_forward_hdr}" + "#pragma once\n" + "#include \"${_hdr_include}\"\n" + ) + + set(_eq_out "${_auto_root}/${_payload_name}_equality.h") + add_custom_command( + OUTPUT "${_eq_out}" + COMMAND ${Python3_EXECUTABLE} + "${_gen_eq}" + "${_eq_out}" "${_meta_out}" "${_payload_name}" "${_eq_payload_search_dir}" + DEPENDS "${_meta_out}" "${_gen_eq}" "${_eq_forward_hdr}" + WORKING_DIRECTORY "${_msg_autosrc}" + COMMENT "Generating payload equality header for ${_payload_name}" + VERBATIM + ) + # Generate the .i interface file from the JSON set(_i_out "${_auto_root}/${_payload_name}.i") add_custom_command( @@ -140,7 +170,7 @@ function(bsk_generate_messages) "${_i_out}" "${_hdr_abs}" "${_payload_name}" "${_hdr_dir}" "${_gen_c}" "${_meta_out}" 0 - DEPENDS "${_hdr_abs}" "${_meta_out}" "${_gen_swig}" "${_msg_autosrc}/msgInterfacePy.i.in" + DEPENDS "${_hdr_abs}" "${_meta_out}" "${_eq_out}" "${_gen_swig}" "${_msg_autosrc}/msgInterfacePy.i.in" WORKING_DIRECTORY "${_msg_autosrc}" COMMENT "Generating SWIG interface for ${_payload_name}" VERBATIM @@ -169,6 +199,21 @@ function(bsk_generate_messages) endif() endif() + if(NOT EXISTS "${_eq_out}") + execute_process( + COMMAND ${Python3_EXECUTABLE} + "${_gen_eq}" + "${_eq_out}" "${_meta_out}" "${_payload_name}" "${_eq_payload_search_dir}" + WORKING_DIRECTORY "${_msg_autosrc}" + RESULT_VARIABLE _gen_rc + ERROR_VARIABLE _gen_err + ) + if(NOT _gen_rc EQUAL 0) + message(FATAL_ERROR + "generatePayloadEqualityHeader.py failed for ${_payload_name}:\n${_gen_err}") + endif() + endif() + if(NOT EXISTS "${_i_out}") execute_process( COMMAND ${Python3_EXECUTABLE} @@ -203,7 +248,7 @@ function(bsk_generate_messages) _bsk_configure_swig_target( ${_payload_name} "${BSK_OUTPUT_DIR}" "${BSK_TARGET_LINK_LIBS}" - "${BSK_INCLUDE_DIRS};${_hdr_dir}" + "${BSK_INCLUDE_DIRS};${_hdr_dir};${_auto_root}" ) if(_bsk_msg_sdk_sources) diff --git a/examples/custom-atm-plugin/README.md b/examples/custom-atm-plugin/README.md index 82f1863..b597ed2 100644 --- a/examples/custom-atm-plugin/README.md +++ b/examples/custom-atm-plugin/README.md @@ -23,7 +23,7 @@ custom-atm-plugin/ ## Building ```bash -pip install bsk-sdk bsk +pip install bsk-sdk "bsk[all]" pip install build scikit-build-core python -m build --wheel --no-isolation ``` diff --git a/external/basilisk b/external/basilisk index 5cb7219..6c1511f 160000 --- a/external/basilisk +++ b/external/basilisk @@ -1 +1 @@ -Subproject commit 5cb7219b368224753bf6c1c44fb8eb22da22b545 +Subproject commit 6c1511f5385dccaa73c9ae24522a74adc24fe623 diff --git a/pyproject.toml b/pyproject.toml index 4a02f23..24b9819 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ backend-path = ["."] [project] name = "bsk-sdk" -version = "2.11.0beta" +version = "2.11.0" description = "Vendored Basilisk SDK headers, runtime, and CMake integration for plugin authors" readme = "README.md" license = { text = "ISC" } @@ -35,7 +35,11 @@ wheel.py-api = "py3" wheel.platlib = false wheel.install-dir = "bsk_sdk" +sdist.inclusion-mode = "explicit" sdist.include = [ + "pyproject.toml", + "build_backend.py", + "README.md", "CMakeLists.txt", "cmake/**", "src/bsk_sdk/include/**", @@ -57,6 +61,8 @@ sdist.exclude = [ "examples/**", "external/**", "tests/**", + ".DS_Store", + "**/.DS_Store", "**/__pycache__/**", "**/*.pyc", ] diff --git a/src/bsk_sdk/_bsk_version.txt b/src/bsk_sdk/_bsk_version.txt index 7ef80bc..46b81d8 100644 --- a/src/bsk_sdk/_bsk_version.txt +++ b/src/bsk_sdk/_bsk_version.txt @@ -1 +1 @@ -2.11.0beta +2.11.0 diff --git a/tests/test_smoke.py b/tests/test_smoke.py index 4ef27d0..e38d896 100644 --- a/tests/test_smoke.py +++ b/tests/test_smoke.py @@ -78,6 +78,11 @@ def test_builtin_c_msg_interfaces_present() -> None: def test_msg_autosource_generators_present() -> None: autosrc = Path(bsk_sdk.msg_autosource_dir()) assert autosrc.is_dir(), f"msg_autosource_dir() does not exist: {autosrc}" - for name in ("generatePayloadMetaJson.py", "generateSWIGModules.py", - "msgInterfacePy.i.in", "cMsgCInterfacePy.i.in"): + for name in ( + "generatePayloadEqualityHeader.py", + "generatePayloadMetaJson.py", + "generateSWIGModules.py", + "msgInterfacePy.i.in", + "cMsgCInterfacePy.i.in", + ): assert (autosrc / name).exists(), f"Missing msgAutoSource file: {name}"