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

Unable to find out actual class definition: ''. #45

Closed
othi opened this issue Mar 23, 2016 · 14 comments
Closed

Unable to find out actual class definition: ''. #45

othi opened this issue Mar 23, 2016 · 14 comments
Assignees
Labels
Milestone

Comments

@othi
Copy link

othi commented Mar 23, 2016

I seem to have stumbled on a bug while trying to use Py++ on a larger project.

Here is a snippet that reproduces the bug (edited out the namespace blunder for clearness sake):

#include <map>
using namespace std;
class apta_node;
typedef map<int, apta_node*> child_map;
class apta_node{
public:
    child_map children;
};

Here's how I try to build the module:

from pyplusplus import module_builder
mb = module_builder.module_builder_t(
    files=['test.h'],
    include_paths=["/usr/include/x86_64-linux-gnu/c++/5", "/usr/include/c++/5"],
    cflags="-std=c++11"
)

And here's the output and error message:

d@machine:~/dev/pyplusplustest$ python3 test_generate.py 
INFO Parsing source file "test.h" ... 
error: invalid argument '-std=c++11' not allowed with 'C/ObjC'         # I need to add it or --castxml-gccxml doesn't work. The XML files generates fine.
Traceback (most recent call last):
  File "test_generate.py", line 8, in <module>
    cflags="-std=c++11"
  File "/usr/local/lib/python3.4/dist-packages/pyplusplus-1.1.0-py3.4.egg/pyplusplus/module_builder/boost_python_builder.py", line 106, in __init__
  File "/usr/local/lib/python3.4/dist-packages/pyplusplus-1.1.0-py3.4.egg/pyplusplus/module_builder/boost_python_builder.py", line 149, in __parse_declarations
  File "/usr/local/lib/python3.4/dist-packages/pygccxml/parser/project_reader.py", line 249, in read_files
    return self.__parse_file_by_file(files)
  File "/usr/local/lib/python3.4/dist-packages/pygccxml/parser/project_reader.py", line 319, in __parse_file_by_file
    self._relink_declarated_types(leaved_classes, types)
  File "/usr/local/lib/python3.4/dist-packages/pygccxml/parser/project_reader.py", line 544, in _relink_declarated_types
    raise Exception(os.linesep.join(msg))
Exception: Unable to find out actual class definition: ''.
Class definition has been changed from one compilation to an other.
Why did it happen to me? Here is a short list of reasons: 
    1. There are different preprocessor definitions applied on same file during compilation
    2. Bug in pygccxml.

After a bit of fiddling, I think the problematic line is /usr/include/c++/5/bits/stl_tree.h:1407

Using Ubuntu 15.10, pygccxml 1.7.2 (and latest development branch), gccxml from Ubuntu repository (wrapper around CastXML 0.1-g8a08a44).

@praetorian20
Copy link
Contributor

Why are you adding things to namespace std? That makes your code ill-formed. Can the problem be reproduced if you add those definitions to your own namespace?

If you can reproduce the error with a different namespace, then paste these lines in your test_generate.py file (at the very top, immediately after you import modules) to enable debug logging and paste the output here.

import logging
pyplusplus.module_builder.set_logger_level(logging.DEBUG)
pygccxml.utils.loggers.set_level(logging.DEBUG)

@othi
Copy link
Author

othi commented Mar 24, 2016

The namespace was a blunder from when I created the test file. The problem remains the same if I just use the std namespace. :)

Here's the output after adding the debug logging:

