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 programs
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.