-
Notifications
You must be signed in to change notification settings - Fork 18
Fix CMake export and include interfaces #181
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
base: main
Are you sure you want to change the base?
Conversation
- Add install/export rules for PETSIRD targets - Provide PETSIRDConfig.cmake and version file - Fix include directories using BUILD/INSTALL interfaces - Export PETSIRD::petsird target for find_package() - Prepare PETSIRD for external consumers (STIR -- this has been going on for a while )
for more information, see https://pre-commit.ci
|
Finally, this took me 2 week of bouncing around and many problems in STIR: Very brief summary. This PR fixes PETSIRD integration issues by properly exporting PETSIRD as a CMake package instead of relying on in-tree submodule builds. Specifically, it: ⸻ Background / Motivation PETSIRD was previously consumed via a submodule and built inside STIR, which caused: These issues became visible once CI enabled stricter sanitizers and newer compilers. Exporting PETSIRD as a proper CMake package ensures a single canonical definition of all PETSIRD/STIR types across the entire build. |
|
Further to the previous posts, While PETSIRD built correctly on my PC, it failed when used as an external dependency in CI. Several independent problems linked.
Fixes:
|
KrisThielemans
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the export is a good idea. It'll also make it easier for putting on conda etc. However, I think it'd be best to export 2 targets: PETSIRD::generated and PETSIRD::helpers.
Potentially, we should INSTALL the examples.
And I guess we need a simple CI test for this as well. sorry.
cpp/helpers/CMakeLists.txt
Outdated
| find_package(xtensor-blas REQUIRED) | ||
| find_package(xtensor REQUIRED) | ||
| # find_package(xtensor-blas REQUIRED) | ||
| find_package(BLAS REQUIRED) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree.
geometry.huses
#include <xtensor-blas/xlinalg.hpp>
helpersdepends ongenerated, which hasWe don't usefind_package(xtensor ${XTENSOR_MINIMUM_VERSION} REQUIRED)
BLASdirectly.xtensor-blaswill requirextensor(and I see no reason we need its variables, see below)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I commented out xtensor-blas because of an unwanted lxtensor linkage (When linking with STIR, in a conda environemet I was gettign a lxtensor ), but that’s a packaging issue. I will bring this back now and see how it goes. Maybe other changes resolved this.
cpp/helpers/CMakeLists.txt
Outdated
|
|
||
| target_include_directories(petsird_helpers | ||
| INTERFACE | ||
| ${xtensor_INCLUDE_DIRS} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should not be necessary. Depending on xtensor-blas should take care of this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See the comment before. Xtensor is headers only, but somehow STIR, for example:
| collect2: error: ld returned 1 exit status
| gmake[2]: *** [src/test/numerics/CMakeFiles/test_IR_filters.dir/build.make:121: src/test/numerics/test_IR_filters] Error 1
| gmake[1]: *** [CMakeFiles/Makefile2:8070: src/test/numerics/CMakeFiles/test_IR_filters.dir/all] Error 2
| gmake[1]: *** Waiting for unfinished jobs....
/root/micromamba/envs/yardl/bin/ld: cannot find -lxtensor: No such file or directory
| collect2: error: ld returned 1 exit status
| gmake[2]: *** [src/test/numerics/CMakeFiles/test_BSplines.dir/build.make:121: src/test/numerics/test_BSplines] Error 1
| gmake[1]: *** [CMakeFiles/Makefile2:8102: src/test/numerics/CMakeFiles/test_BSplines.dir/all] Error 2```
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have to note that the error in the comment above was just an instance of a torrent of similar problems.
| foreach(t petsird petsird_generated petsird_helpers) | ||
| if(TARGET ${t}) | ||
| get_target_property(_libs ${t} INTERFACE_LINK_LIBRARIES) | ||
| if(_libs) | ||
| list(FILTER _libs EXCLUDE REGEX "xtensor") | ||
| set_target_properties(${t} | ||
| PROPERTIES INTERFACE_LINK_LIBRARIES "${_libs}") | ||
| endif() | ||
| endif() | ||
| endforeach() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why did you need this? (probably because you removed target_link_libraries)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To undo an overly-aggressive dependency propagation introduced by generated / helper targets.
xtensor is header-only
However… Some targets propagate xtensor via INTERFACE_LINK_LIBRARIES
Something like:
INTERFACE_LINK_LIBRARIES xtensor::xtensor
This becomes a real problem in STIR / STIR2PETSIRD. Header-only deps should not force downstream linking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As long as xtensor is header-only, we could use the same trick as https://github.com/UCL/STIR/blob/ec3a5670f9b63cb10f4bebce6edf22d6f028a6fb/src/buildblock/CMakeLists.txt#L125-L137, i.e. only add the include path.
However, this is all quite ugly. I'd rather avoid it as much as possible.
As long as we have find_dependency(xtensor) in the Config.cmake, there should be no problem
cpp/CMakeLists.txt
Outdated
| date::date | ||
| ) | ||
|
|
||
| target_compile_features(petsird PUBLIC cxx_std_17) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting. Do we have to do this explicitly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought it would be a good idea. idk? Initially I was getting many mysterious compiler errors and tried to cover all bases.
NikEfth
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will try step-by-step to bring lxtensor-blas back and see when linking becomes an issue.
cpp/helpers/CMakeLists.txt
Outdated
|
|
||
| target_include_directories(petsird_helpers | ||
| INTERFACE | ||
| ${xtensor_INCLUDE_DIRS} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have to note that the error in the comment above was just an instance of a torrent of similar problems.
| foreach(t petsird petsird_generated petsird_helpers) | ||
| if(TARGET ${t}) | ||
| get_target_property(_libs ${t} INTERFACE_LINK_LIBRARIES) | ||
| if(_libs) | ||
| list(FILTER _libs EXCLUDE REGEX "xtensor") | ||
| set_target_properties(${t} | ||
| PROPERTIES INTERFACE_LINK_LIBRARIES "${_libs}") | ||
| endif() | ||
| endif() | ||
| endforeach() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To undo an overly-aggressive dependency propagation introduced by generated / helper targets.
xtensor is header-only
However… Some targets propagate xtensor via INTERFACE_LINK_LIBRARIES
Something like:
INTERFACE_LINK_LIBRARIES xtensor::xtensor
This becomes a real problem in STIR / STIR2PETSIRD. Header-only deps should not force downstream linking.
|
@KrisThielemans I am about to finish the CI yml and I think I have to apologize but my yml skill are not as good as yours (or @casperdcl ) and I make just as typing commands in the terminal :) I could not modify yours successfully, running to all sort of issues. Have a look at mine and let me know if I can improve. |
Co-authored-by: Kris Thielemans <[email protected]>
Co-authored-by: Kris Thielemans <[email protected]>
Co-authored-by: Kris Thielemans <[email protected]>
Export 2 targets: PETSIRD::generated and PETSIRD::helpers and PETSIRD as interface target. Reverted Xtesnor dependency
KrisThielemans
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no idea what you tried to change in CI. I see you use APT, but then conda anyway. I see no fantastic reason to try and avoid conda for the moment. (There's microsoft/yardl#154)
I can't see anything else in the ci.yml that we immediately need for testing functionality of this PR.
I'd therefore suggest to revert ci.yml, but maybe I'm missing something.
Instead, I think we need to do a "ninja install" and add a new step which then links an independent program that against the installed version to test (similar to what we do for the STIR example here).
Maybe we can create cpp/example/ (or examples/cpp I suppose) with a cut-down version of the analysis.cpp.
I can do that, if you prefer.
| PETSIRD::helpers | ||
| ) | ||
|
|
||
| target_compile_features(petsird INTERFACE cxx_std_17) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like this is set minimum version, and is therefore useful, see https://stackoverflow.com/questions/70667513/cmake-cxx-standard-vs-target-compile-features and in particular https://stackoverflow.com/questions/70667513/cmake-cxx-standard-vs-target-compile-features#comment135186815_70667652
However, probably should be added to the generated library already. (In fact, should be in the generated CMakeLists.txt)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
microsoft/yardl#261. but we can still add it ourselves
| foreach(t petsird petsird_generated petsird_helpers) | ||
| if(TARGET ${t}) | ||
| get_target_property(_libs ${t} INTERFACE_LINK_LIBRARIES) | ||
| if(_libs) | ||
| list(FILTER _libs EXCLUDE REGEX "xtensor") | ||
| set_target_properties(${t} | ||
| PROPERTIES INTERFACE_LINK_LIBRARIES "${_libs}") | ||
| endif() | ||
| endif() | ||
| endforeach() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As long as xtensor is header-only, we could use the same trick as https://github.com/UCL/STIR/blob/ec3a5670f9b63cb10f4bebce6edf22d6f028a6fb/src/buildblock/CMakeLists.txt#L125-L137, i.e. only add the include path.
However, this is all quite ugly. I'd rather avoid it as much as possible.
As long as we have find_dependency(xtensor) in the Config.cmake, there should be no problem
|
I had to change the CI, because I could not make it to compile yardl. I tried. If you can tell me how to make this work, I am happy to revert.
I do this quite extensively in STIR and STIR2PETSIRD. But, sure we can do it here, too. |
Changes in this pull request
When PETSIRD is used as a subproject and exported by a parent project, CMake
requires that exported targets do not reference source-tree paths and that all
public dependencies are also exported.
This PR fixes those issues while keeping standalone PETSIRD builds unchanged.
Related issues
Checklist before requesting a review
Please tick the following: