11

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

我已经尝试将其重命名为 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)
4

1 回答 1

17

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

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

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

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

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

首先,您可以创建一个指向您的 .so 库的链接,其名称为 .dll

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

在这种情况下,不必更改生成文件,-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路径环境变量中。否则,调试会话会立即终止而不会出现错误。

于 2013-04-23T07:42:13.607 回答