2017-02-19 2 views
-1

(プラットフォーム:C++ 14、クラン3.8は、Ubuntu 16.04、CMakeの3.5.1)ネスト静的リンクライブラリと薄気味悪いバグ

私は2つの静的ライブラリ(PawLIB、CalikoCat)、および依存する実行可能ファイルを持っていますOtherLibraryで。 CalkoCat内には、単一クラスのDummyがあります。 (私はこのライブラリで深刻な開発を始める前にすべてのリンクが正しいことを確認しています)。

Dummyクラスは現在、テスト目的でPawLIBの関数に依存しています。

calikocat-source/include/calikocat/dummy.hpp

#include "pawlib/iochannel.hpp" 

class Dummy 
{ 
    public: 
     Dummy(){} 
     static void speak(); 
     ~Dummy(){} 
}; 

calikocat-source/src/dummy.cpp

#include "otherlibrary/dummy.hpp" 

void Dummy::speak() 
{ 
    pawlib::ioc << "Hello, world!" << pawlib::io_end; 
} 

問題はありません。コンパイルし、CMakeと正しくリンクします。

注:この質問の両方のCMakeLists.txtファイル内のすべての変数が慎重にテストされ、動作しているとは限りません。私はそれぞれ3重チェックしました。今

calikocat-source/CMakeLists.txt(スニペット)

include_directories(include) 

# Include headers of dependencies. 
include_directories(${PAWLIB_DIR}/include) 

add_library(${TARGET_NAME} STATIC 
    include/calikocat/dummy.hpp 
    src/dummy.cpp 
) 

# Link against dependencies. 
target_link_libraries(${TARGET_NAME} ${PAWLIB_DIR}/lib/libpawlib.a) 

、私は自分のライブラリとテスターアプリケーションを含む好きで、これは例外ではありません。レポでは、ライブラリとテスターコードをcalikocat-sourcecalikocat-testerのディレクトリに分けます。私は...だけでなく、テスターのためにCMakeを使用

calikocat-tester/CMakeLists.txt(スニペット)

include_directories(include) 

# Include headers of dependencies. 
include_directories(${PAWLIB_DIR}/include) 
include_directories(../calikocat-source/include) 

add_executable(calikocat-tester 
    main.cpp 
) 

# Link against dependencies. 
target_link_libraries(${TARGET_NAME} ${CPGF_DIR}/lib/libcpgf.a) 
target_link_libraries(${TARGET_NAME} ${PAWLIB_DIR}/lib/libpawlib.a) 
target_link_libraries(${TARGET_NAME} ${CMAKE_HOME_DIRECTORY}/../calikocat-source/lib/$<CONFIG>/libcalikocat.a) 

これは正しく構築さmain.cpp上の単一のラインの存在に完全に依存するかどうか!以下を注意深くお読みください。

calikocat-tester/main.cpp、WORKING VERSION

#include <calikocat/dummy.hpp> 
#include <pawlib/iochannel.hpp> 

int main() 
{ 
    pawlib::ioc << "Hello, world!" << pawlib::io_end; 
    Dummy::speak(); 

    return 0; 
} 

のコンパイルと、このバージョンを実行すると、二回の端末にアウトHello, world!を印刷し、期待通りに動作します。

calikocat-tester/main.cpp、NON-WORKING VERSION

#include <calikocat/dummy.hpp> 
#include <pawlib/iochannel.hpp> 

int main() 
{ 
    //pawlib::ioc << "Hello, world!" << pawlib::io_end; 
    Dummy::speak(); 

    return 0; 
} 

私が直接PawLIBを使用して行をコメントアウトしたファイル、このバージョンの、コンパイルされません。ここでエラーが、私はそれをコンパイルし、実行したときに、一度だけ端末にHello, world!をプリントアウトするを期待してい...

[100%] Linking CXX executable ../../bin/Debug/calikocat-tester 
../../../calikocat-source/lib/Debug/libcalikocat.a(dummy.cpp.o): In function `Dummy::speak()': 
/home/jason/Code/Repositories/calikocat/calikocat-source/src/dummy.cpp:4: undefined reference to `pawlib::ioc' 
/home/jason/Code/Repositories/calikocat/calikocat-source/src/dummy.cpp:5: undefined reference to `pawlib::iochannel::operator<<(pawlib::ioformat::IOControl const&)' 
../../../calikocat-source/lib/Debug/libcalikocat.a(dummy.cpp.o): In function `pawlib::iochannel::operator<<(char const*)': 
/home/jason/Code/Repositories/calikocat/calikocat-source/../../pawlib/pawlib/include/pawlib/iochannel.hpp:521: undefined reference to `pawlib::iochannel::resolve_pointer(char const*)' 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 
CMakeFiles/calikocat-tester.dir/build.make:99: recipe for target '../../bin/Debug/calikocat-tester' failed 

です。

ここでは何が起こっていますか、私は何が欠けていますか?

答えて

1

あなたはこの2行を逆に試してみてください:

target_link_libraries(${TARGET_NAME} ${PAWLIB_DIR}/lib/libpawlib.a) 
target_link_libraries(${TARGET_NAME} ${CMAKE_HOME_DIRECTORY}/../calikocat-source/lib/$<CONFIG>/libcalikocat.a) 

をlibcalikocat.aがlibpawlib.aからシンボルを使用しているので、コマンドラインの最初に表示されます。

+0

感謝のように働いた、ありがとう。つまり、 'D 'が' C '、' B 'の' C '、' A 'の' B 'に依存している場合、' D 'は' C B A'の順にリンクする必要があります。それだけで十分です。 – CodeMouse92

関連する問題