feat: support with plugin build

This commit is contained in:
insleker 2026-05-21 12:46:25 +08:00
parent d877661507
commit 0ec592a2be
8 changed files with 219 additions and 159 deletions

4
.gitignore vendored
View File

@ -70,4 +70,6 @@ Testing/
# user # user
**/CMakeUserPresets.json **/CMakeUserPresets.json
/test_package/bin /test_package/test_package
*.exe
_tmp_install

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.21) cmake_minimum_required(VERSION 3.23)
project(webots_controller LANGUAGES C CXX) project(webots_controller LANGUAGES C CXX)
option(WEBOTS_CONTROLLER_NO_PLUGINS "Disable runtime plugin loading (dlopen/LoadLibrary paths)." ON) option(WEBOTS_CONTROLLER_NO_PLUGINS "Disable runtime plugin loading (dlopen/LoadLibrary paths)." ON)

View File

@ -1,7 +1,7 @@
from conan import ConanFile from conan import ConanFile
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout
from conan.tools.files import copy from conan.tools.files import copy
from conan.tools.microsoft import is_msvc
class WebotsControllerConan(ConanFile): class WebotsControllerConan(ConanFile):
name = "webots-controller" name = "webots-controller"
@ -26,6 +26,18 @@ class WebotsControllerConan(ConanFile):
if self.settings.os == "Windows": if self.settings.os == "Windows":
del self.options.fPIC del self.options.fPIC
def configure(self):
# plugins use dlopen therefore ABI need to be match (same compiler type and compiler version)
if self.options.get_safe("no_plugins", True):
return
if self.settings.os == "Windows" and is_msvc(self):
raise ValueError("Official windows webots is build under msys2 mingw(gcc), rather than MSVC.")
def requirements(self):
# self.requires("stb/cci.20240531")
pass
def layout(self): def layout(self):
cmake_layout(self) cmake_layout(self)
@ -34,7 +46,7 @@ class WebotsControllerConan(ConanFile):
deps.generate() deps.generate()
tc = CMakeToolchain(self) tc = CMakeToolchain(self)
tc.variables["BUILD_SHARED_LIBS"] = bool(self.options.shared) # tc.variables["BUILD_SHARED_LIBS"] = bool(self.options.shared)
tc.variables["WEBOTS_CONTROLLER_NO_PLUGINS"] = bool(self.options.no_plugins) tc.variables["WEBOTS_CONTROLLER_NO_PLUGINS"] = bool(self.options.no_plugins)
tc.generate() tc.generate()
@ -50,4 +62,4 @@ class WebotsControllerConan(ConanFile):
def package_info(self): def package_info(self):
self.cpp_info.libs = ["webots_cpp_controller", "webots_controller"] self.cpp_info.libs = ["webots_cpp_controller", "webots_controller"]
self.cpp_info.includedirs = ["include/controller/cpp", "include/controller/c"] self.cpp_info.includedirs = ["include", "include/controller/cpp", "include/controller/c"]

13
lefthook.yml Normal file
View File

@ -0,0 +1,13 @@
pre-commit:
commands:
cmake-format:
glob: "{**/CMakeLists.txt,**/*.cmake}"
run: uvx --with pyyaml --from cmakelang cmake-format -i {staged_files}
stage_fixed: true
# clang-format:
# run: uvx run-clang-format -i ./src ./include ./tests
# stage_fixed: true
# post-checkout:
# commands:
# inkr-skill-sync:
# run: uvx --from git+https://github.com/existedinnettw/inkr-harness-tools.git inkr-skill-sync .local .agents --recursive

View File

