makefile for boost crossplatform - c++

I have created a makefile for a library I am compiling.
I have already got the makefile working on windows and linux , but there is a different makefile for each OS.
How could I allow this to work on both OS without hardcoding the path to the boost library and boost headers below:
Do I need to add the boost folder to the path variable? do I need to add the library directory to some OS variable?
makefile windows:
# source files.
SRC = protoService.cpp protocolBaseServer.cpp client.cpp
OBJ = $(SRC:.cpp=.o)
OUT = ../libutils.a
# include directories
INCLUDES = -I. -I../include/ -IC:\boost_1_59_0\
# C++ compiler flags (-g -O2 -Wall)
CCFLAGS = -g -MD -MP -std=c++0x -Wall -c
# compiler
CCC = g++
# library paths
LIBS = -LC:\boost_1_59_0\libs -lboost_serialization
# compile flags
LDFLAGS = -g
.SUFFIXES: .cpp
default: $(OUT)
.cpp.o:
$(CCC) $(INCLUDES) $(CCFLAGS) $< -o $#
$(OUT): $(OBJ)
ar rcs $(OUT) $(OBJ)
#depend: dep
#dep:
# makedepend -- $(CFLAGS) -- $(INCLUDES) $(SRC)
clean:
rm -f $(OBJ) $(OUT) Makefile.bak
-include $(DEPS:%.o=%.d)
makefile linux:
# source files.
SRC = protoService.cpp protocolBaseServer.cpp client.cpp
OBJ = $(SRC:.cpp=.o)
OUT = ../libutils.a
# include directories
INCLUDES = -I. -I../include/ -I/usr/local/include -I/usr/share/boost_1_58_0/
# C++ compiler flags (-g -O2 -Wall)
CCFLAGS = -g -MD -MP -std=c++0x -Wall -c
# compiler
CCC = g++
# library paths
LIBS = -L/usr/share/boost_1_58_0/lib/ -lboost_serialization
# compile flags
LDFLAGS = -g
.SUFFIXES: .cpp
default: $(OUT)
.cpp.o:
$(CCC) $(INCLUDES) $(CCFLAGS) $< -o $#
$(OUT): $(OBJ)
ar rcs $(OUT) $(OBJ)
#depend: dep
#dep:
# makedepend -- $(CFLAGS) -- $(INCLUDES) $(SRC)
clean:
rm -f $(OBJ) $(OUT) Makefile.bak
-include $(DEPS:%.o=%.d)

Make passes environment variables to the makefile processor, so you can create make variables based on them.
INC_PATHS := ../include/ .
LIBS += boost_serialization
ifeq ($(OS),"Windows_NT")
INC_PATHS += ../include/ C:/boost_1_59_0/libs
LIBS += boost_serialization
else
INC_PATHS += /usr/local/include /usr/share/boost_1_58_0/lib/
endif
And then
INCLUDES = $(prepend -I,$(INC_PATHS))
or something like that. I'm not in front of make to ensure the syntax is exactly correct, but it should get you moving in the right direction.

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)

'SDL2/SDL_image.h' file not found

I'm programming on Xcode. I include SDL_image.h as
#include <SDL2/SDL_image.h>
and it says 'SDL2/SDL_image.h' file not found
I have installed and linked binary with libraries both SDL2.framework and SDL2_image.framework.
I used a Makefile to compile and there is an error: fatal error: 'SDL2/SDL_image.h' file not found
Here is my Makefile
# set the compiler
CC := clang
# set the compiler flags
CXXFLAGS = -std=c++14 -Wall -MMD -Werror=vla pkg-config --cflags --libs sdl2 `-L/Library/Frameworks/ sdl2-config --libs --cflags` -ggdb3 -O0 --std=c99 -Wall -l SDL2_image -lm
# add source files here
SRCS := main.cpp #file-name.c
# generate names of object files
OBJS := $(SRCS:.c=.o)
# name of executable
EXEC := sdl #name your executable file
# default recipe
all: $(EXEC)
showfont: showfont.c Makefile
$(CC) -o $# $#.c $(CFLAGS) $(LIBS)
glfont: glfont.c Makefile
$(CC) -o $# $#.c $(CFLAGS) $(LIBS)
# recipe for building the final executable
$(EXEC): $(OBJS) $(HDRS) Makefile
$(CC) -o $# $(OBJS) $(CFLAGS)
# recipe for building object files
#$(OBJS): $(#:.o=.c) $(HDRS) Makefile
# $(CC) -o $# $(#:.o=.c) -c $(CFLAGS)
# recipe to clean the workspace
clean:
rm -f $(EXEC) $(OBJS)
.PHONY: all clean

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.

