【问题标题】:cygwin g++ Linker doesn't find shared librarycygwin g++ 链接器找不到共享库
【发布时间】:2013-04-15 18:27:51
【问题描述】:

我一直在创建一个库。当我将它编译为静态库时,它工作正常。现在我想把它变成一个共享库。该库已创建并位于正确的位置,但是当我尝试编译客户端代码时,链接阶段说它找不到该库。

我已经尝试将其重命名为 al 或 dylib,但这也无济于事。当我将 -v 标志放在链接上时,我可以看到我的库路径在那里。我也尝试了不同的路径。我使用了相对路径,但即使使用完整路径也找不到。

库中的 Makefile:

.SUFFIXES:
.SUFFIXES: .o .cpp
.SUFFIXES: .o .d

CC := g++
LNK:= g++

CXXFLAGS_RELEASE    = -fPIC -shared -O2 -Wall -fmessage-length=0
CXXFLAGS_DEBUG      = -fPIC -shared -g -Wall -fmessage-length=0 -D _DEBUG

CXXFLAGS =  $(CXXFLAGS_DEBUG)

OBJDIR:=        obj
SRCDIR:=        src
HDIR:=          include

INCLUDE_PATHS:= -Iinclude -Iinclude/interfaces -Iinclude/support

CPP_FILES := propertyfile/propertyfile.cpp \
            propertyfile/propertyitem.cpp \
            propertyfile/propertyfactory.cpp \
            helper/string_helper.cpp

OBJ :=      $(patsubst %.cpp,$(OBJDIR)/%.o, $(CPP_FILES))
SRC :=      $(patsubst %.cpp,$(SRCDIR)/%.o, $(CPP_FILES))

LIBS:=      

TARGET:=    libsupport.so

all:    $(TARGET)

$(TARGET):  $(OBJ)
    $(LNK) -o $(TARGET) $(OBJ) -shared  
    @cp $(TARGET) ../lib
    @cp -r include ..

clean:
    rm -f $(OBJ) $(ASM) $(TARGET)

-include $(patsubst %.cpp,$(OBJDIR)/%.d, $(CPP_FILES))

$(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(OBJDIR)/%.d 
    @mkdir -p `dirname $@`
    $(CC) $(CXXFLAGS) -c $< -o $@ $(INCLUDE_PATHS)

$(OBJDIR)/%.d: $(SRCDIR)/%.cpp 
    @mkdir -p `dirname $@`
    $(CC) $(CXXFLAGS) -MM -MT $@ -MF $(OBJDIR)/$*.d -c $< $(INCLUDE_PATHS)

这是应用程序的 Makefile:

.SUFFIXES:
.SUFFIXES: .o .cpp

CC := g++
LD := g++

CXXFLAGS_RELEASE    = -O2 -Wall -fmessage-length=0
CXXFLAGS_DEBUG      = -g -Wall -fmessage-length=0 -D _DEBUG
CXXFLAGS =  $(CXXFLAGS_DEBUG)

OBJDIR:=        obj
SRCDIR:=        src

INCLUDE_PATHS:= -Iinclude -I../include
LIBS:=      -L /cygdrive/d/src/c/lib -lsupport

CPP_FILES := nohupshd.cpp \
            daemon.cpp \
            task.cpp

OBJ :=      $(patsubst %.cpp,$(OBJDIR)/%.o, $(CPP_FILES))
SRC :=      $(patsubst %.cpp,$(SRCDIR)/%.o, $(CPP_FILES))

TARGET:=    nohupshd

all:    $(TARGET)

$(TARGET):  $(OBJ)
    $(LD) -o $(TARGET) $(OBJ) $(LIBS)

clean:
    rm -f $(OBJ) $(ASM) $(TARGET)

-include $(patsubst %.cpp,$(OBJDIR)/%.d, $(CPP_FILES))

$(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(OBJDIR)/%.d 
    @mkdir -p `dirname $@`
    $(CC) $(CXXFLAGS) -c $< -o $@ $(INCLUDE_PATHS)

$(OBJDIR)/%.d: $(SRCDIR)/%.cpp 
    @mkdir -p `dirname $@`
    $(CC) $(CXXFLAGS) -MM -MT $@ -MF $(OBJDIR)/$*.d -c $< $(INCLUDE_PATHS)

【问题讨论】:

    标签: c++ shared


    【解决方案1】:

    经过一些实验,我找到了如何在 cygwin 下编译共享库的解决方案。

    显然编译器正在寻找一个 DLL 文件,即使它位于 cygwin 中。所以第一步是将你的路径添加到 PATH 变量中。

     export PATH=$PATH:/cygdrive/d/src/c/lib
    

    显然,当链接到共享库时,链接器似乎默认寻找 DLL 文件。我不知道为什么,因为在 cygwin 中我希望它像在其他 UNIX 系统上一样查找 .so 文件。

    但是,有两种解决方案,它们都有效。

    首先,您可以使用名称 .dll 创建指向 .so 库的链接

    ln -s /cygdrive/d/src/lib/libsupport.so libsupport.dll
    

    在这种情况下,不必更改 makefile,-lsupport 将在链接时找到库。我更喜欢这个解决方案。

    其次,您可以使用全名指定链接器选项。

    LIBS:=      -L /cygdrive/d/src/c/lib -l:libsupport.so
    

    那么您不必创建链接。

    所以关键似乎是共享库必须在cygwin下的PATH中。在这种情况下使用 LD_LIBRARY_PATH 并没有帮助,因为您可以链接可执行文件,但是在尝试运行它时,它不会找到它。

    ldd nohupshd.exe
    
    libsupport.so => not found
    

    更新:由于某种原因,当我检查 ldd 时,我的库突然从列表中消失了。我发现 cygwin 使用该名称来区分 MS Windows 和 Unix 共享库。所以为了让它工作,库的名称必须是 cyg.so 才能让它工作,否则可执行文件似乎是一些 Windows 构建。在这种情况下,您不需要创建名为 x.dll 的链接,因为共享库保留在 Unix 环境中。

        $(LNK) -o cyg$(TARGET).so $(OBJ) -shared  
    

    使用eclipse进行调试时,共享库的路径也必须在windows路径环境变量中。否则调试会话会立即终止而不会出错。

    【讨论】:

    • 在我的情况下,从 .lib.dlllib.o 的符号链接有效,但我不需要添加扩展名,所以 -L. -llibcygwin(mingw32-gcc)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    • 1970-01-01
    • 1970-01-01
    • 2015-10-03
    • 2014-04-29
    • 2012-09-30
    相关资源
    最近更新 更多