2015-08-07 2 views
1

У меня есть следующие Makefile я использую, чтобы составить простой проект (этот пример только один .cpp, который включает в себя некоторые внешние файлы заголовков и разделяемые библиотеки):Связанные библиотеки не настроен должным образом в Makefile

ifndef _ARCH 
_ARCH := $(shell uname -m) 
export _ARCH 
endif 

NAME := Test 
MAJOR := 1 
MINOR := 5 
VERSION := v$(MAJOR)_$(MINOR) 
TARGET := $(NAME)_$(VERSION).o 

SRCEXT := cpp 
SRCDIR := src 
INCPATH := inc 
OBJDIR := obj 
BINDIR := bin 
BIN_DEBUGDIR := $(BINDIR)/debug 
API_DIR := /DEM_API/Multibody/DEMCoupling 


INCLUDES := -I. \ 
      -I$(INCPATH) \ 
      -I$(API_DIR) 

# C++ compiler flag 
CXXFLAGS := -Wall -march=native $(INCLUDES) -c 

# Linker parameter flags 

# Linker library flags 
LIBDIRS := -L$(API_DIR)/lib 
LDLIBS := -lEDEMCouplingClientV2_2_0 
LDFLAGS := $(LIBDIRS) 


SRCS := $(shell find $(SRCDIR) -name '*.$(SRCEXT)') 
SRCDIRS := $(shell find . -name '*.$(SRCEXT)' -exec dirname {} \; | uniq) 
OBJS := $(patsubst %.$(SRCEXT),$(OBJDIR)/%.o,$(SRCS)) 


########################################################################### 
# Rules to compile our files - Do not change below this line! 
########################################################################### 

ifeq ($(SRCEXT), cpp) 
CC  = $(CXX) 
else 
CXXFLAGS += -std=gnu99 
endif 

.PHONY: all debug release clean distclean 


all: $(BINDIR)/$(TARGET) 

# Build debug library 
debug: CXXFLAGS += -g 
debug: clean $(BIN_DEBUGDIR)/$(TARGET) 


# strip all symbols from release verison 
release: LDFLAGS += -s 
release: CXXFLAGS += -O2 
release: $(BINDIR)/$(TARGET) 

$(BINDIR)/$(TARGET): buildrepo $(OBJS) 
    @mkdir -p `dirname [email protected]` 
# @echo "Linking [email protected]" 
    $(CC) $(LDFLAGS) $(OBJS) $(LDLIBS) -o [email protected] 
# @echo "[email protected] sucessfully built." 

$(BIN_DEBUGDIR)/$(TARGET): buildrepo $(OBJS) 
    @mkdir -p `dirname [email protected]` 
# @echo "Linking [email protected]" 
    $(CC) $(LDFLAGS) $(OBJS) $(LDLIBS) -o [email protected] 
# @echo "[email protected] sucessfully built." 

$(OBJDIR)/%.o: %.$(SRCEXT) 
# @echo "Generating dependencies for $<..." 
    $(call make-depend,$<,[email protected],$(subst .o,.d,[email protected])) 
# @echo "Compiling $<..." 
    $(CC) $(CXXFLAGS) $< -o [email protected] 

clean: 
    $(RM) -r $(OBJDIR) 

distclean: clean 
    $(RM) -r $(BINDIR)/$(TARGET) 
    $(RM) -r $(BIN_DEBUGDIR)/$(TARGET) 

buildrepo: 
    $(call make-repo) 

define make-repo 
    for dir in $(SRCDIRS); \ 
    do \ 
    mkdir -p $(OBJDIR)/$$dir; \ 
    done 
endef 


# usage: $(call make-depend,source-file,object-file,depend-file) 
define make-depend 
    $(CC) -MM  \ 
     -MMD  \ 
     -MF $3 \ 
     -MP  \ 
     -MT $2 \ 
     $(CXXFLAGS) \ 
     $(LDFLAGS) \ 
     $1 
endef 

Он компилирует этот проект успешно, но когда я пытаюсь запустить исполняемый файл из терминала я только получаю следующее сообщение об ошибке:

./Test_v1_5.o: error while loading shared libraries: libEDEMCouplingClientV2_2_0.so: cannot open shared object file: No such file or directory 

Я не понимаю, почему.

В качестве теста я настроил один и тот же проект в блоках кода и скомпилировал версию выпуска, и он отлично работает.

Вот сборки из положить от моего Makefile:

for dir in ./src ./old; do mkdir -p obj/$dir; done 

g++ -MM -MMD -MF obj/src/Test_v11.d -MP -MT obj/src/Test_v11.o -Wall -march=native -I. -Iinc -I/home/DEM_API/Multibody/DEMCoupling -c -L/opt/DEM/DEM_2.7/lib src/Test_v11.cpp 
g++ -Wall -march=native -I. -Iinc -I/home/DEM_API/Multibody/DEMCoupling -c src/Test_v11.cpp -o obj/src/Test_v11.o 

src/Test_v11.cpp: In function ‘int main()’: 
src/Test_v11.cpp:199: warning: deprecated conversion from string constant to ‘char*’ 
/home/DEM_API/Multibody/DEMCoupling/ApiTypes.h: At global scope: 
/home/DEM_API/Multibody/DEMCoupling/ApiTypes.h:193: warning: ‘const char* NApi::delim()’ defined but not used 

g++ -L/home/DEM_API/Multibody/DEMCoupling/lib obj/src/Test_v11.o -lDEMCouplingClientV2_2_0 -o bin/Test_v1_5.o 

А вот журнал сборки из кода :: блоков:

g++ -Wall -fexceptions -O2 -O3 -Wfatal-errors -Wall -I../Multibody/DEMCoupling -I/home/DEM_API/Multibody/DEMCoupling -c /home/DEM_API/Multibody/EPT/src/Test_v11.cpp -o obj/Release/Multibody/EPT/src/Test_v11.o 

/home/DEM_API/Multibody/EPT/src/Test_v11.cpp: In function ‘int main()’: 
/home/DEM_API/Multibody/EPT/src/Test_v11.cpp:199: warning: deprecated conversion from string constant to ‘char*’ 
../Multibody/DEMCoupling/ApiTypes.h: At global scope: 
../Multibody/DEMCoupling/ApiTypes.h:193: warning: ‘const char* NApi::delim()’ defined but not used 

g++ -L../Multibody/DEMCoupling/lib -L/home/DEM_API/Multibody/DEMCoupling/lib -o bin/Release/Test obj/Release/Multibody/EPT/src/Test_v11.o -s /home/DEM_API/Multibody/DEMCoupling/lib/libDEMCouplingClientV2_2_0.so 

Output size is 48.21 KB 
Process terminated with status 0 (0 minutes, 2 seconds) 
0 errors, 2 warnings (0 minutes, 2 seconds) 

Кто-нибудь знает, что это скорее всего проблема в Makefile? Помощь очень ценится!

ответ

0

Ваша библиотека находится в нестандартном месте, поэтому динамический компоновщик не может ее найти.

Вы можете сказать, где искать, установив LD_LIBRARY_PATH так:

$ export LD_LIBRARY_PATH=/home/jmorrise/Dropbox/PhD_Docs/EDEM_API/Multibody/EDEMCoupling/lib 
$ ./bin/Release/Test 

В качестве альтернативы, если вы хотите установить библиотеку в нестандартном месте вы можете установить флаги компилятора для связи:

-Wl,-rpath -Wl,LIBDIR 

Где LIBDIR - это путь к вашим библиотекам (и без пробелов до запятых или после них).

К (примерно) процитировать инструкции Autotools:

If you want to link against installed libraries in a given directory, LIBDIR, you must use the `-LLIBDIR' flag during linking and do at least one of the following:

  • add LIBDIR to the `LD_LIBRARY_PATH' environment variable during execution
  • add LIBDIR to the `LD_RUN_PATH' environment variable during linking
  • use the `-Wl,-rpath -Wl,LIBDIR' linker flag
  • have your system administrator add LIBDIR to `/etc/ld.so.conf'
+0

- Хорошо, да, что работает, но мне не нужно, чтобы установить «LD_LIBRARY_PATH», когда код :: блоки компилирует из одних и тех же файлов. Просто «./Test». Почему не нужно компилировать версию code :: blocks (доступ ко всем тем же файлам в тех же местах), чтобы установить путь? – jpmorr

+0

Я видел это [сообщение] (http://stackoverflow.com/a/15065359/1506763), но он тоже не работает. – jpmorr

+0

@jpmorr Его возможный «code :: blocks» устанавливает флаг компоновщика '-Wl, -rpath -Wl, LIBDIR', поэтому исполняемый файл имеет место расположения библиотеки« жестко закодировано ». Или иначе 'code :: blocks' может создать сценарий запуска, который устанавливает' LD_LIBRARY_PATH'. – Galik

Смежные вопросы