parsing filparsing files - started
DEBUG Reading project files: file by file
INFO Parsing source file "test.h" ... 
DEBUG Reading source file: [test.h].
DEBUG File has not been found in cache, parsing...
DEBUG gccxml cmd: /usr/bin/gccxml  -std=c++11   -I"." -I"/usr/include/x86_64-linux-gnu/c++/5" -I"/usr/include/c++/5" "test.h" -fxml="/tmp/tmpuzy87zqz.xml"
error: invalid argument '-std=c++11' not allowed with 'C/ObjC'
DEBUG CASTXML version - None ( 1.136 )
DEBUG Flushing cache... 
DEBUG Cache has been flushed in 0.0 secs
DEBUG Joining namespaces ...
DEBUG Joining declarations ...
DEBUG Relinking declared types ...
Traceback (most recent call last):
  File "test_generate.py", line 13, in <module>
    cflags="-std=c++11"
  File "/usr/local/lib/python3.4/dist-packages/pyplusplus-1.1.0-py3.4.egg/pyplusplus/module_builder/boost_python_builder.py", line 106, in __init__
  File "/usr/local/lib/python3.4/dist-packages/pyplusplus-1.1.0-py3.4.egg/pyplusplus/module_builder/boost_python_builder.py", line 149, in __parse_declarations
  File "/usr/local/lib/python3.4/dist-packages/pygccxml/parser/project_reader.py", line 249, in read_files
    return self.__parse_file_by_file(files)
  File "/usr/local/lib/python3.4/dist-packages/pygccxml/parser/project_reader.py", line 319, in __parse_file_by_file
    self._relink_declarated_types(leaved_classes, types)
  File "/usr/local/lib/python3.4/dist-packages/pygccxml/parser/project_reader.py", line 544, in _relink_declarated_types
    raise Exception(os.linesep.join(msg))
Exception: Unable to find out actual class definition: ''.
Class definition has been changed from one compilation to an other.
Why did it happen to me? Here is a short list of reasons: 
    1. There are different preprocessor definitions applied on same file during compilation
    2. Bug in pygccxml.

@laxris
Copy link

laxris commented Mar 24, 2016

It also does not work when just trying to create an instance of map, without typedef or forward declaration. The debug and log output is the same.

#include <map>

using namespace std;

class mytest {
        map<int, int> mymap; // works without this
};

@praetorian20
Copy link
Contributor

Your problem is you're using GCCXML for parsing your header. GCCXML is a fork of a very old GCC (version 4.3 IIRC), so it's no wonder it doesn't know what -std=c++11 is, there was no C++11 standard at that time. You may be able to use -std=c++0x instead, but even then it might fail to parse the header.

You should switch over to CastXML, it's the successor to GCCXML, and works with -std=c++11.

@othi
Copy link
Author

othi commented Mar 24, 2016

Indeed.

I switched to CastXML:

generator_path, generator_name = pygccxml.utils.find_xml_generator('castxml')
xml_generator_config = pygccxml.parser.xml_generator_configuration_t(
  cflags="-std=c++11",
  xml_generator=generator_name,
  xml_generator_path=generator_path)

mb = pyplusplus.module_builder.module_builder_t(
        files=['test.h'],
        xml_generator_config=xml_generator_config
)

The end result remains the same:

parsing files - started
DEBUG Reading project files: file by file
INFO Parsing source file "test.h" ... 
DEBUG Reading source file: [test.h].
DEBUG File has not been found in cache, parsing...
DEBUG castxml cmd: /usr/bin/castxml  -std=c++11   -I. -c -x c++ --castxml-cc-gnu  "(" /usr/bin/c++ -std=c++11 ")" --castxml-gccxml -o /tmp/tmpcy3u3zdi.xml test.h
DEBUG CASTXML version - None ( 1.136 )
DEBUG find single query execution - started
DEBUG running query: (decl type==variable_t) and (name==static_cast< size_t >)
DEBUG running non optimized query - optimization has not been done
DEBUG find single query execution - started
DEBUG running query: (decl type==variable_t) and (name==static_cast< size_t >)
DEBUG running non optimized query - optimization has not been done
DEBUG find single query execution - started
DEBUG running query: (decl type==variable_t) and (name==static_cast< size_t >)
DEBUG running non optimized query - optimization has not been done
DEBUG find single query execution - started
DEBUG running query: (decl type==variable_t) and (name==static_cast< size_t >)
DEBUG running non optimized query - optimization has not been done
DEBUG find single query execution - started
DEBUG running query: (decl type==variable_t) and (name==static_cast< size_t >)
DEBUG running non optimized query - optimization has not been done
DEBUG find single query execution - started
DEBUG running query: (decl type==variable_t) and (name==static_cast< size_t >)
DEBUG running non optimized query - optimization has not been done
DEBUG Flushing cache... 
DEBUG Cache has been flushed in 0.0 secs
DEBUG Joining namespaces ...
DEBUG Joining declarations ...
DEBUG Relinking declared types ...
Traceback (most recent call last):
  File "test_generate.py", line 17, in <module>
    xml_generator_config=xml_generator_config
  File "/usr/local/lib/python3.4/dist-packages/pyplusplus-1.1.0-py3.4.egg/pyplusplus/module_builder/boost_python_builder.py", line 106, in __init__
  File "/usr/local/lib/python3.4/dist-packages/pyplusplus-1.1.0-py3.4.egg/pyplusplus/module_builder/boost_python_builder.py", line 149, in __parse_declarations
  File "/usr/local/lib/python3.4/dist-packages/pygccxml-1.7.2-py3.4.egg/pygccxml/parser/project_reader.py", line 249, in read_files
  File "/usr/local/lib/python3.4/dist-packages/pygccxml-1.7.2-py3.4.egg/pygccxml/parser/project_reader.py", line 319, in __parse_file_by_file
  File "/usr/local/lib/python3.4/dist-packages/pygccxml-1.7.2-py3.4.egg/pygccxml/parser/project_reader.py", line 544, in _relink_declarated_types
