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

Fix the rpath with option - plugins fail without #5298

Merged
merged 10 commits into from
Feb 14, 2025

Conversation

byrnHDF
Copy link
Contributor

@byrnHDF byrnHDF commented Feb 6, 2025

Fixes issue #5297 Removal of rpath breaks plugins by restoring the necessary rpath changes

@byrnHDF byrnHDF added Priority - 2. Medium ⏹ It would be nice to have this in the next release Component - Build CMake, Autotools Type - Bug / Bugfix Please report security issues to help@hdfgroup.org instead of creating an issue on GitHub Type - Improvement Improvements that don't add a new feature or functionality labels Feb 6, 2025
@byrnHDF byrnHDF self-assigned this Feb 6, 2025
@@ -458,6 +458,21 @@ macro (HDF_DIR_PATHS package_prefix)
endif ()
message(STATUS "Final: ${${package_prefix}_INSTALL_DOC_DIR}")

# Define the needed INSTALL_RPATH for HDF Standard binary packages
option (HDF5_SET_DEFAULT_RPATH "Set the default RPATH for the common installation" OFF)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why again with even more options? Better solutions were given in the related issue in the first place, including never overriding CMAKE_INSTALL_RPATH.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because it would require multiple options with STRING attributes to be on the command line when one option just does it correctly.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I get the convenience aspect, but really the command-line options should pretty much be the standard way. Plus, if you turn this option on we're back to overriding what may have been desired to be passed in from the user, in addition to what we're setting.

Are we really sure that modifying the rpath is absolutely necessary and that we aren't doing something wrong here in the first place?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, modifying the rpath gives the app/lib an expected search path

@@ -43,6 +43,8 @@ set (HDF5_MINGW_STATIC_GCC_LIBS ON CACHE BOOL "Statically link libgcc/libstdc++"
set (HDF5_ALLOW_EXTERNAL_SUPPORT "TGZ" CACHE STRING "Allow External Library Building (NO GIT TGZ)" FORCE)
set_property (CACHE HDF5_ALLOW_EXTERNAL_SUPPORT PROPERTY STRINGS NO GIT TGZ)

set (HDF5_SET_DEFAULT_RPATH ON "Set the default RPATH for the common installation" FORCE)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Presumably this is just going to be a problem for ccmake builds since the cacheinit file isn't necessarily going to be used.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why? ccmake could use the presets file and I will have a a followup PR that adds the dependent_option form to all options that are behind another option.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd say for the average user building from source there really is no reason to use the presets, cacheinit, etc. files. The default configuration you get when just running ccmake on a build directory should be the happy path.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The defaults should build a limited but workable solution. cacheinit.cmake is mostly for our testing as the settings match our expected/typical build. presets are useful for use cases.

release_docs/RELEASE.txt Outdated Show resolved Hide resolved
option (HDF5_BUILD_WITH_INSTALL_NAME "Build with library install_name set to the installation path" OFF)
if (HDF5_BUILD_WITH_INSTALL_NAME)
set_target_properties (${libtarget} PROPERTIES
INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib"
Copy link
Contributor

@haampie haampie Feb 8, 2025

Choose a reason for hiding this comment

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

This is not immediately related to the issue, is it? The default install name as of CMake 3.0 is @rpath/lib<name>.dylib (before it was lib<name>.dylib). When users link against the library, it copies the install name @rpath/lib<name>.dylib as a load command, so rpaths set by the user in the dependent executable/library are respected when searching for libhdf5.dylib at runtime. Then the situation is exactly the same as on Linux, where users also have to set an rpath. If you set it to an absolute path, then rpaths no longer work, and the library is always opened directly by absolute path (not relocatable). So, bit unclear why this is added now, and why the apple situation should be different from linux.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was added as it was previously removed - can be removed if some apple developer knows this is not needed.

if (HDF5_BUILD_WITH_INSTALL_NAME)
set_target_properties (${libtarget} PROPERTIES
INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib"
BUILD_WITH_INSTALL_RPATH ${HDF5_BUILD_WITH_INSTALL_NAME}
Copy link
Contributor

@haampie haampie Feb 8, 2025

Choose a reason for hiding this comment

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

Why BUILD_WITH_INSTALL_RPATH?

Copy link
Contributor Author

@byrnHDF byrnHDF Feb 10, 2025

Choose a reason for hiding this comment

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

Definition:


BUILD_WITH_INSTALL_RPATH is a boolean specifying whether to link the target in the build tree with the INSTALL_RPATH. This takes precedence over SKIP_BUILD_RPATH and avoids the need for relinking before installation.

This property is initialized by the value of the CMAKE_BUILD_WITH_INSTALL_RPATH variable if it is set when a target is created.

If policy CMP0068 is not NEW, this property also controls use of INSTALL_NAME_DIR in the build tree on macOS. Either way, the BUILD_WITH_INSTALL_NAME_DIR target property takes precedence.


Eliminating this option then just forces the change onto the user?

Copy link
Contributor

@haampie haampie Feb 10, 2025

Choose a reason for hiding this comment

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

I guess the idea of adding these lines was to use $ORIGIN/.. style relative rpaths also during the build? (But then why if (APPLE)?) That I think is redundant, cause cmake sets build specific rpaths for any target you're linking, including the path to just-built libhdf5.dylib. CMake knows better where executables and libraries are located relatively during the build, and it may differ from where they are upon install, so using install rpath during the build is not helpful.

If you don't set anything related to build rpaths, and you need to run a just-built executable as part of the build (before install), cmake ensures that these executables can find their libraries. If you meddle with it, then maybe not.

I think the only case where you may benefit from setting build rpaths yourself is when you run just-built executables during the build that dlopen(...) just-built libraries that cmake is not aware of as part of target_link_libraries.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Like the plugins.

I'm not aware of it's use by us in our CI. However, I also don't develop with macs either.
It is one of those long-ago implemented options, that just get brought along. I put it back, along with the other code to fix CI and plugins, but maybe it wasn't necessary?

Comment on lines 464 to 465
"@executable_path/../${${package_prefix}_INSTALL_LIB_DIR}"
"@executable_path/"
Copy link
Contributor

@haampie haampie Feb 8, 2025

Choose a reason for hiding this comment

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

I think @executable_path is redundant. You want to resolve libraries relative to the current binary right? Then @loader_path should suffice.

Copy link
Contributor Author

@byrnHDF byrnHDF Feb 10, 2025

Choose a reason for hiding this comment

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

In general, @loader_path is preferred over @executable_path, as it allows embedded frameworks to work in both an executable and a bundle, plugin, or sub-framework. The only downside is that @loader_path requires 10.4 or newer. If you're on 10.5 or newer, @rpath is even better than @loader_path.

I ran across this statement, which seems to just make things more confusing! Even though we only test on the latest two versions of MAC, forcing a single setting could cause someone problems. However, 10.5 is pretty old and maaybe it should just be @rpath?

Copy link
Contributor

@haampie haampie Feb 10, 2025

Choose a reason for hiding this comment

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

Hm, I don't think the statement is entirely correct, in the sense that the one does not replace the other 🤔.

If you have libhdf5.dylib, the cmake "trick" is to set its install name to @rpath/libhdf5.dylib.

Then an executable or library that links against libhdf5.dylib will register @rpath/libhdf5.dylib as a needed library (LC_LOAD_DYLIB load command). If it additionally sets @loader_path/../lib as an rpath (LC_RPATH load command), then that value may be substituted for @rpath.

That way, after substitution: @rpath/libhdf5.dylib -> @loader_path/../lib/libhdf5.dylib -> $(dirname /path/to/binary)/../lib/libhdf5.dylib is a search path.

The main difference between linux and macOS is that for rpaths to "work" you need to opt-in by marking the needed library as @rpath/<name>. Otherwise I think @loader_path can be taken as equivalent to $ORIGIN on Linux. CMake enables this "opt-in" by default. And yeah, macOS 10.14 is pretty much just for retro apple machines.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So the suggestion then is to only use "@loader_path" ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, that + requiring cmake 3.0 should give equivalent behavior as on linux.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay - will do.

@lrknox
Copy link
Collaborator

lrknox commented Feb 12, 2025

Builds and passes tests with zlib, libaec and hdf5_plugins on macOS 15.3.

lrknox
lrknox previously approved these changes Feb 12, 2025
@byrnHDF
Copy link
Contributor Author

byrnHDF commented Feb 13, 2025

Just ran across this somewhat related question on the CMake discourse. https://discourse.cmake.org/t/question-re-cmake-build-with-install-rpath/13568
Might be just a Ninja issue, though.

@lrknox lrknox merged commit d4200dc into HDFGroup:develop Feb 14, 2025
77 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component - Build CMake, Autotools Priority - 2. Medium ⏹ It would be nice to have this in the next release Type - Bug / Bugfix Please report security issues to help@hdfgroup.org instead of creating an issue on GitHub Type - Improvement Improvements that don't add a new feature or functionality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants