Skip to content

Commit c89138b

Browse files
authored
Merge pull request #1573 from opensim-org/macOS_RPATH_relative
On macOS, use relative RPATHs to make the installation relocatable.
2 parents 4480425 + 6b1996b commit c89138b

File tree

5 files changed

+88
-37
lines changed

5 files changed

+88
-37
lines changed

.travis.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,10 @@ script:
222222
- make -j8 install > /dev/null
223223

224224
## Test python wrapping.
225+
# Since we use OPENSIM_COPY_SIMBODY=ON, ensure the Python bindings are not
226+
# relying on the original Simbody libraries but rather the copied ones.
227+
# This should make sure we have the correct RPATH for Simbody on macOS.
228+
- rm -r ~/simbody
225229
# Go to the python wrapping package directory.
226230
- if [ "$WRAP" = "on" ]; then cd $OPENSIM_HOME/lib/python2.7/site-packages; fi
227231
# Run the python tests, verbosely.

Bindings/Java/OpenSimJNI/CMakeLists.txt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,15 @@ set_source_files_properties(
114114
PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS}")
115115

116116
if(${OPENSIM_USE_INSTALL_RPATH})
117-
set_target_properties(osim${KIT} PROPERTIES
118-
INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}"
117+
# TODO @loader_path only makes sense on macOS, so we need to revisit for
118+
# Linux (use $ORIGIN).
119+
120+
# The osim libraries that osimJavaJNI needs are in the same folder as
121+
# osimJavaJNI. Adding @loader_rpath (the \ is to escape the @) to the
122+
# run-path list will let osimJavaJNI find osimTools, etc.
123+
# Use APPEND to include the BTK RPATH, set in CMAKE_INSTALL_RPATH.
124+
set_property(TARGET osim${KIT} APPEND PROPERTY
125+
INSTALL_RPATH "\@loader_path/"
119126
)
120127
endif()
121128

Bindings/Python/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,9 @@ macro(OpenSimAddPythonModule)
160160
endif()
161161

162162
if(${OPENSIM_USE_INSTALL_RPATH})
163-
set_target_properties(${_libname} PROPERTIES
163+
# Use APPEND to include the BTK RPATH, set in CMAKE_INSTALL_RPATH.
164+
# TODO test that NOT using APPEND causes BTK to not be found.
165+
set_property(TARGET ${_libname} APPEND PROPERTY
164166
INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}"
165167
)
166168
endif()

CMakeLists.txt

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,17 @@ from the internet, we turn this option OFF." ON)
8989
set(SIMBODY_HOME $ENV{SIMBODY_HOME} CACHE
9090
PATH "The location of the Simbody installation to use; you can change this. Set as empty to let CMake search for Simbody automatically.")
9191

92+
# TODO rename to OPENSIM_COPY_DEPENDENCIES and handle BTK.
9293
option(OPENSIM_COPY_SIMBODY "Copy Simbody headers and libraries into the
9394
OpenSim installation. This way, you can treat OpenSim and Simbody as one
9495
package, and you only need to set environment variables (e.g., PATH,
9596
LD_LIBRARY_PATH, DYLD_LIBRARY_PATH) for OpenSim. On Windows, this also copies
9697
Simbody dll's and exe's into the OpenSim build directory, so that you don't
9798
need to set PATH to run OpenSim tests and examples; this is done via the
9899
SimbodyFiles project. If OFF, you likely must set those environment variables
99-
for both OpenSim and Simbody." ON)
100+
for both OpenSim and Simbody. To make a distributable installation on macOS,
101+
this should be set to ON to avoid using absolute paths for RPATHs to Simbody
102+
libraries." ON)
100103

101104
option(BUILD_API_ONLY "Build/install only headers, libraries,
102105
wrapping, tests; not applications (opensim, ik, rra, etc.)." OFF)
@@ -457,39 +460,40 @@ if(${CMAKE_C_COMPILER} MATCHES "cc" OR ${CMAKE_C_COMPILER} MATCHES "clang")
457460
endif()
458461

459462

460-
## On APPLE, use MACOSX_RPATH.
461-
## On Linux, this variable has no effect.
462-
set(OPENSIM_USE_INSTALL_RPATH FALSE)
463+
## RPATH
464+
# If it is necesasry to not put RPATHS in the installed binaries, set
465+
# set CMAKE_SKIP_INSTALL_RPATH to OFF.
463466
if(APPLE)
464-
option(OPENSIM_NO_LIBRARY_PATH_ENV_VAR
465-
"If ON, you don't need to set
466-
DYLD_LIBRARY_PATH (on OSX) to make use of OpenSim's executables.
467-
Instead, we bake the location of OpenSim's libraries into the
468-
executables, so the executables already know where to find the
469-
libraries. This uses the RPATH mechanism." ON)
470-
if(${OPENSIM_NO_LIBRARY_PATH_ENV_VAR})
471-
# CMake 2.8.12 introduced the ability to set RPATH for shared libraries on
472-
# OSX. This helps executables find the libraries they depend on without
473-
# having to set the DYLD_LIBRARY_PATH environment variable.
474-
# The code below is all taken from the link below, and implements the
475-
# scenario "Always use full RPATH".
476-
# http://www.cmake.org/Wiki/CMake_RPATH_handling
477-
# Note: the RPATH won't succeed if the libraries are moved; in this case,
478-
# one will still need to set DYLD_LIBRARY_PATH (or alter the RPATH in the
479-
# executables/libraries that depend on Simbody's libraries).
480-
set(CMAKE_MACOSX_RPATH ON)
481-
482-
# Add the automatically determined parts of the RPATH
483-
# which point to directories outside the build tree to the install RPATH.
467+
# CMake 2.8.12 introduced the ability to set RPATH for shared libraries
468+
# on OSX. This helps executables find the libraries they depend on
469+
# without having to set the DYLD_LIBRARY_PATH environment variable.
470+
# See http://www.cmake.org/Wiki/CMake_RPATH_handling and `man dydl`.
471+
# We have attempted to make the RPATH work even if the
472+
# installation is relocated (using relative paths), but you may need to
473+
# use DYLD_LIBRARY_PATH (or alter the RPATH using install_name_tool) in
474+
# these cases.
475+
## On Linux, this variable has no effect.
476+
set(CMAKE_MACOSX_RPATH ON)
477+
478+
if(NOT OPENSIM_COPY_SIMBODY)
479+
# Add the automatically determined parts of the RPATH which point
480+
# to directories outside the build tree to the install RPATH.
481+
# If we are copying Simbody into OpenSim's installation, then
482+
# there's no need to link to the libraries in Simbody's original
483+
# installation. Furthermore, we may be distributing OpenSim to
484+
# other computers that will not have our original Simbody
485+
# installation, and so the RPATH would point to a nonexistant
486+
# directory on others' computers.
487+
# TODO handle copying BTK.
484488
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
489+
endif()
485490

486-
# The RPATH to be used when installing, but only if it's not a system
487-
# directory.
488-
list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES
489-
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" isSystemDir)
490-
if("${isSystemDir}" STREQUAL "-1")
491-
set(OPENSIM_USE_INSTALL_RPATH TRUE)
492-
endif()
491+
# Set RPATH so that OpenSim can find its own libraries, but only if
492+
# OpenSim is not installed into a system library directory.
493+
list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES
494+
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" isSystemDir)
495+
if("${isSystemDir}" STREQUAL "-1")
496+
set(OPENSIM_USE_INSTALL_RPATH TRUE)
493497
endif()
494498
endif()
495499
## Add rpath to the binaries on Linux.
@@ -522,6 +526,7 @@ if(WITH_BTK)
522526
include(${BTK_USE_FILE})
523527
add_definitions(-DWITH_BTK)
524528
CopyDependencyDLLsForWin(BTK ${BTK_INSTALL_PREFIX})
529+
# TODO this should be handled separately between macOS and Linux.
525530
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};${BTK_LIBRARY_DIRS}")
526531
endif()
527532

@@ -606,6 +611,7 @@ include_directories("${Simbody_INCLUDE_DIR}")
606611
# Copy files over from the Simbody installation.
607612
# ----------------------------------------------
608613
if(${OPENSIM_COPY_SIMBODY})
614+
# TODO copy BTK as well.
609615

610616
# Install Simbody headers into OpenSim installation.
611617
install(DIRECTORY "${Simbody_INCLUDE_DIR}/"

cmake/OpenSimMacros.cmake

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,38 @@ function(OpenSimAddLibrary)
123123
DESTINATION ${_INCLUDE_PREFIX}/${_INCLUDE_LIBNAME})
124124
endif()
125125

126+
# RPATH (so that libraries find library dependencies)
127+
if(${OPENSIM_USE_INSTALL_RPATH})
128+
# TODO @loader_path only makes sense on macOS, so we need to revisit
129+
# for Linux (use $ORIGIN).
130+
131+
set(run_path_list "\@loader_path/")
132+
# TODO if/when Simbody and BTK libraries are installed in their own
133+
# directories (not beside OpenSim libraries), we will have to add the
134+
# following (also for BTK; this commented code has not been tested):
135+
#if(${OPENSIM_COPY_SIMBODY})
136+
# file(RELATIVE_PATH lib_dir_to_install_dir
137+
# "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}"
138+
# "${CMAKE_INSTALL_PREFIX}")
139+
# # The location of Simbody's libraries within the Simbody root.
140+
# file(RELATIVE_PATH simbody_root_dir_to_simbody_lib_dir
141+
# "${SIMBODY_ROOT_DIR}" "${SIMBODY_LIB_DIR}")
142+
# )
143+
# # The location of Simbody's libraries relative to OpenSim's
144+
# # installation root (OPENSIM_INSTALL_SIMBODYDIR does not exist).
145+
# file(install_dir_to_simbody_lib_dir
146+
# "${OPENSIM_INSTALL_SIMBODYDIR}${simbody_root_dir_to_simbody_lib_dir}"
147+
# )
148+
# set(lib_dir_to_simbody_lib_dir
149+
# "${lib_dir_to_install_dir}${install_dir_to_simbody_lib_dir}")
150+
# list(APPEND run_path_list
151+
# "\@loader_path/${lib_dir_to_simbody_lib_dir}")
152+
#endif()
153+
# Use APPEND to include the BTK RPATH, set in CMAKE_INSTALL_RPATH.
154+
set_property(TARGET ${OSIMADDLIB_LIBRARY_NAME} APPEND PROPERTY
155+
INSTALL_RPATH "${run_path_list}"
156+
)
157+
endif()
126158

127159
# Testing.
128160
# --------
@@ -255,16 +287,16 @@ function(OpenSimAddApplication)
255287

256288
# RPATH (so that the executable finds libraries without using env. vars).
257289
if(${OPENSIM_USE_INSTALL_RPATH})
258-
# TODO @executable_path only makes sense on OSX, so if we use RPATH on
259-
# Linux we'll have to revisit.
290+
# TODO @executable_path only makes sense on macOS, so we need to revisit
291+
# for Linux (use $ORIGIN).
260292

261293
# bin_dir_to_install_dir is most likely "../"
262294
file(RELATIVE_PATH bin_dir_to_install_dir
263295
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}"
264296
"${CMAKE_INSTALL_PREFIX}")
265297
set(bin_dir_to_lib_dir
266298
"${bin_dir_to_install_dir}${CMAKE_INSTALL_LIBDIR}")
267-
set_target_properties(${OSIMADDAPP_NAME} PROPERTIES
299+
set_property(TARGET ${OSIMADDAPP_NAME} APPEND PROPERTY
268300
INSTALL_RPATH "\@executable_path/${bin_dir_to_lib_dir}"
269301
)
270302
endif()

0 commit comments

Comments
 (0)