coin-or / Cbc

COIN-OR Branch-and-Cut solver
Other
814 stars 115 forks source link

Undefined reference to `node_count` when compiling #628

Closed akazachk closed 11 months ago

akazachk commented 11 months ago

Hi all, a few weeks ago in commit ec17748, the typedef node_count was introduced into CbcConfig.h, moved I think from CbcModel.hpp where it was previously; node_count is used in various places, such as CbcNodeInfo.hpp:347, CbcModel, and CbcNode. It seems to me that the proper inclusion of CbcConfig.h exists in all the files (or, as in the case of CbcNodeInfo, via another include).

For some reason, my code that is using Cbc is now getting compiler errors (on macOS Sonoma 14.1.2 with the clang compiler, running on a MacBook Pro laptop with M3 Pro processor, and checking out the master version of the Cbc code via coinbrew) that look like the following, and I am wondering if anyone could please lend insights into a fix:

In file included from ${COIN_OR}/build/include/coin-or/CbcModel.hpp:15:
In file included from ${COIN_OR}/build/include/coin-or/CbcCompareBase.hpp:20:
In file included from ${COIN_OR}/build/include/coin-or/CbcNode.hpp:14:
${COIN_OR}/build/include/coin-or/CbcNodeInfo.hpp:269:10: error: unknown type name 'node_count'
  inline node_count nodeNumber() const
         ^
${COIN_OR}/build/include/coin-or/CbcNodeInfo.hpp:273:29: error: unknown type name 'node_count'
  inline void setNodeNumber(node_count node)
                            ^
${COIN_OR}/build/include/coin-or/CbcNodeInfo.hpp:347:3: error: unknown type name 'node_count'
  node_count nodeNumber_;
  ^

Thank you, Aleks

akazachk commented 11 months ago

I think I have figured out the cause of the problem (but not quite a fix yet). It is an issue with my compilation command. My compiler command looks like (edited to keep the main point):

clang++ -isystem ${COIN_OR}/build/include/coin-or -c file.cpp -o file.o

The version of the header file CbcConfig.h located in ${COIN_OR}/build/include/coin-or is not that of ${COIN_OR}/Cbc/src/CbcConfig.h.

@tkralphs Maybe this is me using coinbrew incorrectly?

It seems the version of CbcConfig.h in the build directory is autogenerated as the first line is

/* src/config_cbc.h.  Generated from config_cbc.h.in by configure.  */
tkralphs commented 11 months ago

For arcane historical reasons, when building with the autotools, CbcConfig.h is replaced by an auto-generated header when it is installed, So what you are seeing is correct. The problem is that in ec1774, @jjhforrest inserted a typedef for node_count into the source version of CbcConfig.h and since this file itself does not get installed, that's not the right place for it. So I don't think anyone building with the autotools can build successfully at the moment. We need to move that typedef somewhere. Let me look at it.

svigerske commented 11 months ago

Apart from the "arcane historical reasons" (I actually find it quite elegant how we deal with the different config header variants and avoid that users would have to define HAVE_CONFIG_H, but I'm biased), what Ted wrote is correct. I took the liberty to move the typedef into a better place. (Just adding that I don't think that it's a great idea that Cbc defines a type named node_count on the global namespace.)

jjhforrest commented 11 months ago

I have changed node_count to cbc_node_count which should be safe enough. I am trying to solve my effort to experiment with problem mas76. My version is smaller, but slightly difficult to solve. The best possible objective was -10512. I have managed to find a value of -10508 and I am hoping the run will finish this year. The last node count was 8834862000 so you can see why long int is needed.

tkralphs commented 11 months ago

@svigerske Sorry for offending your sensibilities :). I guess you're right that it's a pretty elegant solution, but we did sort of back into it rather than purpose-building it this way, so it feels like a historical artifact. And it would be hard to argue that the reasons are not arcane :). But thanks for the quick fix!