2013-04-22 7 views
7

Ich habe eine Bibliothek wurde zu schaffen. Wenn ich es als statische Bibliothek kompiliere, funktioniert es gut. Jetzt wollte ich es in eine gemeinsame Bibliothek verwandeln. Die Bibliothek wird an der richtigen Stelle erstellt, aber wenn ich versuche, den Client-Code zu kompilieren, sagt die Verknüpfungsphase, dass sie die Bibliothek nicht finden kann.Cygwin g ++ Linker findet nicht Bibliothek geteilt

Ich habe bereits versucht, es zu al oder dylib umbenennen aber, dass entweder nicht hilft. Wenn ich das Flag -v auf die Verknüpfung setze, kann ich sehen, dass mein Bibliothekspfad da ist. Ich habe auch verschiedene Wege ausprobiert. Ich benutze einen relativen Pfad, aber auch mit einem vollständigen Pfad, den er nicht findet.

.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) 

für die Anwendung Und hier ist das Makefile:

Das Makefile der Bibliothek bildet

.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) 

Antwort

11

Nach einigem Experimentieren fand ich eine Lösung auf, wie eine gemeinsame Bibliothek unter Cygwin kompilieren.

Anscheinend ist der Compiler sucht eine DLL-Datei, obwohl es innerhalb Cygwin ist. Der erste Schritt besteht darin, den Pfad zu der PATH-Variablen hinzuzufügen.

Offenbar scheint der Linker bei der Verknüpfung mit einer gemeinsam genutzten Bibliothek standardmäßig nach einer DLL-Datei zu suchen. Ich weiß nicht warum, denn in cygwin würde ich erwarten, dass es wie bei anderen UNIX-Systemen nach einer .so-Datei sucht.

Allerdings gibt es zwei Lösungen für diese, die beide arbeiten.

Erstens können Sie einen Link zu Ihrem .so-Bibliothek mit dem Namen erstellen DLL

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

In diesem Fall wird die Make-Datei nicht geändert werden muss, und -lsupport wird die Bibliothek finden, während der Verknüpfung. Ich bevorzuge diese Lösung.

Zweitens können Sie die Linker-Option mit dem vollständigen Namen angeben.

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

dann müssen Sie keine Verknüpfung erstellen.

So ist die entscheidende Sache scheint zu sein, dass die gemeinsam genutzte Bibliothek in der PATH unter Cygwin sein muss. Die Verwendung von LD_LIBRARY_PATH hilft in diesem Fall nicht, da Sie die ausführbare Datei verknüpfen können, aber wenn Sie versuchen, sie auszuführen, wird sie nicht gefunden.

UPDATE: Aus irgendeinem Grund, als ich mit ldd überprüft wurde, war meine Bibliothek plötzlich von der Liste verschwunden. Ich habe herausgefunden, dass Cygwin den Namen verwendet, um zwischen MS Windows und Unix Shared Libraries zu unterscheiden. Um es funktionieren zu lassen, muss der Name der Bibliothek cyg.so lauten, damit es funktioniert, ansonsten scheint das executable ein bisschen Windows zu sein. In diesem Fall müssen Sie den Link x.dll nicht erstellen, da die gemeinsam genutzte Bibliothek in der Unix-Umgebung verbleibt.

Wenn Sie Eclipse zum Debuggen verwenden, muss der Pfad zur gemeinsam genutzten Bibliothek auch in der Windows-Pfadumgebungsvariablen enthalten sein. Andernfalls wird die Debugsitzung sofort ohne Fehler beendet.