Linking Boost::system library with OpenNI makefile - c++

I'm trying to use the C++ Boost library to write some depth data I get form my Kinect to the serial port. In order to do this I need to link the appropriate libraries with this pre-written Makefile. I wrote a basic program using boost/asio to get a feel for the libraries and in order to compile I had to link to the boost_system library located in /usr/local/lib and include the header files from /usr/local/include/boost. I figured to use it in my OpenNI code I'd just have to make the same connection from this Makefile instead.
# take this file's dir
COMMON_CPP_MAKE_FILE_DIR = $(dir $(lastword $(MAKEFILE_LIST)))
include $(COMMON_CPP_MAKE_FILE_DIR)CommonDefs.mak
# define a function to figure .o file for each source file (placed under intermediate directory)
SRC_TO_OBJ = $(addprefix ./$(INT_DIR)/,$(addsuffix .o,$(notdir $(basename $1))))
# create a list of all object files
OBJ_FILES = $(call SRC_TO_OBJ,$(SRC_FILES_LIST))
# define a function to translate any source file to its dependency file (note that the way we create
# dep files, as a side affect of compilation, always puts the files in the INT_DIR with suffix .d)
SRC_TO_DEP = $(addprefix ./$(INT_DIR)/,$(addsuffix .d,$(notdir $(basename $1))))
# create a list of all dependency files
DEP_FILES = $(call SRC_TO_DEP,$(SRC_FILES_LIST))
# older version of gcc doesn't support the '=' symbol in include dirs, so we replace it ourselves with sysroot
INC_DIRS_FROM_SYSROOT = $(patsubst =/%,$(TARGET_SYS_ROOT)/%,$(INC_DIRS))
# append the -I switch to each include directory
INC_DIRS_OPTION = $(foreach dir,$(INC_DIRS_FROM_SYSROOT),-I$(dir)) -I/usr/local/include/boost
# append the -L switch to each library directory
LIB_DIRS_OPTION = $(foreach dir,$(LIB_DIRS),-L$(dir)) -L$(OUT_DIR) -L/usr/local/lib
# append the -l switch to each library used
USED_LIBS_OPTION = $(foreach lib,$(USED_LIBS),-l$(lib)) -lboost_system
# append the -D switch to each define
DEFINES_OPTION = $(foreach def,$(DEFINES),-D$(def))
# tell compiler to use the target system root
ifdef TARGET_SYS_ROOT
CFLAGS += --sysroot=$(TARGET_SYS_ROOT)
LDFLAGS += --sysroot=$(TARGET_SYS_ROOT)
endif
# set Debug / Release flags
ifeq "$(CFG)" "Debug"
CFLAGS += -O0 -g
endif
ifeq "$(CFG)" "Release"
CFLAGS += -O2 -DNDEBUG
endif
CFLAGS += $(INC_DIRS_OPTION) $(DEFINES_OPTION)
LDFLAGS += $(LIB_DIRS_OPTION) $(USED_LIBS_OPTION)
# some lib / exe specifics
ifneq "$(LIB_NAME)" ""
OUTPUT_NAME = lib$(LIB_NAME).so
CFLAGS += -fPIC -fvisibility=hidden
ifneq ("$(OSTYPE)","Darwin")
LDFLAGS += -Wl,--no-undefined
OUTPUT_NAME = lib$(LIB_NAME).so
OUTPUT_COMMAND = $(CXX) -o $(OUTPUT_FILE) $(OBJ_FILES) $(LDFLAGS) -shared
else
LDFLAGS += -undefined error
OUTPUT_NAME = lib$(LIB_NAME).dylib
OUTPUT_COMMAND = $(CXX) -o $(OUTPUT_FILE) $(OBJ_FILES) $(LDFLAGS) -dynamiclib -headerpad_max_install_names
endif
endif
ifneq "$(EXE_NAME)" ""
OUTPUT_NAME = $(EXE_NAME)
OUTPUT_COMMAND = $(CXX) -o $(OUTPUT_FILE) $(OBJ_FILES) $(LDFLAGS)
endif
ifneq "$(SLIB_NAME)" ""
CFLAGS += -fPIC
OUTPUT_NAME = lib$(SLIB_NAME).a
OUTPUT_COMMAND = $(AR) -cq $(OUTPUT_FILE) $(OBJ_FILES)
endif
define CREATE_SRC_TARGETS
# create a target for the object file (the CXX command creates both an .o file
# and a .d file)
ifneq ("$(OSTYPE)","Darwin")
$(call SRC_TO_OBJ,$1) : $1 | $(INT_DIR)
$(CXX) -MD -MP -MT "$(call SRC_TO_DEP,$1) $$#" -c $(CFLAGS) -o $$# $$<
else
$(call SRC_TO_OBJ,$1) : $1 | $(INT_DIR)
$(CXX) -c $(CFLAGS) -o $$# $$<
endif
endef
#############################################################################
# Targets
#############################################################################
.PHONY: clean-objs clean-defs
include $(COMMON_CPP_MAKE_FILE_DIR)CommonTargets.mak
# create targets for each source file
$(foreach src,$(SRC_FILES_LIST),$(eval $(call CREATE_SRC_TARGETS,$(src))))
# include all dependency files (we don't need them the first time, so we can use -include)
-include $(DEP_FILES)
$(OUTPUT_FILE): $(OBJ_FILES)
$(OUTPUT_COMMAND)
clean-objs:
rm -rf $(OBJ_FILES)
clean-defs:
rm -rf $(DEP_FILES)
clean: clean-objs clean-defs
I added:
-I/usr/local/include/boost
to the INC_DIRS_OPTION
-L/usr/local/lib
to the LIBS_DIRS_OPTION, and
-lboost_system
to the USED_LIBS_OPTION (asio relies on the boost system library for error generation of some sort)
I get this error:
c++ -o ../Bin/x64-Release/Sample-NiSimpleRead ./x64-Release/NiSimpleRead.o -arch i386 -arch x86_64 -L../../Lib -L../Bin/x64-Release -lOpenNI -lboost_system
ld: warning: ignoring file /usr/local/lib/libboost_system.dylib, file was built for unsupported file format which is not the architecture being linked (i386)
Undefined symbols for architecture i386:
"boost::system::generic_category()", referenced from:
__GLOBAL__I_a in NiSimpleRead.o
"boost::system::system_category()", referenced from:
__GLOBAL__I_a in NiSimpleRead.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [../Bin/x64-Release/Sample-NiSimpleRead] Error 1
I've tried adding the lib directory to my DYLD_LIBRARY_PATH which did nothing. I've also tried creating some kind of shared (*.so) library, first using the NiSimpleRead.o binary combined with the libboost_system.a file, which brought up a lot of errors. Then tried changing the boost_system.a file by itself, to a .so, which also did nothing. Any advice on this would be great.

