pybind11_add_module(${LIBRARY_NAME}
    gafropy.cpp

    algebra/cga/Circle.cpp
    algebra/cga/Dilator.cpp
    algebra/cga/DirectionVector.cpp
    algebra/cga/FlatPoint.cpp
    algebra/cga/Line.cpp
    algebra/cga/Motor.cpp
    algebra/cga/Plane.cpp
    algebra/cga/Point.cpp
    algebra/cga/PointPair.cpp
    algebra/cga/Rotor.cpp
    algebra/cga/RotorGenerator.cpp
    algebra/cga/Sphere.cpp
    algebra/cga/TangentVector.cpp
    algebra/cga/Translator.cpp
    algebra/cga/Transversion.cpp
    algebra/cga/Vector.cpp

    algebra/Cayley.cpp

    physics/Inertia.cpp
    physics/Twist.cpp
    physics/Wrench.cpp

    robots/ChainParameters.cpp
    robots/Joint.cpp
    robots/Body.cpp
    robots/Link.cpp
    robots/KinematicChain.cpp
    robots/System.cpp
    robots/Actuator.cpp
    robots/Sensor.cpp
    robots/TaskSpace.cpp
    robots/Serialization.cpp

    optimization/Optimization.cpp

    control/Control.cpp

    robot_interface/RobotInterface.cpp
    robot_interface/Controllers.cpp
)

target_include_directories(${LIBRARY_NAME}
    PRIVATE
        ${CMAKE_SOURCE_DIR}/src
        ${GAFROPY_DEP_INCLUDE_DIRS}
)

target_link_libraries(${LIBRARY_NAME}
    PRIVATE
        yaml-cpp
        gafro::gafro
        behemoth::behemoth
        # Since robot-interface-unify the backend is chosen by a direct
        # std::make_unique<mujoco::MujocoBackend>() (no sackmesser REGISTER_CLASS factory),
        # so the MujocoBackend object is referenced directly and a normal static link keeps
        # it — WHOLE_ARCHIVE is no longer needed.
        robot_interface::robot_interface
)

# Runtime shared libraries the extension dlopens at import:
#   * libgafro.so       — gafro's CMake hardcodes add_library(gafro SHARED); rather than patch
#                         it static we ship the .so next to _gafropy.so (installed below) and
#                         add $ORIGIN to the install RPATH so the loader finds it there.
#   * libmujoco.so      — robot_interface's backend links it; it lives in the pip `mujoco`
#                         wheel. RPATH $ORIGIN/../mujoco rather than the build-time absolute
#                         path of wherever `mujoco` happened to be installed while compiling
#                         (an isolated pip build env, gone by the time the extension is
#                         actually imported) -- pip always installs packages as siblings under
#                         the same site-packages root, so this resolves correctly for editable,
#                         sdist, and wheel installs alike, and keeps sharing the *same*
#                         libmujoco.so instance the `mujoco` package itself loads (needed for
#                         gafropy and mujoco's Python API to interoperate on the same native
#                         objects) rather than a private copy bundled in by auditwheel.
# Everything else (behemoth, robot_interface) is baked in statically. $ORIGIN must be
# present whether or not MuJoCo is found, hence it is set first.
set(GAFROPY_INSTALL_RPATH "$ORIGIN")

if (GAFROPY_MUJOCO_FOUND)
    target_link_libraries(${LIBRARY_NAME} PRIVATE ${GAFROPY_MUJOCO_LIBRARY})
    target_include_directories(${LIBRARY_NAME} PRIVATE ${GAFROPY_MUJOCO_INCLUDE_DIR})
    target_compile_definitions(${LIBRARY_NAME} PRIVATE GAFROPY_WITH_MUJOCO=1)

    list(APPEND GAFROPY_INSTALL_RPATH "$ORIGIN/../mujoco")
endif()

# For the build tree, CMake automatically adds linked-target dirs (incl. libgafro.so's) to
# the RPATH, so only the install RPATH needs setting: $ORIGIN (for the shipped libgafro.so,
# installed below) plus the mujoco dir appended above.
set_target_properties(${LIBRARY_NAME} PROPERTIES
    INSTALL_RPATH "${GAFROPY_INSTALL_RPATH}"
)

if (CMAKE_CXX_COMPILER_ID MATCHES "(C|c?)lang")
    target_compile_options(${LIBRARY_NAME} PRIVATE
        "-Wall" "-Wno-unused-local-typedef" "-Wno-unused-command-line-argument")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    target_compile_options(${LIBRARY_NAME} PRIVATE
        "-Wall" "-Wno-unused-local-typedefs" "-Wno-class-memaccess")
endif()

install(TARGETS ${LIBRARY_NAME} DESTINATION gafropy)
# Ship libgafro.so alongside the extension (kept SHARED upstream); $ORIGIN in the install
# RPATH (above) lets _gafropy.so find it here at import time. gafro is an in-tree FetchContent
# target, so install its LIBRARY artifact directly.
install(TARGETS gafro
    LIBRARY DESTINATION gafropy
    RUNTIME DESTINATION gafropy
)
install(
    FILES
        ${CMAKE_SOURCE_DIR}/src/gafropy/__init__.py
        ${CMAKE_SOURCE_DIR}/src/gafropy/viz.py
    DESTINATION
        gafropy
)
install(
    DIRECTORY
        ${CMAKE_SOURCE_DIR}/src/gafropy/torch/
    DESTINATION
        gafropy/torch
    FILES_MATCHING PATTERN "*.py"
)
# Robot assets are no longer bundled (gafro_robot_descriptions removed). Load robots from
# your own absolute paths, or set GAFRO_ASSETS_DIR to an external asset tree.