@ -2,12 +2,19 @@ set(WEBOTS_HEADERS_ROOT "${CMAKE_SOURCE_DIR}/include/controller/c")
set(WEBOTS_INCLUDE_ROOT "${CMAKE_SOURCE_DIR}/include") set(WEBOTS_INCLUDE_ROOT "${CMAKE_SOURCE_DIR}/include")
set(WEBOTS_STB_DIR "${CMAKE_SOURCE_DIR}/src/stb") set(WEBOTS_STB_DIR "${CMAKE_SOURCE_DIR}/src/stb")
file(GLOB_RECURSE WEBOTS_CONTROLLER_C_PUBLIC_HEADERS CONFIGURE_DEPENDS
"${WEBOTS_HEADERS_ROOT}/webots/*.h")
file(GLOB_RECURSE WEBOTS_CONTROLLER_PLUGIN_PUBLIC_HEADERS CONFIGURE_DEPENDS
"${WEBOTS_INCLUDE_ROOT}/plugins/*.h")
if(NOT EXISTS "${WEBOTS_HEADERS_ROOT}/webots") if(NOT EXISTS "${WEBOTS_HEADERS_ROOT}/webots")
message(FATAL_ERROR "Missing required repo path: ${WEBOTS_HEADERS_ROOT}/webots") message(
FATAL_ERROR "Missing required repo path: ${WEBOTS_HEADERS_ROOT}/webots")
endif() endif()
if(NOT EXISTS "${WEBOTS_STB_DIR}/stb_image.h") if(NOT EXISTS "${WEBOTS_STB_DIR}/stb_image.h")
message(FATAL_ERROR "Missing required repo path: ${WEBOTS_STB_DIR}/stb_image.h") message(
FATAL_ERROR "Missing required repo path: ${WEBOTS_STB_DIR}/stb_image.h")
endif() endif()
set(WEBOTS_CONTROLLER_C_CORE_SOURCES set(WEBOTS_CONTROLLER_C_CORE_SOURCES
@ -60,20 +67,12 @@ set(WEBOTS_CONTROLLER_C_CORE_SOURCES
system.c system.c
tcp_client.c tcp_client.c
touch_sensor.c touch_sensor.c
vacuum_gripper.c vacuum_gripper.c)
)
set(WEBOTS_CONTROLLER_C_PLUGIN_SOURCES set(WEBOTS_CONTROLLER_C_PLUGIN_SOURCES dynamic_library.c html_robot_window.c
dynamic_library.c radio.c remote_control.c robot_window.c)
html_robot_window.c
radio.c
remote_control.c
robot_window.c
)
set(WEBOTS_CONTROLLER_C_STUB_SOURCES set(WEBOTS_CONTROLLER_C_STUB_SOURCES no_plugins_stubs.c)
no_plugins_stubs.c
)
set(WEBOTS_CONTROLLER_C_SOURCES ${WEBOTS_CONTROLLER_C_CORE_SOURCES}) set(WEBOTS_CONTROLLER_C_SOURCES ${WEBOTS_CONTROLLER_C_CORE_SOURCES})
if(WEBOTS_CONTROLLER_NO_PLUGINS) if(WEBOTS_CONTROLLER_NO_PLUGINS)
@ -82,27 +81,48 @@ else()
list(APPEND WEBOTS_CONTROLLER_C_SOURCES ${WEBOTS_CONTROLLER_C_PLUGIN_SOURCES}) list(APPEND WEBOTS_CONTROLLER_C_SOURCES ${WEBOTS_CONTROLLER_C_PLUGIN_SOURCES})
endif() endif()
# add_library without STATIC/SHARED follows BUILD_SHARED_LIBS automatically in cmake. # add_library without STATIC/SHARED follows BUILD_SHARED_LIBS automatically in
# cmake.
add_library(webots_controller ${WEBOTS_CONTROLLER_C_SOURCES}) add_library(webots_controller ${WEBOTS_CONTROLLER_C_SOURCES})
add_library(webots-controller::webots_controller ALIAS webots_controller) add_library(webots-controller::webots_controller ALIAS webots_controller)
target_sources(
webots_controller
PUBLIC FILE_SET
webots_c_headers
TYPE
HEADERS
BASE_DIRS
"${WEBOTS_HEADERS_ROOT}"
FILES
${WEBOTS_CONTROLLER_C_PUBLIC_HEADERS}
FILE_SET
webots_plugin_headers
TYPE
HEADERS
BASE_DIRS
"${WEBOTS_INCLUDE_ROOT}"
FILES
${WEBOTS_CONTROLLER_PLUGIN_PUBLIC_HEADERS})
if(WIN32) if(WIN32)
set_target_properties(webots_controller PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) set_target_properties(webots_controller PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS
ON)
target_link_libraries(webots_controller PRIVATE ws2_32) target_link_libraries(webots_controller PRIVATE ws2_32)
endif() endif()
target_include_directories(webots_controller target_include_directories(
PUBLIC webots_controller
$<BUILD_INTERFACE:${WEBOTS_HEADERS_ROOT}> PUBLIC $<BUILD_INTERFACE:${WEBOTS_INCLUDE_ROOT}>
$<BUILD_INTERFACE:${WEBOTS_HEADERS_ROOT}> $<INSTALL_INTERFACE:include>
$<INSTALL_INTERFACE:include/controller/c> $<INSTALL_INTERFACE:include/controller/c>
PRIVATE PRIVATE ${WEBOTS_STB_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
${WEBOTS_STB_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
)
target_compile_definitions(webots_controller PRIVATE LIBCONTROLLER_VERSION="R2025a") target_compile_definitions(webots_controller
PRIVATE LIBCONTROLLER_VERSION="R2025a")
if(WEBOTS_CONTROLLER_NO_PLUGINS) if(WEBOTS_CONTROLLER_NO_PLUGINS)
target_compile_definitions(webots_controller PUBLIC WEBOTS_CONTROLLER_NO_PLUGINS=1) target_compile_definitions(webots_controller
PUBLIC WEBOTS_CONTROLLER_NO_PLUGINS=1)
endif() endif()
if(UNIX) if(UNIX)
@ -115,5 +135,8 @@ if(UNIX)
endif() endif()
endif() endif()
install(TARGETS webots_controller) install(
install(DIRECTORY "${WEBOTS_HEADERS_ROOT}/webots" DESTINATION "include/controller/c") TARGETS webots_controller FILE_SET webots_c_headers
DESTINATION "include/controller/c"
FILE_SET webots_plugin_headers
DESTINATION "include")

View File

@ -33,26 +33,39 @@ set(WEBOTS_CONTROLLER_CPP_SOURCES
Speaker.cpp Speaker.cpp
Supervisor.cpp Supervisor.cpp
TouchSensor.cpp TouchSensor.cpp
VacuumGripper.cpp VacuumGripper.cpp)
)
file(GLOB_RECURSE WEBOTS_CONTROLLER_CPP_PUBLIC_HEADERS CONFIGURE_DEPENDS
"${CMAKE_SOURCE_DIR}/include/controller/cpp/webots/*.hpp")
add_library(webots_cpp_controller ${WEBOTS_CONTROLLER_CPP_SOURCES}) add_library(webots_cpp_controller ${WEBOTS_CONTROLLER_CPP_SOURCES})
add_library(webots-controller::webots_cpp_controller ALIAS webots_cpp_controller) add_library(webots-controller::webots_cpp_controller ALIAS
webots_cpp_controller)
target_sources(
webots_cpp_controller
PUBLIC FILE_SET
webots_cpp_headers
TYPE
HEADERS
BASE_DIRS
"${CMAKE_SOURCE_DIR}/include/controller/cpp"
FILES
${WEBOTS_CONTROLLER_CPP_PUBLIC_HEADERS})
if(WIN32) if(WIN32)
set_target_properties(webots_cpp_controller PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) set_target_properties(webots_cpp_controller
PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif() endif()
target_include_directories(webots_cpp_controller target_include_directories(
PUBLIC webots_cpp_controller
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include/controller/cpp> PUBLIC $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include/controller/cpp>
$<INSTALL_INTERFACE:include/controller/cpp> $<INSTALL_INTERFACE:include/controller/cpp>)
)
target_link_libraries(webots_cpp_controller target_link_libraries(webots_cpp_controller PUBLIC webots_controller)
PUBLIC
webots_controller
)
install(TARGETS webots_cpp_controller) install(
install(DIRECTORY "${CMAKE_SOURCE_DIR}/include/controller/cpp/webots" DESTINATION "include/controller/cpp") TARGETS webots_cpp_controller
# `include "../../c/webots/types.h"` in `Robot.hpp`
FILE_SET webots_cpp_headers DESTINATION "include/controller/cpp")

View File

@ -20,38 +20,35 @@ if(WIN32 AND DEFINED ENV{MINGW_HOME})
list(APPEND _extra_runtime_dirs "$ENV{MINGW_HOME}/bin") list(APPEND _extra_runtime_dirs "$ENV{MINGW_HOME}/bin")
endif() endif()
# Webots controllers rely on seeing shared deps in the same directory as the executable. # Webots controllers rely on seeing shared deps in the same directory as the
install(TARGETS test_package # executable. Destination therefore change to "."
RUNTIME_DEPENDENCY_SET test_package_runtime_deps install(
RUNTIME DESTINATION bin TARGETS test_package RUNTIME_DEPENDENCY_SET test_package_runtime_deps
LIBRARY DESTINATION lib RUNTIME DESTINATION .
ARCHIVE DESTINATION lib) LIBRARY DESTINATION .
ARCHIVE DESTINATION .)
if(WIN32) if(WIN32)
set(_runtime_dep_pre_excludes set(_runtime_dep_pre_excludes "^api-ms-win-.*" "^ext-ms-.*")
"^api-ms-win-.*" set(_runtime_dep_post_excludes ".*/system32/.*" ".*/Windows/.*"
"^ext-ms-.*")
set(_runtime_dep_post_excludes
".*/system32/.*"
".*/Windows/.*"
".*/SysWOW64/.*") ".*/SysWOW64/.*")
else() else()
set(_runtime_dep_pre_excludes set(_runtime_dep_pre_excludes
[[libc\.so\..*]] [[libc\.so\..*]] [[libgcc_s\.so\..*]] [[libm\.so\..*]]
[[libgcc_s\.so\..*]] [[libstdc\+\+\.so\..*]] [[ld-linux-x86-64\.so\..*]])
[[libm\.so\..*]] set(_runtime_dep_post_excludes [[^/lib.*]] [[^/usr/lib.*]])
[[libstdc\+\+\.so\..*]]
[[ld-linux-x86-64\.so\..*]])
set(_runtime_dep_post_excludes
[[^/lib.*]]
[[^/usr/lib.*]])
endif() endif()
install( install(
RUNTIME_DEPENDENCY_SET test_package_runtime_deps RUNTIME_DEPENDENCY_SET
PRE_EXCLUDE_REGEXES ${_runtime_dep_pre_excludes} test_package_runtime_deps
POST_EXCLUDE_REGEXES ${_runtime_dep_post_excludes} PRE_EXCLUDE_REGEXES
${_runtime_dep_pre_excludes}
POST_EXCLUDE_REGEXES
${_runtime_dep_post_excludes}
DIRECTORIES DIRECTORIES
${CONAN_RUNTIME_LIB_DIRS} ${CONAN_RUNTIME_LIB_DIRS}
${CMAKE_SYSROOT}/lib ${CMAKE_SYSROOT}/lib
${_extra_runtime_dirs}) ${_extra_runtime_dirs}
DESTINATION
.)

View File

@ -25,6 +25,6 @@ class TestPackageConan(ConanFile):
cmake = CMake(self) cmake = CMake(self)
cmake.install() cmake.install()
if can_run(self): if can_run(self):
exe = os.path.join(self.source_folder, "bin", "test_package") exe = os.path.join(self.source_folder, "test_package")
self.run(exe, env="conanrun") self.run(exe, env="conanrun")