coin-or / Osi

Open Solver Interface
Other
54 stars 41 forks source link

Necessity for --with-cplex=false #143

Closed akazachk closed 3 years ago

akazachk commented 4 years ago

I have a report of a possibly unintended behavior when I was trying to follow the Quick Start example on a machine running Oracle Linux Server release 7.7. Specifically, I run these commands:

wget https://raw.githubusercontent.com/coin-or/coinbrew/master/coinbrew
chmod u+x coinbrew
./coinbrew build Cbc@master

However, the build fails:

##################################################
### Building Osi master
##################################################

[COIN_INSTALL_DIR]/Osi/src/OsiCpx/OsiCpxSolverInterface.cpp:22:10: fatal error: cplex.h: No such file or directory
   22 | #include "cplex.h"
      |          ^~~~~~~~~
compilation terminated.
make[2]: *** [OsiCpxSolverInterface.lo] Error 1
make[1]: *** [all] Error 2
make: *** [all-recursive] Error 1

Build failed, see error output above

If I instead I call ./coinbrew build Cbc@master --with-cplex=false, the build succeeds. Note that CPLEX is installed on the server, but perhaps in an unusual location.

It might be worth adding this information to the README + documentation and describe the --with-cplex option when calling coinbrew -h. I would also suggest telling the user they may need to call chmod u+x coinbrew in the Quick Start.

tkralphs commented 4 years ago

Hmm, something weird is going on. This is probably some kind of user error, but if not, it's a bug, not an undocumented feature. The build should not even descend into the OsiCpx subdirectory unless you provided paths to the CPLEX headers and libraries when you originally configured.

Currently, I can't replicate using the exact set of commands you provided. It would be pretty surprising if this common workflow were broken. I suspect you may be accidentally re-building in a directory that was previously configured with some CPLEX paths that are somehow now wrong? Not sure. Is there an existing build/ already present in the directory you're running coinbrew from?

Can you try to do the whole thing in a fresh directory?

mkdir foobar
cd foobar
wget https://raw.githubusercontent.com/coin-or/coinbrew/master/coinbrew
chmod u+x coinbrew
./coinbrew build Cbc@master

I have a feeling that will work. If not, run coinbrew with --verbosity 4 and attach the entire output of the failed build. I should be able to see what's going on from there.

svigerske commented 4 years ago

Osi configure checks whether CPXgetstat is resolved when using -lcplex -lpthread -lm -ldl (which probably succeeded on that machine), but it doesn't check whether cplex.h can also be found in the standard include paths (which apparently is not the case on that machine).

tkralphs commented 4 years ago

Ah, OK, I stand corrected. I actually didn't realize there was an automated link check for the CPLEX library. So I guess we should be checking for cplex.h as well, right? And only build OsiCpx if both the library and the header are found? We could output a warning in case one is found, but not the other?

akazachk commented 4 years ago

@svigerske I think that's exactly right, and it would be good for the configure script to check whether the CPLEX include directory can be found. I guess I should have made this issue in Osi.

@tkralphs You posted a second before me : ), and clearly I agree.

tkralphs commented 4 years ago

The issue is now transferred.

svigerske commented 4 years ago

Doing a warning only is a bit difficult without going deep into coin.m4, as it is difficult to undo some of the setting that the AC_COIN_CHK_LIB macro does at the end when it concluded that the library is present.

akazachk commented 4 years ago

I think adding the descriptive error in 4ac0b26 is definitely an improvement.

I am not sure if this is already done, but possibly if the library check is concluded and CPLEX is found, maybe in addition to the standard include paths, cplex.h can be searched for in a modification of where the library was found. E.g., if the library is found in /path/to/cplex/version/cplex/lib/x86-64_linux/static_pic, then the base CPLEX directory is CPLEX_DIR=/path/to/cplex/version and the include path is likely to be ${CPLEX_DIR}/cplex/include/ilcplex, I think (or ${CPLEX_DIR}/cplex/include if the code has #include <ilcplex/cplex.h> not #include <cplex.h>).

Alternatively, it might help the user to state (in the error message) that they can either compile with --without-cplex (I just learned this was an option, as I have been doing --with-cplex=false) OR with --with-cplex-incdir=....

tkralphs commented 4 years ago

It seems reasonable to me just not to do the automatic link check if we don't also check for the header. We would just only check for the library if the user explicitly asks. How do we do this with other libraries? I would have thought we always check for the header, too, as this could be an issue with any library.

At any rate, this is a pretty unusual case where the CPLEX library path is in LD_LIBRARY_PATH, but the header is not installed in a system directory.

svigerske commented 4 years ago

For libs like readline, zlib, gmp, we check for both the header and the library. For those, only the systems standard search paths are checked (no options to specify cflags and lflags).

tkralphs commented 3 years ago

There is now further work on this in https://github.com/coin-or-tools/BuildTools/#143 and https://github.com/coin-or-tools/BuildTools/#148.