0

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.

izaak_pyzaak
  • 930
  • 8
  • 23

1 Answers1

0

You need to use $ORIGIN with -Wl,-R to locate the library in relative path:

LINKDIVSUF = ... -Wl,-R,'$ORIGIN/libdivsufsort-master/build/lib'
Employed Russian
  • 199,314
  • 34
  • 295
  • 362
yugr
  • 19,769
  • 3
  • 51
  • 96