2013-04-22 15 views
7

Ho creato una libreria. Quando lo compilo come libreria statica, funziona bene. Ora volevo trasformarlo in una libreria condivisa. La libreria è creata e nel posto giusto, ma quando provo a compilare il codice client, la fase di collegamento dice che non riesce a trovare la libreria.cygwin g ++ Il linker non trova la libreria condivisa

Ho già provato a rinominarlo a al o dylib ma non è di aiuto neanche questo. Quando metto il flag -v sul collegamento, posso vedere che il mio percorso della libreria è lì. Ho anche provato diversi percorsi. Io uso un percorso relativo, ma anche con un percorso completo non lo trova.

Il Makefile formano la libreria:

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

E qui ist il Makefile per l'applicazione:

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

risposta

11

Dopo alcuni esperimenti ho trovato una soluzione su come compilare una libreria condivisa sotto Cygwin.

Apparentemente il compilatore sta cercando un file DLL anche se è all'interno di cygwin. quindi il primo passo è aggiungere il tuo percorso, dove la libreria sarà nella variabile PATH.

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

A quanto pare quando si collega contro una libreria condivisa, il linker sembra cercare un file DLL per impostazione predefinita. Non so perché, perché all'interno di cygwin mi aspetterei che cerchi un file .so proprio come su altri sistemi UNIX.

Tuttavia, ci sono due soluzioni a questo, che funzionano entrambe.

In primo luogo, è possibile creare un collegamento al vostro .so libreria con il nome dll

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

In questo caso il makefile non deve essere cambiato e -lsupport troverete la libreria durante il collegamento. Preferisco questa soluzione.

In secondo luogo, è possibile specificare l'opzione linker con il nome completo.

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

quindi non è necessario creare un collegamento.

Quindi la cosa fondamentale sembra essere che la libreria condivisa deve essere nel PERCORSO sotto cygwin. L'utilizzo di LD_LIBRARY_PATH non aiuta in questo caso poiché è possibile collegare l'eseguibile, ma quando si tenta di eseguirlo, non lo troverà.

ldd nohupshd.exe 

libsupport.so => not found 

UPDATE: Per qualche ragione quando ho controllato con LDD, la mia biblioteca è stata improvvisamente scomparso dalla lista. Ho scoperto che Cygwin usa il nome per distinguere tra MS Windows e le librerie condivise Unix. Quindi, per farlo funzionare, il nome della libreria deve essere cyg.so per farlo funzionare, altrimenti l'exectuable sembra essere una build di Windows. In questo caso non è necessario creare il collegamento denominato x.dll poiché la libreria condivisa rimane all'interno dell'ambiente Unix.

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

Quando si utilizza Eclipse per il debug, il percorso della libreria condivisa deve essere anche nella variabile di ambiente Windows percorso. In caso contrario, la sessione di debug termina immediatamente senza errori.