简体   繁体   English

cygwin g ++链接器找不到共享库

[英]cygwin g++ Linker doesn't find shared library

I have been creating a library. 我一直在创建图书馆。 When I compile it as a static library, it works fine. 当我将其编译为静态库时,它可以正常工作。 Now I want to turn it into a shared library. 现在,我想将其转换为共享库。 The library is created and in the proper place, but when I try to compile the client code, the linking phase says that it can't find the library. 库已创建并放置在正确的位置,但是当我尝试编译客户端代码时,链接阶段说找不到该库。

I already tried to rename it to al or dylib but that doesn't help either. 我已经尝试将其重命名为al或dylib,但这都无济于事。 When I put the -v flag on the linking, I can see that my library path is there. 当我在链接上放置-v标志时,可以看到我的库路径在那里。 I also tried different paths. 我还尝试了不同的路径。 I used a relative path, but even with a full path it doesn't find it. 我使用了相对路径,但是即使使用完整路径也找不到它。

The Makefile from the library: 库中的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)

And here is the Makefile for the application: 这是该应用程序的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)

After some experimenting I found a solution on how to compile a shared library under cygwin. 经过一些实验后,我找到了关于如何在cygwin下编译共享库的解决方案。

Apparently the compiler is looking for a DLL file even though it is inside cygwin. 显然,即使编译器在cygwin中,它也在寻找DLL文件。 so the first step is to add your path, where the library is going to be to the PATH variable. 因此,第一步是添加路径,库将位于PATH变量中。

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

Apparently when linking against a shared library, the linker seems to look for a DLL file by default. 显然,当链接共享库时,链接器默认情况下似乎在寻找DLL文件。 I don't know why, because inside cygwin I would expect it to look for a .so file just like on other UNIX systems. 我不知道为什么,因为在cygwin内部,我希望它像在其他UNIX系统上一样寻找.so文件。

However, there are two solutions to this, which both work. 但是,有两种解决方案都可以。

First, you can create a link to your .so library with the name .dll 首先,您可以创建一个名为.dll的.so库链接。

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

In this case the makefile doesn't have to be changed and -lsupport will find the library while linking. 在这种情况下,无需更改makefile,并且-lsupport会在链接时找到该库。 I prefer this solution. 我更喜欢这种解决方案。

Second, you can specify the linker option with the full name. 其次,您可以使用全名指定链接器选项。

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

then you don't have to create a link. 那么您不必创建链接。

So the crucial thing seems to be that the shared library must be in the PATH under cygwin. 因此,关键的事情似乎是共享库必须位于cygwin下的PATH中。 Using LD_LIBRARY_PATH doesn't help in that case as you can link the executable, but when trying to run it, it will not find it. 在这种情况下,使用LD_LIBRARY_PATH没有帮助,因为您可以链接可执行文件,但是在尝试运行它时,它将找不到它。

ldd nohupshd.exe

libsupport.so => not found

UPDATE: For some reason when I checked with ldd, my library was suddenly gone from the list. 更新:由于某种原因,当我使用ldd检查时,我的库突然从列表中消失了。 I found out that cygwin uses the name to differentiate between MS Windows and Unix shared libraries. 我发现cygwin使用该名称区分MS Windows和Unix共享库。 So in order to make it work, the name of the library must be cyg.so to make it work, otherwise the exectuable seems to be some Windows build. 因此,为了使其工作,该库的名称必须为cyg.so才能使其工作,否则该可执行文件似乎是某些Windows构建。 In this case you don't need to create the link named x.dll as the shared library stays inside the Unix environment. 在这种情况下,您无需创建名为x.dll的链接,因为共享库位于Unix环境中。

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

When using eclipse for debugging, the path to the shared library must also be in the windows path environment variable. 使用eclipse进行调试时,共享库的路径也必须位于Windows路径环境变量中。 Otherwise the debug session immediately terminates without an error. 否则,调试会话将立即终止而不会出现错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM