I have the following Makefile:
OBJ=main.o other.o other1.o other2.o
LINKDIVSUF=-L libdivsufsort-master/build/lib/ -ldivsufsort64 -Wl,-R libdivsufsort-master/build/lib/
INCDIVSUF=-I libdivsufsort-master/build/include -ldivsufsort64
EXE=program
COMPFLAGS=-MMD -fopenmp -std=c++17 -O3
CXX=g++
$(EXE):$(OBJ)
$(CXX) $(COMPFLAGS) $(OBJ) -o $(EXE) $(LINKDIVSUF) -lz -lboost_regex -lboost_program_options
%.o: %.cpp
$(CXX) $(COMPFLAGS) $(INCDIVSUF) -c $<
-include $(OBJ:.o=.d)
The program
links to a dynamic library, libdivsufsort64.so.3
, located from the build directory at ./libdivsufsort-master/build/lib/
.
Use of -Wl,-R libdivsufsort-master/build/lib/
is to avoid having to concatenate absolute/path/to/libdivsufsort-master/build/lib/
to LD_LIBRARY_PATH
in order to run program
. Indeed, when I make
program
without -Wl, -R libdivsufsort-master/build/lib/
, and without setting the LD_LIBRARY_PATH
as mentioned and subsequently run program
, I get the following error message:
./program: error while loading shared libraries: libdivsufsort64.so.3: cannot open shared object file: No such file or directory
With -Wl, -R libdivsufsort-master/build/lib/
, program
runs successfully with no alteration to LD_LIBRARY_PATH
, but only when
I run program
from the same directory in which it was built.
If I try to run program
when compiled with -Wl, -R libdivsufsort-master/build/lib/
from any other directory, it fails to run, terminating with
the aforementioned error message.
How can I change the g++
compilation options (or anything else at compilation time) to enable program
to run from
any directory whilst avoiding the need to alter LD_LIBRARY_PATH
? The only "solution" I have found is to concatenate libdivsufsort-master/build/lib/
to LD_LIBRARY_PATH
. By doing so, I can run program
from any
directory, thus removing the need to compile with Wl,-R libdivsufsort-master/build/lib/
, however, this of course requires the user of program
to manually set their LD_LIBRARY_PATH
, which I specifically want to avoid.
Solution Reading this post that discusses the use of relative or absolute paths with -R (-rpath) I came up with this solution.
Append the following lines, such that the Makefile is now:
libdivsufsort_lib = $(addprefix $(shell pwd), /libdivsufsort-master/build/lib/)
libdivsufsort_include = $(addprefix $(shell pwd), /libdivsufsort-master/build/include/)
OBJ=main.o other.o other1.o other2.o
LINKDIVSUF=-L libdivsufsort-master/build/lib/ -ldivsufsort64 -Wl,-R libdivsufsort-master/build/lib/
INCDIVSUF=-I libdivsufsort-master/build/include -ldivsufsort64
EXE=program
COMPFLAGS=-MMD -fopenmp -std=c++17 -O3
CXX=g++
$(EXE):$(OBJ)
$(CXX) $(COMPFLAGS) $(OBJ) -o $(EXE) $(LINKDIVSUF) -lz -lboost_regex -lboost_program_options
%.o: %.cpp
$(CXX) $(COMPFLAGS) $(INCDIVSUF) -c $<
-include $(OBJ:.o=.d)
This avoids the use of $ORIGIN
, to produce an absolute path to program
s
directory, which is not supported on some systems. The two additional
lines produce the absolute path irrespective of the binary's location -
it just needs to kept in the build directory and compiled again if the build
directory moves. Importantly, program
can now be called from outside the
build directory.