2013-04-22 21 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) 

そして、ここで:

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の下に共有ライブラリをコンパイルする方法についての解決策を見つけたいくつかの実験をした後。

明らかに、コンパイラはcygwinの内部にあってもDLLファイルを探しています。最初のステップはパスを追加することです。ここでライブラリはPATH変数になります。

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

明らかに共有ライブラリとリンクするとき、リンカはデフォルトでDLLファイルを探すようです。理由は分かりません。cygwinの内部では、他のUNIXシステムと同じように.soファイルを探すことが期待されるためです。

ただし、これには2つの解決策があり、いずれも機能します。

まず、あなたの名前とあなたの.soライブラリーへのリンクを作成することができます。この場合、メイクファイルを変更する必要がないとリンクしながら、-lsupportライブラリを見つける

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

を.dllを。私はこの解決策を好む。

第2に、フルネームでリンカーオプションを指定できます。

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でなければなりません。そうでなければ、exectuableはいくつかのWindowsビルドのようです。この場合、共有ライブラリはUnix環境内にとどまるので、x.dllという名前のリンクを作成する必要はありません。

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

デバッグにeclipseを使用する場合、共有ライブラリへのパスもWindowsパス環境変数に含める必要があります。そうしないと、デバッグセッションはエラーなしで直ちに終了します。

関連する問題