I am working on the project which has to include the CPLEX tool at some point.
More in detail, I have the following classes implemented
(i.e. the corresponding files): Random.cpp, Instance.cpp, Timer.cpp. Solution.cpp which are included into Hybrid_ea.cpp which also have to include cplex library.
Finally, the project has been executed by running Algorithm.cpp (the main() function defined here).
I want to run the project on Linux platform, creating Makefile which looks like:
TARGET = Algorithm
CXXFLAGS = -ansi -O3
GENOBJS = Random.o
#CPLOBJS = Timer.o Random.o Instance.o Hybrid_ea.o
GREOBJS = Timer.o Random.o Instance.o Solution.o Hybrid_ea.o
SYSTEM = x86-64_linux
LIBFORMAT = static_pic
CPLEXDIR = /home/root/Desktop/projects/software/cplex-12.5/cplex
CONCERTDIR = /home/root/Desktop/projects/software/cplex-12.5/concert
CCC = g++
CCOPT = -m64 -O -fPIC -fexceptions -DNDEBUG -DIL_STD -std=c++11 -fpermissive -w
CPLEXBINDIR = $(CPLEXDIR)/bin/$(BINDIST)
CPLEXLIBDIR = $(CPLEXDIR)/lib/$(SYSTEM)/$(LIBFORMAT)
CONCERTLIBDIR = $(CONCERTDIR)/lib/$(SYSTEM)/$(LIBFORMAT)
CCLNFLAGS = -L$(CPLEXLIBDIR) -lilocplex -lcplex -L$(CONCERTLIBDIR) -lconcert -lm -pthread
CLNFLAGS = -L$(CPLEXLIBDIR) -lcplex -lm -pthread
CONCERTINCDIR = $(CONCERTDIR)/include
CPLEXINCDIR = $(CPLEXDIR)/include
CCFLAGS = $(CCOPT) -I$(CPLEXINCDIR) -I$(CONCERTINCDIR)
all: ${TARGET}
Algorithm: Algorithm.o $(GREOBJS)
$(CCC) $(CCFLAGS) Algorithm.o $(GREOBJS) -o Algorithm $(CCLNFLAGS)
Algorithm.o: Algorithm.cpp
$(CCC) -c $(CCFLAGS) Algorithm.cpp -o Algorithm.o
clean:
#rm -f *~ *.o ${TARGET} core
The linking process is somehow wrong. I checked, my CPLEX version is the right one since the others, simpler projects can be executed;
The full output given when trying to compile the project:
g++ -c -m64 -O -fPIC -fexceptions -DNDEBUG -DIL_STD -std=c++11 -fpermissive -w -I/home/root/Desktop/projects/LCAPS_software/cplex-12.5/cplex/include -I/home/root/Desktop/projects/LCAPS_software/cplex-12.5/concert/include Algorithm.cpp -o Algorithm.o
g++ -ansi -O3 -c -o Timer.o Timer.cc
g++ -ansi -O3 -c -o Random.o Random.cc
g++ -ansi -O3 -c -o Instance.o Instance.cpp
g++ -ansi -O3 -c -o Solution.o Solution.cpp
g++ -ansi -O3 -c -o hybrid_ea.o hybrid_ea.cpp
In file included from hybrid_ea.cpp:22:0:
hybrid_ea.h:39:10: fatal error: ilcplex/ilocplex.h: No such file or directory
#include <ilcplex/ilocplex.h>
^~~~~~~~~~~~~~~~~~~~
compilation terminated.
<builtin>: recipe for target 'hybrid_ea.o' failed
make: *** [hybrid_ea.o] Error 1
Any help would be appreciated.
Only the file Algorithm.cpp is compiled with appropriate options for finding the CPLEX include files:
-I/home/root/Desktop/projects/LCAPS_software/cplex-12.5/cplex/include
-I/home/root/Desktop/projects/LCAPS_software/cplex-12.5/concert/include
As hybrid_ea.h also tries to include some CPLEX header files, the compilation of hybrid_ea.cpp should also have the options above.
If the makefile that you posted in your question is complete, then I suspect that the issue is the following: you didn't define a specific command to compile any .cc or .cpp file, except for Algorithm.cpp. Therefore, all other files are compiled using a default command g++ -ansi -O3 -c -o [file].o [file].cpp. And this default command doesn't have the include directives for the location of the CPLEX libraries.
As explained in ftp://ftp.gnu.org/old-gnu/Manuals/make-3.79.1/html_chapter/make_10.html, these files are compiled using make's implicit rules. The implicit rule for C++ files is to use $(CXX) -c $(CPPFLAGS) $(CXXFLAGS). Notice how this rule uses CPPFLAGS and CXXFLAGS rather than the variable CCFLAGS that you defined at the end of your makefile to include the proper include directives.
So changing the end of your makefile to the following should work:
CPPFLAGS = $(CCOPT) -I$(CPLEXINCDIR) -I$(CONCERTINCDIR)
all: ${TARGET}
Algorithm: Algorithm.o $(GREOBJS)
$(CCC) $(CCFLAGS) Algorithm.o $(GREOBJS) -o Algorithm $(CCLNFLAGS)
clean:
#rm -f *~ *.o ${TARGET} core
Once you define the variable CPPFLAGS, it will be used automatically to compile any .cpp file that you have in your project.
Related
I am trying to convert a Makefile project to cmake.
My project has an executable which gets built and linked to both an internal shared library, and an external shared library (there are dependencies in the executable to both).
Here is my old Makefile (generalised):
Include = -I$(PROJ_DIRECTORY)/include -I/${EXTERN}/lnInclude
Library = -L$(PROJ_DIRECTORY)/build -lshared -L$(EXTERN_LIBBIN) -lextern
CPPFLAGS = -D_GLIBCXX_DEBUG -DProjectRescource=$(PROJ_DIRECTORY)/resources -O0 -g3 -Wall -c -fpermissive -std=c++0x -fPIC -MMD -MP
CCC = g++
TARGET = ExecutableName
all: $(TARGET)
clean:
rm -f $(TARGET).o $(TARGET).d $(TARGET)
$(TARGET) : $(TARGET).o
$(CCC) -o $(TARGET) $(TARGET).o $(Library)
$(TARGET).o :
$(CCC) $(Include) $(CPPFLAGS) $(TARGET).cpp
Here is my attempt at CMakeLists.txt (generalised):
include_directories(${PROJECT_SOURCE_DIR}/include/)
add_executable(test1 test1.cpp)
set (CMAKE_CXX_FLAGS "-D_GLIBCXX_DEBUG -DProjectRescource=${PROJECT_SOURCE_DIR}/resources -O0 -g3 -Wall -fpermissive -std=c++0x -fPIC -MMD -MP")
include_directories($ENV{EXTERN_INCLUDE}/lnInclude)
target_link_libraries(test1 "$ENV{EXTERN_LIBBIN}/libextern.so" Project)
When I run the executable, calls to functions defined in the include directory return -nan. Does anyone know why?
The reason for the issue was due to the linking order of the shared libraries.
I was able to solve the problem by changing the last line of CMakeLists.txt to:
target_link_libraries(test1 Project "$ENV{EXTERN_LIBBIN}/libextern.so")
i'm trying to use the boost_math libs on OS X (i'm not using Xcode), specifically the one containing the error function
I downloaded and compiled boost_1_60_0 myself (using bootstrap.sh and following the instructions.) I didn't use home-brew or something else, which might be why my installation seems so screwed up.
What i'm trying to include in my Szabo.hpp is this:
#include <boost/math/special_functions/erf.hpp>
My makefile goes like this:
LIB_FLAGS = -L/Documents/boost_1_60_0/stage/lib -lboost_math
ALL_OBJECTS = main.o Gaussienne.o Grille.o Szabo.o
all: $(ALL_OBJECTS)
g++ -o hydrogene $(ALL_OBJECTS) $(LIB_FLAGS)
Gaussienne.o: Gaussienne.cpp
g++ -o Gaussienne.o -c Gaussienne.cpp -W -Wall -ansi
main.o: Gaussienne.hpp Grille.hpp main.cpp Szabo.o
g++ -o main.o -c main.cpp -W -Wall -ansi
Grille.o: Grille.cpp Gaussienne.cpp
g++ -o Grille.o -c Grille.cpp -W -Wall -ansi
Szabo.o: Szabo.cpp Gaussienne.cpp
g++ -o Szabo.o -c Szabo.cpp -W -Wall -ansi
clean:
rm -rf *.o
mrproper: clean
rm -rf hydrogene
I get no linking error from g++, however i got:
In file included from Szabo.cpp:12:
./Szabo.hpp:21:10: fatal error: 'boost/math/special_functions/erf.hpp' file not found
#include <boost/math/special_functions/erf.hpp>
^
1 error generated.
Can you please provide help on how to fix this? Thanks in advance
Ok so apparently likes this, it works:
LIB_FLAGS = -L/Users/devolution/Documents/boost_1_60_0/stage/lib -lboost_math_tr1
I_FLAGS = -I/Users/devolution/Documents/boost_1_60_0/
ALL_OBJECTS = main.o Gaussienne.o Grille.o Szabo.o
all: $(ALL_OBJECTS)
g++ -o hydrogene $(ALL_OBJECTS) $(LIB_FLAGS)
Gaussienne.o: Gaussienne.cpp
g++ -o Gaussienne.o -c Gaussienne.cpp -ansi ${I_FLAGS}
main.o: Gaussienne.hpp Grille.hpp main.cpp Szabo.o
g++ -o main.o -c main.cpp -ansi ${I_FLAGS}
Grille.o: Grille.cpp Gaussienne.cpp
g++ -o Grille.o -c Grille.cpp -ansi ${I_FLAGS}
Szabo.o: Szabo.cpp Gaussienne.cpp
g++ -o Szabo.o -c Szabo.cpp -ansi ${I_FLAGS}
.PHONY: clean mrproper
clean:
rm -rf *.o
mrproper: clean
rm -rf hydrogene
Is there a way to pass I_FLAGS?
You've compiled Boost's separately-compiled libraries, which is great, but you didn't copy the headers to your toolchain's include path. Indeed, most of Boost is comprised of header-only libraries, so this is arguably the more crucial step of installing Boost.
The internet tells me you may be able to find the default header search path with the following command at shell:
gcc -x c++ -v -E /dev/null
(https://stackoverflow.com/a/19852298/560648)
When you find it, copy the distribution's boost subdirectory to it.
And, yes, having home-brew install Boost for you would have been much easier… probably one command!
# Compiler
CXX := g++
CF := -g
# c files
CFILES := $(wildcard src/*.cpp)
SOURCES := $(CFILES) # $(CFILES2) all CFILES
# o files
OBJECTS := $(SOURCES:.cpp=.o)
OBJECTS_A:= $(SOURCES:.cpp=_a.o)
# Macros
MACRO = -D
INFO = -DINFO // optional
DCDREAD = -DDCDREAD
# More Macros
DEFAULT = -DDEFAULT
CONTACT = -DDEFAULT -DCONTACT -DCONTACTPERSIST -DTENSION_COSTHETA
MTCONTACT = -DDEFAULT -DMTCON1 -DMTCON2
DCDCON = -DDCDREAD -DCONTACT -DCONTACTPERSIST -DTENSION_COSTHETA
DCDMT = -DDCDREAD -DMTCON1 -DMTCON2
CENMOV = -DDCDREAD -DMTCON1 -DCENTROIDMOVEMENT
ANGLE = -DDCDREAD -DINERTIA -DANGLE
ANG3 = -DDCDREAD -DMTCON1 -DANGLE3CENTROID
ang3o: $(OBJECTS_A)
$(CXX) $(OBJECTS_A) -o test/$(EXEC)_dcd_angle3centroid
cd test && ./$(EXEC)_dcd_angle3centroid mtonly_seamup.ref.pdb mtonly_seamup_d1_indent.dcd 1 209 1
ang3: $(OBJECTS)
$(CXX) $(SOURCES) $(CF) $(INC) $(LIB) $(ANG3) -o test/$(EXEC)_dcd_angle3centroid
cd test && ./$(EXEC)_dcd_angle3centroid mtonly_seamup.ref.pdb mtonly_seamup_d1_indent.dcd 1 209 1
# To obtain object files
$(OBJECTS_A) : $(SOURCES)
$(CXX) $(CF) $(INC) $(LIB) $(ANG3) -c $< -o $#
%.o: %.cpp
$(CXX) $(CC_FLAGS) $(INC) $(LIB) -c $< -o $#
I know the objects are unnecessary in the ANG3 rule. The c files are compiled directly, the executable runs correctly! I'd like to switch to objects, an ANG3O rule. HERE is my main question, am I trying to link .o files incorrectly at the end of the ANG3O rule?
ANG3 works.
ANG3O fails. Multiple Definitions of Function Error.
make ang3
g++ -g -O3 -Iinclude -pthread -c src/readfile.cpp -o src/readfile.o
g++ -g -O3 -Iinclude -pthread -c src/main.cpp -o src/main.o
g++ -g -O3 -Iinclude -pthread -c src/md.cpp -o src/md.o
g++ -g -O3 -Iinclude -pthread -c src/chain.cpp -o src/chain.o
g++ src/readfile.cpp src/main.cpp src/md.cpp src/chain.cpp -g -Iinclude -pthread -DDCDREAD -DMTCON1 -DANGLE3CENTROID -o test/run_segment_dcd_angle3centroid
make ang3o
g++ -g -Iinclude -pthread -DDCDREAD -DMTCON1 -DANGLE3CENTROID -c src/readfile.cpp -o src/readfile_a.o
g++ -g -Iinclude -pthread -DDCDREAD -DMTCON1 -DANGLE3CENTROID -c src/readfile.cpp -o src/main_a.o
g++ -g -Iinclude -pthread -DDCDREAD -DMTCON1 -DANGLE3CENTROID -c src/readfile.cpp -o src/md_a.o
g++ -g -Iinclude -pthread -DDCDREAD -DMTCON1 -DANGLE3CENTROID -c src/readfile.cpp -o src/chain_a.o
g++ src/readfile_a.o src/main_a.o src/md_a.o src/chain_a.o -o test/run_segment_dcd_angle3centroid
src/main_a.o: In function `ReadLines(Chain*)':
/home/d/sop_dev/contacts/segment/src/readfile.cpp:43: multiple definition of `ReadLines(Chain*)'
src/readfile_a.o:/home/d/sop_dev/contacts/segment/src/readfile.cpp:43: first defined here
src/main_a.o: In function `ReadMolecularContent(char*)':
/home/d/sop_dev/contacts/segment/src/readfile.cpp:208: multiple definition of `ReadMolecularContent(char*)'
src/readfile_a.o:/home/d/sop_dev/contacts/segment/src/readfile.cpp:208: first defined here
src/md_a.o: In function `ReadLines(Chain*)':
/home/d/sop_dev/contacts/segment/src/readfile.cpp:43: multiple definition of `ReadLines(Chain*)'
src/readfile_a.o:/home/d/sop_dev/contacts/segment/src/readfile.cpp:43: first defined here
src/md_a.o: In function `ReadMolecularContent(char*)':
/home/d/sop_dev/contacts/segment/src/readfile.cpp:208: multiple definition of `ReadMolecularContent(char*)'
src/readfile_a.o:/home/d/sop_dev/contacts/segment/src/readfile.cpp:208: first defined here
src/chain_a.o: In function `ReadLines(Chain*)':
/home/d/sop_dev/contacts/segment/src/readfile.cpp:43: multiple definition of `ReadLines(Chain*)'
src/readfile_a.o:/home/d/sop_dev/contacts/segment/src/readfile.cpp:43: first defined here
src/chain_a.o: In function `ReadMolecularContent(char*)':
/home/d/sop_dev/contacts/segment/src/readfile.cpp:208: multiple definition of `ReadMolecularContent(char*)'
src/readfile_a.o:/home/d/sop_dev/contacts/segment/src/readfile.cpp:208: first defined here
/usr/lib/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../lib/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:172: recipe for target 'ang3o' failed
make: *** [ang3o] Error 1
NOTES:
Related question: Error with multiple definitions of function
Possibly related: One definition rule and different class definitions in two translation units
However, in my situation:
the headers are in the include directory. The c files are in a src directory. All functions are declared in the headers. Only headers are included, no c/cpp files. Makefile examples seem to halt just before this level of complexity, the use of different define segments of code, and the need to compile objects with/without certain defined sections.
It helps to actually read the output.
g++ -g -Iinclude -pthread -DDCDREAD -DMTCON1 -DANGLE3CENTROID -c src/readfile.cpp -o src/readfile_a.o
g++ -g -Iinclude -pthread -DDCDREAD -DMTCON1 -DANGLE3CENTROID -c src/readfile.cpp -o src/main_a.o
g++ -g -Iinclude -pthread -DDCDREAD -DMTCON1 -DANGLE3CENTROID -c src/readfile.cpp -o src/md_a.o
g++ -g -Iinclude -pthread -DDCDREAD -DMTCON1 -DANGLE3CENTROID -c src/readfile.cpp -o src/chain_a.o
You're compiling the same C++ source file over and over again, then linking it to itself.
Your mistake is in the recipe to build objects. I'll leave you to read the documentation and find out why.
I have a makefile as follows:
# Makefile for VocabLearn
MACHTYPE=$(shell uname -m)
GCC = g++
CC=gcc
# OPTFLAGS=-g2
OPTFLAGS=-O3 -ffast-math -Wall -mfpmath=sse -msse2 -funroll-loops -march=core2
OTHERFLAGS=-Wall -fopenmp
INCLUDE_PATH=-I../lib/ann_1.1/include/ANN -I../lib/ann_1.1_char/include/ANN \
-I../lib/imagelib -I../VocabLib -I../lib/zlib/include
LIB_PATH=-L../lib -L../VocabLib -L../lib/zlib/lib
OBJS=VocabLearn.o
LIBS=-lvocab -lANN -lANN_char -limage -lz
CPPFLAGS=$(INCLUDE_PATH) $(LIB_PATH) $(OTHERFLAGS) $(OPTFLAGS)
BIN=VocabLearn
all: $(BIN)
$(BIN): $(OBJS)
g++ -o $(CPPFLAGS) -o $(BIN) $(OBJS) $(LIBS)
clean:
rm -f *.o *~ $(LIB)
When I 'make' it in the prompt, it works fine and output the following info:(I use Mac OS, c++ means clang compiler)
c++ -I../lib/ann_1.1/include/ANN -I../lib/ann_1.1_char/include/ANN
-I../lib/imagelib -I../VocabLib -I../lib/zlib/include -L../lib -L../VocabLib -L../lib/zlib/lib -Wall -fopenmp -O3 -ffast-math -Wall -mfpmath=sse -msse2 -funroll-loops -march=core2 -c -o VocabLearn.o VocabLearn.cpp
g++ -o -I../lib/ann_1.1/include/ANN -I../lib/ann_1.1_char/include/ANN
-I../lib/imagelib -I../VocabLib -I../lib/zlib/include -L../lib -L../VocabLib -L../lib/zlib/lib -Wall -fopenmp -O3 -ffast-math -Wall -mfpmath=sse -msse2 -funroll-loops -march=core2 -o VocabLearn VocabLearn.o -lvocab -lANN -lANN_char -limage -lz
I just want to know how this makefile works. As you can see, since this makefile doesn't specify which source code to compile, how does the compiler know it is 'VocabLearn.cpp' that it should process? (My guess is that it will search source file according to the name of the object file, VocabLearn.o) Also this line seems a bit strange for me:
g++ -o $(CPPFLAGS) -o $(BIN) $(OBJS) $(LIBS)
Why is there a '-o' before '$(CPPFLAGS)'?
This makefile is using implicit rules to compile the source files. The rule:
$(BIN): $(OBJS)
asks for the object files in OBJS, and make already knows how to build VocabLearn.o if there is a file VocabLean.cpp.
Basically there is an implicit rule to convert *.cpp files to *.o files, however you have to have *.o as a dependency in one your targets. In the given Makefile, you have VocabLearn.o as a dependency for $(BIN). So, VocabLearn.o gets auto-generated from VocabLearn.cpp file.
I'm trying to compile a program (which isn't mine):
make -f makefile
... using the following makefile:
# Compiler for .cpp files
CPP = g++
# Use nvcc to compile .cu files
NVCC = nvcc
NVCCFLAGS = -arch sm_20 # For fermi's in keeneland
# Add CUDA Paths
ICUDA = /usr/lib/nvidia-cuda-toolkit/include
LCUDA = /usr/lib/nvidia-cuda-toolkit/lib64
# Add CUDA libraries to the link line
LFLAGS += -lcuda -lcudart -L$(LCUDA) -lgomp
# Include standard optimization flags
CPPFLAGS = -O3 -c -I $(ICUDA) -Xcompiler -fopenmp -DTHRUST_DEVICE_BACKEND=THRUST_DEVICE_BACKEND_OMP
# List of all the objects you need
OBJECTS = timer.o ar1.o kGrid.o vfInit.o parameters.o
# Rule that tells make how to make the program from the objects
main : main.o $(OBJECTS)
$(CPP) -o main main.o $(OBJECTS) $(LFLAGS)
# Rule that tells make how to turn a .cu file into a .o
%.o: %.cu
$(NVCC) ${NVCCFLAGS} $(CPPFLAGS) -c $<
# How does make know how to turn a .cpp into a .o? It's built-in!
# but if you wanted to type it out it would look like:
# %.o: %.cpp
# $(CPP) $(CPPFLAGS) -c $<
clean :
rm -f *.o
rm -f core core.*
veryclean :
rm -f *.o
rm -f core core.*
rm -f main
Which results in the following commands:
nvcc -arch sm_20 -O3 -c -I /usr/lib/nvidia-cuda-toolkit/include -Xcompiler -fopenmp -DTHRUST_DEVICE_BACKEND=THRUST_DEVICE_BACKEND_OMP -c main.cu
g++ -O3 -c -I /usr/lib/nvidia-cuda-toolkit/include -Xcompiler -fopenmp -DTHRUST_DEVICE_BACKEND=THRUST_DEVICE_BACKEND_OMP -c -o timer.o timer.cpp
g++: error: unrecognized command line option â-Xcompilerâ
make: *** [timer.o] Error 1
I don't understand the makefile: the -xCompiler flag (in the variable CPPFLAGS) should be used only by the nvcc compiler, not g++. Therefore, I understand why I am getting an error. However, I don't understand, from my basic understanding of the makefile above, why at some point the variable CPPFLAGS follows g++ (variable CPP). I don't see any such sequence in the makefile.
Your main rule requires timer.o. There is no explicit rule for timer.o so make uses a built in implicit rule (as mentioned in the comment at the end of your makefile). The implicit rule for converting .cpp files into .o files has the form
$(CPP) $(CPPFLAGS) -c $<
So it's compiling using the options in CPPFLAGS which contains -Xcompiler. You probably want the -Xcompiler flag to be in NVCCFLAGS and not CPPFLAGS.