Description
I'm having issues building a legacy plugin against the official release of OpenSim 4.2. The codebase pulls in OpenSim via a standard CMake find_package
and configures + compiles fine, but can't link because:
make[2]: *** No rule to make target `/Applications/Xcode_12.4.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk/System/Library/Frameworks/Accelerate.framework', needed by `libReflexControllersPlugin.dylib'. Stop.
make[1]: *** [CMakeFiles/ReflexControllersPlugin.dir/all] Error 2
make: *** [all] Error 2
Despite the plugin only referring to OpenSim+Simbody directly. My dev laptop does not have XCode installed (XCode isn't a requirement for building C/C++ on a Macbook). Even if it were installed, it is unlikely that it would be the same version as what is being looked for (12.4
) because Apple have subsequently released 13
:
https://developer.apple.com/xcode/
The issue is that the as-released OpenSim 4.2 SDK now contains hardcoded absolute paths in the CMake files. You can grep -ri 'Applications/
in sdk/
to see all occurrences:
Simbody/lib/cmake/simbody/SimbodyTargets-release.cmake: IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE "/Applications/Xcode_12.4.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk/System/Library/Frameworks/Accelerate.framework;/Applications/Xcode_12.4.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk/System/Library/Frameworks/Accelerate.framework;-lm;-ldl;dl;m"
Simbody/lib/cmake/simbody/SimbodyTargets-release.cmake: IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE "SimTKcommon;/Applications/Xcode_12.4.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk/System/Library/Frameworks/Accelerate.framework;/Applications/Xcode_12.4.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk/System/Library/Frameworks/Accelerate.framework;-lm;-ldl;dl;m"
Simbody/lib/cmake/simbody/SimbodyTargets-release.cmake: IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE "SimTKmath;SimTKcommon;/Applications/Xcode_12.4.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk/System/Library/Frameworks/Accelerate.framework;/Applications/Xcode_12.4.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk/System/Library/Frameworks/Accelerate.framework;-lm;-ldl;dl;m"
include/casadi/config.h:#define CASADI_COMPILER "/Applications/Xcode_12.4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++" // NOLINT(whitespace/line_length)
Binary file lib/libosimCommon.dylib matches
Binary file lib/libcasadi.dylib matches
Binary file lib/libcasadi.3.6.dylib matches
Where IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE
will force all downstream projects (e.g. the plugin) to search for the (non-existent) hard-coded path. This is probably not desired, because the library should be transitively dynamically loaded when dynamically loading SimTKcommon
.
SimTKcommon
, itself, seems to link the Accelerate
framework in a version-agnostic, probably-binary-portable, way:
/Applications % otool -L OpenSim\ 4.2/sdk/Simbody/lib/libSimTKcommon.3.8.dylib
OpenSim 4.2/sdk/Simbody/lib/libSimTKcommon.3.8.dylib:
@rpath/libSimTKcommon.3.8.dylib (compatibility version 3.8.0, current version 0.0.0)
/System/Library/Frameworks/Accelerate.framework/Versions/A/Accelerate (compatibility version 1.0.0, current version 4.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1292.60.1)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 904.4.0)
As does libosimCommon
:
otool -L OpenSim\ 4.2/sdk/lib/libosimCommon.dylib
OpenSim 4.2/sdk/lib/libosimCommon.dylib:
@rpath/libosimCommon.dylib (compatibility version 0.0.0, current version 0.0.0)
@rpath/libSimTKsimbody.3.8.dylib (compatibility version 3.8.0, current version 0.0.0)
@rpath/libezc3d.dylib (compatibility version 0.0.0, current version 0.0.0)
@rpath/libSimTKmath.3.8.dylib (compatibility version 3.8.0, current version 0.0.0)
@rpath/libSimTKcommon.3.8.dylib (compatibility version 3.8.0, current version 0.0.0)
/System/Library/Frameworks/Accelerate.framework/Versions/A/Accelerate (compatibility version 1.0.0, current version 4.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1292.60.1)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 904.4.0)
(The grep
hits for Applications/
above in the binaries seem to be because the compiler command was saved into the binary itself as /Applications/Xcode_12.4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
and have nothing to do with linking)
I have no idea why libosimCommon
is correctly linking Accelerate
. It would imply that OpenSim, itself, is locating Accelerate, or that OpenSim links to simbody slightly differently from how a typical find_package
command works. The problem is that any downstream dev using find_package
against OpenSim 4.2
will run into this problem.
The (extremely hacky) solution is to delete the IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE
lines in the `cmake files when building. They're not necessary because OpenSim/simbody will link the libraries transitively anyway.
This may be an upstream (simbody) issue, rather than an OpenSim one. It depends on how locating Accelerate
is handled in either project (e.g. if it is overwritten with an environment variable in OpenSim's release build then it's not entirely simbody's issue).