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

Improve ign tool support on macOS #477

Merged
merged 5 commits into from
Jan 11, 2021
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: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ set(IGN_RENDERING_VER ${ignition-rendering4_VERSION_MAJOR})
ign_find_package(ignition-math6 REQUIRED COMPONENTS eigen3 VERSION 6.6)
set(IGN_MATH_VER ${ignition-math6_VERSION_MAJOR})

#--------------------------------------
# Find ignition-tools
ign_find_package(ignition-tools
REQUIRED
PKGCONFIG "ignition-tools")

#--------------------------------------
# Find protobuf
set(REQ_PROTOBUF_VER 3)
Expand Down
30 changes: 30 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,36 @@ ign_build_tests(TYPE UNIT
ignition-gazebo${PROJECT_VERSION_MAJOR}
)

if(TARGET UNIT_ign_TEST)

# Running `ign gazebo` on macOS has problems when run with /usr/bin/ruby
# due to System Integrity Protection (SIP). Try to find ruby from
# homebrew as a workaround.
chapulina marked this conversation as resolved.
Show resolved Hide resolved
if (APPLE)
find_program(BREW_RUBY ruby HINTS /usr/local/opt/ruby/bin)
endif()

add_dependencies(UNIT_ign_TEST
${ign_lib_target}
TestModelSystem
TestSensorSystem
TestWorldSystem
)

target_compile_definitions(UNIT_ign_TEST PRIVATE
"BREW_RUBY=\"${BREW_RUBY} \"")

target_compile_definitions(UNIT_ign_TEST PRIVATE
"IGN_PATH=\"${IGNITION-TOOLS_BINARY_DIRS}\"")

set(_env_vars)
list(APPEND _env_vars "IGN_CONFIG_PATH=${CMAKE_BINARY_DIR}/test/conf")
list(APPEND _env_vars "IGN_GAZEBO_SYSTEM_PLUGIN_PATH=$<TARGET_FILE_DIR:TestModelSystem>")

set_tests_properties(UNIT_ign_TEST PROPERTIES
ENVIRONMENT "${_env_vars}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, I don't think we've been setting environment variables for tests from CMake.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I learned it from Dirk; it's not universal, but we have done it in a few places:

I think it's a bit cleaner to set them from cmake. One drawback is that executing the binaries directly (like ./UNIT_ign_TEST) may not work, but it's easy enough to use ctest -R UNIT_ign_TEST -VV once you know to do so

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One drawback is that executing the binaries directly (like ./UNIT_ign_TEST) may not work

Oh no, that sounds like a regression. We have that workflow documented in a few places, it would be unfortunate not to support it anymore.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mentioned during the meeting, I don't see the advantage of moving the environment variables to CMake.

It prevents a common workflow, and it hides the environment configuration from anyone who's debugging the tests or looking into them to understand how the code works. Especially for variables like IGN_GAZEBO_SYSTEM_PLUGIN_PATH, which are set by the user at runtime, I think it's valuable to explicitly set them during the tests.

But I'm not going to block this PR on this, I'll leave it up to you.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pointed to 3 examples in our code where it's already being used, so this isn't a completely new thing, but you're right that the docs need to be updated to handle this case. I'll merge this then open a pull request to update the docs

endif()

if(NOT WIN32)
add_subdirectory(cmd)
endif()
Expand Down
23 changes: 23 additions & 0 deletions src/cmd/cmdgazebo.rb.in
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,17 @@ class Cmd
Importer.dlload plugin
rescue DLError => e
puts "Library error for [#{plugin}]: #{e.to_s}"
if plugin.end_with? ".dylib"
puts "
If this script was executed with /usr/bin/ruby, this error may be caused by
macOS System Integrity Protection. One workaround is to use a different
version of ruby, for example:
brew install ruby
and add the following line to your shell profile:
export PATH=/usr/local/opt/ruby/bin:$PATH
If you are using a colcon workspace, please ensure that the setup script
has properly set the DYLD_LIBRARY_PATH environment variables."
end
exit(-1)
end

Expand Down Expand Up @@ -435,6 +446,12 @@ class Cmd
# and gui.
if options['server'] == 0 && options['gui'] == 0

if plugin.end_with? ".dylib"
puts "`ign gazebo` currently only works with the -s argument on macOS.
See https://github.com/ignitionrobotics/ign-gazebo/issues/44 for more info."
exit(-1)
end

serverPid = Process.fork do
ENV['RMT_PORT'] = '1500'
Process.setpgid(0, 0)
Expand Down Expand Up @@ -484,6 +501,12 @@ class Cmd
options['file'], options['record-topics'].join(':'))
# Otherwise run the gui
else options['gui']
if plugin.end_with? ".dylib"
puts "`ign gazebo` currently only works with the -s argument on macOS.
See https://github.com/ignitionrobotics/ign-gazebo/issues/44 for more info."
exit(-1)
end

ENV['RMT_PORT'] = '1501'
Importer.runGui(options['gui_config'])
end
Expand Down
22 changes: 2 additions & 20 deletions src/ign_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,8 @@

static const std::string kBinPath(PROJECT_BINARY_PATH);

// Command line not working on OSX, see
// https://github.com/ignitionrobotics/ign-gazebo/issues/25/
#ifndef __APPLE__
static const std::string kIgnCommand(
"IGN_GAZEBO_SYSTEM_PLUGIN_PATH=" + kBinPath + "/lib LD_LIBRARY_PATH=" +
kBinPath + "/lib:/usr/local/lib:${LD_LIBRARY_PATH} ign gazebo -s ");
std::string(BREW_RUBY) + std::string(IGN_PATH) + "/ign gazebo -s ");

/////////////////////////////////////////////////
std::string customExecStr(std::string _cmd)
Expand Down Expand Up @@ -90,8 +86,7 @@ TEST(CmdLine, Server)
}

/////////////////////////////////////////////////
// Not supported on Mac's command line tool
TEST(CmdLine, IGN_UTILS_TEST_DISABLED_ON_MAC(CachedFuelWorld))
TEST(CmdLine, CachedFuelWorld)
{
std::string projectPath = std::string(PROJECT_SOURCE_PATH) + "/test/worlds";
setenv("IGN_FUEL_CACHE_PATH", projectPath.c_str(), true);
Expand Down Expand Up @@ -164,16 +159,3 @@ TEST(CmdLine, ResourcePath)
EXPECT_EQ(output.find("Unable to find file plugins.sdf"), std::string::npos)
<< output;
}
#endif

/////////////////////////////////////////////////
/// Main
int main(int _argc, char **_argv)
{
// Set IGN_CONFIG_PATH to the directory where the .yaml configuration files
// is located.
setenv("IGN_CONFIG_PATH", IGN_CONFIG_PATH, 1);

::testing::InitGoogleTest(&_argc, _argv);
return RUN_ALL_TESTS();
}