Exception: Unable to find out actual class definition: ''.
Class definition has been changed from one compilation to an other.
Why did it happen to me? Here is a short list of reasons: 
    1. There are different preprocessor definitions applied on same file during compilation
    2. Bug in pygccxml.

Note:
The module_builder completes when I remove the cflags="-std=c++11" configuration, but that is not really an option.

@praetorian20
Copy link
Contributor

CastXML is being invoked with this command

/usr/bin/castxml  -std=c++11   -I. -c -x c++ --castxml-cc-gnu  "(" /usr/bin/c++ -std=c++11 ")" --castxml-gccxml -o /tmp/tmpcy3u3zdi.xml test.h

Is /usr/bin/c++ an alias for gcc-5 (I assume you want to use gcc-5.x from the include paths above)? If that's not the correct path, try passing compiler_path=... to xml_generator_configuration_t.

@iMichka Can you please takeover helping with this issue? I won't be able to get back to it until next week.

@iMichka iMichka added the bug label Mar 24, 2016
@iMichka
Copy link
Contributor

iMichka commented Mar 24, 2016

@praetorian20 Thanks for starting debugging this.

@othi thanks for reporting the problem. I hope we will be able to get that sorted out.

I just ran the code on my Mac with py++ (latest commit) and pygccxml (latest commit), using the latest castxml and clang. Everything went fine. But it should also work with older versions of py++/pygccxml.

I think knowing which compiler was used would help debug this. As asked above, is /usr/bin/c++ the correct compiler, and what version is it ? Setting the right compiler_path is recommended if you have multiple compilers installed.

I can try to install ubuntu 15.10 in a virtual box and setup the same build env as you, to try to reproduce the error. I'll do that this weekend if the debugging here is not helping.

@othi
Copy link
Author

othi commented Mar 25, 2016

Sorry I didn't have a lot of time today to work on this.

/usr/bin/c++ is an alias for /usr/bin/g++-5. I'm going to fiddle around with the compiler path and report back.

Thanks for your quick responses!

@othi
Copy link
Author

othi commented Mar 26, 2016

The result is the same when used with the compiler_path explicitly set to /usr/bin/g++:

generator_path, generator_name = pygccxml.utils.find_xml_generator('castxml')
xml_generator_config = pygccxml.parser.xml_generator_configuration_t(
  cflags="-std=c++11",
  compiler_path="/usr/bin/g++",
  xml_generator=generator_name,
  xml_generator_path=generator_path)
parsing files - started
DEBUG Reading project files: file by file
INFO Parsing source file "test.h" ... 
DEBUG Reading source file: [test.h].
DEBUG File has not been found in cache, parsing...
DEBUG castxml cmd: /usr/bin/castxml  -std=c++11   -I. -c -x c++ --castxml-cc-gnu  "(" /usr/bin/g++ -std=c++11 ")" --castxml-gccxml -o /tmp/tmphqxl1mt2.xml test.h
DEBUG CASTXML version - None ( 1.136 )
<snip>
  File "/usr/local/lib/python3.4/dist-packages/pygccxml-1.7.2-py3.4.egg/pygccxml/parser/project_reader.py", line 544, in _relink_declarated_types
Exception: Unable to find out actual class definition: ''.
Class definition has been changed from one compilation to an other.
Why did it happen to me? Here is a short list of reasons: 
    1. There are different preprocessor definitions applied on same file during compilation
    2. Bug in pygccxml.

Or when used with clang:

parsing files - started
DEBUG Reading project files: file by file
INFO Parsing source file "test.h" ... 
DEBUG Reading source file: [test.h].
DEBUG File has not been found in cache, parsing...
DEBUG castxml cmd: /usr/bin/castxml  -std=c++11   -I. -c -x c++ --castxml-cc-gnu  "(" /usr/bin/clang -std=c++11 ")" --castxml-gccxml -o /tmp/tmpmsq0r7kr.xml test.h
DEBUG CASTXML version - None ( 1.136 )
<snip>
  File "/usr/local/lib/python3.4/dist-packages/pygccxml-1.7.2-py3.4.egg/pygccxml/parser/project_reader.py", line 544, in _relink_declarated_types
Exception: Unable to find out actual class definition: ''.
Class definition has been changed from one compilation to an other.
Why did it happen to me? Here is a short list of reasons: 
    1. There are different preprocessor definitions applied on same file during compilation
    2. Bug in pygccxml.

pyplusplus is the latest commit from Bitbucket, pygccxml the latest commit from here, castxml version 0.1-g8a08a44, compilers from the Ubuntu repositories.

@iMichka
Copy link
Contributor

iMichka commented Mar 26, 2016

Ok thanks. I am currently installing Wily and gcc5, I'll try to reproduce the problem there.

@iMichka
Copy link
Contributor

iMichka commented Mar 27, 2016

Good news, I could reproduce the error. I'll try to fix this but it may take a little bit of time, depending on how complex that part of the code is.

iMichka added a commit that referenced this issue Mar 27, 2016
This is failing with gcc5 + castxml + std=c++11 flag with the
following error:

parsing files - started
DEBUG Reading project files: file by file
INFO Parsing source file "test.h" ...
DEBUG Reading source file: [test.h].
DEBUG File has not been found in cache, parsing...
DEBUG castxml cmd: /usr/bin/castxml  -std=c++11   -I. -c -x c++ --castxml-cc-gnu  "(" /usr/bin/clang -std=c++11 ")" --castxml-gccxml -o /tmp/tmpmsq0r7kr.xml test.h
DEBUG CASTXML version - None ( 1.136 )
<snip>
  File "/usr/local/lib/python3.4/dist-packages/pygccxml-1.7.2-py3.4.egg/pygccxml/parser/project_reader.py", line 544, in _relink_declarated_types
Exception: Unable to find out actual class definition: ''.
Class definition has been changed from one compilation to an other.
Why did it happen to me? Here is a short list of reasons:
    1. There are different preprocessor definitions applied on same file during compilation
    2. Bug in pygccxml.
iMichka added a commit that referenced this issue Mar 27, 2016
With gcc5 + castxml + std=c++11 some code was not
parseable by pygccxml (see previous commit).

This fixes the problem, but is probably not the
final solution, but as the other cases in the relink
method, a better understanding of this code part
should hopefully help find a better strategy to
handle these cases.
@iMichka iMichka added this to the 1.7.3 milestone Mar 27, 2016
@iMichka
Copy link
Contributor

iMichka commented Mar 27, 2016

I pushed a fix. It's not perfect, as this part of the code is not really clear. As all the tests pass, I am quite confident this did not break anything else. Could you please test again on your side ?
The fix will be in release v1.7.3.

Be aware that there are still a bunch of errors in the container traits part with gcc5, which I discovered while running the tests. If you happen to use pygccxml's container traits it may be broken. I opened another bug for this (#47) (this problem is not related to this one).

@iMichka iMichka self-assigned this Mar 27, 2016
@othi
Copy link
Author

othi commented Mar 30, 2016

This fixed the issue, thank you very much.

I may have found another one - I'll dig a little deeper and try to build a concise test case before I report it.

@iMichka
Copy link
Contributor

iMichka commented Mar 30, 2016

Great. I'll close this issue then.

Please open a new one for the second issue. A test case is always welcome.

@iMichka iMichka closed this as completed Mar 30, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants