COIN-OR::LEMON - Graph Library

Opened 14 years ago

Closed 6 years ago

#365 closed defect (fixed)

Cannot include <lemon/adaptors.h> in any of my application source files

Reported by: William Ford Owned by: Alpar Juttner
Priority: critical Milestone:
Component: core Version: hg main
Keywords: Cc: wford@…
Revision id:

Description (last modified by Alpar Juttner)

I am using the Gnu 4.4 compiler under MinGW with Codeblocks on Windows to build a large application. I cannot include <lemon/adaptors.h> or <lemon/connectivity.h> in my application without getting a stream of error messages I cannot figure out. My application must use these included file. I have placed error messages below.

Thanks for any help you can provide.

C:\usr\include\lemon\adaptors.h|3459|error: expected nested-name-specifier before 'Value'|
C:\usr\include\lemon\adaptors.h|3459|error: expected ';' before 'Value'|
C:\usr\include\lemon\adaptors.h|3461|error: wrong number of template arguments (0, should be 2)|
C:\usr\include\lemon\bits\traits.h|155|error: provided for 'template<class Map, class Enable> struct lemon::MapTraits'|
C:\usr\include\lemon\adaptors.h|3462|error: wrong number of template arguments (0, should be 2)|
C:\usr\include\lemon\bits\traits.h|155|error: provided for 'template<class Map, class Enable> struct lemon::MapTraits'|
C:\usr\include\lemon\adaptors.h|3463|error: wrong number of template arguments (0, should be 2)|
C:\usr\include\lemon\bits\traits.h|155|error: provided for 'template<class Map, class Enable> struct lemon::MapTraits'|
C:\usr\include\lemon\adaptors.h|3464|error: wrong number of template arguments (0, should be 2)|
C:\usr\include\lemon\bits\traits.h|155|error: provided for 'template<class Map, class Enable> struct lemon::MapTraits'|
C:\usr\include\lemon\adaptors.h|3465|error: wrong number of template arguments (0, should be 2)|
C:\usr\include\lemon\bits\traits.h|155|error: provided for 'template<class Map, class Enable> struct lemon::MapTraits'|
C:\usr\include\lemon\adaptors.h|3468|error: expected ')' before ',' token|
C:\usr\include\lemon\adaptors.h|3472|error: ISO C++ forbids declaration of 'Value' with no type|
C:\usr\include\lemon\adaptors.h|3472|error: expected ';' before 'operator'|
C:\A+MyPrograms\CombinatoricsCalculator\src\graphs\algorithms\GraphAlgorithmCanvas.cpp|698|error: expected ';' at end of input|
C:\A+MyPrograms\CombinatoricsCalculator\src\graphs\algorithms\GraphAlgorithmCanvas.cpp|698|error: expected '}' at end of input|
C:\A+MyPrograms\CombinatoricsCalculator\src\graphs\algorithms\GraphAlgorithmCanvas.cpp|698|error: expected unqualified-id at end of input|
C:\A+MyPrograms\CombinatoricsCalculator\src\graphs\algorithms\GraphAlgorithmCanvas.cpp|698|error: expected '}' at end of input|
C:\usr\include\lemon\adaptors.h|3443|error: expected unqualified-id at end of input|
C:\usr\include\lemon\adaptors.h|3443|error: expected '}' at end of input|
||=== Build finished: 21 errors, 0 warnings ===|

Attachments (4)

comptest.zip (16.0 KB) - added by William Ford 14 years ago.
windows_h_fix_default.patch (4.0 KB) - added by Akos Ladanyi 14 years ago.
41a05d15c7dc
windows_h_fix_1.2.patch (4.0 KB) - added by Akos Ladanyi 14 years ago.
a85009634531
windows_h_fix_1.1.patch (4.0 KB) - added by Akos Ladanyi 14 years ago.
b265952526f2

Download all attachments as: .zip

Change History (27)

comment:1 Changed 14 years ago by Peter Kovacs

Just some questions:

  • Could you include other headers of the LEMON library properly?
  • Could you preform make check properly?
  • Do you include windows.h in any of your source files? As far as I remember, it caused some compliation problems if this header was included _before_ lemon headers, so it should be included after includeing all lemon headers.

comment:2 Changed 14 years ago by Alpar Juttner

Description: modified (diff)

comment:3 Changed 14 years ago by Alpar Juttner

Could you please provide a code example reproducing this problem?

Changed 14 years ago by William Ford

Attachment: comptest.zip added

comment:4 Changed 14 years ago by William Ford

I have developed a simple application using Code::Blocks that does not dompile and attached it in a ZIP file. Like my application, it uses wxWidgets, version 2.8.10. The include files are in a directory C:\usr\include, and the LEMON library in C:\usr\lib.

I would like to add that I searched long and hard for a graph library I could use. Yours was the only library that was robust, has documentation that makes sense, and is not obfuscated by excessive use of templates. For example, I spent quite some time with the Boost Graph Library and got nowhere. It builds generality upon generality.

Thanks for looking into this for me.

comment:5 Changed 14 years ago by William Ford

The best way to install wxWidgets is using wxPack at http://wxpack.sourceforge.net/Main/HomePage. When installing Codeblocks, install all the plugins. The one named "Library finder" under the "Plugins" menu finds wxWidgets, sets the global variable $(#wx) and fills all the necessary information. I can try to build a makefile to avoid Codeblocks if that would help. I'm not much good with makefiles, but there is a makefile plugin that may work.

I found that in the application I sent you, things worked if I did not use precompiled headers, so I took them out of my application, and it still did not compile. I am using a drawing library developed by Michal Bližňák at http://sourceforge.net/projects/wxsf/. When I included its general header file <wx/wxsf/wxShapeFramework.h> into the code sample I sent you, the sample failed to compile with exactly the same error message. By moving the #include after the lemon includes, the sample compiled. However, this does not work for my application. Aside from experimenting with moving #include's around, I am stumped.

Thanks for looking into this.

comment:6 Changed 14 years ago by Peter Kovacs

Milestone: LEMON 1.3 release
Priority: majorcritical

comment:7 Changed 14 years ago by Peter Kovacs

Cc: wford@… added

comment:8 in reply to:  5 ; Changed 14 years ago by Alpar Juttner

Replying to wford:

The best way to install wxWidgets is using wxPack at http://wxpack.sourceforge.net/Main/HomePage.

Ouch! This is a huge package (250MB to download, ~3GB when installed)!

The one named "Library finder" under the "Plugins" menu finds wxWidgets, sets the global variable $(#wx) and fills all the necessary information.

It didn't work for me thus I had to do it manually.

I found that in the application I sent you, things worked if I did not use precompiled headers, so I took them out of my application, and it still did not compile.

I'm not sure if it is the same, but I noticed that if I remove the

-include wx_pch.h

compiler flag from Project->Build option->Compiler Setting->Other Options, then it goes further and dies only at the linking phase:

Linking executable: bin\Debug\conntest.exe
C:\SourceCode\Libraries\wxWidgets2.8\lib\gcc_lib/libwxmsw28d.a(monolib_string.o):C:\BuildAgent\work\wxPack\wxwidgets\build\msw/../../src/common/string.cpp:418: undefined reference to `__Unwind_Resume'
C:\SourceCode\Libraries\wxWidgets2.8\lib\gcc_lib/libwxmsw28d.a(monolib_string.o):C:\BuildAgent\work\wxPack\wxwidgets\build\msw/../../src/common/string.cpp:495: undefined reference to `__Unwind_Resume'
...

I guess it is unrelated to LEMON, but instead it is due to some improper wx linker flags.

I am using a drawing library developed by Michal Bližňák at http://sourceforge.net/projects/wxsf/.

I tried to install this, but to no avail, as usual.

I must say, installing and using these 3rd party tools is a big suck on Windows. The CMAKE based build env of LEMON we provide for M$ is better by magnitudes.

When I included its general header file <wx/wxsf/wxShapeFramework.h> into the code sample I sent you, the sample failed to compile with exactly the same error message. By moving the #include after the lemon includes, the sample compiled. However, this does not work for my application. Aside from experimenting with moving #include's around, I am stumped.

I don't understand what happens here. But header precompilation is always a dirty business in C++, especially when templates comes into the picture. I tried it in the past with Intel C++, but never worked for me.

comment:9 Changed 14 years ago by William Ford

In order to move on, I have switched to using the GTL graph library. It is not as complete, but it does most of what I need. I appreciate the help provided with the compilation problem. You are right, getting things to work on Windows is a pain! My application compiles and runs perfectly on Linux. I feel the problem lies entirely with Windows and not with the LEMON graph library.

Again, thanks for your time.

comment:10 in reply to:  9 Changed 14 years ago by Alpar Juttner

Replying to wford:

In order to move on, I have switched to using the GTL graph library. It is not as complete, but it does most of what I need. I appreciate the help provided with the compilation problem.

I would still be very grateful if you could help us in resolving this issue, as it may be interesting for others as well.

I guess it is all about proper configuration of CodeBlocks. For example what happens if you remove the -include wx_pch.h compiler directive as I suggested above?

BTW haven't you considered using CMAKE build environment? It makes the software build maintenance much easier, and - amongst many other IDEs and platforms - it works quite well with codeblocks (it can generate .cbp file and codeblocks makefiles). We have CMAKE based a project template using LEMON, please check out this link for a short guide about it:

comment:11 Changed 14 years ago by William Ford

I do prefer LEMON. I have already run into basic things GTL does not do that I will have to code myself. I will go back to my last LEMON-based project and keep working on getting it to compile without the strange template error.

I will also look into CMAKE.

Thanks for your persistence in helping me.

comment:12 Changed 14 years ago by William Ford

I spent some time last night working on the problem. I created a file connections.cpp to include all my functions that need "lemon/connectivity.h". I used the lemon function dag() in my function isADag() within connections.cpp and placed

extern isADag();

in files needing isADag(). This avoided directly including "lemon/connectivity.h" in any but the one file. This worked. I then wrote another function tsort() in connections.cpp, externed it in the application file that needs to compute a topological sort and back came the strange error! Very frustrating!

I can try to use CMAKE, but that won't solve the problem with Codeblocks. I need it for the wxSmith plugin I use to generate wxWidgets code. This RAD tool saves me hours of endless typing and allows me to view a component as I create it.

I have purged anything related to precompiled headers, which took some effort, but it did not help. Do you have any additional suggestions? I can send you the entire application and all the support libraries (NTL, GMP, OGDF, wxShapeFramework, etc.) if that would help.

I have an unrelated question. When doing a DFS traversal, I have an option that outputs a classification of each edge (tree, back, forward, cross). I could not get that to go with the LEMON dfs function or class, even by using a visitor, so I wrote my own class. Am I missing something that makes this easy to do using the standard software?

Thanks.

comment:13 in reply to:  8 Changed 14 years ago by Akos Ladanyi

Replying to kpeter:

Do you include windows.h in any of your source files? As far as I remember, it caused some compliation problems if this header was included _before_ lemon headers, so it should be included after includeing all lemon headers.

You were right, this is the problem here. "wx/wx.h" indirectly includes "wx/msw/wrapwin.h" which includes "windows.h". I'm not sure how to solve this if you want to use precompiled headers, since they need to be the first included header.

Replying to alpar:

Linking executable: bin\Debug\conntest.exe
C:\SourceCode\Libraries\wxWidgets2.8\lib\gcc_lib/libwxmsw28d.a(monolib_string.o):C:\BuildAgent\work\wxPack\wxwidgets\build\msw/../../src/common/string.cpp:418: undefined reference to `__Unwind_Resume'
C:\SourceCode\Libraries\wxWidgets2.8\lib\gcc_lib/libwxmsw28d.a(monolib_string.o):C:\BuildAgent\work\wxPack\wxwidgets\build\msw/../../src/common/string.cpp:495: undefined reference to `__Unwind_Resume'
...

I guess it is unrelated to LEMON, but instead it is due to some improper wx linker flags.

I think I saw this error message recently. Is it possible that you are using a version other than 4.4.0 of MinGW gcc (the wx libs installed by wxPack were compiled with this version)?

Changed 14 years ago by Akos Ladanyi

Attachment: windows_h_fix_default.patch added

Changed 14 years ago by Akos Ladanyi

Attachment: windows_h_fix_1.2.patch added

Changed 14 years ago by Akos Ladanyi

Attachment: windows_h_fix_1.1.patch added

comment:14 Changed 14 years ago by Akos Ladanyi

The problem is caused by the IN and OUT names. I guess these are preprocessor macros defined in windows.h. I've attached patches for the affected branches.

comment:15 in reply to:  14 ; Changed 14 years ago by Alpar Juttner

Replying to ladanyi:

The problem is caused by the IN and OUT names.

I wanna cry.

I guess these are preprocessor macros defined in windows.h. I've attached patches for the affected branches.

Are these patches the same but applied to different branches?

comment:16 in reply to:  15 ; Changed 14 years ago by Akos Ladanyi

Replying to alpar:

Are these patches the same but applied to different branches?

Yes (although the original adaptors.h in 1.1 differs in some whitespace from the other two). Should I send them in the usual way instead (one patch on top of the common ancestor and three merges)?

comment:17 in reply to:  16 ; Changed 14 years ago by Alpar Juttner

Replying to ladanyi:

Replying to alpar:

Are these patches the same but applied to different branches?

Yes (although the original adaptors.h in 1.1 differs in some whitespace from the other two). Should I send them in the usual way instead (one patch on top of the common ancestor and three merges)?

Don't bother. I'll do it.

More importantly, can't we test somehow these problems in the test file? For example by including 'windows.h' into all test codes when appropriate?

Or should we simply suggest separating any LEMON related code from those are using windows.h?

comment:18 in reply to:  17 ; Changed 14 years ago by Akos Ladanyi

Replying to alpar:

More importantly, can't we test somehow these problems in the test file? For example by including 'windows.h' into all test codes when appropriate?

Or by creating a new test where we include windows.h and after it all LEMON headers.

Or should we simply suggest separating any LEMON related code from those are using windows.h?

I think this would be a hard requirement on our users. If possible we should avoid it.

comment:19 in reply to:  12 Changed 14 years ago by Balazs Dezso

Replying to wford:

I have an unrelated question. When doing a DFS traversal, I have an option that outputs a classification of each edge (tree, back, forward, cross). I could not get that to go with the LEMON dfs function or class, even by using a visitor, so I wrote my own class. Am I missing something that makes this easy to do using the standard software?

It is possible with the visitor interface, but it is not much simpler than writing an own Dfs algorithm.

You can see some visitor algorithms in lemon/connectivity.h, for example. The tree edges can be found simply with discover() function. The other arcs must be separated in the examine() function. It is possible to calculate step in and step out numbers in reach() and leave() functions. The relationship of intervals of the source and target nodes determines the type of arc. If the source interval contains the target interval then the arc is forward arc, if the target interval contains the source interval, then the arc is backward arc. If the intervals are disjoint then the arc is cross.

comment:20 in reply to:  18 ; Changed 14 years ago by Alpar Juttner

Replying to ladanyi:

Replying to alpar:

More importantly, can't we test somehow these problems in the test file? For example by including 'windows.h' into all test codes when appropriate?

Or by creating a new test where we include windows.h and after it all LEMON headers.

Or should we simply suggest separating any LEMON related code from those are using windows.h?

I think this would be a hard requirement on our users. If possible we should avoid it.

I don't know, look at ticket #215 for example. At that case, the conclusion was to never include windows.h in any LEMON related code. And this conclusion was not without rhyme or reason.

windows.h is so carelessly written that it only causes problems. It liberally defines any random names -- such as Arc, IN and OUT -- in the global namespace. Unbelievable. Even worse, this set of globally defined names changes from version to version.

If fact the safe solution I would suggest to anyone is not to separate the LEMON related code, but to wrap around and separate windows.h itself from anything else. (In fact LEMON also does this internally). For it is windows.h that causes the problem here and LEMON not the only one affected by this issue. Any other library is in danger, especially the cross platform ones.

comment:21 in reply to:  20 Changed 14 years ago by Akos Ladanyi

Replying to alpar:

windows.h is so carelessly written that it only causes problems. It liberally defines any random names -- such as Arc, IN and OUT -- in the global namespace. Unbelievable. Even worse, this set of globally defined names changes from version to version.

The way I see it is the following.

We have no problem with names defined in the global namespace by windows.h, since we put everything in the lemon namespace. I agree, the users of the library can have problems with this if they do a using namespace lemon. But again they can solve this by not bringing everything into scope from the lemon namespace, or by doing what you suggest, i.e. separating LEMON related code from code utilizing the Windows API.

On the other hand we can have problems with preprocessor macros that come from windows.h and do not have a prefix (e.g. TRUE, FALSE, IN, OUT, max, min). What I meant to suggest is to create a test case to check whether this happens. Actually I did this test and we are fine.

comment:22 Changed 11 years ago by Alpar Juttner

Milestone: LEMON 1.3 release

comment:23 Changed 6 years ago by Alpar Juttner

Resolution: fixed
Status: newclosed

See #612.

Note: See TracTickets for help on using tickets.