2013-04-22 5 views
7

저는 라이브러리를 만들고 있습니다. 정적 라이브러리로 컴파일하면 정상적으로 작동합니다. 이제 공유 라이브러리로 바꾸고 싶었습니다. 라이브러리가 만들어지고 적절한 위치에 있지만 클라이언트 코드를 컴파일하려고하면 링크 단계에서 라이브러리를 찾을 수 없다고 말합니다.cygwin g ++ 링커가 공유 라이브러리를 찾지 못했습니다.

이미 al 또는 dylib로 이름을 바꾸려고했으나 도움이되지 않습니다. 링크에 -v 플래그를 붙이면 내 라이브러리 경로가 있음을 알 수 있습니다. 나는 또한 다른 경로를 시도했다. 나는 상대 경로를 사용하지만, 찾지 못한 전체 경로를 사용한다. 응용 프로그램에 대한 여기에 메이크 IST

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

을 그리고 :

makefile은 라이브러리를 형성 내가 Cygwin에서 아래의 공유 라이브러리를 컴파일하는 방법에 대한 해결책을 발견 실험을 몇 후

.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 파일을 찾고 있습니다. 그래서 첫 번째 단계는 PATH 변수에 라이브러리가있는 경로를 추가하는 것입니다.

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

분명히 공유 라이브러리에 대해 링크 할 때 링커는 기본적으로 DLL 파일을 찾는 것처럼 보입니다. 이유는 모르겠지만 cygwin 내부에서 다른 UNIX 시스템과 마찬가지로 .so 파일을 찾길 기대하기 때문입니다.

그러나 두 가지 해결 방법이 있는데 두 가지 방법이 있습니다.

첫째, 당신은 변경 될 메이크가없는이 경우

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

.DLL 이름으로 당신의 .so는 라이브러리에 대한 링크를 만들 수 있으며, 연결하면서 -lsupport 라이브러리를 찾을 수 있습니다. 나는이 해결책을 선호한다.

둘째, 전체 이름과 함께 링커 옵션을 지정할 수 있습니다.

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

링크를 만들 필요가 없습니다.

그래서 중요한 것은 cygwin에서 공유 라이브러리가 PATH에 있어야한다는 것입니다. LD_LIBRARY_PATH를 사용하면 실행 파일을 연결할 수 있기 때문에 도움이되지 않지만 실행하려고 시도하면 LD_LIBRARY_PATH를 찾을 수 없습니다.

ldd nohupshd.exe 

libsupport.so => not found 

업데이트 : ldd로 확인할 때 어떤 이유로 라이브러리가 갑자기 사라졌습니다. cygwin이 MS Windows와 Unix 공유 라이브러리를 구별하기 위해이 이름을 사용한다는 것을 알게되었습니다. 그래서 작동 시키려면 라이브러리의 이름이 cyg.so이어야합니다. 그렇지 않으면 exectuable이 일부 Windows 빌드처럼 보입니다. 이 경우 공유 라이브러리가 유닉스 환경에 있기 때문에 x.dll 링크를 만들 필요가 없습니다.

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

디버깅에 eclipse를 사용하는 경우 공유 라이브러리의 경로도 Windows 경로 환경 변수에 있어야합니다. 그렇지 않으면 디버그 세션이 오류없이 즉시 종료됩니다.

관련 문제