diff --git a/.gitignore b/.gitignore index 333e6dfb634..cd98d4609c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,74 +1,76 @@ -# Global rules # -################ - -# Build directories -build -com -webots_catkin_ws - -# Compiled source -*.exe -*.o -*.d -*.class -*.so -*.dylib -*.dll -*.lib -*.a -*.cof -*.hex -*.pyc -*.gch - -# Packages -*.7z -*.bz2 -*.dmg -*.gz -*.iso -*.jar -*.rar -*.tar -*.xz -*.zip - -# OS generated files -.DS_Store -.DS_Store? -._* -.Spotlight-V100 -.Trashes -.directory -ehthumbs.db -Thumbs.db -*.swp - -# Text editor backup files -*~ - -# Log files -*.log - -# Blender cache -*.blend1 - -# Webots generated files -*.cache - -# IDE files -.vscode - -# Local rules # -############### - -/.clang-format -/msys64 -/webots -/webots-controller -/webots.lnk -/webots_debug_output.txt -/util - -# world thumbnail files -.*.jpg +# Global rules # +################ + +# Build directories +build +com +webots_catkin_ws + +# Compiled source +*.exe +*.o +*.d +*.class +*.so +*.dylib +*.dll +*.lib +*.a +*.cof +*.hex +*.pyc +*.gch + +# Packages +*.7z +*.bz2 +*.dmg +*.gz +*.iso +*.jar +*.rar +*.tar +*.xz +*.zip + +# OS generated files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +.directory +ehthumbs.db +Thumbs.db +*.swp + +# Text editor backup files +*~ + +# Log files +*.log + +# Blender cache +*.blend1 + +# Webots generated files +*.cache + +# IDE files +.vscode + +# Local rules # +############### + +/.clang-format +/msys64 +/webots +/webots-controller +/webots.lnk +/webots_debug_output.txt +/util + +# world thumbnail files +.*.jpg +.aider* +.env diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000000..13e623a5182 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,38 @@ +cmake_minimum_required(VERSION 3.10) +project(webots) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTORCC ON) +# Set C++ standard +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Find Qt6 components +find_package(Qt6 REQUIRED COMPONENTS + Core + Gui + OpenGL + Qml + QmlIntegration + PrintSupport + Widgets + Xml + OpenGLWidgets + WebSockets + Test + Network +) +file(READ ${CMAKE_SOURCE_DIR}/resources/version.txt WEBOTS_VERSION) +string(STRIP ${WEBOTS_VERSION} WEBOTS_VERSION) +# Find other required packages +find_package(OpenAL REQUIRED) +find_package(OpenGL REQUIRED) +find_package(PkgConfig REQUIRED) +find_package(Freetype REQUIRED) +find_package(assimp REQUIRED) +pkg_check_modules(OPENVR REQUIRED IMPORTED_TARGET openvr) +# Include external dependencies +include(src/webots/cmake/ExternalDependencies.cmake) + +# Add subdirectories +add_subdirectory(src) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000000..a442eb40c9d --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,51 @@ +# Find required packages + +# Add glad library +add_library(glad glad/glad.c) +target_include_directories(glad PUBLIC ${CMAKE_SOURCE_DIR}/include) +target_compile_options(glad PUBLIC -fPIC) + +add_custom_target(stb + COMMAND git submodule update --init --recursive src/stb + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMENT "Initializing stb submodule" +) + +# --- Handle stb_image.h --- + +# Check for system installation of stb +find_path(STB_INCLUDE_DIR + NAMES stb_image.h + PATHS + /usr/include/stb + /usr/local/include/stb + $ENV{MSYSTEM_PREFIX}/include/stb + $ENV{MSYSTEM_PREFIX}/local/include/stb +) + +# If not found, use the stb submodule +if(NOT STB_INCLUDE_DIR) + message(STATUS "System installation of stb not found. Using stb submodule.") + + # Initialize and update the stb submodule + execute_process( + COMMAND ${CMAKE_COMMAND} --build . --target stb + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) + + # Set STB_INCLUDE_DIR to the submodule's include path + set(STB_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/stb) + + # Cache the variable so it persists across CMake runs + set(STB_INCLUDE_DIR ${STB_INCLUDE_DIR} CACHE PATH "Path to stb include directory") +endif() + +message(STATUS "STB_INCLUDE_DIR: ${STB_INCLUDE_DIR}") + +# Make STB_INCLUDE_DIR available to other CMake files (e.g., in src/controller/c) +set(STB_INCLUDE_DIR ${STB_INCLUDE_DIR} CACHE PATH "Path to stb include directory" FORCE) + +add_subdirectory(ode) +add_subdirectory(wren) +add_subdirectory(webots) +add_subdirectory(controller) diff --git a/src/controller/CMakeLists.txt b/src/controller/CMakeLists.txt new file mode 100644 index 00000000000..c3c7a1eaab4 --- /dev/null +++ b/src/controller/CMakeLists.txt @@ -0,0 +1,4 @@ +# Add subdirectories for C and C++ controllers +add_subdirectory(c) +add_subdirectory(cpp) +add_subdirectory(java) diff --git a/src/controller/c/CMakeLists.txt b/src/controller/c/CMakeLists.txt new file mode 100644 index 00000000000..4822400b906 --- /dev/null +++ b/src/controller/c/CMakeLists.txt @@ -0,0 +1,150 @@ +# Name of the library to be created +set(CONTROLLER_LIBRARY_NAME Controller) + +# Source files for the controller library +set(CONTROLLER_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 + dynamic_library.c + emitter.c + file.c + g_image.c + g_pipe.c + gps.c + gyro.c + html_robot_window.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 + radio.c + range_finder.c + receiver.c + remote_control.c + request.c + robot.c + robot_window.c + scheduler.c + sha1.c + skin.c + speaker.c + string.c + supervisor.c + system.c + tcp_client.c + touch_sensor.c + vacuum_gripper.c +) + +# Header files for internal use within the library +set(CONTROLLER_HEADERS + abstract_camera.h + base64.h + camera_private.h + default_robot_window_private.h + device_private.h + display_private.h + dynamic_library.h + file.h + g_image.h + g_pipe.h + html_robot_window_private.h + image_private.h + joystick_private.h + keyboard_private.h + messages.h + motion_private.h + mouse_private.h + percent.h + remote_control_private.h + request.h + robot_private.h + robot_window_private.h + scheduler.h + sha1.h + supervisor_private.h + tcp_client.h +) + +# Create the shared library +add_library(${CONTROLLER_LIBRARY_NAME} SHARED ${CONTROLLER_SOURCES} ${CONTROLLER_HEADERS}) + +# Include directories for the controller library + target_include_directories(${CONTROLLER_LIBRARY_NAME} + PUBLIC + $ + $ + $ + $ + $ + $ +) +# Find libraries on Windows (using MSYS2) +if (WIN32) + # Directly use MSYSTEM_PREFIX for library paths + set(winsock_LIBRARY_PATH "$ENV{MSYSTEM_PREFIX}/lib/libws2_32.a") + + # Check if winsock library exists and link it + if (EXISTS ${winsock_LIBRARY_PATH}) + message(STATUS "winsock library found: ${winsock_LIBRARY_PATH}") + else() + message(FATAL_ERROR "winsock library not found at ${winsock_LIBRARY_PATH}. Please ensure it is installed in your MSYS2 environment.") + endif() + + # Link libraries if found + target_link_libraries(Controller + PRIVATE + ${winsock_LIBRARY_PATH} + ) +endif() + +target_compile_definitions(${CONTROLLER_LIBRARY_NAME} + PUBLIC + "LIBCONTROLLER_VERSION=\"${WEBOTS_VERSION}\"" +) +# Link necessary libraries to the controller +target_link_libraries(${CONTROLLER_LIBRARY_NAME} + PUBLIC + # glad + # ${Freetype_LIBRARIES} +) + +# Set properties for the library (adjust as needed) +#set_target_properties(${CONTROLLER_LIBRARY_NAME} PROPERTIES +# VERSION 0.1 +# SOVERSION 0 +# PUBLIC_HEADER "${CONTROLLER_HEADERS}" +#) + +# Install rules +install(TARGETS ${CONTROLLER_LIBRARY_NAME} + DESTINATION lib +) + +install(FILES ${CONTROLLER_HEADERS} + DESTINATION include +) diff --git a/src/controller/cpp/CMakeLists.txt b/src/controller/cpp/CMakeLists.txt new file mode 100644 index 00000000000..864dbb97fec --- /dev/null +++ b/src/controller/cpp/CMakeLists.txt @@ -0,0 +1,81 @@ +# src/controller/cpp/CMakeLists.txt + +# Name of the C++ controller library +set(CONTROLLER_CPP_LIBRARY_NAME CppController) + +# Source files for the C++ controller library +set(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 +) + +# Create the shared library +add_library(${CONTROLLER_CPP_LIBRARY_NAME} SHARED ${CONTROLLER_CPP_SOURCES}) + +# Include directories for the C++ controller library +target_include_directories(${CONTROLLER_CPP_LIBRARY_NAME} + PUBLIC + $ + $ + $ # added because some include files are not in the cpp folder + $ # added because some include files are not in the cpp folder# + PRIVATE + $ + $ +) +target_compile_definitions(${CONTROLLER_CPP_LIBRARY_NAME} + PUBLIC + "LIBCONTROLLER_VERSION=\"${WEBOTS_VERSION}\"" +) +# Link necessary libraries to the C++ controller +target_link_libraries(${CONTROLLER_CPP_LIBRARY_NAME} + PUBLIC + Controller +) + +# Set properties for the library (adjust as needed) +#set_target_properties(${CONTROLLER_CPP_LIBRARY_NAME} PROPERTIES +# VERSION 0.1 +# SOVERSION 0 +# PUBLIC_HEADER "${CONTROLLER_CPP_HEADERS}" # No need for PUBLIC_HEADER with C++ +#) + +# Install rules +install(TARGETS ${CONTROLLER_CPP_LIBRARY_NAME} + DESTINATION lib +) + +# No need to install header files separately in C++, they are typically included via target_include_directories diff --git a/src/controller/java/CMakeLists.txt b/src/controller/java/CMakeLists.txt new file mode 100644 index 00000000000..2650442937f --- /dev/null +++ b/src/controller/java/CMakeLists.txt @@ -0,0 +1,322 @@ +# Find SWIG +find_package(SWIG) + +# Check if SWIG was found +if(SWIG_FOUND) + include(UseSWIG) + message(STATUS "SWIG found: ${SWIG_EXECUTABLE}") + + # Set the module name (should match %module in the .i file) + set(SWIG_MODULE_NAME wrapper) + + # Set the output directory for generated Java files + set(SWIG_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/SWIG_generated_files) + + # Set the package name for the generated Java code + set(SWIG_PACKAGE_NAME com.cyberbotics.webots.controller) + + # Set the input SWIG interface file + set(SWIG_INTERFACE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/controller.i) + + # Set include directories for C++ headers + set(SWIG_INCLUDE_DIRS + ${CMAKE_SOURCE_DIR}/include/controller/cpp + ${CMAKE_SOURCE_DIR}/include/controller/c + ) + + # Create the output directory if it doesn't exist + file(MAKE_DIRECTORY ${SWIG_OUTPUT_DIR}) + + # Configure SWIG + set_source_files_properties(${SWIG_INTERFACE_FILE} + PROPERTIES CPLUSPLUS ON) + set_source_files_properties(${SWIG_INTERFACE_FILE} + PROPERTIES SWIG_FLAGS "-c++;-package;${SWIG_PACKAGE_NAME};-outdir;${SWIG_OUTPUT_DIR}") + + # Generate the SWIG wrapper code + swig_add_library(${SWIG_MODULE_NAME} TYPE SHARED + LANGUAGE java + SOURCES ${SWIG_INTERFACE_FILE}) + set_property(TARGET ${SWIG_MODULE_NAME} PROPERTY SWIG_USE_TARGET_INCLUDE_DIRECTORIES TRUE) + swig_link_libraries(${SWIG_MODULE_NAME} + PRIVATE + Controller + CppController + ) + + target_include_directories(${SWIG_MODULE_NAME} + PUBLIC + ${SWIG_INCLUDE_DIRS} + ) + + # Get the SWIG generated source file name + get_property(SWIG_WRAPPER_SOURCE TARGET ${SWIG_MODULE_NAME} PROPERTY SWIG_GENERATED_SOURCE_NAME_JAVA) + + # --- Compilation of Generated Java Code --- + # Create a list of Java source files (including generated ones) + file(GLOB_RECURSE JAVA_SOURCES LIST_DIRECTORIES false + "${SWIG_OUTPUT_DIR}/*.java" + "${CMAKE_CURRENT_SOURCE_DIR}/*.java") + + # Remove some of the auto-generated SWIG files which are not needed + list(FILTER JAVA_SOURCES EXCLUDE REGEX ".*(swigjni|Swig).*") + + # Compile Java source files into a JAR file + set(JAR_OUTPUT_PATH ${WEBOTS_CONTROLLER_LIB_PATH}/java/Controller.jar) + file(MAKE_DIRECTORY ${WEBOTS_CONTROLLER_LIB_PATH}/java) + + # Add custom command to compile Java files after SWIG generation + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${SWIG_PACKAGE_NAME} + COMMAND javac --release 11 ${JAVA_SOURCES} -d ${CMAKE_CURRENT_BINARY_DIR} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS ${SWIG_MODULE_NAME} + COMMENT "Compiling Java sources" + VERBATIM + ) + + # Add custom command to create JAR after Java compilation + add_custom_command( + OUTPUT ${JAR_OUTPUT_PATH} + COMMAND jar cfv ${JAR_OUTPUT_PATH} ${SWIG_PACKAGE_NAME}/*.class + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${SWIG_PACKAGE_NAME} + COMMENT "Creating JAR file" + VERBATIM + ) + + # Add a custom target to trigger the build of the java library + add_custom_target(java_controller + DEPENDS ${JAR_OUTPUT_PATH} + ) + # --- Compilation of Native Library --- + + # OS-specific settings + if(WIN32) + # Windows + set(JNI_LIBRARY_NAME JavaController) + set(JNI_LIBRARY_OUTPUT_PATH ${WEBOTS_CONTROLLER_LIB_PATH}/java/${JNI_LIBRARY_NAME}.dll) + set(JNI_LINK_FLAGS "-shared -mwindows -Wl,--add-stdcall-alias -Wl,--enable-auto-import -O") + + # Find Java include directories (prefer JAVA_HOME, then registry) + if(DEFINED ENV{JAVA_HOME}) + find_path(JAVA_INCLUDE_PATH jni.h + PATHS + "$ENV{JAVA_HOME}/include" + ) + + find_path(JAVA_MD_INCLUDE_PATH jni_md.h + PATHS + "$ENV{JAVA_HOME}/include/win32" + ) + else() + # Query the Windows Registry for Java installations + # 64-bit Java + file(READ "/HKEY_LOCAL_MACHINE/SOFTWARE/JavaSoft/Java Development Kit" JAVA_KEYS_64) + string(REPLACE "\n" ";" JAVA_KEYS_64 ${JAVA_KEYS_64}) + foreach(JAVA_KEY ${JAVA_KEYS_64}) + file(READ "/HKEY_LOCAL_MACHINE/SOFTWARE/JavaSoft/Java Development Kit/${JAVA_KEY}" JAVA_DATA_64) + string(REPLACE "\n" ";" JAVA_DATA_64 ${JAVA_DATA_64}) + list(FIND JAVA_DATA_64 "JavaHome" JAVA_HOME_INDEX_64) + if(NOT ${JAVA_HOME_INDEX_64} EQUAL -1) + math(EXPR JAVA_HOME_INDEX_64 "${JAVA_HOME_INDEX_64} + 1") + list(GET JAVA_DATA_64 ${JAVA_HOME_INDEX_64} JAVA_HOME_PATH_64) + string(REPLACE "\\" "/" JAVA_HOME_PATH_64 ${JAVA_HOME_PATH_64}) + find_path(JAVA_INCLUDE_PATH jni.h PATHS "${JAVA_HOME_PATH_64}/include") + find_path(JAVA_MD_INCLUDE_PATH jni_md.h PATHS "${JAVA_HOME_PATH_64}/include/win32") + if(JAVA_INCLUDE_PATH AND JAVA_MD_INCLUDE_PATH) + break() + endif() + endif() + endforeach() + + # 32-bit Java (on 64-bit Windows) + if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND (NOT JAVA_INCLUDE_PATH OR NOT JAVA_MD_INCLUDE_PATH)) + file(READ "/HKEY_LOCAL_MACHINE/SOFTWARE/Wow6432Node/JavaSoft/Java Development Kit" JAVA_KEYS_32) + string(REPLACE "\n" ";" JAVA_KEYS_32 ${JAVA_KEYS_32}) + foreach(JAVA_KEY ${JAVA_KEYS_32}) + file(READ "/HKEY_LOCAL_MACHINE/SOFTWARE/Wow6432Node/JavaSoft/Java Development Kit/${JAVA_KEY}" JAVA_DATA_32) + string(REPLACE "\n" ";" JAVA_DATA_32 ${JAVA_DATA_32}) + list(FIND JAVA_DATA_32 "JavaHome" JAVA_HOME_INDEX_32) + if(NOT ${JAVA_HOME_INDEX_32} EQUAL -1) + math(EXPR JAVA_HOME_INDEX_32 "${JAVA_HOME_INDEX_32} + 1") + list(GET JAVA_DATA_32 ${JAVA_HOME_INDEX_32} JAVA_HOME_PATH_32) + string(REPLACE "\\" "/" JAVA_HOME_PATH_32 ${JAVA_HOME_PATH_32}) + find_path(JAVA_INCLUDE_PATH jni.h PATHS "${JAVA_HOME_PATH_32}/include") + find_path(JAVA_MD_INCLUDE_PATH jni_md.h PATHS "${JAVA_HOME_PATH_32}/include/win32") + if(JAVA_INCLUDE_PATH AND JAVA_MD_INCLUDE_PATH) + break() + endif() + endif() + endforeach() + endif() + endif() + + elseif(APPLE) + # macOS + set(JNI_LIBRARY_NAME libJavaController.jnilib) + set(JNI_LIBRARY_OUTPUT_PATH ${WEBOTS_CONTROLLER_LIB_PATH}/java/${JNI_LIBRARY_NAME}) + set(JNI_LINK_FLAGS "-dynamiclib -install_name @rpath/Contents/lib/controller/java/libJavaController.jnilib -Wl,-rpath,@loader_path/../../../..") + + # Find Java include directories (prefer JAVA_HOME, then system paths) + if(DEFINED ENV{JAVA_HOME}) + find_path(JAVA_INCLUDE_PATH jni.h + PATHS + "$ENV{JAVA_HOME}/include" + ) + + find_path(JAVA_MD_INCLUDE_PATH jni_md.h + PATHS + "$ENV{JAVA_HOME}/include/darwin" + ) + else() + # Use 'which javac' to find the Java installation + execute_process( + COMMAND which javac + OUTPUT_VARIABLE JAVAC_PATH + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + get_filename_component(JAVA_BIN_DIR ${JAVAC_PATH} DIRECTORY) + get_filename_component(JAVA_HOME_GUESS ${JAVA_BIN_DIR} DIRECTORY) + + find_path(JAVA_INCLUDE_PATH jni.h + PATHS + "${JAVA_HOME_GUESS}/include" + "/Library/Java/JavaVirtualMachines/*/Contents/Home/include" # Common macOS location + "/System/Library/Frameworks/JavaVM.framework/Headers" + ) + find_path(JAVA_MD_INCLUDE_PATH jni_md.h + PATHS + "${JAVA_HOME_GUESS}/include/darwin" + "/Library/Java/JavaVirtualMachines/*/Contents/Home/include/darwin" + "/System/Library/Frameworks/JavaVM.framework/Headers" + ) + endif() + + else() + # Linux + set(JNI_LIBRARY_NAME libJavaController.so) + set(JNI_LIBRARY_OUTPUT_PATH ${WEBOTS_CONTROLLER_LIB_PATH}/java/${JNI_LIBRARY_NAME}) + set(JNI_LINK_FLAGS "-shared -fPIC") + + # Find Java include directories (prefer JAVA_HOME, then system paths) + if(DEFINED ENV{JAVA_HOME}) + find_path(JAVA_INCLUDE_PATH jni.h + PATHS + "$ENV{JAVA_HOME}/include" + ) + + find_path(JAVA_MD_INCLUDE_PATH jni_md.h + PATHS + "$ENV{JAVA_HOME}/include/linux" + ) + endif() + endif() + + # Fallback: If JAVA_HOME is not defined or not found, use javac to find Java include paths + if(NOT JAVA_INCLUDE_PATH OR NOT JAVA_MD_INCLUDE_PATH) + # Use 'which javac' to find the Java installation + execute_process( + COMMAND which javac + OUTPUT_VARIABLE JAVAC_PATH + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + if(JAVAC_PATH) + # Extract JAVA_HOME from javac path + get_filename_component(JAVA_BIN_DIR ${JAVAC_PATH} DIRECTORY) + get_filename_component(JAVA_HOME_GUESS ${JAVA_BIN_DIR} DIRECTORY) # Correctly go up one level for JAVA_HOME + + # Search for jni.h + find_path(JAVA_INCLUDE_PATH jni.h + PATHS + "${JAVA_HOME_GUESS}/include" + "/usr/lib/jvm/*/include" # Common Debian/Ubuntu locations + "/usr/java/*/include" # Common RedHat/Fedora locations + "/usr/include/java" + ) + + # OS-specific search for jni_md.h + if(WIN32) + find_path(JAVA_MD_INCLUDE_PATH jni_md.h + PATHS + "${JAVA_HOME_GUESS}/include/win32" + ) + elseif(APPLE) + find_path(JAVA_MD_INCLUDE_PATH jni_md.h + PATHS + "${JAVA_HOME_GUESS}/include/darwin" + "/Library/Java/JavaVirtualMachines/*/Contents/Home/include/darwin" + "/System/Library/Frameworks/JavaVM.framework/Headers" + ) + else() # Linux + find_path(JAVA_MD_INCLUDE_PATH jni_md.h + PATHS + "${JAVA_HOME_GUESS}/include/linux" + "/usr/lib/jvm/*/include/linux" + "/usr/java/*/include/linux" + "/usr/include/java/linux" + ) + endif() + else() + message(WARNING "Could not find 'javac'. Java include paths may not be found.") + endif() + endif() + + + target_include_directories(${SWIG_MODULE_NAME} + PUBLIC + ${JAVA_INCLUDE_PATH} # Add this line + ${JAVA_MD_INCLUDE_PATH} # Add this line + ) + + + # Check if Java include directories were found + if(NOT JAVA_INCLUDE_PATH OR NOT JAVA_MD_INCLUDE_PATH) + message(FATAL_ERROR "Java include directories not found. Please ensure Java is properly installed.") + else() + message(STATUS "JAVA_INCLUDE_PATH: ${JAVA_INCLUDE_PATH}") + message(STATUS "JAVA_MD_INCLUDE_PATH: ${JAVA_MD_INCLUDE_PATH}") + endif() + + # Generate the JNI library in a separate target + add_library(${JNI_LIBRARY_NAME} SHARED ${SWIG_WRAPPER_SOURCE}) + add_dependencies(${JNI_LIBRARY_NAME} ${SWIG_MODULE_NAME}) + + target_include_directories(${JNI_LIBRARY_NAME} + PUBLIC + ${JAVA_INCLUDE_PATH} + ${JAVA_MD_INCLUDE_PATH} + ${SWIG_INCLUDE_DIRS} + ) + + target_link_libraries(${JNI_LIBRARY_NAME} + PRIVATE + Controller + CppController + ) + + set_target_properties(${JNI_LIBRARY_NAME} PROPERTIES + PREFIX "" + OUTPUT_NAME ${JNI_LIBRARY_NAME} + LIBRARY_OUTPUT_DIRECTORY ${JNI_LIBRARY_OUTPUT_PATH} + ) + + # Set linker flags for the JNI library + set_target_properties(${JNI_LIBRARY_NAME} PROPERTIES LINK_FLAGS ${JNI_LINK_FLAGS}) + + # Add dependency on the SWIG module + add_dependencies(java_controller ${JNI_LIBRARY_NAME}) + + # Create a symbolic link or copy the JNI library to the output directory + # This simplifies loading the library from Java code + add_custom_command(TARGET ${JNI_LIBRARY_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E create_symlink + ${JNI_LIBRARY_OUTPUT_PATH} + ${CMAKE_CURRENT_BINARY_DIR}/${JNI_LIBRARY_NAME} + COMMENT "Creating symbolic link for ${JNI_LIBRARY_NAME}" + ) + +else() + message(WARNING "SWIG not found. Skipping Java API generation.") +endif() diff --git a/src/ode/CMakeLists.txt b/src/ode/CMakeLists.txt new file mode 100644 index 00000000000..7896c269941 --- /dev/null +++ b/src/ode/CMakeLists.txt @@ -0,0 +1,103 @@ +# ODE (Open Dynamics Engine) CMake configuration + +# ODE (Open Dynamics Engine) CMake configuration + +# Create ODE library target +add_library(ode STATIC) + +# Find all cpp files recursively in ode/src and its subdirectories +file(GLOB_RECURSE ODE_SOURCES + "${CMAKE_CURRENT_SOURCE_DIR}/ode/src/*.cpp" +) + +# Find all c files recursively in ode/src and its subdirectories +file(GLOB_RECURSE ODE_C_SOURCES + "${CMAKE_CURRENT_SOURCE_DIR}/ode/src/*.c" +) + +# Find all OPCODE collision detection library sources +file(GLOB_RECURSE OPCODE_SOURCES + "${CMAKE_CURRENT_SOURCE_DIR}/OPCODE/*.cpp" +) + + +# Find all libccd collision detection library sources +target_sources(ode PRIVATE + libccd/src/alloc.c + libccd/src/ccd.c + libccd/src/mpr.c + libccd/src/polytope.c + libccd/src/support.c + libccd/src/vec3.c +) + +# Add source files +target_sources(ode PRIVATE + ${ODE_SOURCES} + ${ODE_C_SOURCES} + ${OPCODE_SOURCES} +) + +# Set include directories +target_include_directories(ode + PUBLIC + $ + $ + $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/ode/src + ${CMAKE_CURRENT_SOURCE_DIR}/OPCODE + ${CMAKE_CURRENT_SOURCE_DIR}/OPCODE/Ice + ${CMAKE_CURRENT_SOURCE_DIR}/libccd/src + ${CMAKE_CURRENT_SOURCE_DIR}/libccd/src/custom +) + +# Define compile definitions and options +target_compile_definitions(ode + PRIVATE + dTRIMESH_ENABLED + dTRIMESH_OPCODE +) + +target_compile_options(ode PRIVATE + -I${CMAKE_SOURCE_DIR}/include + -fPIC +) + +# Set properties +set_target_properties(ode PROPERTIES + VERSION 0.16.2 + SOVERSION 8 + PUBLIC_HEADER "${CMAKE_SOURCE_DIR}/include/ode/ode.h" +) + +# Install rules +include(GNUInstallDirs) +install(TARGETS ode + EXPORT odeTargets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + #PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ode + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) + +# Export targets +#install(EXPORT odeTargets +# FILE odeTargets.cmake +# NAMESPACE ode:: +# DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ode +#) +# +## Create and install config file +#include(CMakePackageConfigHelpers) +#configure_package_config_file( +# ${CMAKE_CURRENT_SOURCE_DIR}/odeConfig.cmake.in +# ${CMAKE_CURRENT_BINARY_DIR}/odeConfig.cmake +# INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ode +#) +# +#install(FILES +# ${CMAKE_CURRENT_BINARY_DIR}/odeConfig.cmake +# DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ode +#) diff --git a/src/ode/odeConfig.cmake.in b/src/ode/odeConfig.cmake.in new file mode 100644 index 00000000000..18e3ffd24a3 --- /dev/null +++ b/src/ode/odeConfig.cmake.in @@ -0,0 +1,4 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/odeTargets.cmake") +check_required_components(ode) diff --git a/src/webots/.gitignore b/src/webots/.gitignore index 45f62bb8cd3..d5ac7638866 100644 --- a/src/webots/.gitignore +++ b/src/webots/.gitignore @@ -1 +1,2 @@ -cppclean.output +.aider* +.env diff --git a/src/webots/CMakeLists.txt b/src/webots/CMakeLists.txt new file mode 100644 index 00000000000..a89ce20b82f --- /dev/null +++ b/src/webots/CMakeLists.txt @@ -0,0 +1,80 @@ +cmake_minimum_required(VERSION 3.10) +project(Webots VERSION 1.0) + +# Set C++ standard +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Enable PIC globally +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + +# Enable RTTI globally +add_compile_options(-frtti) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -frtti") +if(WIN32) + add_definitions(-DUNICODE -D_UNICODE) +endif() +# Set visibility settings globally +add_compile_options(-fvisibility=default -fno-gnu-unique) + +# Add cmake modules +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +include(FileUtils) + + +# Find OIS +find_package(PkgConfig REQUIRED) +pkg_check_modules(OIS REQUIRED IMPORTED_TARGET OIS) + + +# Add subdirectories +add_subdirectory(app) +add_subdirectory(control) +add_subdirectory(core) +add_subdirectory(editor) +add_subdirectory(engine) +add_subdirectory(gui) +add_subdirectory(maths) +add_subdirectory(nodes) +add_subdirectory(ode) +add_subdirectory(plugins) +add_subdirectory(scene_tree) +add_subdirectory(sound) +add_subdirectory(user_commands) +add_subdirectory(util) +add_subdirectory(vrml) +add_subdirectory(widgets) +add_subdirectory(wren) + +# Main executable +add_executable(webots gui/main.cpp) + +# Link main executable with all components +target_link_libraries(webots + PRIVATE + app_lib + gui_lib + scene_tree_lib + editor_lib + engine_lib + control_lib + plugins_lib + nodes_utils_lib + nodes_lib + ode_lib + wren_lib + sound_lib + user_commands_lib + widgets_lib + vrml_lib + core_lib + maths_lib + util_lib + Qt6::Core + Qt6::Gui + Qt6::Widgets + Qt6::Network + Qt6::OpenGL + Qt6::QmlIntegration + ${OPENGL_LIBRARIES} +) diff --git a/src/webots/app/CMakeLists.txt b/src/webots/app/CMakeLists.txt new file mode 100644 index 00000000000..a04f1da025e --- /dev/null +++ b/src/webots/app/CMakeLists.txt @@ -0,0 +1,31 @@ +# Enable Qt MOC +set(CMAKE_AUTOMOC ON) + +add_webots_library(app_lib) + + +# Set position independent code +set_property(TARGET app_lib PROPERTY POSITION_INDEPENDENT_CODE ON) + +# Ensure symbols are exported +set_target_properties(app_lib PROPERTIES + ENABLE_EXPORTS ON + WINDOWS_EXPORT_ALL_SYMBOLS ON + CXX_VISIBILITY_PRESET default + VISIBILITY_INLINES_HIDDEN OFF +) + +target_link_libraries(app_lib + PUBLIC + nodes_utils_lib + nodes_lib + Qt6::Core + Qt6::Gui + Qt6::Widgets + Qt6::Network + Qt6::OpenGL + Qt6::QmlIntegration + engine_lib + wren_lib + ode +) diff --git a/src/webots/app/WbPerspective.cpp b/src/webots/app/WbPerspective.cpp index 1152bebabbb..fcc3d0a6cb7 100644 --- a/src/webots/app/WbPerspective.cpp +++ b/src/webots/app/WbPerspective.cpp @@ -284,12 +284,16 @@ bool WbPerspective::save() const { out << "renderingDevicePerspectives: " << it.key() << ";" << it.value().join(";") << "\n"; outputFile.close(); - #ifdef _WIN32 // set hidden attribute to WBPROJ file - const QByteArray nativePathByteArray = QDir::toNativeSeparators(fileName()).toUtf8(); - const LPCSTR nativePath = nativePathByteArray.constData(); - SetFileAttributes(nativePath, GetFileAttributes(nativePath) | FILE_ATTRIBUTE_HIDDEN); + const QString nativePath = QDir::toNativeSeparators(fileName()); + #ifdef UNICODE + SetFileAttributes((LPCWSTR)nativePath.utf16(), + GetFileAttributes((LPCWSTR)nativePath.utf16()) | FILE_ATTRIBUTE_HIDDEN); + #else + SetFileAttributes((LPCSTR)nativePath.toLocal8Bit().constData(), + GetFileAttributes((LPCSTR)nativePath.toLocal8Bit().constData()) | FILE_ATTRIBUTE_HIDDEN); + #endif #endif return true; diff --git a/src/webots/cmake/ExternalDependencies.cmake b/src/webots/cmake/ExternalDependencies.cmake new file mode 100644 index 00000000000..c18ee057d36 --- /dev/null +++ b/src/webots/cmake/ExternalDependencies.cmake @@ -0,0 +1,68 @@ +include(ExternalProject) + +# Determine library suffix based on platform +if(WIN32) + set(PICO_LIB_NAME "libpico.dll") + set(PICO_IMPLIB_NAME "libpico.dll.a") +elseif(APPLE) + set(PICO_LIB_NAME "libpico.dylib") +else() + set(PICO_LIB_NAME "libpico.so") +endif() + +# Set paths +set(PICOTTS_PREFIX ${CMAKE_BINARY_DIR}/external/picotts) +set(PICOTTS_LIBRARY ${PICOTTS_PREFIX}/lib/${PICO_LIB_NAME}) +set(PICOTTS_INCLUDE_DIR ${PICOTTS_PREFIX}/include) + +if(WIN32) + set(PICOTTS_IMPLIB ${PICOTTS_PREFIX}/lib/${PICO_IMPLIB_NAME}) +endif() + +# Create necessary directories +file(MAKE_DIRECTORY ${PICOTTS_INCLUDE_DIR}) + +# PicoTTS +ExternalProject_Add( + picotts_external + GIT_REPOSITORY https://github.com/Kreijstal/picotts.git + GIT_TAG master + PREFIX ${PICOTTS_PREFIX} + SOURCE_SUBDIR pico + CMAKE_ARGS + -DCMAKE_INSTALL_PREFIX=${PICOTTS_PREFIX} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + BUILD_BYPRODUCTS + ${PICOTTS_LIBRARY} + ${PICOTTS_IMPLIB} + # Copy header files after build + INSTALL_COMMAND + ${CMAKE_COMMAND} -E copy_directory /pico/lib ${PICOTTS_INCLUDE_DIR} + COMMAND + ${CMAKE_COMMAND} -E copy_directory /pico/compat ${PICOTTS_INCLUDE_DIR} + COMMAND + ${CMAKE_MAKE_PROGRAM} install +) + +# Create the imported library target +add_library(pico::pico SHARED IMPORTED GLOBAL) + +# Set properties on the target +if(WIN32) + set_target_properties(pico::pico PROPERTIES + IMPORTED_LOCATION "${PICOTTS_LIBRARY}" + IMPORTED_IMPLIB "${PICOTTS_IMPLIB}" + INTERFACE_INCLUDE_DIRECTORIES "${PICOTTS_INCLUDE_DIR}" + ) +else() + set_target_properties(pico::pico PROPERTIES + IMPORTED_LOCATION "${PICOTTS_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${PICOTTS_INCLUDE_DIR}" + ) +endif() + +# Create a custom target that depends on the external project +add_custom_target(picotts ALL DEPENDS picotts_external) +add_dependencies(pico::pico picotts) diff --git a/src/webots/cmake/FileUtils.cmake b/src/webots/cmake/FileUtils.cmake new file mode 100644 index 00000000000..d091aa918f5 --- /dev/null +++ b/src/webots/cmake/FileUtils.cmake @@ -0,0 +1,77 @@ +# Helper function to get source files +function(get_source_files DIR SOURCES_OUT) + file(GLOB SOURCES "${DIR}/*.cpp") + set(${SOURCES_OUT} ${SOURCES} PARENT_SCOPE) +endfunction() + +# Helper function to create a library with standard settings +function(add_webots_library LIB_NAME) + get_filename_component(DIR_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) + + # Get all cpp files + file(GLOB ALL_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") + + # Filter out Windows-specific files on non-Windows platforms + if(NOT WIN32) + list(FILTER ALL_SOURCES EXCLUDE REGEX "WbVirtualRealityHeadset\\.cpp$") + list(FILTER ALL_SOURCES EXCLUDE REGEX "WbMicrosoftTextToSpeech\\.cpp$") + list(FILTER ALL_SOURCES EXCLUDE REGEX "WbWindowsRegistry\\.cpp$") + endif() + if(WIN32) + list(FILTER ALL_SOURCES EXCLUDE REGEX "WbPosixMemoryMappedFile\\.cpp$") + endif() + + add_library(${DIR_NAME}_lib ${ALL_SOURCES}) + target_include_directories(${DIR_NAME}_lib PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/src/webots/core + ${CMAKE_SOURCE_DIR}/src/webots/vrml + ${CMAKE_SOURCE_DIR}/src/webots/util + ${CMAKE_SOURCE_DIR}/src/webots/widgets + ${CMAKE_SOURCE_DIR}/src/webots/external/compilation_timestamp + ${CMAKE_SOURCE_DIR}/src/webots/user_commands + ${CMAKE_SOURCE_DIR}/src/webots/maths + ${CMAKE_SOURCE_DIR}/src/webots/nodes/utils + ${CMAKE_SOURCE_DIR}/src/webots/wren + ${CMAKE_SOURCE_DIR}/src/webots/ode + ${CMAKE_SOURCE_DIR}/src/webots/nodes + ${CMAKE_SOURCE_DIR}/src/webots/app + ${CMAKE_SOURCE_DIR}/src/webots/plugins + ${CMAKE_SOURCE_DIR}/src/webots/engine + ${CMAKE_SOURCE_DIR}/src/webots/control + ${CMAKE_SOURCE_DIR}/src/webots/editor + ${CMAKE_SOURCE_DIR}/src/webots/scene_tree + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/include/ode + ${CMAKE_SOURCE_DIR}/src/webots/sound + ${CMAKE_SOURCE_DIR}/src/webots/external/siphash + ${CMAKE_SOURCE_DIR}/include/controller/c + ${PICOTTS_INCLUDE_DIR} + /usr/include/stb + /usr/local/include/stb + $ENV{MINGW_PREFIX}/include/stb + /usr/include + /usr/local/include + $ENV{MINGW_PREFIX}/include + ${FREETYPE_INCLUDE_DIRS} + ) + target_link_libraries(${DIR_NAME}_lib + PUBLIC + Qt6::Core + Qt6::Network + Qt6::QmlIntegration + Qt6::Gui + Qt6::Widgets + Qt6::OpenGL + ) + + # Set C files to be compiled as C and add needed flags + file(GLOB PICO_C_FILES "${CMAKE_BINARY_DIR}/external/picotts/src/picotts/pico/lib/*.c") + set_source_files_properties( + ${PICO_C_FILES} + PROPERTIES + COMPILE_FLAGS "-x c -fno-strict-aliasing" + LANGUAGE C + ) +endfunction() diff --git a/src/webots/control/CMakeLists.txt b/src/webots/control/CMakeLists.txt new file mode 100644 index 00000000000..87675a36610 --- /dev/null +++ b/src/webots/control/CMakeLists.txt @@ -0,0 +1,6 @@ +add_webots_library(control_lib) + +target_link_libraries(control_lib + PRIVATE + core_lib +) diff --git a/src/webots/core/CMakeLists.txt b/src/webots/core/CMakeLists.txt new file mode 100644 index 00000000000..81e51f72ae1 --- /dev/null +++ b/src/webots/core/CMakeLists.txt @@ -0,0 +1,37 @@ +add_webots_library(core_lib) + +# Find libraries on Windows (using MSYS2) +if (WIN32) + # Directly use MSYSTEM_PREFIX for library paths + set(D3D9_LIBRARY_PATH "$ENV{MSYSTEM_PREFIX}/lib/libd3d9.a") + set(IPHLPAPI_LIBRARY_PATH "$ENV{MSYSTEM_PREFIX}/lib/libiphlpapi.a") + + # Check if D3D9 library exists and link it + if (EXISTS ${D3D9_LIBRARY_PATH}) + message(STATUS "D3D9 library found: ${D3D9_LIBRARY_PATH}") + else() + message(FATAL_ERROR "D3D9 library not found at ${D3D9_LIBRARY_PATH}. Please ensure it is installed in your MSYS2 environment.") + endif() + + # Check if IPHLPAPI library exists and link it + if (EXISTS ${IPHLPAPI_LIBRARY_PATH}) + message(STATUS "IPHLPAPI library found: ${IPHLPAPI_LIBRARY_PATH}") + else() + message(FATAL_ERROR "IPHLPAPI library not found at ${IPHLPAPI_LIBRARY_PATH}. Please ensure it is installed in your MSYS2 environment.") + endif() + + # Link libraries if found + target_link_libraries(core_lib + PRIVATE + Qt6::Qml + Qt6::Test + ${D3D9_LIBRARY_PATH} + ${IPHLPAPI_LIBRARY_PATH} + ) +else() + target_link_libraries(core_lib + PRIVATE + Qt6::Qml + Qt6::Test + ) +endif() diff --git a/src/webots/core/WbQtObjectSpy.cpp b/src/webots/core/WbQtObjectSpy.cpp index f6f6f156bbb..f214c6ff737 100644 --- a/src/webots/core/WbQtObjectSpy.cpp +++ b/src/webots/core/WbQtObjectSpy.cpp @@ -35,7 +35,7 @@ void WbQtObjectSpy::beginSignalSpy() { for (int i = 0; i < mMetaObject->methodCount(); i++) { const QMetaMethod &method = mMetaObject->method(i); if (method.methodType() == QMetaMethod::Signal) { - QString signalSignature = QString("2%1").arg(method.signature()); + QString signalSignature = QString("2%1").arg(QString::fromLatin1(method.methodSignature())); mSignalSpies << new QSignalSpy(mObject, signalSignature.toLatin1().data()); } } @@ -45,7 +45,7 @@ void WbQtObjectSpy::endSignalSpy() { foreach (QSignalSpy *spy, mSignalSpies) { QString debugMessage; debugMessage += mMetaObject->className(); - debugMessage += QString("[%1]").arg((long)mObject); + debugMessage += QString("[%1]").arg((quintptr)mObject); debugMessage += "::"; debugMessage += spy->signal(); debugMessage += " was emitted"; diff --git a/src/webots/core/WbWindowsRegistry.cpp b/src/webots/core/WbWindowsRegistry.cpp index 85d92307287..63d54bbec2b 100644 --- a/src/webots/core/WbWindowsRegistry.cpp +++ b/src/webots/core/WbWindowsRegistry.cpp @@ -42,7 +42,7 @@ WbWindowsRegistry::WbWindowsRegistry(const QString &key) { #ifndef NDEBUG LONG successCode = #endif - RegOpenKeyEx(baseKey, keys.join("\\").toStdString().c_str(), 0, KEY_READ, &mCurrentKey); + RegOpenKeyExW(baseKey, keys.join(L"\\").toStdWString().c_str(), 0, KEY_READ, &mCurrentKey); assert(successCode == ERROR_SUCCESS); } diff --git a/src/webots/editor/CMakeLists.txt b/src/webots/editor/CMakeLists.txt new file mode 100644 index 00000000000..5b131fd6ac9 --- /dev/null +++ b/src/webots/editor/CMakeLists.txt @@ -0,0 +1,10 @@ +add_webots_library(editor_lib) + + +target_link_libraries(editor_lib + PRIVATE + Qt6::Gui + Qt6::Widgets + Qt6::PrintSupport Qt6::Widgets + core_lib +) diff --git a/src/webots/engine/CMakeLists.txt b/src/webots/engine/CMakeLists.txt new file mode 100644 index 00000000000..7f2313d63bd --- /dev/null +++ b/src/webots/engine/CMakeLists.txt @@ -0,0 +1,24 @@ +# Enable Qt MOC +set(CMAKE_AUTOMOC ON) + +file(GLOB SOURCES "*.cpp") +add_webots_library(engine_lib ${SOURCES}) + +target_include_directories(engine_lib PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/webots/core + ${CMAKE_SOURCE_DIR}/src/webots/nodes + ${CMAKE_SOURCE_DIR}/src/webots/vrml + ${CMAKE_SOURCE_DIR}/include +) + +target_link_libraries(engine_lib + PUBLIC + Qt6::Core + Qt6::Gui + Qt6::Widgets + core_lib + nodes_lib + ode_lib + vrml_lib +) diff --git a/src/webots/gui/CMakeLists.txt b/src/webots/gui/CMakeLists.txt new file mode 100644 index 00000000000..7f888dcdeb5 --- /dev/null +++ b/src/webots/gui/CMakeLists.txt @@ -0,0 +1,12 @@ +add_webots_library(gui_lib) +target_link_libraries(gui_lib + PRIVATE + Qt6::Gui + Qt6::Widgets + Qt6::Network + Qt6::OpenGL + Qt6::WebSockets + Qt6::OpenGLWidgets + ${OPENGL_LIBRARIES} + app_lib +) diff --git a/src/webots/gui/WbSplashScreen.cpp b/src/webots/gui/WbSplashScreen.cpp index e1c982ce466..c4810c4b9fd 100644 --- a/src/webots/gui/WbSplashScreen.cpp +++ b/src/webots/gui/WbSplashScreen.cpp @@ -20,16 +20,35 @@ #include #include +#include + WbSplashScreen::WbSplashScreen(const QStringList &screenshots, const QString &logoFileName) { QPixmap background(960, 580); background.fill(Qt::black); QSplashScreen::setPixmap(background); - // rand is already given a fixed seed so use millisecond-time since epoch for pseudorandomness - int randomImageIndex = QTime::currentTime().msecsSinceStartOfDay() % screenshots.size(); + // Handle empty screenshots list + if (screenshots.isEmpty()) { + QMessageBox::warning(nullptr, "Warning", "No splash screen images provided."); + } else { + // rand is already given a fixed seed so use millisecond-time since epoch for pseudorandomness + int randomImageIndex = QTime::currentTime().msecsSinceStartOfDay() % screenshots.size(); + + mScreenshot = QImage("images:splash_images/" + screenshots.at(randomImageIndex)); + if (mScreenshot.isNull()) { + QMessageBox::warning(nullptr, "Error", + "Failed to load splash screen image: " + screenshots.at(randomImageIndex)); + // Optionally load a default image here or skip loading a screenshot + // mScreenshot = QImage("path/to/default/image.png"); + } + } - mScreenshot = QImage("images:splash_images/" + screenshots.at(randomImageIndex)); mWebotsLogo = QImage("images:" + logoFileName); + if (mWebotsLogo.isNull()) { + QMessageBox::warning(nullptr, "Error", "Failed to load Webots logo image: " + logoFileName); + // You might decide to exit the program here or continue without a logo + } + #ifdef _WIN32 setWindowModality(Qt::ApplicationModal); #endif diff --git a/src/webots/maths/CMakeLists.txt b/src/webots/maths/CMakeLists.txt new file mode 100644 index 00000000000..b72d9b3dcd3 --- /dev/null +++ b/src/webots/maths/CMakeLists.txt @@ -0,0 +1 @@ +add_webots_library(maths_lib) diff --git a/src/webots/nodes/CMakeLists.txt b/src/webots/nodes/CMakeLists.txt new file mode 100644 index 00000000000..3b1adc91f32 --- /dev/null +++ b/src/webots/nodes/CMakeLists.txt @@ -0,0 +1,28 @@ +add_subdirectory(utils) +add_webots_library(nodes_lib) + +# Enable RTTI and visibility +target_compile_options(nodes_lib + PUBLIC + -frtti + -fvisibility=default + -fno-gnu-unique +) + +# Set position independent code +set_property(TARGET nodes_lib PROPERTY POSITION_INDEPENDENT_CODE ON) + +# Ensure symbols are exported +set_target_properties(nodes_lib PROPERTIES + ENABLE_EXPORTS ON + WINDOWS_EXPORT_ALL_SYMBOLS ON + CXX_VISIBILITY_PRESET default + VISIBILITY_INLINES_HIDDEN OFF +) + +target_link_libraries(nodes_lib + PUBLIC + core_lib + vrml_lib + ${CMAKE_DL_LIBS} +) diff --git a/src/webots/nodes/utils/CMakeLists.txt b/src/webots/nodes/utils/CMakeLists.txt new file mode 100644 index 00000000000..6f03a4f9759 --- /dev/null +++ b/src/webots/nodes/utils/CMakeLists.txt @@ -0,0 +1,61 @@ + +file(GLOB SOURCES "*.cpp") +list(REMOVE_ITEM SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/WbVirtualRealityHeadset.cpp") + +if(WIN32) + list(APPEND SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/WbVirtualRealityHeadset.cpp") +endif() + +add_library(nodes_utils_lib STATIC ${SOURCES}) + +# Enable RTTI and visibility +target_compile_options(nodes_utils_lib + PUBLIC + -frtti + -fvisibility=default + -fno-gnu-unique +) + +# Set position independent code +set_property(TARGET nodes_utils_lib PROPERTY POSITION_INDEPENDENT_CODE ON) + +# Ensure symbols are exported +set_target_properties(nodes_utils_lib PROPERTIES + ENABLE_EXPORTS ON + WINDOWS_EXPORT_ALL_SYMBOLS ON + CXX_VISIBILITY_PRESET default + VISIBILITY_INLINES_HIDDEN OFF + BUILD_SHARED_LIBS ON +) + +target_include_directories(nodes_utils_lib PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/webots/nodes + ${CMAKE_SOURCE_DIR}/src/webots/core + ${CMAKE_SOURCE_DIR}/src/webots/vrml + ${CMAKE_SOURCE_DIR}/src/webots/util + ${CMAKE_SOURCE_DIR}/include + $ENV{MINGW_PREFIX}/include + $ENV{MINGW_PREFIX}/local/include + /usr/include + /usr/local/include +) + +target_link_libraries(nodes_utils_lib + PUBLIC vrml_lib + PUBLIC util_lib + PUBLIC core_lib + PUBLIC Qt6::Core + PUBLIC Qt6::Gui + PUBLIC Qt6::Widgets + PUBLIC ${OIS_LIBRARIES} + PUBLIC PkgConfig::OIS + PUBLIC PkgConfig::OPENVR + PUBLIC ode + wren_lib + nodes_lib + app_lib +) + +# Ensure this library is built with -fPIC +set_property(TARGET nodes_utils_lib PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/src/webots/nodes/utils/WbJoystickInterface.cpp b/src/webots/nodes/utils/WbJoystickInterface.cpp index 822e37fcf18..67d392bae34 100644 --- a/src/webots/nodes/utils/WbJoystickInterface.cpp +++ b/src/webots/nodes/utils/WbJoystickInterface.cpp @@ -17,10 +17,10 @@ #include -#include -#include -#include -#include +#include +#include +#include +#include #define SIGMOID_LAMBDA 0.0001 diff --git a/src/webots/nodes/utils/WbJoystickListener.hpp b/src/webots/nodes/utils/WbJoystickListener.hpp index 13cb2d0809d..a5bf410f542 100644 --- a/src/webots/nodes/utils/WbJoystickListener.hpp +++ b/src/webots/nodes/utils/WbJoystickListener.hpp @@ -15,7 +15,7 @@ #ifndef WB_JOYSTICK_LISTENER_HPP #define WB_JOYSTICK_LISTENER_HPP -#include +#include #include class WbJoystickListener : public QObject, public OIS::JoyStickListener { diff --git a/src/webots/ode/CMakeLists.txt b/src/webots/ode/CMakeLists.txt new file mode 100644 index 00000000000..571893fa3ab --- /dev/null +++ b/src/webots/ode/CMakeLists.txt @@ -0,0 +1,6 @@ +add_webots_library(ode_lib) + +target_link_libraries(ode_lib + PRIVATE + maths_lib +) diff --git a/src/webots/plugins/CMakeLists.txt b/src/webots/plugins/CMakeLists.txt new file mode 100644 index 00000000000..6570ab611e7 --- /dev/null +++ b/src/webots/plugins/CMakeLists.txt @@ -0,0 +1,6 @@ +add_webots_library(plugins_lib) + +target_link_libraries(plugins_lib + PRIVATE + core_lib +) diff --git a/src/webots/scene_tree/CMakeLists.txt b/src/webots/scene_tree/CMakeLists.txt new file mode 100644 index 00000000000..522b60dc3dd --- /dev/null +++ b/src/webots/scene_tree/CMakeLists.txt @@ -0,0 +1,7 @@ +add_webots_library(scene_tree_lib) + +target_link_libraries(scene_tree_lib + PRIVATE + Qt6::Widgets + nodes_lib +) diff --git a/src/webots/sound/CMakeLists.txt b/src/webots/sound/CMakeLists.txt new file mode 100644 index 00000000000..bf562834d10 --- /dev/null +++ b/src/webots/sound/CMakeLists.txt @@ -0,0 +1,32 @@ +add_webots_library(sound_lib) +add_dependencies(sound_lib picotts) + +# Find SAPI (Speech API) +if (WIN32) + # Directly use MSYSTEM_PREFIX + set(SAPI_LIBRARY_PATH "$ENV{MSYSTEM_PREFIX}/lib/libsapi.a") + + # Check if SAPI library exists and link it + if (EXISTS ${SAPI_LIBRARY_PATH}) + target_link_libraries(sound_lib + PRIVATE + core_lib + OpenAL::OpenAL + pico::pico + Qt6::Xml + ${SAPI_LIBRARY_PATH} + ) + message(STATUS "SAPI library found and linked: ${SAPI_LIBRARY_PATH}") + else() + message(FATAL_ERROR "SAPI library not found at ${SAPI_LIBRARY_PATH}. Please ensure it is installed in your MSYS2 environment.") + endif() +else() + target_link_libraries(sound_lib + PRIVATE + core_lib + OpenAL::OpenAL + pico::pico + Qt6::Xml + ) +endif() + diff --git a/src/webots/sound/PicoTTSWrapper.h b/src/webots/sound/PicoTTSWrapper.h new file mode 100644 index 00000000000..c16a80a211d --- /dev/null +++ b/src/webots/sound/PicoTTSWrapper.h @@ -0,0 +1,21 @@ +#ifndef PICO_TTS_WRAPPER_H +#define PICO_TTS_WRAPPER_H + +// Rename C keyword 'this' to avoid conflicts +#define this pico_this + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#ifdef __cplusplus +} +#endif + +#undef this + +#endif // PICO_TTS_WRAPPER_H diff --git a/src/webots/sound/WbMicrosoftTextToSpeech.cpp b/src/webots/sound/WbMicrosoftTextToSpeech.cpp index 71674dbacfe..ea905b7eaae 100644 --- a/src/webots/sound/WbMicrosoftTextToSpeech.cpp +++ b/src/webots/sound/WbMicrosoftTextToSpeech.cpp @@ -18,7 +18,6 @@ #include #include #include - #include #include diff --git a/src/webots/sound/WbPicoTextToSpeech.cpp b/src/webots/sound/WbPicoTextToSpeech.cpp index 93b83f6d5aa..776a4a51620 100644 --- a/src/webots/sound/WbPicoTextToSpeech.cpp +++ b/src/webots/sound/WbPicoTextToSpeech.cpp @@ -20,9 +20,7 @@ #include #include -#include -#include -#include +#include "PicoTTSWrapper.h" #include // adaptation layer defines diff --git a/src/webots/user_commands/CMakeLists.txt b/src/webots/user_commands/CMakeLists.txt new file mode 100644 index 00000000000..e851bb57a35 --- /dev/null +++ b/src/webots/user_commands/CMakeLists.txt @@ -0,0 +1,7 @@ +add_webots_library(user_commands_lib) + +target_link_libraries(user_commands_lib + PRIVATE + Qt6::Widgets + editor_lib +) diff --git a/src/webots/util/CMakeLists.txt b/src/webots/util/CMakeLists.txt new file mode 100644 index 00000000000..358b23007a0 --- /dev/null +++ b/src/webots/util/CMakeLists.txt @@ -0,0 +1,7 @@ +add_webots_library(util_lib) + +target_link_libraries(util_lib + PRIVATE + Qt6::Network + Qt6::Widgets +) diff --git a/src/webots/vrml/CMakeLists.txt b/src/webots/vrml/CMakeLists.txt new file mode 100644 index 00000000000..f21391e3808 --- /dev/null +++ b/src/webots/vrml/CMakeLists.txt @@ -0,0 +1,20 @@ +# Enable Qt MOC +set(CMAKE_AUTOMOC ON) + +file(GLOB SOURCES "*.cpp") +add_webots_library(vrml_lib ${SOURCES}) + +target_include_directories(vrml_lib PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/webots/core + ${CMAKE_SOURCE_DIR}/src/webots/maths + ${CMAKE_SOURCE_DIR}/include +) + +target_link_libraries(vrml_lib + PUBLIC + Qt6::Core + Qt6::Gui + maths_lib + core_lib +) diff --git a/src/webots/widgets/CMakeLists.txt b/src/webots/widgets/CMakeLists.txt new file mode 100644 index 00000000000..ee46b39e408 --- /dev/null +++ b/src/webots/widgets/CMakeLists.txt @@ -0,0 +1,8 @@ +add_webots_library(widgets_lib) + +target_link_libraries(widgets_lib + PRIVATE + Qt6::Gui + Qt6::Widgets + maths_lib +) diff --git a/src/webots/wren/CMakeLists.txt b/src/webots/wren/CMakeLists.txt new file mode 100644 index 00000000000..2169599f1d4 --- /dev/null +++ b/src/webots/wren/CMakeLists.txt @@ -0,0 +1,20 @@ +# Enable Qt MOC +set(CMAKE_AUTOMOC ON) + +file(GLOB SOURCES "*.cpp") +add_webots_library(wren_lib ${SOURCES}) + +target_include_directories(wren_lib PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/include +) + +target_link_libraries(wren_lib + PUBLIC + Qt6::Core + Qt6::Gui + Qt6::OpenGL + ${OPENGL_LIBRARIES} + maths_lib + wren +) diff --git a/src/wren/CMakeLists.txt b/src/wren/CMakeLists.txt new file mode 100644 index 00000000000..34cf3b2c404 --- /dev/null +++ b/src/wren/CMakeLists.txt @@ -0,0 +1,49 @@ +# Wren library configuration + +# Source files +file(GLOB WREN_SOURCES + "*.cpp" +) + +# Header files +file(GLOB WREN_HEADERS + "*.hpp" +) + +# Create wren library +add_library(wren STATIC ${WREN_SOURCES} ${WREN_HEADERS}) +target_compile_options(wren PUBLIC -fPIC) + +# Find required packages +find_package(Freetype REQUIRED) +find_package(assimp REQUIRED) + +# Include directories +target_include_directories(wren PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/webots/external + ${CMAKE_SOURCE_DIR}/src/webots/external/siphash + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/src/webots/core + ${OPENGL_INCLUDE_DIR} + ${Qt6Core_INCLUDE_DIRS} + ${Qt6Gui_INCLUDE_DIRS} + ${Qt6OpenGL_INCLUDE_DIRS} + ${FREETYPE_INCLUDE_DIRS} + ${ASSIMP_INCLUDE_DIRS} +) + +# Define GLM experimental features +add_definitions(-DGLM_ENABLE_EXPERIMENTAL) + +# Link libraries +target_link_libraries(wren PUBLIC + ${OPENGL_LIBRARIES} + Qt6::Core + Qt6::Gui + Qt6::OpenGL + ${FREETYPE_LIBRARIES} + assimp + glad +) +