嵌套的静态链接库和一个怪异的Bug

时间:2017-02-19 03:19:34

标签: c++ cmake c++14 static-linking clang++

(平台:C ++ 14,Clang 3.8,Ubuntu 16.04,CMake 3.5.1)

我有两个静态库(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文件中的所有变量都经过仔细测试和运行。我对每个人进行了三次检查。

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)

现在,我喜欢将测试器应用程序包含在我的库中,这也不例外。在repo中,我将库和测试器代码分成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!打印到终端一次。

这里发生了什么,我错过了什么?

1 个答案:

答案 0 :(得分:1)

你应该尝试颠倒这两行:

<script>
  window.sessionStorage.redirect = window.location.href;
</script>

因为libcalikocat.a正在使用libpawlib.a中的符号,所以它应首先出现在命令行中。