Conversion of Makefile to CMake - c++

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")

Related

Error while loading shared libraries when running executable

When I make the Makefile everything works fine, I get a library in the directory dir. And when I run "Make test" I get a testfile that I want to run. But when I want to run this file I get this weird error: ./programma: error while loading shared libraries: libprogramma.so: cannot open shared object file: No such file or directory. I have tried running the program on both WSL and Linux, but nothing makes this error go away. Can anyone help me?
Here I have my Makefile which makes the library and the executable:
INC_DIR = include
SRC_DIR = src
SOURCES = $(sort $(shell find $(SRC_DIR) -name '*.cc'))
OBJECTS = $(SOURCES:.cc=.o)
DEPS = $(OBJECTS:.o=.d)
TARGET = programma
CXX = g++
CFLAGS = -Wall -Wextra -Wpedantic -std=c++11
CPPFLAGS = $(addprefix -I, $(INC_DIR))
.PHONY: all clean debug release
release: CFLAGS += -O3 -DNDEBUG
release: all
debug: CFLAGS += -O0 -DDEBUG -ggdb3
debug: all
all: $(TARGET)
clean:
rm -f $(OBJECTS) $(DEPS) lib/*.so programma *.d
$(TARGET): $(OBJECTS)
$(CXX) $(CFLAGS) $(CPPFLAGS) -fPIC -shared -o lib/lib$#.so $^
-include $(DEPS)
%.o: %.cc
$(CXX) $(CFLAGS) $(CPPFLAGS) -fPIC -MMD -o $# -c $<
test:
$(CXX) $(CFLAGS) -L./lib $(CPPFLAGS) -MMD -o programma tests/main.cc -l$(TARGET)
Executables on Linux don't look for shared libraries in the directory they're located in, at least by default.
You can either fix that at link-time, by passing -Wl,-rpath='$ORIGIN', or at runtime, by setting LD_LIBRARY_PATH env variable to the directory with the library. (LD_LIBRARY_PATH=path/to/lib ./programma)

Error while compiling a project which includes CPLEX tool

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.

makefile not finding header file from -I include path

I have the makefile given below. When I do make I get the following error
cc -c -o timing.o timing.c
test_c.c:5:17: fatal error: test.h: No such file or directory
#include "test.h"
I have manually verfied that test.h is present in ../include path. I am not sure why this is not finding the header file.It would be great if someone could help.Also I would expect g++ instead of cc
# Makefile template for shared library
CXX = g++ # C++ compiler
CXXFLAGS = -fPIC -Wall -Wextra -O2 -g -I../include #CXX flags
LDFLAGS = -lboost_system -shared # linking flags
RM = rm -f # rm command
TARGET_LIB = libtest.a # target lib
C_SRCS := test_a.c test_b.c
CPP_SRCS := test_c.cpp test_d.cpp
OBJS := $(C_SRCS:.c=.o) $(CPP_SRCS:.cpp=.o)
.PHONY: all
all: ${TARGET_LIB}
$(TARGET_LIB): $(OBJS)
$(CXX) $(CXXFLAGS) ${LDFLAGS} -o $# $^
.PHONY: clean
clean:
-${RM} ${TARGET_LIB} ${OBJS}
~
You have not written a rule for building timing.o from timing.c, so Make uses the default rule it has for that.
But that rule uses CFLAGS, not CXXFLAGS. The CXXFLAGS variable appears in the rule for building object files from C++ sources.
So modify CFLAGS instead of CXXFLAGS, and it should work.

Cannot properly use the Makefile for some course files

I am trying to work through the following http://www.cs.columbia.edu/~keenan/Projects/DGPDEC/paper.pdf. The following source files are used to illustrate what is going on https://github.com/dgpdec/course. Now I cannot get it to work. Here is what I tried:
First I went into the folder 'basecode', edited the Makefile to have the right include and library paths. Then I want to make but it gives me the error
'ostream’ in namespace ‘std’ does not name a type
I looked for this error online but I could not find a solution to the problem. In the included file libddg_userguide.pdf it says that I should edit the Makefile in root libddg folder but I don't know which folder that is. I am sorry for the kind of nooby question but I am really stuck and have been trying for a long time. Here is the Makefile I used (in the Basecode folder) for reference:
##########################################################################################
# Specify library locations here (add or remove "#" marks to comment/uncomment lines for your platform)
# Linux
DDG_INCLUDE_PATH = -I/usr/include/ -I/usr/local/include -I/usr/include/suitesparse
DDG_LIBRARY_PATH = -L/usr/lib -L/usr/local/lib
DDG_BLAS_LIBS = -llapack -lblas -lgfortran
DDG_SUITESPARSE_LIBS = -lspqr -lcholmod -lmetis -lcolamd -lccolamd -lcamd -lamd -lm
DDG_OPENGL_LIBS = -lglut -lGL -lGLU -lX11
########################################################################################
TARGET = ddg
CC = g++
LD = g++
CFLAGS = -O3 -Wall -Werror -ansi -pedantic $(DDG_INCLUDE_PATH) -I./include -I./src
LFLAGS = -O3 -Wall -Werror -ansi -pedantic $(DDG_LIBRARY_PATH)
LIBS = $(DDG_OPENGL_LIBS) $(DDG_SUITESPARSE_LIBS) $(DDG_BLAS_LIBS)
########################################################################################
## !! Do not edit below this line
HEADERS := $(wildcard include/*.h)
SOURCES := $(wildcard src/*.cpp)
OBJECTS := $(addprefix obj/,$(notdir $(SOURCES:.cpp=.o)))
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(LD) $(OBJECTS) -o $(TARGET) $(CFLAGS) $(LFLAGS) $(LIBS)
obj/%.o: src/%.cpp ${HEADERS}
$(CC) -c $< -o $# $(CFLAGS)
clean:
rm -f $(OBJECTS)
rm -f $(TARGET)
rm -f $(TARGET).exe
Thanks in advance for any help!
It means there is a bug in the code: a header's missing because someone made an assumption.
Your particular toolchain does not satisfy that assumption.
Find the problematic file (you didn't say which it is) and add #include <ostream> to it.
(course/Connection/include/DenseMatrix.h appears to be one such file; there may be others.)
N.B. I must say that, despite the bug, overall this is incredibly good C++ code for a University course. I'm impressed.

Multiple compile modes in makefile

I want to use a single make file to generate a project in multiple modes, and then each mode in a "normal" and "debug" mode, ie:
I have the following files (ofc more in reality, but this will serve to show my point):
kernel/core/main.cpp
kernel/processor/Processor.cpp
kernel/processor/x86/Processor.cpp
kernel/processor/x86_common/Processor.cpp
kernel/processor/x64/Processor.cpp
And i want to be able to use my makefile in the following ways:
make x86
(compiles all files except "kernel/processor/x64/Processor.cpp")
(enables the pre-processor directives X86 & X86_COMMON)
And,
make x86debug
(compiles all files except "kernel/processor/x64/Processor.cpp")
(enables the pre-processor directives X86 & X86_COMMON & DEBUG)
(puts "-g -ggdb" infront of all gcc/g++/as arguments)
And so on.
Currently i have the following makefile, which while it works, only lets me compile in x86-debug mode and now that i am porting my software to other platforms I wish to be able to specify what mode to build in.
CC = i586-elf-g++
CFLAGS = -g -ggdb -ffreestanding -Wall -Wextra -fno-exceptions -fno-rtti -std=gnu++11 -Isrc/system/include -DX86 -DX86_COMMON
LD = i586-elf-gcc
LDFLAGS = -g -ggdb -ffreestanding -O2 -nostdlib -lgcc
AS = i586-elf-as
ASFLAGS = -g -ggdb
OBJECTS = src/system/kernel/core/main.o
ALL_OBJECTS = $(OBJECTS) $(X86_OBJECTS)
X86COMMON_OBJECTS = src/system/kernel/core/processor/x86_common/Processor.o
X86_OBJECTS = $(X86COMMON_OBJECTS) src/system/kernel/core/processor/x86/boot.o
X86_LINKER = src/system/kernel/core/processor/x86/link.ld
X86_OUTPUT = bin/kernel_x86.bin
.PHONY: clean
clean: $(ALL_OBJECTS)
rm $(ALL_OBJECTS)
.PHONY: all
all: $(X86_OUTPUT)
$(X86_OUTPUT): $(X86_LINKER) $(OBJECTS) $(X86_OBJECTS)
$(LD) $(LDFLAGS) -T $(X86_LINKER) $^ -o $#
%.o: %.cpp
$(CC) $(CFLAGS) -c $< -o $#
%.o: %.asm
$(AS) $(ASFLAGS) $< -o $#
As you can probably tell, im not an expert with make so any help/ideas would be appreciated.
Remove -g from CFLAGS and LDFLAGS, and add the following PHONY:
.PHONY: x86_debug
x86_debug: CFLAGS += -g
x86_debug: LDFLAGS += -g
x86_debug: $(X86_OUTPUT)
To compile in normal mode: make.
To compile in debug mode: make x86_debug
It may not do exactly what you're expecting, but it's easy to modify