(Платформа: C++ 14, Clang 3.8, Ubuntu 16.04, CMake 3.5.1)Уплотненный Static Linked Библиотеки и Spooky Bug
У меня есть два статических библиотек (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)
Теперь, мне нравится, включая тестер приложений с моими библиотеками, и это не является исключением. В репо я разделяю код библиотеки и тестера на calikocat-source
и calikocat-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!
на терминал один раз.
Что здесь происходит, а что мне не хватает?
Работал как очарование, спасибо. Иными словами, если 'D' полагается на' C', 'C' на' B' и 'B' на' A', тогда 'D' должен ссылаться в порядке' C B A'. Это достаточно легко. – CodeMouse92