Building multiple shared libraries with one Makefile

I'm trying to build multiple shared libraries in one makefile. This is what I'm using to build one shared library:
CC = gcc # C compiler
PWD := $(shell pwd)
CFLAGS = -fPIC -Wall -Wextra -O2 -g # C flags
LDFLAGS = -shared # linking flags
RM = rm -f # rm command
CFLAGS += $(DFLAGS)
TARGET_LIB := lib1.so # target lib
#TARGET_LIB += lib2.so
SRCS := lib1.c # source files
#SRCS += lib2.c # source files
OBJS = $(SRCS:.c=.o)
.PHONY: all
all: $(TARGET_LIB)
$(TARGET_LIB): $(OBJS)
$(CC) $(INC) $(LDFLAGS) $(CFLAGS) -o $# $^
However, I can't just uncomment the lines for lib2 and have it being built as well. It's likely because $(TARGET_LIB): $(OBJS) expands to lib1.so lib2.so : lib1.o lib2.o which isn't what I want.
Instead, I want something like
lib1.so : lib1.o
lib2.so : lib2.o
But I'm not sure how to do so or what it is called. Can someone tell me what to do to achieve what I'm looking for?
EDIT: I should have been more clear. I realize you can add more targets to build these. But is there a way to do it without having to write a new target everytime I want to add a new library?
Thanks.
You can do something like this -
all : lib1.so lib2.so
and provide rules to make lib1.so and lib2.so
You can separate sources of two libraries into different directories. It also may help in further maintenance of your libraries. Then use one make file which will trigger corresponding sub-makefiles. I may be better than one big makefile
You can do it by separating targets like this:
CC = gcc # C compiler
PWD := $(shell pwd)
CFLAGS = -fPIC -Wall -Wextra -O2 -g # C flags
LDFLAGS = -shared # linking flags
RM = rm -f # rm command
CFLAGS += $(DFLAGS)
TARGET_LIB1 = lib1.so # target lib
TARGET_LIB2 = lib2.so
TARGET_LIBS = $(TARGET_LIB1) $(TARGET_LIB2)
SRCS1 = lib1.c # source files
SRCS2 = lib2.c # source files
SRCS = $(SRCS1) $(SRCS2)
OBJS1 = $(SRCS1:.c=.o)
OBJS2 = $(SRCS2:.c=.o)
OBJS = $(OBJS1) $(OBJS2)
.PHONY: all
all: $(TARGET_LIBS)
$(TARGET_LIB1): $(OBJS1)
$(CC) $(INC) $(LDFLAGS) $(CFLAGS) -o $# $^
$(TARGET_LIB2): $(OBJS2)
$(CC) $(INC) $(LDFLAGS) $(CFLAGS) -o $# $^
The implicit rules are for that. Read about them in the GNU Make manual.
Replace
$(TARGET_LIB): $(OBJS)
with
%.so: %.c

Makefile C++11 - Compiling to static library

I am trying to compile my source files to a static library, however, it doesn't seem to want to work. Here is the code:
#-----------------------------------------------------------------------------
# Usage of make file
#-----------------------------------------------------------------------------
# Clean operation:
# make -f MakeClient clean
#
# Make operation:
# make -f MakeClient
#
#
#OBJ = $(SRC:.cpp=.o)
OBJ_DIR = ./obj
OUT_DIR= ../lib
OUT_FILE_NAME = libclient.a
# include directories
INCLUDES=-I. -I../common -I../../depends -I../../depends/zlib
# C++ compiler flags (-g -O2 -Wall)
CXXFLAGS := -Wall -Wextra -pedantic-errors -std+c++0x
# compiler
CCC = g++
# Enumerating of every *.cpp as *.o and using that as dependency
$(OUT_FILE_NAME): $(patsubst %.cpp,$(OBJ_DIR)/%.o,$(wildcard *.cpp))
$(CCC) -o $(OUT_DIR)/$# $^ -static $(LIB_DIR) $(LIBS) -std=c++11
#Compiling every *.cpp to *.o
$(OBJ_DIR)/%.o: %.cpp dircreation
$(CCC) -c $(INCLUDES) $(CCFLAGS) -o $# $<
dircreation:
#mkdir -p $(OUT_DIR)
#mkdir -p $(OBJ_DIR)
.PHONY : clean
clean:
rm -f $(OBJ_DIR)/*.o $(OUT_DIR)/$(OUT_FILE_NAME) Makefile.bak
The problem seems to be recognising that I'm using C++11 since the actual code does not compile.
Any ideas?
Replace CCFLAGS with CXXFLAGS, or vice versa.
And the flag is spelled -std=c++0x (thanks, #Pixelchemist).