Your problem seems to be that you have only 64-bit Boost, and you're trying to make an universal (both 32-bit and 64-bit) binary. Make sure to install dependencies in both 32-bit and 64-bit versions, or throw away this -arch i386 from your build instructions.

Related

How to modify this C++ Makefile to make multiple binaries with same sources files but from differents main.cpp

Currently, i have a pretty cool generic C++ makefile that can make only one binary from multiple source files and headers. It's all-sufficient. I would like to know how to modify it in order to generate 2 binaries. Only the mains.cpp would be different. The headers are the same too. The source files are the same. I think for sure it's possible and I'd even wonder if a loop trough exec and binaries (EXEC files) exists to generate more than 2 binaries (with same sources file). I
don't master enough the GNU makefile language to know that. Thx a lot. I just sure that i have to add a .all rule with my 2 binaries but nothing after.
Look at this :
# sources (*.cpp)
SRC := sources
# headers (*.cpp)
INC := include
MAIN := kwic_personnel.cpp
EXEC := kwic
# second binary here
MAIN2 := other.cpp
EXEC2 := other
# main file is in current directory or in sources file but here the main files are in out of
# sources file for sure
ifneq ("$(wildcard $(MAIN))","")
sources := $(MAIN) $(wildcard $(SRC)/*.cpp)
else
sources := $(wildcard $(SRC)/*.cpp)
endif
# obj files
objects := $(sources:.cpp=.o)
# dep files
deps := $(objects:.o=.d)
CXX := g++
CXXFLAGS := -I $(INC) -MMD -MP -g -std=c++17 -Wall -pedantic -Weffc++ -Werror
# OS name
UNAME := $(shell uname -s)
# NOT SURE ABOUT THAT FOR MAC OS
# if linux
ifeq ($(UNAME), Linux)
LDFLAGS := -L/usr/lib/x86_64-linux-gnu
LDLIBS := -lcurl
# else but mac OS
else
CXXFLAGS += -D OSX
LDFLAGS := -stdlib=libstdc++
endif
# linking
$(EXEC) : $(objects)
#echo "Generation du fichier executable..."
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
$(RM) $(objects) $(deps)
#echo "Compilation réussie !"
# compilation of cpp files
$(SRC)/%.o: $(SRC)/%.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $^ -o $#
# remove exec
.PHONY: clean
clean:
$(RM) $(EXEC)
# dependencies
-include $(deps)

GNU Makefile running on Mac OS?

I've written a simple generic makefile for c++. It works great on Debian/Ubuntu.
I would like to know if it could be running on MAC OS. I ask the question because i have no Mac OS at home and i can't test. Furthermore, if you have some advice, let's go.
I'm not sure about these lines
CXXFLAGS += -D OSX
LDFLAGS := -stdlib=libstdc++
I precise that it for build only STL C++ programm for the moment. No dynamic libraries.
# sources (*.cpp)
SRC := sources
# headers (*.cpp)
INC := include
MAIN := kwic_personnel.cpp
EXEC := prog
# main file is in current directory or in sources file
ifneq ("$(wildcard $(MAIN))","")
sources := $(MAIN) $(wildcard $(SRC)/*.cpp)
else
sources := $(wildcard $(SRC)/*.cpp)
endif
# obj files
objects := $(sources:.cpp=.o)
# dep files
deps := $(objects:.o=.d)
CXX := g++
CXXFLAGS := -I $(INC) -MMD -MP -g -std=c++17 -Wall -pedantic -Weffc++ -Werror
# OS name
UNAME := $(shell uname -s)
# if linux
ifeq ($(UNAME), Linux)
# my own choices on compilator with Debian
LDFLAGS := -L /usr/lib/x86_64-linux-gnu
LDLIBS := -lcurl
# else but mac OS
else
# NOT SURE ABOUT THAT
CXXFLAGS += -D OSX
LDFLAGS := -stdlib=libstdc++
endif
# linking
$(EXEC) : $(objects)
#echo "Generation du fichier executable..."
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
$(RM) $(objects) $(deps)
#echo "Compilation réussie !"
# compilation of cpp files
$(SRC)/%.o: $(SRC)/%.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $^ -o $#
# remove exec
.PHONY: clean
clean:
$(RM) $(EXEC)
# dependencies
-include $(deps)
I use gnu make on both Mac and Ubuntu. I do a bunch of things I'll explain.
First my Ubuntu is via a local Docker container, and it NFS mounts my local Mac work directory. So I can edit locally on my Mac but compile for Linux. This means if I build on both, I could have a mix of different targets being built. Clearly, this is problematic, so here are some tricks.
UNAME := $(shell uname)
MACAPPEND=
LIB_ARGS= -cvrU
ifeq ($(UNAME), Darwin)
MACAPPEND=-mac
CXX=clang++
LIB_ARGS= -cvr
endif
SRCDIR := src
OBJDIR := obj${MACAPPEND}
DEPDIR := .d
BINDIR := bin${MACAPPEND}
Then it's the same ${SRCDIR} for everything, but $OBJDIR} might resolve to obj or obj-mac. Same with bin and bin-mac. I compile with this:
${OBJDIR}/%.o : %.cpp
$(COMPILE.cc) ${CXXFLAGS} $(OUTPUT_OPTION) $<
Note that I do this stuff so much, that I produce a Makefile-Base and stuff it into /usr/local/etc and then can do this:
include /usr/local/etc/Makefile-Base
If I'm making a library:
LIBNAME=show${MACAPPEND}
LIB=lib/libshow${MACAPPEND}.a
lib: ${LIB}
${LIB}: ${LIB_OBJ}
#mkdir -p lib
ar ${LIB_ARGS} ${LIB} ${LIB_OBJ}
ranlib ${LIB}
See LIB_ARGS used here and defined near the top of this post.
Note that a LOT of what I'm doing is because of the way I share my directory across both environments and might be bulding in both. There are very few things that you need to do special on Mac.

Makefile unable to link libraries during runtime

So I am using nvidia's deepstream sdk and trying to modify the makefile of one of the sample examples given as I wish to link and add my own libraries. This is the makefile being employed where I am setting the path of the CUSTOM_LIB to point to the location of my library. The issue is the project gets compiled successfully but during run time, its unable to find the custom library. I performed ldd on the executable generated and there also it was showing the library as 'not found'. I think it's something to do with rpath but I am not sure about that.
APP:= sample
TARGET_DEVICE = $(shell gcc -dumpmachine | cut -f1 -d -)
NVDS_VERSION:=4.0
LIB_INSTALL_DIR?=/opt/nvidia/deepstream/deepstream-$(NVDS_VERSION)/lib/
ifeq ($(TARGET_DEVICE),aarch64)
CFLAGS:= -DPLATFORM_TEGRA
endif
CUDA_VER:=10.0
CC:=g++
SRCS:= $(wildcard ../src/*.c)
#SRCS+= $(wildcard ../../apps-common/src/*.c)
#SRCS+=
INCS:= $(wildcard ../include/*.h)
PKGS:= gstreamer-1.0 gstreamer-video-1.0 x11 opencv
OBJS:= $(SRCS:.c=.o)
CFLAGS+= -I../include -I/usr/include -I$(CUSTOM_LIB)/include -I/usr/local/cuda-10.0/targets/aarch64-linux/include/ -I/usr/include/jsoncpp -DDS_VERSION_MINOR=0 -DDS_VERSION_MAJOR=4 -fpermissive -Wnarrowing
LIBS+= -L$(LIB_INSTALL_DIR) -L/usr/lib/aarch64-linux-gnu -L$(CUSTOM_LIB)/lib -L/usr/lib/aarch64-linux-gnu/ -lcurl -letlic -letolm -lssl -lcrypto -llogger -lpthread -lsqlite3 -ljsoncpp -lnvdsgst_meta -lnvbufsurface -lnvbufsurftransform -lnvds_meta -lnvdsgst_helper -lnvds_utils -lm -L/usr/local/cuda-$(CUDA_VER)/lib64/ -lcudart \
-lgstrtspserver-1.0 -Wl,-rpath,$(LIB_INSTALL_DIR)
CFLAGS+= `pkg-config --cflags $(PKGS)`
LIBS+= `pkg-config --libs $(PKGS)`
all: $(APP)
debug: CXXFLAGS += -DDEBUG -g
debug: CFLAGS += -DDEBUG -g
debug: $(APP)
%.o: %.c $(INCS) Makefile
$(CC) -c -o $# $(CFLAGS) $<
$(APP): $(OBJS) Makefile
$(CC) -o $(APP) $(OBJS) $(LIBS)
clean:
rm -rf $(OBJS) $(APP)
You need to set rpath to a colon-separated list of directories where your libraries are found. You only add LIB_INSTALL_DIR but not CUSTOM_LIB_DIR. Generally everything you pass to -L you need to pass to -rpath too, unless there is a specific reason not to. For example, if you are building a package that has more than a single library and you are going to install in a standard place like /usr/lib, you don't have to add the directory where libraries temporarily live to -rpath. If you are going to install to a non-standard directory, add that directory.

Getting Eclipse to read includes from makefile

I have a makefile which compiles my code just fine when running make.
If a create a makefile project in eclipse and import my already existing makefile it is possible to build the project.
But Eclipse does not resolve names, as it cannot find my include files. Is there a way where Eclipse automatically can read include paths from the makefile?
My makefile looks like this
# Put your stlink folder here so make burn will work.
STLINK=~/Programs/stlink
# Put your source files here (or *.c, etc)
SRCS=main.c system_stm32f4xx.c ../src/*.c
# Binaries will be generated with this name (.elf, .bin, .hex, etc)
PROJ_NAME=blinky
# Put your STM32F4 library code directory here
STM_COMMON=../STM32F4-Discovery_FW_V1.1.0
# Normally you shouldn't need to change anything below this line!
#######################################################################################
CC=arm-none-eabi-gcc
OBJCOPY=arm-none-eabi-objcopy
CFLAGS = -g -O2 -Wall -Tstm32_flash.ld
CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m4 -mthumb-interwork
CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
CFLAGS += -I.
# Include files from STM libraries
CFLAGS += -I$(STM_COMMON)/Utilities/STM32F4-Discovery
CFLAGS += -I$(STM_COMMON)/Libraries/CMSIS/Include -I$(STM_COMMON)/Libraries/CMSIS/ST/STM32F4xx/Include
CFLAGS += -I$(STM_COMMON)/Libraries/STM32F4xx_StdPeriph_Driver/inc
CFLAGS += -I ../include/
# add startup file to build
SRCS += $(STM_COMMON)/Libraries/CMSIS/ST/STM32F4xx/Source/Templates/TrueSTUDIO/startup_stm32f4xx.s
OBJS = $(SRCS:.c=.o)
.PHONY: proj
all: proj
proj: $(PROJ_NAME).elf
$(PROJ_NAME).elf: $(SRCS)
$(CC) $(CFLAGS) $^ -o $#
$(OBJCOPY) -O ihex $(PROJ_NAME).elf $(PROJ_NAME).hex
$(OBJCOPY) -O binary $(PROJ_NAME).elf $(PROJ_NAME).bin
clean:
rm -f *.o $(PROJ_NAME).elf $(PROJ_NAME).hex $(PROJ_NAME).bin
# Flash the STM32F4
burn: proj
$(STLINK)/st-flash write $(PROJ_NAME).bin 0x8000000

How do I link with GLU?

I've just discovered FLTK and I made a makefile for my test. Here is my makefile:
################ template makefile ##############
# We don't know what compiler to use to build fltk on this machine - but fltk-config does...
CC  = $(shell fltk-config --cc)
CXX = $(shell fltk-config --cxx)
# Set the flags for compiler: fltk-config knows the basic settings, then we can add our own...
CFLAGS   = $(shell fltk-config --cflags)
CXXFLAGS = $(shell fltk-config --cxxflags) -I/System/Library/Frameworks/OpenGL.framework/Versions/A/
# We don't know what libraries to link with: fltk-config does...
LINKFLTK = $(shell fltk-config --ldstaticflags)
LINKFLTK_GL = $(shell fltk-config --use-gl --ldstaticflags) -lGLU
LINKFLTK_IMG = $(shell fltk-config --use-images --ldstaticflags)
# Possible steps to run after linking...
STRIP      = strip
POSTBUILD  = fltk-config --post # Required on OSX, does nothing on other platforms, so safe to call
TARGET = CompletedFile
# Define what your target application is called
all: $(TARGET)
# Define how to build the various object files... -snip-
# Now define how to link the final app - let's assume it needs image and OpenGL support
$(TARGET): MyWindow.o main.o
$(CXX) -o $# MyWindow.o main.o $(LINKFLTK_IMG) $(LINKFLTK_GL)
$(STRIP) $#
$(POSTBUILD) $#  # only required on OSX, but call it anyway for portability
############### end #################
(Heres the object file code:)main.o: main.cpp MyWindow.h main.h
$(CXX) -c $< \
$(CXXFLAGS)
MyWindow.o: MyWindow.cpp MyWindow.h
$(CXX) -c $< \
$(CXXFLAGS)
Here is the error it gives me:
In file included from MyWindow.cpp:10:
MyWindow.h:14:20: error: GL/glu.h: No such file or directory
MyWindow.cpp: In member function ‘virtual void MyWindow::draw()’:
MyWindow.cpp:49: error: ‘gluPerspective’ was not declared in this scope
make: * [MyWindow.o] Error 1
(The code is irrelevant)
Depending on the fltk version you are using it has some of it's own openGL headers. I add the following lines to my include libraries:
-lfltk -lfltk_gl -lGL -lGLU
Overkill but it gets the job done.
The compiler can't find your GLU.h header. Adjust your #include or -I switch to point to the right location.