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

Do not include ROOT's CMake "use" file to avoid potential nlohmann_json conflicts #556

Merged
merged 2 commits into from
Nov 23, 2022

Conversation

drbenmorgan
Copy link
Contributor

ROOT's "use" file for CMake executes CMake include_directories, link_directories and add_definitions as well as appending to CMAKE_CXX_FLAGS among others. The primary issue here is the use of include_directories, which

  • adds -I rather than -isystem paths to compile commands
  • mixes these with project-local setttings (in Celeritas, the ROOT path appears before anything else)
  • flags appear in all subsequent compilations at the same directory scope any further subdirectories

This was observed to cause an issue at link time for Celeritas programs using nlohmann_json, where the found ROOT install was using a builtin nlohmann_json of different version to that found by CMake. The above scoped injection of the ROOT include path meant that different nlohmann_json headers were used at library and application compile time resulting in undefined symbol errors when linking.

Whilst that's fundamentally an issue with the install of ROOT I was building against (to be fixed!), Celeritas does not appear to need the use file. ROOT's CMake config file should include ROOTMacros.cmake for the dictionary generation, and usage requirements should be propagated through the imported targets. I've removed inclusion of ROOT's use file from Celeritas build scripts in this PR, and builds appear o.k. both on macOS and CentOS with different ROOT installs, however, let's see if CI throws up any issues.

ROOT's "use" file executes CMake {include,link}_directories as well
as appending to CMAKE_CXX_FLAGS and executing add_definitions. The
primary issue here is the use of include_directories, which

- adds "-I" rather than "-isystem" paths to compile commands
- mixes these with project-local setttings
- flags appear in all subsequent compilations at the same directory
  scope any further subdirectories

This was observed to cause an issue at link time for Celeritas programs
using nlohmann_json, where the found ROOT had been installed with a
builtin nlohmann_json of different version to that found by CMake. The
above scoped injection of the ROOT include path meant that different
nlohmann_json headers were used at library, application compile time
resulting in undefined symbol errors.

Remove inclusion of ROOT's use file from Celeritas build scripts.
ROOTConfig.cmake, and hence find_package(ROOT) now set up the needed
CMAKE_MODULE_PATH and other ROOT-related variables with relevant compile
options propagated through target usage requirements.
@sethrj
Copy link
Member

sethrj commented Nov 23, 2022

Weird, thanks @drbenmorgan . I thought including this file was necessary to get the ROOT macros to load (since it seems like the path to that file might be an implementation detail?). If this works, then great! and we could even move it outside the function, which I created mainly to avoid propagating the other variables/includes/etc.

@drbenmorgan
Copy link
Contributor Author

Hi @sethrj, indeed I think it was necessary in older ROOT versions, but current versions include the ROOTMacros.cmake file in ROOTConfig.cmake. Given that is version dependent, I can go back through ROOT versions to find the minimum needed for this behaviour if you think that's needed.

@@ -140,7 +140,6 @@ if(CELERITAS_USE_ROOT)
# Call the ROOT library generation inside a function to prevent ROOT-defined
# directory properties from escaping
Copy link
Member

Choose a reason for hiding this comment

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

Since this no longer applies, and the function is only called once (just for this purpose), can you delete the function and just inline the content?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in latest commit - the use of include_directories is safe in the sense it's only adding project local paths, as is the setting of CMAKE_LIBRARY_OUTPUT_DIRECTORY.

Longer term, I think use of include_directories can be removed completely if this code block is moved after the declaration of the celeritas target. ROOT will then pick up usage requirements from the target. However, that will require a celeritas_target_sources command analogous to target_sources to add the object lib to celeritas afterwards. Best done as/when that functionality becomes needed more widely.

@sethrj
Copy link
Member

sethrj commented Nov 23, 2022

If the CI works, then it's an "old enough" change for me. We're going to have to build with relatively recent versions of vecgeom etc., so we shouldn't worry too much about compatibility with older software.

Use of a function to hide ROOT setting directory properties is now
redundant as ROOT "use" file no longer included.

Inline function code in script, removing/updating function variables
as needed.
@drbenmorgan
Copy link
Contributor Author

drbenmorgan commented Nov 23, 2022

Just for reference after a bit more digging, this occurred when building Celeritas on macOS against a Homebrew stack with ROOT 6.26/06. That still uses a builtin nlohmann_json as Homebrew haven't yet patched for root-project/root#11130 and root-project/root#11312, whilst Spack have. Once there's a version bump in Homebrew to ROOT 6.26/08, that should be fixable. Edit: coming soon, including removal of builtin nlohmann_json: Homebrew/homebrew-core#114543

Copy link
Member

@sethrj sethrj left a comment

Choose a reason for hiding this comment

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

Thanks @drbenmorgan !

@sethrj sethrj merged commit 2519121 into celeritas-project:master Nov 23, 2022
@sethrj sethrj added core Software engineering infrastructure bug Something isn't working labels Nov 23, 2022
@drbenmorgan drbenmorgan deleted the no-root-include-file branch November 24, 2022 11:27
@sethrj sethrj added external Dependencies and framework-oriented features and removed core Software engineering infrastructure labels Feb 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working external Dependencies and framework-oriented features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants