【问题标题】:Linked libraries not set up properly in makefile在 makefile 中未正确设置链接库
【发布时间】:2015-08-07 10:55:38
【问题描述】:

我有以下用于编译一个简单项目的 makefile(此示例只是一个包含一些外部头文件和一个共享库的单个 .cpp):

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 $@`
#   @echo "Linking $@..."
    $(CC) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $@ 
#   @echo "$@ sucessfully built."

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

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

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 

这是来自 code::blocks 的构建日志:

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 中可能出现的问题是什么?非常感谢您的帮助!

【问题讨论】:

    标签: c++ makefile shared-libraries


    【解决方案1】:

    您的库位于非标准位置,因此动态链接器无法找到它。

    你可以通过像这样设置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 是你的库的路径(逗号前后没有空格)。

    (大致)引用自动工具说明:

    如果您想链接给定目录中已安装的库, LIBDIR,您必须在链接期间使用 `-LLIBDIR' 标志并在 以下至少一项:

    • 将 LIBDIR 添加到“LD_LIBRARY_PATH”环境变量 执行期间
    • 将 LIBDIR 添加到 `LD_RUN_PATH' 环境变量 链接期间
    • 使用 `-Wl,-rpath -Wl,LIBDIR' 链接器标志
    • 让您的系统管理员将 LIBDIR 添加到 `/etc/ld.so.conf'

    【讨论】:

    • - 好的,可以,但是当 code::blocks 从相同的文件编译时,我不需要设置 'LD_LIBRARY_PATH '。只是'./Test'。为什么code::blocks编译后的版本(访问相同位置的所有相同文件)不需要设置路径?
    • 我看到了这个post,但它似乎也不起作用。
    • @jpmorr 它可能的code::blocks 设置链接器标志-Wl,-rpath -Wl,LIBDIR,因此可执行文件具有“硬编码”的库位置。否则code::blocks 可能会创建一个设置LD_LIBRARY_PATH 的启动脚本。
    • @jpmorr 我在答案中添加了更多细节
    • 好的,所以我已将LDFLAGS 选项更改为LDFLAGS := -Wl,-rpath -Wl, $(LIBDIRS),并且像以前一样编译,没有任何错误。但是,如果没有额外的命令来声明路径,它仍然无法运行。我错过了什么?
    猜你喜欢
    • 2023-01-17
    • 1970-01-01
    • 1970-01-01
    • 2016-08-26
    • 1970-01-01
    • 2012-09-12
    • 2023-03-30
    • 2011-12-11
    • 1970-01-01
    相关资源
    最近更新 更多