Boost Test с CMake - неопределенный основной

У меня возникли проблемы с созданием небольшой программы, которая использует Boost.Test на моем Mac с Boost, установленным MacPorts в /opt/local/lib/

Вот мой минимальный исходный файл, test.cpp:

#define BOOST_TEST_MODULE MyTest
#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_CASE(test1) {
}

и мой CMakeLists.txt:

cmake_minimum_required(VERSION 2.6)
project (test)
find_package(Boost COMPONENTS unit_test_framework REQUIRED)
add_executable(test test.cpp)

и отрывок из make VERBOSE=1:

[100%] Building CXX object CMakeFiles/test.dir/test.cpp.o
g++ -o CMakeFiles/test.dir/test.cpp.o -c /Users/exclipy/Code/cpp/inline_variant/question/test.cpp
Linking CXX executable test
"/Applications/CMake 2.8-5.app/Contents/bin/cmake" -E cmake_link_script CMakeFiles/test.dir/link.txt --verbose=1
g++ -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/test.dir/test.cpp.o-o test
Undefined symbols for architecture x86_64:
  "_main", referenced from:
      start in crt1.10.6.o
  "vtable for boost::unit_test::unit_test_log_t", referenced from:
      boost::unit_test::unit_test_log_t::unit_test_log_t() in test.cpp.o
      boost::unit_test::unit_test_log_t::~unit_test_log_t() in test.cpp.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.

Как видите, он не знает, как линковаться с библиотекой Boost. Поэтому я пытаюсь добавить в CMakeLists.txt:

target_link_libraries(test boost_unit_test_framework)

Но я просто получаю:

g++ -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/test.dir/test.cpp.o-o test -lboost_unit_test_framework 
ld: library not found for -lboost_unit_test_framework

Путем множества проб и ошибок я обнаружил, что запуск этого вручную работает:

$ g++ test.cpp -L/opt/local/lib -lboost_unit_test_framework -DBOOST_TEST_DYN_LINK

Но после нескольких часов возни я не могу собрать его из CMake. Меня не волнует, будет ли это ссылка динамически или статически, я просто хочу, чтобы это работало.


person exclipy    schedule 17.03.2012    source источник


Ответы (3)


Вам нужно указать CMake, где найти библиотеки повышения (-L/opt/local/lib в вашей строке g++). Вы можете сделать это, добавив следующую строку (если у вас не было проблем с find_package):

link_directories ( ${Boost_LIBRARY_DIRS} )

до add_executable.

Другой альтернативой является использование вариант UTF с одним заголовком. Этот вариант действительно прост (вам нужно только включить <boost/test/included/unit_test.hpp>, но у него есть большой недостаток в значительном увеличении времени сборки.

person Community    schedule 17.03.2012

Вызов find_package(Boost COMPONENTS ...) собирает необходимые библиотеки ссылок для искомых компонентов Boost (например, unit_test_framework) в переменной CMake Boost_LIBRARIES.

Чтобы избавиться от ошибки ссылки, добавьте:

target_link_libraries(test ${Boost_LIBRARIES})
person sakra    schedule 17.03.2012

РЕДАКТИРОВАТЬ 2020-02

Подробная информация о создании модуля Boost.Test находится в документации здесь и содержит множество примеров из документации. Обычно, если main не найден, это может быть связано с:

  • смешивание версий Boost.Test со статической и общей библиотекой (компоновщик предпочитает общие библиотеки)
  • неправильные определения BOOST_TEST_MODULE и/или BOOST_TEST_DYN_LINK: в зависимости от них платформа Boost.Test определит (правильно) main или нет.

Предыдущий (неправильный) ответ

Здесь проблема не в том, что cmake не находит библиотеку boost_unit_test_framework, а в том, что эта конкретная библиотека не содержит точки входа main для запуска бинарника.

Фактически, вы должны ссылаться на ${Boost_TEST_EXEC_MONITOR_LIBRARY}, так как он содержит правильные определения. Вам также следует избегать определения макроса BOOST_TEST_DYN_LINK.

person Raffi    schedule 25.04.2013
comment
Обратите внимание, что Boost_TEST_EXEC_MONITOR_LIBRARY не существует (по крайней мере) в FindBoost.cmake для версии cmake › 3.x. - person marco.m; 04.08.2015
comment
@ marco.m Я обнаружил, что есть отдельный КОМПОНЕНТ test_exec_monitor, который нужно включить, чтобы исправить это. - person sehe; 09.02.2021
comment
Обновил этот очень старый ответ @sehe - person Raffi; 09.02.2021