1

I have a directory structure:

include/foo/bar/header1.h
include/foo/bar/header2.h

header1.h includes header2.h. However, when I attempt this:

import cppyy

cppyy.add_include_path('include')
cppyy.include('foo/bar/header1.h')

I get the error:

ImportError: Failed to load header file "foo/bar/header1.h"
In file included from input_line_33:1:
./include/foo/bar/header1.h:11:10: fatal error: 'foo/bar/header2.h' file not found
#include "foo/bar/header2.h"
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I am not sure what to do here. I could include header2.h manually, but it in turn has other include files and I would probably end up including the entire project manually, which seems like it doesn't need to happen. I have tried both cppyy.include('include/foo/bar/header1.h') and cppyy.include('foo/bar/header1.h'). I have also tried cppyy.add_include_path('include') and cppyy.add_include_path('include/foo'). Neither of those helped.

DLAN
  • 581
  • 1
  • 4
  • 10
  • 1
    It appears the issue is restricted to when I am using the Python interpreter. If I put my code in a file and call it from the command line, it finds the include files without issue. – DLAN Sep 14 '21 at 23:37
  • "Works for me" (TM) both as a file and in the interpreter... There are also tests based on Eigen and Boost that deal with similar directory structures, and so hasn't been an issue there either. So, on what platform and for which version of cppyy is this failing so that I can reproduce? – Wim Lavrijsen Sep 15 '21 at 01:33
  • I think I must have just had an issue when launching the interpreter, maybe I was starting it in the wrong directory. It appears to be working fine for me now. For reference I am on Linux with cppyy 2.1.0 I believe. – DLAN Sep 15 '21 at 16:52
  • Interpreter or module, it didn't matter. Still failed (on Windows, of course). I had to add to do add_include_path as mentioned in the current top (and only) answer. Also cppyy 2.3.1 does NOT understand pathlib, need to convert to strings. – Zim Jun 07 '22 at 22:00

2 Answers2

2

Notwithstanding the conclusion in the comments above, the following is for future reference to aid debugging in case someone stumbles on this question with the same problem.

To print the full set of include directories as seen by Cling, do:

import cppyy
print(cppyy.gbl.gInterpreter.GetIncludePath())

It will show as a range of -I<dir> arguments, just as would be given to a C++ compiler on the command line.

Paths in the <dir> part of each can be both absolute or relative. If any relative paths are present, Cling will consider them from the current directory of the process, so a basic os.getcwd() will do to retrieve it and os.chdir() can be used to change it.

If at any time during the program run the current working directory could change unexpectedly, then I recommend making all paths as given to Cling absolute (or include all relevant headers immediately). For example:

cppyy.add_include_path(os.path.abspath('include'))
Wim Lavrijsen
  • 3,453
  • 1
  • 9
  • 21
0

I would like to point out one other thing, for the benefit of anyone who finds this question while trying to understand cppyy.include.

The behavior of cppyy.include appears to be affected by affected by previous calls. Specifically, the following works for me:

>>> import cppyy
>>> cppyy.add_include_path("include")
>>> cppyy.include("include/foo/bar/header1.h")
True
>>> 

Whereas the following does not:

>>> import cppyy
>>> cppyy.include("include/foo/bar/header1.h")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/micaiah/.local/lib/python3.10/site-packages/cppyy/__init__.py", line 248, in include
    raise ImportError('Failed to load header file "%s"%s' % (header, err.err))
ImportError: Failed to load header file "include/foo/bar/header1.h"
In file included from input_line_18:1:
./include/foo/bar/header1.h:1:10: fatal error: 'foo/bar/header2.h' file not found
#include "foo/bar/header2.h"
         ^~~~~~~~~~~~~~~~~~~

>>> cppyy.add_include_path("include")
>>> cppyy.include("include/foo/bar/header1.h")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/micaiah/.local/lib/python3.10/site-packages/cppyy/__init__.py", line 248, in include
    raise ImportError('Failed to load header file "%s"%s' % (header, err.err))
ImportError: Failed to load header file "include/foo/bar/header1.h"
In file included from input_line_19:1:
./include/foo/bar/header1.h:1:10: fatal error: 'foo/bar/header2.h' file not found
#include "foo/bar/header2.h"
         ^~~~~~~~~~~~~~~~~~~
>>> 

That said, the exact code from the OP, reproduced as accurately as I could, does work for me, which makes me wonder if some of the confusion in the above discussion resulted from people (understandably) assuming that previous failed attempts to include files were irrelevant.

micaiah
  • 101
  • 4