3
\$\begingroup\$

CPLEX is a solver for mathematical problems made by IBM, and it offers callable C libraries.

My usual project configuration is a main.cpp file will all the important code and a simple cpxmacro.h file with some macros. Sometimes there are also .dat files with problem data. When the solver does its job (i.e. the main is run), it outputs .lp and .sol files.

I used to let my IDE come up with proper make files, but this time I was provided with a hand-made make file. What a good opportunity to look into it.

CXX = g++
CXXFLAGS = -g -Wall -O
LDADD =
CPX_INCDIR = /opt/ibm/ILOG/CPLEX_Studio126/cplex/include
CPX_LDPATH = /opt/ibm/ILOG/CPLEX_Studio126/cplex/lib/x86-64_linux/static_pic
CPX_LDADD = -lcplex -lm -pthread
OBJ = main.o 
%.o: %.cpp
 $(CXX) $(CXXFLAGS) -I$(CPX_INCDIR) -c $^ -o $@
main: $(OBJ)
 $(CXX) $(CXXFLAGS) $(OBJ) -o main -L$(CPX_LDPATH) $(CPX_LDADD)
clean:
 rm -rf $(OBJ) main
.PHONY: clean

As long as I only change the main file, it works. I just have to manually load a small file first, by typing . cplex_env. This is what the file contains:

#!/bin/sh
export PATH=$PATH:/opt/ibm/ILOG/CPLEX_Studio126/opl/bin/x86-64_linux:/opt/ibm/ILOG/CPLEX_Studio126/cplex/bin/x86-64_linux
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/opt/ibm/ILOG/CPLEX_Studio126/opl/bin/x86-64_linux:/opt/ibm/ILOG/CPLEX_Studio126/cplex/bin/x86-64_linux:/opt/ibm/ILOG/CPLEX_Studio126/cpoptimizer/bin/x86-64_linux/

I never tried to change the .h macro file and see what happens, it doesn't look to me like it's being accounted for anywhere in the makefile.

I'd like to:

  • include the path exports in the make file
  • make the makefile a little more generic
Toby Speight
87.2k14 gold badges104 silver badges322 bronze badges
asked Oct 24, 2014 at 10:37
\$\endgroup\$
3
  • 2
    \$\begingroup\$ Minor suggestions: CC (C compiler) -> CXX (C++ compiler); CPPFLAGS (C preprocessor flags) -> CXXFLAGS (C++ compiler flags); CPX_LIBDIR -> CPX_LDPATH; CPX_LDFLAGS -> CPX_LDADD; LDFLAGS -> LDADD. \$\endgroup\$ Commented Oct 24, 2014 at 12:08
  • \$\begingroup\$ @Agostino: You should use CXX=g++. BUT also replace all locations where you use CC with CXX. If you are writing C++ code use the correct variables ore represent it. \$\endgroup\$ Commented Oct 25, 2014 at 7:43
  • \$\begingroup\$ @Gluttton renamings done and makefile working again. Is there anything else I can do? E.g. why is LDADD empty, and why should I call it like that instead of LDFLAGS? \$\endgroup\$ Commented Oct 29, 2014 at 7:48

1 Answer 1

1
\$\begingroup\$

Instead of providing your own %.o: %.cpp rule, you can let Make use its built-in one. You need to pass your extra include directory, and the standard way to do that is to add to CXXFLAGS:

CXXFLAGS += -I$(CPX_INCDIR)

Or perhaps

CPLEX_DIR = /opt/ibm/ILOG/CPLEX_Studio126/cplex
CXXFLAGS += -I$(CPLEX_DIR)/include

Similarly, take advantage of the built-in link command; this is especially easy, as there's a built-in rule that will create main from main.o. You need to tell Make to use the C++ linker rather than the plain (C) linker:

LINK.o = $(LINK.cc)
LDFLAGS += -L$(CPLEX_DIR)/lib/x86-64_linux/static_pic
LDLIBS += -lcplex -lm -pthread

To declare the dependency on the header file, note that main.o needs to be rebuilt whenever the header changes:

main.o: cpxmacro.h

That's all!

Header file dependencies can be hard to manage by hand in larger projects; for these, search for "automatic dependency generation", or read Paul D. Smith's excellent article.


Modified makfile

With my changes:

CPLEX_DIR = /opt/ibm/ILOG/CPLEX_Studio126/cplex
CXX = g++
CXXFLAGS = -g -Wall -O
CXXFLAGS += -I$(CPLEX_DIR)/include
LINK.o = $(LINK.cc)
LDFLAGS += -L$(CPLEX_DIR)/lib/x86-64_linux/static_pic
LDLIBS += -lcplex -lm -pthread
all: main
main.o: cpxmacro.h
clean:
 $(RM) *~ *.o main
.PHONY: all clean
answered Aug 11, 2017 at 12:26
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.