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

Rework CMake code for v3.0.0. #897

Merged
merged 3 commits into from
Feb 14, 2024
Merged

Rework CMake code for v3.0.0. #897

merged 3 commits into from
Feb 14, 2024

Conversation

1uc
Copy link
Collaborator

@1uc 1uc commented Dec 18, 2023

This PR develops the next version of HighFive's CMake code. The ideas are:

  • Avoid one flag for each per optional dependency (other than testing and examples).
  • Use targets only.

Copy link

codecov bot commented Dec 18, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (f71c7c4) 85.75% compared to head (64e27c1) 84.55%.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #897      +/-   ##
==========================================
- Coverage   85.75%   84.55%   -1.21%     
==========================================
  Files          89       86       -3     
  Lines        5695     5220     -475     
==========================================
- Hits         4884     4414     -470     
+ Misses        811      806       -5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@1uc 1uc added the v3 Anything that needs to be resolved before `v3`. label Dec 18, 2023
CMakeLists.txt Outdated Show resolved Hide resolved
CMakeLists.txt Outdated Show resolved Hide resolved
CMakeLists.txt Show resolved Hide resolved
cmake/HighFiveWarnings.cmake Outdated Show resolved Hide resolved
tests/unit/tests_high_five_base.cpp Outdated Show resolved Hide resolved
@1uc
Copy link
Collaborator Author

1uc commented Dec 19, 2023

Currently, there's two interesting things. First:

find_package(HighFive)
target_link_libraries(foo PUBLIC HighFive)

still works, if one doesn't use any optional dependencies. If one does, it'll requires changes to the source code, but not the build-system.

Second: we don't provide code to link to optional dependencies. The argument is that if a library has dependency on, say, Boost, then they already have requirement to do -I${BOOST_DIR}/include and -L${BOOST_DIR}/lib -lboost (or whatever the commands are) even if they don't use HighFive. Hence, we could leave it to them to set it up correctly. Not including the dependencies has advantages, because users are free to pick how it work. For example when they vendor their other optional dependencies find_dependency(Boost) might do the wrong thing.

The question is should we help them? One could by doing the following:

find_package(HighFive COMPONENTS boost)
target_link_libraries(foo PUBLIC HighFive::HighFive HighFive::boost)

The COMPONENTS boost triggers the find_dependency(boost) and HighFive::boost triggers adding -I and -L as needed for the boost dependencies.

@1uc 1uc force-pushed the 1uc/rework-cmake branch 4 times, most recently from 701309b to 1d8ab03 Compare December 19, 2023 16:04
@1uc
Copy link
Collaborator Author

1uc commented Dec 20, 2023

AFAICT one one pitfall is that pHDF5 requires linking to MPI, i.e.

target_link_libraries(HighFive INTERFACE HDF5::HDF5)
if(HDF5_IS_PARALLEL)
  find_package(MPI)
  target_link_libraries(HighFive INTERFACE MPI::MPI_C MPI::MPI_CXX)
endif()

However, now the target HighFive uses the MPI target when on the build machine the HDF5 version happened to be pHDF5. This is why we're using $<BUILD_INTERFACE:MPI::MPI_C>.

@1uc
Copy link
Collaborator Author

1uc commented Dec 22, 2023

Second: we don't provide code to link to optional dependencies.

I'm increasingly convinced that attempting to find and link optional dependencies will likely end up incorrect under too many circumstances. IIUC the Boost ecosystem seems to have not yet settled on a set of commands that works pretty much anywhere. OpenCV has targets, but doesn't document them AFAICT. Even if we did use its targets, they might change them in a manner that's not compatible with our CMake, which seems fair because the project is telling us to not use them. Moreover, we'd probably only include a very small subset of the library and users would almost certainly want more. Same argument for Boost.

Not using targets has issues as documented here:
https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#creating-relocatable-packages

