Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to compile the gazebo executable on Windows #2864

Merged
merged 1 commit into from
Nov 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
if(WIN32)
cmake_minimum_required(VERSION 3.11 FATAL_ERROR)
else()
cmake_minimum_required(VERSION 3.10.2 FATAL_ERROR)
endif()

if(COMMAND CMAKE_POLICY)
CMAKE_POLICY(SET CMP0003 NEW)
Expand Down
15 changes: 15 additions & 0 deletions cmake/SearchForStuff.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -865,3 +865,18 @@ else()
message (STATUS "Looking for qwt >= 6.1.0 - not found")
BUILD_ERROR ("Missing: libqwt-dev. Required for plotting.")
endif ()

########################################
# On Windows, find tiny-process-library
if (WIN32)
option(USE_EXTERNAL_TINY_PROCESS_LIBRARY "Use external tiny-process-library." OFF)
if (USE_EXTERNAL_TINY_PROCESS_LIBRARY)
find_package(tiny-process-library QUIET)
if (NOT tiny-process-library_FOUND)
message (STATUS "Looking for tiny-process-library - not found")
BUILD_ERROR ("Missing: tiny-process-library, even if USE_EXTERNAL_TINY_PROCESS_LIBRARY was enabled.")
else()
message (STATUS "Looking for tiny-process-library - found")
endif()
endif()
endif()
6 changes: 5 additions & 1 deletion deps/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@ if (NOT CCD_FOUND)
add_subdirectory(libccd)
endif()
# add_subdirectory(ann)
# add_subdirectory(fcl)
# add_subdirectory(fcl

if (WIN32 AND NOT USE_EXTERNAL_TINY_PROCESS_LIBRARY)
add_subdirectory(tiny-process-library)
endif()
52 changes: 52 additions & 0 deletions deps/tiny-process-library/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
include(FetchContent)
FetchContent_Declare(
tinyprocesslibrary
GIT_REPOSITORY https://gitlab.com/eidheim/tiny-process-library.git
GIT_TAG v2.0.2)

FetchContent_GetProperties(tinyprocesslibrary)

if(NOT tinyprocesslibrary_POPULATED)
FetchContent_Populate(tinyprocesslibrary)

# We don't want to install this library in the system, we instead
# compile it as an OBJECT library and embed in either the shared or
# static libraries that need it.
# From https://gitlab.kitware.com/cmake/cmake/-/issues/18935 it seems
# that OBJECT libraries that are not installed become INTERFACE when
# part of an EXPORT set.
# This behaviour allows setting transitively tiny-process-library infos
# to the consuming targets while not breaking the EXPORT process. In fact,
# the conversion to INTERFACE allows to add tiny-process-library to the
# targets of the EXPORT that contains targets linking against it.
# See also https://cmake.org/pipermail/cmake/2018-September/068250.html.

if(WIN32)
add_library(tiny-process-library OBJECT
${tinyprocesslibrary_SOURCE_DIR}/process.cpp
${tinyprocesslibrary_SOURCE_DIR}/process_win.cpp)
#If compiled using MSYS2, use sh to run commands
if(MSYS)
target_compile_definitions(tiny-process-library
PUBLIC MSYS_PROCESS_USE_SH)
endif()
else()
add_library(tiny-process-library OBJECT
${tinyprocesslibrary_SOURCE_DIR}/process.cpp
${tinyprocesslibrary_SOURCE_DIR}/process_unix.cpp)
endif()
add_library(tiny-process-library::tiny-process-library ALIAS tiny-process-library)

if(MSVC)
target_compile_definitions(tiny-process-library
PRIVATE /D_CRT_SECURE_NO_WARNINGS)
endif()

find_package(Threads REQUIRED)

target_link_libraries(tiny-process-library PRIVATE
${CMAKE_THREAD_LIBS_INIT})
target_include_directories(tiny-process-library PUBLIC
$<BUILD_INTERFACE:${tinyprocesslibrary_SOURCE_DIR}>)

endif()
45 changes: 26 additions & 19 deletions gazebo/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,28 +82,35 @@ endif()
gz_install_executable(gzserver)
manpage(gzserver 1)

# gazebo executable doesn't yet work on Windows
if (NOT WIN32)
gz_add_executable(gazebo gazebo_main.cc)
target_link_libraries(gazebo
libgazebo
libgazebo_client
gazebo_common
gazebo_util
gazebo_transport
gazebo_physics
gazebo_sensors
gazebo_rendering
gazebo_msgs
gazebo_gui
)

gz_install_executable(gazebo)
manpage(gazebo 1)

gz_add_executable(gazebo gazebo_main.cc)
target_link_libraries(gazebo
libgazebo
libgazebo_client
gazebo_common
gazebo_util
gazebo_transport
gazebo_physics
gazebo_sensors
gazebo_rendering
gazebo_msgs
gazebo_gui
)

if(WIN32)
target_link_libraries(gazebo tiny-process-library::tiny-process-library)
endif()

gz_install_executable(gazebo)
manpage(gazebo 1)


gz_add_library(libgazebo Server.cc Master.cc gazebo.cc gazebo_shared.cc)
set_target_properties(libgazebo PROPERTIES OUTPUT_NAME "gazebo")

# On Windows calling libgazebo "gazebo" will conflict with the Gazebo executable
if (NOT WIN32)
set_target_properties(libgazebo PROPERTIES OUTPUT_NAME "gazebo")
endif()

target_link_libraries(libgazebo
gazebo_common
Expand Down
106 changes: 97 additions & 9 deletions gazebo/gazebo_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,20 @@
* limitations under the License.
*
*/

#ifndef _WIN32
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#else
#include <process.hpp>
#endif

#include "gazebo/common/Console.hh"
#include "gazebo/Server.hh"
#include "gazebo/gui/GuiIface.hh"

bool sig_killed = false;
int status1, status2;
// pid of server process
pid_t pid1;
// pid of client process
pid_t pid2;
bool killed1 = false;
bool killed2 = false;

/////////////////////////////////////////////////
void help()
{
Expand Down Expand Up @@ -77,6 +73,16 @@ void help()
<< "\n";
}

#ifndef _WIN32
bool sig_killed = false;
int status1, status2;
// pid of server process
pid_t pid1;
// pid of client process
pid_t pid2;
bool killed1 = false;
bool killed2 = false;

/// \brief Try to kill a single process.
/// \param[in] _pid Process ID.
/// \param[in] _name Process name.
Expand Down Expand Up @@ -216,3 +222,85 @@ int main(int _argc, char **_argv)

return returnValue;
}

#else

std::atomic<bool> g_shouldExit = false;

int main(int _argc, char **_argv)
{
if (_argc >= 2 &&
(strcmp(_argv[1], "-h") == 0 || strcmp(_argv[1], "--help") == 0)) {
help();
return 0;
}

std::vector<std::string> argvServer;
std::vector<std::string> argvClient;

argvServer.push_back("gzserver");
argvClient.push_back("gzclient");

for (int i = 1; i < _argc; ++i)
{
argvServer.push_back(std::string(_argv[i]));
argvClient.push_back(std::string(_argv[i]));
}

// Start server
TinyProcessLib::Process server(argvServer);

// Start client
TinyProcessLib::Process client(argvClient);

// Wait
bool serverClosed = false;
bool clientClosed = false;
int serverExitCode = 0;
int clientExitCode = 0;

while (!g_shouldExit)
{
std::this_thread::sleep_for(std::chrono::milliseconds(20));

// Check if server and gui are still open, if they are closed
// close this process as well
serverClosed = server.try_get_exit_status(serverExitCode);
clientClosed = client.try_get_exit_status(clientExitCode);

if (serverClosed || clientClosed)
{
g_shouldExit = true;
}

}

// Cleanup
serverClosed = server.try_get_exit_status(serverExitCode);

if (!serverClosed)
{
server.kill();
}

clientClosed = client.try_get_exit_status(clientExitCode);

if (!clientClosed)
{
client.kill();
}

// Get exit status
serverExitCode = server.get_exit_status();
clientExitCode = client.get_exit_status();

int exitCode = 0;
if (serverExitCode != 0 || clientExitCode != 0)
{
exitCode = 1;
}

return exitCode;
}

#endif