2013-04-22 69 views
7

我一直在創建一個庫。當我將它編譯爲靜態庫時,它工作正常。現在我想把它變成一個共享庫。該庫是在適當的位置創建的,但是當我嘗試編譯客戶端代碼時,鏈接階段表示它找不到該庫。cygwin g ++鏈接器沒有找到共享庫

我已經嘗試將其重命名爲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 [email protected]` 
    $(CC) $(CXXFLAGS) -c $< -o [email protected] $(INCLUDE_PATHS) 

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

這裏IST 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 [email protected]` 
    $(CC) $(CXXFLAGS) -c $< -o [email protected] $(INCLUDE_PATHS) 

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

回答

11

經過一些嘗試,我發現瞭如何在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路徑環境變量中。否則,調試會話立即終止而不會出現錯誤。