@1uc 1uc force-pushed the 1uc/rework-cmake branch 2 times, most recently from cc3d00b to 7640eda Compare February 9, 2024 10:48
@1uc 1uc marked this pull request as ready for review February 9, 2024 10:50
Please consult `README.md`, the migration guide and
`test/cmake_integration` for information about what changed.
if(HIGHFIVE_TEST_XTENSOR)
set(CMAKE_CXX_STANDARD 14)
else()
set(CMAKE_CXX_STANDARD 11)
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this get updated now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That's been prepped in the other PR: #957.

cmake/HighFiveConfig.cmake Show resolved Hide resolved
tests/cmake_integration/application/deps/HighFive Outdated Show resolved Hide resolved
README.md Outdated
Comment on lines 212 to 213
# Alternatively:
# add_subdirectory(third_party/HighFive)
Copy link
Collaborator

Choose a reason for hiding this comment

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

It might not be crystal clear that this is an alternative for find_package

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thank you, we just spent the two immediately preceding subsections explaining the difference.

@tdegeus
Copy link
Collaborator

tdegeus commented Feb 13, 2024

Thanks. It seems fair to simply strip third-party dependencies from the target and leave it up to the user. To stay uniform, the defines should be removed everywhere, incl. from H5Easy.

@1uc
Copy link
Collaborator Author

1uc commented Feb 13, 2024

To stay uniform, the defines should be removed everywhere, incl. from H5Easy.

I've spotted this. Solving this nicely kinda requires stripping out all the logic in H5Easy and move everything XTensor and Eigen related into core. After that H5Easy would do very little just a light API change.

The problem is that XTensor doesn't have a compile time constant rank. Which is a non-issue when implemented Easy-style. When we want to move it into the inspector it starts messing with deduction of rank, which becomes an issue with empty arrays and also messes with the "broad-casting" feature. Additionally, the not related issue of string vs arrays of character which cause stripping of dimensions doesn't make that part of the code any easier to understand.

I've mildly come to peace with the idea that Easy is "easy" and opinionated. Therefore, it continues to guess the presence of libraries by checking the existence of dependency related macros.

OTOH, it would be nice to make Easy just a light API change.

@tdegeus
Copy link
Collaborator

tdegeus commented Feb 13, 2024

To stay uniform, the defines should be removed everywhere, incl. from H5Easy.

I've spotted this. Solving this nicely kinda requires stripping out all the logic in H5Easy and move everything XTensor and Eigen related into core. After that H5Easy would do very little just a light API change.

The problem is that XTensor doesn't have a compile time constant rank. Which is a non-issue when implemented Easy-style. When we want to move it into the inspector it starts messing with deduction of rank, which becomes an issue with empty arrays and also messes with the "broad-casting" feature. Additionally, the not related issue of string vs arrays of character which cause stripping of dimensions doesn't make that part of the code any easier to understand.

I've mildly come to peace with the idea that Easy is "easy" and opinionated. Therefore, it continues to guess the presence of libraries by checking the existence of dependency related macros.

OTOH, it would be nice to make Easy just a light API change.

A simpler idea is to make the defines 'private' and have a uniform API:

# include <highfive/eigen.hpp>
# include <highfive/xtensor.hpp>
# include <highfive/H5easy.hpp>

One could then statically assert on features not (yet) in the core. This would simplify the API, I think.

I am not quite up to speed with the templated rank issue. I think it is a separate issue, though.
(That being said: highfive is header-only, it is fine to have templated features??)

@1uc
Copy link
Collaborator Author

1uc commented Feb 13, 2024

Let's track the H5Easy related questions in a different issue/PR. They don't prevent us from merging this as it is; and sort H5Easy separately.

@1uc 1uc merged commit 2877159 into master Feb 14, 2024
36 checks passed
@1uc 1uc deleted the 1uc/rework-cmake branch February 14, 2024 16:06
@1uc 1uc mentioned this pull request Feb 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
v3 Anything that needs to be resolved before `v3`.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants