diff --git a/.gitignore b/.gitignore index 24a1178..ffc3d24 100644 --- a/.gitignore +++ b/.gitignore @@ -70,4 +70,6 @@ Testing/ # user **/CMakeUserPresets.json -/test_package/bin +/test_package/test_package +*.exe +_tmp_install diff --git a/CMakeLists.txt b/CMakeLists.txt index f34378e..24e74f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.21) +cmake_minimum_required(VERSION 3.23) project(webots_controller LANGUAGES C CXX) option(WEBOTS_CONTROLLER_NO_PLUGINS "Disable runtime plugin loading (dlopen/LoadLibrary paths)." ON) diff --git a/conanfile.py b/conanfile.py index 9737fac..a7a2cb7 100644 --- a/conanfile.py +++ b/conanfile.py @@ -1,7 +1,7 @@ from conan import ConanFile from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout from conan.tools.files import copy - +from conan.tools.microsoft import is_msvc class WebotsControllerConan(ConanFile): name = "webots-controller" @@ -26,6 +26,18 @@ class WebotsControllerConan(ConanFile): if self.settings.os == "Windows": 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): cmake_layout(self) @@ -34,7 +46,7 @@ class WebotsControllerConan(ConanFile): deps.generate() 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.generate() @@ -50,4 +62,4 @@ class WebotsControllerConan(ConanFile): def package_info(self): 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"] diff --git a/lefthook.yml b/lefthook.yml new file mode 100644 index 0000000..97edf86 --- /dev/null +++ b/lefthook.yml @@ -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 \ No newline at end of file diff --git a/src/controller/c/CMakeLists.txt b/src/controller/c/CMakeLists.txt index e0b9d1c..115a35a 100644 --- a/src/controller/c/CMakeLists.txt +++ b/src/controller/c/CMakeLists.txt @@ -2,78 +2,77 @@ set(WEBOTS_HEADERS_ROOT "${CMAKE_SOURCE_DIR}/include/controller/c") set(WEBOTS_INCLUDE_ROOT "${CMAKE_SOURCE_DIR}/include") 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") - message(FATAL_ERROR "Missing required repo path: ${WEBOTS_HEADERS_ROOT}/webots") + message( + FATAL_ERROR "Missing required repo path: ${WEBOTS_HEADERS_ROOT}/webots") endif() 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() set(WEBOTS_CONTROLLER_C_CORE_SOURCES - abstract_camera.c - accelerometer.c - altimeter.c - ansi_codes.c - base64.c - brake.c - camera.c - compass.c - connector.c - console.c - default_robot_window.c - device.c - display.c - distance_sensor.c - emitter.c - file.c - g_image.c - g_pipe.c - gps.c - gyro.c - image.c - inertial_unit.c - joystick.c - keyboard.c - led.c - lidar.c - light_sensor.c - microphone.c - motion.c - motor.c - mouse.c - node.c - pen.c - percent.c - position_sensor.c - radar.c - range_finder.c - receiver.c - request.c - robot.c - scheduler.c - sha1.c - skin.c - speaker.c - string.c - supervisor.c - system.c - tcp_client.c - touch_sensor.c - vacuum_gripper.c -) + abstract_camera.c + accelerometer.c + altimeter.c + ansi_codes.c + base64.c + brake.c + camera.c + compass.c + connector.c + console.c + default_robot_window.c + device.c + display.c + distance_sensor.c + emitter.c + file.c + g_image.c + g_pipe.c + gps.c + gyro.c + image.c + inertial_unit.c + joystick.c + keyboard.c + led.c + lidar.c + light_sensor.c + microphone.c + motion.c + motor.c + mouse.c + node.c + pen.c + percent.c + position_sensor.c + radar.c + range_finder.c + receiver.c + request.c + robot.c + scheduler.c + sha1.c + skin.c + speaker.c + string.c + supervisor.c + system.c + tcp_client.c + touch_sensor.c + vacuum_gripper.c) -set(WEBOTS_CONTROLLER_C_PLUGIN_SOURCES - dynamic_library.c - html_robot_window.c - radio.c - remote_control.c - robot_window.c -) +set(WEBOTS_CONTROLLER_C_PLUGIN_SOURCES dynamic_library.c html_robot_window.c + radio.c remote_control.c robot_window.c) -set(WEBOTS_CONTROLLER_C_STUB_SOURCES - no_plugins_stubs.c -) +set(WEBOTS_CONTROLLER_C_STUB_SOURCES no_plugins_stubs.c) set(WEBOTS_CONTROLLER_C_SOURCES ${WEBOTS_CONTROLLER_C_CORE_SOURCES}) if(WEBOTS_CONTROLLER_NO_PLUGINS) @@ -82,27 +81,48 @@ else() list(APPEND WEBOTS_CONTROLLER_C_SOURCES ${WEBOTS_CONTROLLER_C_PLUGIN_SOURCES}) 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 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) - 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) endif() -target_include_directories(webots_controller - PUBLIC - $ - $ - PRIVATE - ${WEBOTS_STB_DIR} - ${CMAKE_CURRENT_SOURCE_DIR} -) +target_include_directories( + webots_controller + PUBLIC $ + $ $ + $ + PRIVATE ${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) - target_compile_definitions(webots_controller PUBLIC WEBOTS_CONTROLLER_NO_PLUGINS=1) + target_compile_definitions(webots_controller + PUBLIC WEBOTS_CONTROLLER_NO_PLUGINS=1) endif() if(UNIX) @@ -115,5 +135,8 @@ if(UNIX) endif() endif() -install(TARGETS webots_controller) -install(DIRECTORY "${WEBOTS_HEADERS_ROOT}/webots" DESTINATION "include/controller/c") +install( + TARGETS webots_controller FILE_SET webots_c_headers + DESTINATION "include/controller/c" + FILE_SET webots_plugin_headers + DESTINATION "include") diff --git a/src/controller/cpp/CMakeLists.txt b/src/controller/cpp/CMakeLists.txt index 43e5ac6..0634c2e 100644 --- a/src/controller/cpp/CMakeLists.txt +++ b/src/controller/cpp/CMakeLists.txt @@ -1,58 +1,71 @@ set(WEBOTS_CONTROLLER_CPP_SOURCES - Accelerometer.cpp - Altimeter.cpp - Brake.cpp - Camera.cpp - Compass.cpp - Connector.cpp - Device.cpp - Display.cpp - DistanceSensor.cpp - Emitter.cpp - Field.cpp - GPS.cpp - Gyro.cpp - InertialUnit.cpp - Joystick.cpp - Keyboard.cpp - LED.cpp - Lidar.cpp - LightSensor.cpp - Motion.cpp - Motor.cpp - Mouse.cpp - Node.cpp - Pen.cpp - PositionSensor.cpp - Proto.cpp - Radar.cpp - RangeFinder.cpp - Receiver.cpp - Robot.cpp - Skin.cpp - Speaker.cpp - Supervisor.cpp - TouchSensor.cpp - VacuumGripper.cpp -) + Accelerometer.cpp + Altimeter.cpp + Brake.cpp + Camera.cpp + Compass.cpp + Connector.cpp + Device.cpp + Display.cpp + DistanceSensor.cpp + Emitter.cpp + Field.cpp + GPS.cpp + Gyro.cpp + InertialUnit.cpp + Joystick.cpp + Keyboard.cpp + LED.cpp + Lidar.cpp + LightSensor.cpp + Motion.cpp + Motor.cpp + Mouse.cpp + Node.cpp + Pen.cpp + PositionSensor.cpp + Proto.cpp + Radar.cpp + RangeFinder.cpp + Receiver.cpp + Robot.cpp + Skin.cpp + Speaker.cpp + Supervisor.cpp + TouchSensor.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-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) - 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() -target_include_directories(webots_cpp_controller - PUBLIC - $ - $ -) +target_include_directories( + webots_cpp_controller + PUBLIC $ + $) -target_link_libraries(webots_cpp_controller - PUBLIC - webots_controller -) +target_link_libraries(webots_cpp_controller PUBLIC webots_controller) -install(TARGETS webots_cpp_controller) -install(DIRECTORY "${CMAKE_SOURCE_DIR}/include/controller/cpp/webots" DESTINATION "include/controller/cpp") +install( + TARGETS webots_cpp_controller + # `include "../../c/webots/types.h"` in `Robot.hpp` + FILE_SET webots_cpp_headers DESTINATION "include/controller/cpp") diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt index 2a25d1a..70ed1a3 100644 --- a/test_package/CMakeLists.txt +++ b/test_package/CMakeLists.txt @@ -20,38 +20,35 @@ if(WIN32 AND DEFINED ENV{MINGW_HOME}) list(APPEND _extra_runtime_dirs "$ENV{MINGW_HOME}/bin") endif() -# Webots controllers rely on seeing shared deps in the same directory as the executable. -install(TARGETS test_package - RUNTIME_DEPENDENCY_SET test_package_runtime_deps - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib) +# Webots controllers rely on seeing shared deps in the same directory as the +# executable. Destination therefore change to "." +install( + TARGETS test_package RUNTIME_DEPENDENCY_SET test_package_runtime_deps + RUNTIME DESTINATION . + LIBRARY DESTINATION . + ARCHIVE DESTINATION .) if(WIN32) - set(_runtime_dep_pre_excludes - "^api-ms-win-.*" - "^ext-ms-.*") - set(_runtime_dep_post_excludes - ".*/system32/.*" - ".*/Windows/.*" - ".*/SysWOW64/.*") + set(_runtime_dep_pre_excludes "^api-ms-win-.*" "^ext-ms-.*") + set(_runtime_dep_post_excludes ".*/system32/.*" ".*/Windows/.*" + ".*/SysWOW64/.*") else() set(_runtime_dep_pre_excludes - [[libc\.so\..*]] - [[libgcc_s\.so\..*]] - [[libm\.so\..*]] - [[libstdc\+\+\.so\..*]] - [[ld-linux-x86-64\.so\..*]]) - set(_runtime_dep_post_excludes - [[^/lib.*]] - [[^/usr/lib.*]]) + [[libc\.so\..*]] [[libgcc_s\.so\..*]] [[libm\.so\..*]] + [[libstdc\+\+\.so\..*]] [[ld-linux-x86-64\.so\..*]]) + set(_runtime_dep_post_excludes [[^/lib.*]] [[^/usr/lib.*]]) endif() install( - RUNTIME_DEPENDENCY_SET test_package_runtime_deps - PRE_EXCLUDE_REGEXES ${_runtime_dep_pre_excludes} - POST_EXCLUDE_REGEXES ${_runtime_dep_post_excludes} + RUNTIME_DEPENDENCY_SET + test_package_runtime_deps + PRE_EXCLUDE_REGEXES + ${_runtime_dep_pre_excludes} + POST_EXCLUDE_REGEXES + ${_runtime_dep_post_excludes} DIRECTORIES - ${CONAN_RUNTIME_LIB_DIRS} - ${CMAKE_SYSROOT}/lib - ${_extra_runtime_dirs}) + ${CONAN_RUNTIME_LIB_DIRS} + ${CMAKE_SYSROOT}/lib + ${_extra_runtime_dirs} + DESTINATION + .) diff --git a/test_package/conanfile.py b/test_package/conanfile.py index 37448dc..469583d 100644 --- a/test_package/conanfile.py +++ b/test_package/conanfile.py @@ -25,6 +25,6 @@ class TestPackageConan(ConanFile): cmake = CMake(self) cmake.install() 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")