Skip to content

rootcling emits #include "execution_defs.h" for a selected header that includes <algorithm>, and the generated dictionary then fails to compile #23640

Open

Description

@olantwin

Check duplicate issues.

  • Checked for duplicates

Description

When a header selected for dictionary generation includes <algorithm>,
rootcling adds

#include "execution_defs.h"

to the generated dictionary. The file it means is libstdc++'s parallel-algorithms
header, which on this installation lives at

$PREFIX/lib/gcc/x86_64-conda-linux-gnu/15.3.0/include/c++/pstl/execution_defs.h

so the correct spelling would be pstl/execution_defs.h. Nothing puts
.../include/c++/pstl on the include path when the dictionary is compiled, so
the basename does not resolve and the build stops:

G__Thing.cxx:54:10: fatal error: execution_defs.h: No such file or directory
   54 | #include "execution_defs.h"
      |          ^~~~~~~~~~~~~~~~~~
compilation terminated.

The include lands in the "Header files passed as explicit arguments" block,
among the ROOT headers rootcling appends for the entities the generated code
references:

// Header files passed as explicit arguments
#include "Thing.hpp"
#include "RtypesCore.h"
#include "strtok.h"
...
#include "TVersionCheck.h"
#include "RVersion.h"
#include "execution_defs.h"

Every other entry there is a basename that resolves because ROOT's include
directory is on the dictionary's include path and those headers sit at its top
level. execution_defs.h is one directory down inside include/c++, so the
basename is not enough to find it.

Nothing in the selected class uses anything from <algorithm>. The include
alone is enough.

Expected behaviour

Either rootcling does not reference an internal libstdc++ implementation header
in the generated dictionary at all, or it emits a spelling that resolves from
the include directories the dictionary is compiled with, i.e.
pstl/execution_defs.h.

Reproducer

Thing.hpp:

#pragma once
#include <algorithm>
struct Thing {
  int value{0};
};

LinkDef.h:

#ifdef __CLING__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ class Thing+;
#endif

Generate and compile. The -compilerI flags below are the ones
root_generate_dictionary passes from CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES;
they are given explicitly here so the reproducer does not need CMake.

P=$CONDA_PREFIX/lib/gcc/x86_64-conda-linux-gnu/15.3.0/include/c++

rootcling -f G__Thing.cxx \
  -compilerI$P \
  -compilerI$P/x86_64-conda-linux-gnu \
  -compilerI$P/backward \
  -compilerI$CONDA_PREFIX/include \
  -I. Thing.hpp LinkDef.h

grep -n execution_defs G__Thing.cxx
# 54:#include "execution_defs.h"

x86_64-conda-linux-gnu-c++ -std=c++23 -fPIC -I. -I$CONDA_PREFIX/include \
  -c G__Thing.cxx -o /dev/null
# fatal error: execution_defs.h: No such file or directory

Replacing <algorithm> with <vector> does not reproduce it.

The issue might be related to the length of the installation prefix: For two different environments from the exact same lock file, in one this reproduces reliably, in the other it doesn't, which the only discernible difference being the installation prefix embedded GCC's specs, conda.specs, configargs.h and mkheaders.conf.

ROOT version

ROOT 6.40.04 (conda-forge root_base-6.40.04-cxx23_hb4c0e43_1 and
root-6.40.04-py314ha8c3725_1, installed with pixi)

  • rootcling reports LLVM 20.1.8
  • GCC 15.3.0 (conda-forge gcc-15.3.0-hc6a0c74_7, gxx-15.3.0-hc6a0c74_7,
    libstdcxx-devel_linux-64-15.3.0-hb2c5482_107)
  • Linux x86_64

Installation method

conda-forge (Linux x86-64)

Operating system

nixOS 26.05

Additional context

Where we hit it: a plain data class whose header includes <algorithm> for a
std::find call in a free function next to the class.

Our workaround is to put the pstl directory on the include path for the
dictionary target. Setting CPLUS_INCLUDE_PATH to it also works. In both cases
rootcling still emits the bare name; it just resolves.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions