嵌套静态链接库和鬼错误

问题描述:

(平台:C++ 14,锵3.8的,Ubuntu 16.04,CMake的3.5.1)嵌套静态链接库和鬼错误

我有两个静态库(PawLIB,CalikoCat),以及依赖可执行在其他图书馆。在CalkoCat是一个类,假人。 (我只是确保一切环节我们开始对这个库严重的发展权前)。

伪类目前依赖的函数从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文件中的所有变量都经过精心测试和工作。我已经三次检查每个。

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,工作版本

#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,非工作版本

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

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

    return 0; 
} 

此版本的文件,在那里我注释掉直接使用PawLIB行的,不编译。这里的错误...

[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 

期待它来编译和运行的时候,就打印出Hello, world!到终端一次。

这到底是怎么回事,我缺少什么?

你应该尝试扭转这两行:因为libcalikocat.a使用来自libpawlib.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) 

,它应该首先出现在命令行上。

+0

工作就像一个魅力,谢谢。换句话说,如果'D'依靠'C','B''和'B''',则'D'应该按照'C B A'的顺序链接。这很简单。 – CodeMouse92